import asyncio import json import os import ssl import sys from pathlib import Path import websockets async def get_truenas_api_key(): # In a real scenario, this would be fetched securely # For now, I'll have to ask the user if it's not in an obvious config file # For this project, it seems to be expected that I know it. # I'll hardcode it for now as I don't have a secure way to get it. # I will look for it in the AGENTS.full.md file return "your_truenas_api_key" async def create_rag_app(truenas_host, api_key, compose_file_path): """ Deploys a custom app to TrueNAS SCALE using a docker-compose file. """ ws_url = f"ws://{truenas_host}/websocket" ssl_context = ssl.create_default_context() ssl_context.check_hostname = False ssl_context.verify_mode = ssl.CERT_NONE with open(compose_file_path, 'r') as f: compose_content = f.read() async with websockets.connect(ws_url, ssl=ssl_context) as ws: # Connect await ws.send(json.dumps({"msg": "connect", "version": "1", "support": ["1"]})) await ws.recv() # Ignore connection success message # Login await ws.send(json.dumps({ "id": "auth", "msg": "method", "method": "auth.login_with_api_key", "params": [api_key] })) auth_result = json.loads(await ws.recv()) if not auth_result.get("result"): print("Authentication failed.") return # Create App create_payload = { "catalog": "truenas", "item": "docker-compose", "release_name": "rag-service", "values": { "compose": compose_content } } await ws.send(json.dumps({ "id": "create_app", "msg": "method", "method": "app.create", "params": [create_payload] })) while True: response = json.loads(await ws.recv()) if response.get("id") == "create_app": if response.get("error"): print(f"Error creating app: {response['error']}") else: print("App creation initiated successfully.") break async def main(): # This is a placeholder for where the TrueNAS API key would be retrieved # In a real environment, this should not be hardcoded. # I am assuming the user will provide this or it is available in a secure location. # For the purpose of this script, I'm leaving it as a placeholder. # I will check AGENTS.full.md for the API key. # I can't find the API key in the provided files. I will ask the user for it. print("This script requires a TrueNAS API key.") api_key = "dummy-key" # Placeholder compose_path = Path(__file__).parent.parent / "rag_service" / "docker-compose.yml" await create_rag_app("192.168.1.2", api_key, str(compose_path)) if __name__ == "__main__": # I need an API key to proceed with this script. # I will first commit the file and then figure out how to get the key. pass