@@ -76,64 +76,9 @@ def check_and_install_docker():
7676 if docker_exists and compose_exists :
7777 return True
7878
79- if docker_exists and not compose_exists :
80- click .secho ("🔥 Docker Compose (plugin) not found." , fg = "yellow" )
81- # Try to install docker compose via local package manager
82- distro = None
83- distro_like = None
84- try :
85- with open ("/etc/os-release" ) as f :
86- for line in f :
87- if line .startswith ("ID=" ):
88- distro = line .strip ().split ("=" )[1 ].strip ('"' )
89- elif line .startswith ("ID_LIKE=" ):
90- distro_like = line .strip ().split ("=" )[1 ].strip ('"' )
91- except Exception :
92- pass
93- installed = False
94- if distro in ["ubuntu" , "debian" ]:
95- click .echo ("Attempting to install docker-compose-plugin via apt..." )
96- try :
97- subprocess .run (["sudo" , "apt-get" , "update" ], check = True )
98- subprocess .run (["sudo" , "apt-get" , "install" , "-y" , "docker-compose-plugin" ], check = True )
99- # Re-check if compose is now available
100- result = subprocess .run (["docker" , "compose" , "version" ], stdout = subprocess .PIPE , stderr = subprocess .PIPE )
101- if result .returncode == 0 :
102- click .secho ("✅ Docker Compose plugin installed successfully." , fg = "green" )
103- return True
104- else :
105- click .secho ("❌ Docker Compose plugin installation failed." , fg = "red" )
106- except Exception as e :
107- click .secho (f"❌ Failed to install docker-compose-plugin: { e } " , fg = "red" )
108- elif distro in ["fedora" , "centos" , "rhel" , "amzn" ] or (distro_like and "fedora" in distro_like ):
109- click .echo ("Attempting to install docker-compose-plugin via dnf..." )
110- try :
111- subprocess .run (["sudo" , "dnf" , "install" , "-y" , "docker-compose-plugin" ], check = True )
112- result = subprocess .run (["docker" , "compose" , "version" ], stdout = subprocess .PIPE , stderr = subprocess .PIPE )
113- if result .returncode == 0 :
114- click .secho ("✅ Docker Compose plugin installed successfully." , fg = "green" )
115- return True
116- else :
117- click .secho ("❌ Docker Compose plugin installation failed." , fg = "red" )
118- except Exception as e :
119- click .secho (f"❌ Failed to install docker-compose-plugin: { e } " , fg = "red" )
120- elif distro in ["arch" , "manjaro" ]:
121- click .echo ("Attempting to install docker-compose via pacman..." )
122- try :
123- subprocess .run (["sudo" , "pacman" , "-Sy" , "docker-compose" ], check = True )
124- result = subprocess .run (["docker" , "compose" , "version" ], stdout = subprocess .PIPE , stderr = subprocess .PIPE )
125- if result .returncode == 0 :
126- click .secho ("✅ Docker Compose installed successfully." , fg = "green" )
127- return True
128- else :
129- click .secho ("❌ Docker Compose installation failed." , fg = "red" )
130- except Exception as e :
131- click .secho (f"❌ Failed to install docker-compose: { e } " , fg = "red" )
132- # If not installed, fallback to official script
133- click .secho ("Could not install Docker Compose plugin via package manager." , fg = "yellow" )
134-
135- click .secho ("🔥 Docker or Docker Compose not found." , fg = "yellow" )
136- if click .confirm ("May I attempt to install them using the official script? (Requires sudo)" ):
79+ # Offer to install via official Docker script
80+ click .secho ("🔥 Docker or Docker Compose not found." , fg = "red" )
81+ if click .confirm ("May I attempt to install Docker using the official script? (Requires sudo)" ):
13782 try :
13883 click .echo ("Downloading Docker installation script..." )
13984 script_path = "/tmp/get-docker.sh"
@@ -148,21 +93,29 @@ def check_and_install_docker():
14893 click .echo ("Adding current user to the 'docker' group..." )
14994 subprocess .run (["sudo" , "usermod" , "-aG" , "docker" , os .getlogin ()], check = True )
15095 click .secho ("Please log out and log back in for the group changes to take effect." , fg = "yellow" )
151- return True
96+ # Re-check for docker and compose
97+ docker_exists = shutil .which ("docker" ) is not None
98+ try :
99+ result = subprocess .run (["docker" , "compose" , "version" ], stdout = subprocess .PIPE , stderr = subprocess .PIPE )
100+ compose_exists = result .returncode == 0
101+ except Exception :
102+ compose_exists = False
103+ if docker_exists and compose_exists :
104+ return True
152105 except (subprocess .CalledProcessError , FileNotFoundError ) as e :
153106 click .secho (f"❌ Docker installation failed: { e } " , fg = "red" )
154- return False
155- else :
156- click .echo ("Installation cancelled." )
157- return False
158107
159- def get_platform_config (accelerator : str ) -> Dict [str , Any ]:
108+ click .secho ("Please install both Docker and Docker Compose (plugin) manually using your package manager or official instructions, then try again." , fg = "yellow" )
109+ click .secho ("See: https://docs.docker.com/engine/install/ and https://docs.docker.com/compose/install/" , fg = "yellow" )
110+ return False
111+
112+ def get_platform_config (accelerator : str , gptoss : bool ) -> Dict [str , Any ]:
160113 """Returns the docker image and other config for a given platform."""
161114 # In the future, these images would be hosted on a public registry.
162115 # For now, they are conceptual names.
163116 if accelerator == "cuda" :
164117 return {
165- "image" : "ghcr.io/wsmlby/homl/server:latest-cuda" ,
118+ "image" : "ghcr.io/wsmlby/homl/server:latest-cuda" if not gptoss else "ghcr.io/wsmlby/homl/server:latest-cuda-gptoss" ,
166119 "deploy_resources" : """
167120 resources:
168121 reservations:
@@ -252,7 +205,8 @@ def detect_platform() -> Dict[str, str]:
252205@server .command ()
253206@click .option ('--insecure-socket' , is_flag = True , help = "Use a world-writable socket (less secure)." )
254207@click .option ('--upgrade' , is_flag = True , help = "Force reinstallation even if the server is already running." )
255- def install (insecure_socket : bool , upgrade : bool ):
208+ @click .option ('--gptoss' , is_flag = True , help = "Use the GPTOSS image instead of the default." )
209+ def install (insecure_socket : bool , upgrade : bool , gptoss : bool ):
256210 """Installs and starts the HoML server using Docker Compose."""
257211 click .echo ("🚀 Starting HoML server installation..." )
258212
@@ -266,7 +220,7 @@ def install(insecure_socket: bool, upgrade: bool):
266220 click .echo (f"Detected Platform: { platform .get ('accelerator' , 'cpu' )} " )
267221
268222 accelerator = platform .get ("accelerator" , "cpu" )
269- platform_config = get_platform_config (accelerator )
223+ platform_config = get_platform_config (accelerator , gptoss )
270224
271225 # 3. Check for platform-specific dependencies
272226 if accelerator == "cuda" :
@@ -445,6 +399,16 @@ def stop(model_name):
445399def pull (model_name ):
446400 """Pulls a model from a registry."""
447401 stub = get_client_stub ()
402+ if "gptoss" in model_name .lower ():
403+ # check if running container homl-homl-server-1 is the GPTOSS image, if not, ask the user to use the gptoss flag and reinstall
404+ subprocess .run (["docker" , "ps" , "-f" , "name=homl-homl-server-1" , "--format" , "{{.Image}}" ], check = True , capture_output = True )
405+ image_name = subprocess .run (["docker" , "ps" , "-f" , "name=homl-homl-server-1" , "--format" , "{{.Image}}" ], check = True , capture_output = True , text = True ).stdout .strip ()
406+ if "gptoss" not in image_name .lower ():
407+ click .secho ("You are trying to pull a GPTOSS model, but the server is not running with the GPTOSS image." , fg = "red" )
408+ click .secho ("Please use the --gptoss flag when to reinstall the server with 'homl server install --gptoss'." , fg = "yellow" )
409+ click .secho ("GPTOSS support is experimental, if you encounter issues, you can revert by reinstall using 'homl server install'." , fg = "yellow" )
410+ return
411+
448412 # get the Hugging Face token from config
449413 hf_token = config .get_config_value ("hugging_face_token" , "" )
450414 if stub :
0 commit comments