From 2964cca3ed5ee6441cbf8d335c563c15e9996a32 Mon Sep 17 00:00:00 2001 From: Adil Hafeez Date: Mon, 25 Nov 2024 18:54:45 -0800 Subject: [PATCH] remove dependency on docker-compose when starting up archgw --- arch/docker-compose.yaml | 24 ------- arch/tools/build_cli.sh | 19 ------ arch/tools/cli/consts.py | 2 + arch/tools/cli/core.py | 132 +++++++++++++++----------------------- arch/tools/poetry.lock | 51 ++++++++++++++- arch/tools/pyproject.toml | 7 +- 6 files changed, 103 insertions(+), 132 deletions(-) delete mode 100644 arch/docker-compose.yaml diff --git a/arch/docker-compose.yaml b/arch/docker-compose.yaml deleted file mode 100644 index 51874ead..00000000 --- a/arch/docker-compose.yaml +++ /dev/null @@ -1,24 +0,0 @@ -services: - archgw: - image: katanemo/archgw:latest - ports: - - "10000:10000" - - "10001:10001" - - "11000:11000" - - "12000:12000" - - "19901:9901" - volumes: - - ${ARCH_CONFIG_FILE:-../demos/weather_forecast/arch_config.yaml}:/app/arch_config.yaml - - /etc/ssl/cert.pem:/etc/ssl/cert.pem - - ~/archgw_logs:/var/log/ - env_file: - - env.list - environment: - - OTEL_TRACING_HTTP_ENDPOINT=http://host.docker.internal:4318/v1/traces - extra_hosts: - - "host.docker.internal:host-gateway" - healthcheck: - test: ["CMD", "curl", "-f", "http://localhost:10000/healthz"] - interval: 30s - timeout: 10s - retries: 3 diff --git a/arch/tools/build_cli.sh b/arch/tools/build_cli.sh index cad766f7..48088b82 100644 --- a/arch/tools/build_cli.sh +++ b/arch/tools/build_cli.sh @@ -1,23 +1,4 @@ #!/bin/bash -# Define paths -source_schema="../arch_config_schema.yaml" -source_compose="../docker-compose.yaml" -destination_dir="config" - -# Ensure the destination directory exists only if it doesn't already -if [ ! -d "$destination_dir" ]; then - mkdir -p "$destination_dir" - echo "Directory $destination_dir created." -fi - -# Copy the files -cp "$source_schema" "$destination_dir/arch_config_schema.yaml" -cp "$source_compose" "$destination_dir/docker-compose.yaml" -touch "$destination_dir/env.list" - -# Print success message -echo "Files copied successfully!" - echo "Building the cli" poetry install diff --git a/arch/tools/cli/consts.py b/arch/tools/cli/consts.py index 86ead07f..598bc29c 100644 --- a/arch/tools/cli/consts.py +++ b/arch/tools/cli/consts.py @@ -9,3 +9,5 @@ SERVICE_NAME_MODEL_SERVER = "model_server" SERVICE_ALL = "all" MODEL_SERVER_LOG_FILE = "~/archgw_logs/modelserver.log" ACCESS_LOG_FILES = "~/archgw_logs/access*" +ARCHGW_DOCKER_NAME = "archgw" +ARCHGW_DOCKER_IMAGE = "katanemo/archgw:latest" diff --git a/arch/tools/cli/core.py b/arch/tools/cli/core.py index f2dc0249..17375cca 100644 --- a/arch/tools/cli/core.py +++ b/arch/tools/cli/core.py @@ -5,9 +5,12 @@ import pkg_resources import select import sys import glob +import docker from cli.utils import run_docker_compose_ps, print_service_status, check_services_state from cli.utils import getLogger from cli.consts import ( + ARCHGW_DOCKER_IMAGE, + ARCHGW_DOCKER_NAME, KATANEMO_LOCAL_MODEL_LIST, MODEL_SERVER_LOG_FILE, ACCESS_LOG_FILES, @@ -27,7 +30,7 @@ def stream_gateway_logs(follow): log.info("Logs from arch gateway service.") - options = ["docker", "compose", "-p", "arch", "logs"] + options = ["docker", "logs", "archgw"] if follow: options.append("-f") try: @@ -88,42 +91,49 @@ def start_arch(arch_config_file, env, log_timeout=120): Start Docker Compose in detached mode and stream logs until services are healthy. Args: - path (str): The path where the prompt_confi.yml file is located. + path (str): The path where the prompt_config.yml file is located. log_timeout (int): Time in seconds to show logs before checking for healthy state. """ log.info("Starting arch gateway") - compose_file = pkg_resources.resource_filename( - __name__, "../config/docker-compose.yaml" - ) try: - # Run the Docker Compose command in detached mode (-d) - subprocess.run( - [ - "docker", - "compose", - "-p", - "arch", - "up", - "-d", - ], - cwd=os.path.dirname( - compose_file - ), # Ensure the Docker command runs in the correct path - env=env, # Pass the modified environment - check=True, # Raise an exception if the command fails - stderr=subprocess.PIPE, - stdout=subprocess.PIPE, + client = docker.from_env() + + container = client.containers.run( + name=ARCHGW_DOCKER_NAME, + image=ARCHGW_DOCKER_IMAGE, + detach=True, # Run in detached mode + ports={ + "10000/tcp": 10000, + "10001/tcp": 10001, + "11000/tcp": 11000, + "12000/tcp": 12000, + "19901/tcp": 19901, + }, + volumes={ + f"{arch_config_file}": { + "bind": "/app/arch_config.yaml", + "mode": "ro", + }, + "/etc/ssl/cert.pem": {"bind": "/etc/ssl/cert.pem", "mode": "ro"}, + "archgw_logs": {"bind": "/var/log"}, + }, + environment={ + "OTEL_TRACING_HTTP_ENDPOINT": "http://host.docker.internal:4318/v1/traces" + }, + extra_hosts={"host.docker.internal": "host-gateway"}, + healthcheck={ + "test": ["CMD", "curl", "-f", "http://localhost:10000/healthz"], + "interval": 5000000000, # 5 seconds + "timeout": 1000000000, # 1 seconds + "retries": 3, + }, ) - log.info(f"Arch docker-compose started in detached.") start_time = time.time() - services_status = {} - services_running = ( - False # assume that the services are not running at the moment - ) while True: + container = client.containers.get(container.id) current_time = time.time() elapsed_time = current_time - start_time @@ -132,53 +142,16 @@ def start_arch(arch_config_file, env, log_timeout=120): log.info(f"Stopping log monitoring after {log_timeout} seconds.") break - current_services_status = run_docker_compose_ps( - compose_file=compose_file, env=env - ) - if not current_services_status: - log.info( - "Status for the services could not be detected. Something went wrong. Please run docker logs" - ) + container_status = container.attrs["State"]["Health"]["Status"] + + if container_status == "healthy": + log.info("Container is healthy!") break + else: + log.info(f"Container health status: {container_status}") + time.sleep(1) - if not services_status: - services_status = current_services_status # set the first time - print_service_status( - services_status - ) # print the services status and proceed. - - # check if anyone service is failed or exited state, if so print and break out - unhealthy_states = ["unhealthy", "exit", "exited", "dead", "bad"] - running_states = ["running", "up"] - - if check_services_state(current_services_status, running_states): - log.info("Arch gateway is up and running!") - break - - if check_services_state(current_services_status, unhealthy_states): - log.info( - "One or more Arch services are unhealthy. Please run `docker logs` for more information" - ) - print_service_status( - current_services_status - ) # print the services status and proceed. - break - - # check to see if the status of one of the services has changed from prior. Print and loop over until finish, or error - for service_name in services_status.keys(): - if ( - services_status[service_name]["State"] - != current_services_status[service_name]["State"] - ): - log.info( - "One or more Arch services have changed state. Printing current state" - ) - print_service_status(current_services_status) - break - - services_status = current_services_status - - except subprocess.CalledProcessError as e: + except docker.errors.APIError as e: log.info(f"Failed to start Arch: {str(e)}") @@ -189,21 +162,16 @@ def stop_arch(): Args: path (str): The path where the docker-compose.yml file is located. """ - compose_file = pkg_resources.resource_filename( - __name__, "../config/docker-compose.yaml" - ) - log.info("Shutting down arch gateway service.") try: - # Run `docker-compose down` to shut down all services subprocess.run( - ["docker", "compose", "-p", "arch", "down"], - cwd=os.path.dirname(compose_file), - check=True, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, + ["docker", "stop", "archgw"], ) + subprocess.run( + ["docker", "remove", "archgw"], + ) + log.info("Successfully shut down arch gateway service.") except subprocess.CalledProcessError as e: diff --git a/arch/tools/poetry.lock b/arch/tools/poetry.lock index e5dc0c81..e46249fd 100644 --- a/arch/tools/poetry.lock +++ b/arch/tools/poetry.lock @@ -193,6 +193,28 @@ files = [ {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, ] +[[package]] +name = "docker" +version = "7.1.0" +description = "A Python library for the Docker Engine API." +optional = false +python-versions = ">=3.8" +files = [ + {file = "docker-7.1.0-py3-none-any.whl", hash = "sha256:c96b93b7f0a746f9e77d325bcfb87422a3d8bd4f03136ae8a85b37f1898d5fc0"}, + {file = "docker-7.1.0.tar.gz", hash = "sha256:ad8c70e6e3f8926cb8a92619b832b4ea5299e2831c14284663184e200546fa6c"}, +] + +[package.dependencies] +pywin32 = {version = ">=304", markers = "sys_platform == \"win32\""} +requests = ">=2.26.0" +urllib3 = ">=1.26.0" + +[package.extras] +dev = ["coverage (==7.2.7)", "pytest (==7.4.2)", "pytest-cov (==4.1.0)", "pytest-timeout (==2.1.0)", "ruff (==0.1.8)"] +docs = ["myst-parser (==0.18.0)", "sphinx (==5.1.1)"] +ssh = ["paramiko (>=2.4.3)"] +websockets = ["websocket-client (>=1.3.0)"] + [[package]] name = "filelock" version = "3.16.1" @@ -561,6 +583,33 @@ files = [ [package.dependencies] typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" +[[package]] +name = "pywin32" +version = "308" +description = "Python for Window Extensions" +optional = false +python-versions = "*" +files = [ + {file = "pywin32-308-cp310-cp310-win32.whl", hash = "sha256:796ff4426437896550d2981b9c2ac0ffd75238ad9ea2d3bfa67a1abd546d262e"}, + {file = "pywin32-308-cp310-cp310-win_amd64.whl", hash = "sha256:4fc888c59b3c0bef905ce7eb7e2106a07712015ea1c8234b703a088d46110e8e"}, + {file = "pywin32-308-cp310-cp310-win_arm64.whl", hash = "sha256:a5ab5381813b40f264fa3495b98af850098f814a25a63589a8e9eb12560f450c"}, + {file = "pywin32-308-cp311-cp311-win32.whl", hash = "sha256:5d8c8015b24a7d6855b1550d8e660d8daa09983c80e5daf89a273e5c6fb5095a"}, + {file = "pywin32-308-cp311-cp311-win_amd64.whl", hash = "sha256:575621b90f0dc2695fec346b2d6302faebd4f0f45c05ea29404cefe35d89442b"}, + {file = "pywin32-308-cp311-cp311-win_arm64.whl", hash = "sha256:100a5442b7332070983c4cd03f2e906a5648a5104b8a7f50175f7906efd16bb6"}, + {file = "pywin32-308-cp312-cp312-win32.whl", hash = "sha256:587f3e19696f4bf96fde9d8a57cec74a57021ad5f204c9e627e15c33ff568897"}, + {file = "pywin32-308-cp312-cp312-win_amd64.whl", hash = "sha256:00b3e11ef09ede56c6a43c71f2d31857cf7c54b0ab6e78ac659497abd2834f47"}, + {file = "pywin32-308-cp312-cp312-win_arm64.whl", hash = "sha256:9b4de86c8d909aed15b7011182c8cab38c8850de36e6afb1f0db22b8959e3091"}, + {file = "pywin32-308-cp313-cp313-win32.whl", hash = "sha256:1c44539a37a5b7b21d02ab34e6a4d314e0788f1690d65b48e9b0b89f31abbbed"}, + {file = "pywin32-308-cp313-cp313-win_amd64.whl", hash = "sha256:fd380990e792eaf6827fcb7e187b2b4b1cede0585e3d0c9e84201ec27b9905e4"}, + {file = "pywin32-308-cp313-cp313-win_arm64.whl", hash = "sha256:ef313c46d4c18dfb82a2431e3051ac8f112ccee1a34f29c263c583c568db63cd"}, + {file = "pywin32-308-cp37-cp37m-win32.whl", hash = "sha256:1f696ab352a2ddd63bd07430080dd598e6369152ea13a25ebcdd2f503a38f1ff"}, + {file = "pywin32-308-cp37-cp37m-win_amd64.whl", hash = "sha256:13dcb914ed4347019fbec6697a01a0aec61019c1046c2b905410d197856326a6"}, + {file = "pywin32-308-cp38-cp38-win32.whl", hash = "sha256:5794e764ebcabf4ff08c555b31bd348c9025929371763b2183172ff4708152f0"}, + {file = "pywin32-308-cp38-cp38-win_amd64.whl", hash = "sha256:3b92622e29d651c6b783e368ba7d6722b1634b8e70bd376fd7610fe1992e19de"}, + {file = "pywin32-308-cp39-cp39-win32.whl", hash = "sha256:7873ca4dc60ab3287919881a7d4f88baee4a6e639aa6962de25a98ba6b193341"}, + {file = "pywin32-308-cp39-cp39-win_amd64.whl", hash = "sha256:71b3322d949b4cc20776436a9c9ba0eeedcbc9c650daa536df63f0ff111bb920"}, +] + [[package]] name = "pyyaml" version = "6.0.2" @@ -830,4 +879,4 @@ zstd = ["zstandard (>=0.18.0)"] [metadata] lock-version = "2.0" python-versions = ">=3.12" -content-hash = "9ab7bd30cd453587818b3ccfb4520a806686e77111ad533429129a833f741fb7" +content-hash = "7d2a1db6c7041a0f41f4cba52ddb7678167c71f4f0787be2eb69edb78b96130d" diff --git a/arch/tools/pyproject.toml b/arch/tools/pyproject.toml index a8378269..5c8029d4 100644 --- a/arch/tools/pyproject.toml +++ b/arch/tools/pyproject.toml @@ -8,12 +8,6 @@ packages = [ ] readme = "README.md" -include = [ -# Include package data (docker-compose.yaml and other files)[ - "config/docker-compose.yaml", - "config/arch_config_schema.yaml", -] - [tool.poetry.dependencies] python = ">=3.12" archgw_modelserver = "0.1.4" @@ -24,6 +18,7 @@ jinja2 = "^3.1.4" jsonschema = "^4.23.0" setuptools = "75.5.0" huggingface_hub = "^0.26.0" +docker = "^7.1.0" [tool.poetry.scripts] archgw = "cli.main:main"