From 4fb4ad336309e36987f027760811d90e07ff0f9e Mon Sep 17 00:00:00 2001 From: Joongi Kim Date: Tue, 7 Nov 2023 03:57:18 +0900 Subject: [PATCH] refactor: Make install steps clearer --- src/ai/backend/install/cli.py | 36 ++++++++---------- src/ai/backend/install/common.py | 2 + src/ai/backend/install/context.py | 63 ++++++++++++++++++++++++++++--- src/ai/backend/install/pkg.py | 2 + src/ai/backend/install/utils.py | 7 ++++ 5 files changed, 84 insertions(+), 26 deletions(-) create mode 100644 src/ai/backend/install/pkg.py diff --git a/src/ai/backend/install/cli.py b/src/ai/backend/install/cli.py index 0383eed546..46d25e3a81 100644 --- a/src/ai/backend/install/cli.py +++ b/src/ai/backend/install/cli.py @@ -24,10 +24,7 @@ from ai.backend.plugin.entrypoint import find_build_root from . import __version__ -from .common import detect_os -from .context import Context, current_app, current_log -from .dev import bootstrap_pants, install_editable_webui, install_git_hooks, install_git_lfs -from .docker import check_docker, get_preferred_pants_local_exec_root +from .context import DevContext, PackageContext, current_app, current_log from .types import InstallModes top_tasks: WeakSet[asyncio.Task] = WeakSet() @@ -48,23 +45,18 @@ async def begin_install(self) -> None: async def install(self) -> None: _log: RichLog = cast(RichLog, self.query_one(".log")) _log_token = current_log.set(_log) + ctx = DevContext() try: # prerequisites - await detect_os() - await install_git_lfs() - await install_git_hooks() - await check_docker() - local_execution_root_dir = await get_preferred_pants_local_exec_root() - await bootstrap_pants(local_execution_root_dir) + await ctx.check_prerequisites() # install - await install_editable_webui() - # TODO: install agent-watcher - # TODO: install storage-agent - # TODO: install storage-watcher - ctx = Context() await ctx.install_halfstack(ha_setup=False) + await ctx.install() # configure - # TODO: ... + await ctx.configure() + await ctx.load_fixtures() + # post-setup + await ctx.dump_etcd_config() except asyncio.CancelledError: _log.write(Text.from_markup("[red]Interrupted!")) await asyncio.sleep(1) @@ -87,16 +79,18 @@ async def begin_install(self) -> None: async def install(self) -> None: log: RichLog = cast(RichLog, self.query_one(".log")) + ctx = PackageContext() try: # prerequisites - await detect_os() - await check_docker() + await ctx.check_prerequisites() # install - # TODO: download packages - ctx = Context() await ctx.install_halfstack(ha_setup=False) + await ctx.install() # configure - # TODO: ... + await ctx.configure() + await ctx.load_fixtures() + # post-setup + await ctx.dump_etcd_config() except asyncio.CancelledError: log.write(Text.from_markup("[red]Interrupted!")) await asyncio.sleep(1) diff --git a/src/ai/backend/install/common.py b/src/ai/backend/install/common.py index d43834a8b3..9c1959e4f5 100644 --- a/src/ai/backend/install/common.py +++ b/src/ai/backend/install/common.py @@ -42,6 +42,8 @@ async def detect_cuda() -> None: async def check_docker_desktop_mount() -> None: + if current_os.get().distro != "Darwin": + return """ echo "validating Docker Desktop mount permissions..." docker pull alpine:3.8 > /dev/null diff --git a/src/ai/backend/install/context.py b/src/ai/backend/install/context.py index 8c25afc0c9..8b4a0dd49e 100644 --- a/src/ai/backend/install/context.py +++ b/src/ai/backend/install/context.py @@ -6,6 +6,9 @@ from textual.widgets import RichLog +from .common import check_docker_desktop_mount, detect_os +from .dev import bootstrap_pants, install_editable_webui, install_git_hooks, install_git_lfs +from .docker import check_docker, get_preferred_pants_local_exec_root from .types import OSInfo if TYPE_CHECKING: @@ -38,9 +41,6 @@ async def install_halfstack(self, ha_setup: bool) -> None: async def load_fixtures(self) -> None: pass - async def configure_services(self) -> None: - pass - async def configure_manager(self) -> None: pass @@ -59,8 +59,61 @@ async def configure_webui(self) -> None: async def dump_etcd_config(self) -> None: pass - async def populate_bundled_images(self) -> None: + async def populate_images(self) -> None: + pass + + +class DevContext(Context): + async def check_prerequisites(self) -> None: + await detect_os() + await install_git_lfs() + await install_git_hooks() + await check_docker() + await check_docker_desktop_mount() + local_execution_root_dir = await get_preferred_pants_local_exec_root() + await bootstrap_pants(local_execution_root_dir) + + async def install(self) -> None: + await install_editable_webui() + # TODO: install agent-watcher + # TODO: install storage-agent + # TODO: install storage-watcher + # TODO: install webserver + + async def configure(self) -> None: + await self.configure_manager() + await self.configure_agent() + await self.configure_storage_proxy() + await self.configure_webserver() + await self.configure_webui() + + async def populate_images(self) -> None: + # TODO: docker pull pass - async def pull_image(self) -> None: + +class PackageContext(Context): + async def check_prerequisites(self) -> None: + await detect_os() + await check_docker() + await check_docker_desktop_mount() + + async def install(self) -> None: + pass + # TODO: install agent-watcher + # TODO: install storage-agent + # TODO: install storage-watcher + # TODO: install webserver + # TODO: install static wsproxy + + async def configure(self) -> None: + await self.configure_manager() + await self.configure_agent() + await self.configure_storage_proxy() + await self.configure_webserver() + await self.configure_webui() + # TODO: install as systemd services? + + async def populate_images(self) -> None: + # TODO: docker load pass diff --git a/src/ai/backend/install/pkg.py b/src/ai/backend/install/pkg.py new file mode 100644 index 0000000000..b90089580c --- /dev/null +++ b/src/ai/backend/install/pkg.py @@ -0,0 +1,2 @@ +async def fetch_binaries() -> None: + pass diff --git a/src/ai/backend/install/utils.py b/src/ai/backend/install/utils.py index 18f3bfb406..d0f76885dc 100644 --- a/src/ai/backend/install/utils.py +++ b/src/ai/backend/install/utils.py @@ -27,3 +27,10 @@ async def request_unix( async with aiohttp.ClientSession(connector=connector) as s: async with s.request(method, url, **kwargs) as r: yield r + + +async def wget(url: str) -> None: + chunk_size = 16384 + async with request("GET", url) as r: + # TODO: implement + await r.content.read(chunk_size)