Skip to content

Commit

Permalink
fix: Community Installer running on macOS (#1716)
Browse files Browse the repository at this point in the history
  • Loading branch information
achimnol authored Nov 14, 2023
1 parent 715c2e4 commit 86ea9ec
Show file tree
Hide file tree
Showing 4 changed files with 185 additions and 87 deletions.
23 changes: 12 additions & 11 deletions src/ai/backend/install/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from pathlib import Path
from typing import TYPE_CHECKING

from rich.text import Text
from ai.backend.common.arch import arch_name_aliases

from .types import OSInfo, Platform

Expand All @@ -16,7 +16,7 @@

async def detect_os(ctx: Context) -> OSInfo:
platform_kernel = sys.platform
platform_arch = platform.machine()
platform_arch = arch_name_aliases.get(platform.machine(), platform.machine())
distro: str | None = None
uname_s_output = b""
try:
Expand All @@ -26,7 +26,7 @@ async def detect_os(ctx: Context) -> OSInfo:
stderr=asyncio.subprocess.DEVNULL,
)
assert p.stdout is not None
uname_s_output = await p.stdout.read()
uname_s_output = (await p.stdout.read()).strip()
await p.wait()
except OSError:
pass
Expand All @@ -38,17 +38,18 @@ async def detect_os(ctx: Context) -> OSInfo:
stderr=asyncio.subprocess.DEVNULL,
)
assert p.stdout is not None
lsb_release_output = await p.stdout.read()
lsb_release_output = (await p.stdout.read()).strip()
await p.wait()
except OSError:
pass
try:
issue_output = Path("/etc/issue").read_bytes()
issue_output = Path("/etc/issue").read_bytes().strip()
except IOError:
issue_output = b""
release_metadata = lsb_release_output + b"\n" + issue_output
if uname_s_output == "Darwin":
if uname_s_output == b"Darwin":
assert platform_kernel == "darwin"
platform_kernel = "macos"
distro = "Darwin"
elif (
Path("/etc/debian_version").exists()
Expand All @@ -70,14 +71,14 @@ async def detect_os(ctx: Context) -> OSInfo:
assert platform_kernel == "linux"
distro = "SUSE"
else:
raise RuntimeError("Unsupported host linux distribution")
os_info = OSInfo(
raise RuntimeError(
"Unsupported host linux distribution: "
f"{uname_s_output.decode()!r}, {release_metadata.decode()!r}"
)
return OSInfo(
platform=Platform(f"{platform_kernel}-{platform_arch}").value, # type: ignore
distro=distro,
)
ctx.log.write(Text.from_markup("Detected OS info: ", end=""))
ctx.log.write(os_info)
return os_info


async def detect_cuda(ctx: Context) -> None:
Expand Down
148 changes: 88 additions & 60 deletions src/ai/backend/install/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,12 @@
install_git_lfs,
pants_export,
)
from .docker import check_docker, check_docker_desktop_mount, get_preferred_pants_local_exec_root
from .docker import (
check_docker,
check_docker_desktop_mount,
determine_docker_sudo,
get_preferred_pants_local_exec_root,
)
from .http import wget
from .python import check_python
from .types import (
Expand All @@ -63,6 +68,7 @@ class PostGuide(enum.Enum):

class Context(metaclass=ABCMeta):
os_info: OSInfo
docker_sudo: list[str]

_post_guides: list[PostGuide]

Expand Down Expand Up @@ -90,7 +96,7 @@ def log_header(self, title: str) -> None:

def mangle_pkgname(self, name: str, fat: bool = False) -> str:
# local-proxy does not have fat variant. (It is always fat.)
if fat and name != "backendai-local-proxy":
if fat and name != "local-proxy":
return f"backendai-{name}-fat-{self.os_info.platform}"
return f"backendai-{name}-{self.os_info.platform}"

Expand Down Expand Up @@ -245,10 +251,11 @@ async def install_halfstack(self) -> None:
("8120:2379", f"{self.install_info.halfstack_config.etcd_addr[0].bind.port}:2379"),
],
)
sudo = " ".join(self.docker_sudo)
await self.run_shell(
"""
sudo docker compose up -d && \\
sudo docker compose ps
f"""
{sudo} docker compose up -d && \\
{sudo} docker compose ps
""",
cwd=self.install_info.base_path,
)
Expand Down Expand Up @@ -592,66 +599,75 @@ async def alias_image(self, alias: str, target_ref: str, arch: str) -> None:

async def populate_images(self) -> None:
data: Any
match self.dist_info.image_source:
case ImageSource.BACKENDAI_REGISTRY:
self.log_header("Scanning and pulling configured Backend.AI container images...")
if self.os_info.platform in (Platform.LINUX_ARM64, Platform.MACOS_ARM64):
project = "stable,community,multiarch"
else:
project = "stable,community"
data = {
"docker": {
"image": {
"auto_pull": "tag", # FIXME: temporary workaround for multiarch
},
"registry": {
"cr.backend.ai": {
"": "https://cr.backend.ai",
"type": "harbor2",
"project": project,
for image_source in self.dist_info.image_sources:
match image_source:
case ImageSource.BACKENDAI_REGISTRY:
self.log_header(
"Scanning and pulling configured Backend.AI container images..."
)
if self.os_info.platform in (Platform.LINUX_ARM64, Platform.MACOS_ARM64):
project = "stable,community,multiarch"
else:
project = "stable,community"
data = {
"docker": {
"image": {
"auto_pull": "tag", # FIXME: temporary workaround for multiarch
},
"registry": {
"cr.backend.ai": {
"": "https://cr.backend.ai",
"type": "harbor2",
"project": project,
},
},
},
},
}
await self.etcd_put_json("config", data)
await self.run_manager_cli(["mgr", "image", "rescan", "cr.backend.ai"])
if self.os_info.platform in (Platform.LINUX_ARM64, Platform.MACOS_ARM64):
await self.alias_image(
"python",
"cr.backend.ai/stable/python:3.9-ubuntu20.04",
"aarch64",
)
else:
await self.alias_image(
"python",
"cr.backend.ai/stable/python:3.9-ubuntu20.04",
"x86_64",
}
await self.etcd_put_json("config", data)
await self.run_manager_cli(["mgr", "image", "rescan", "cr.backend.ai"])
if self.os_info.platform in (Platform.LINUX_ARM64, Platform.MACOS_ARM64):
await self.alias_image(
"python",
"cr.backend.ai/stable/python:3.9-ubuntu20.04",
"aarch64",
)
else:
await self.alias_image(
"python",
"cr.backend.ai/stable/python:3.9-ubuntu20.04",
"x86_64",
)
case ImageSource.DOCKER_HUB:
self.log_header(
"Scanning and pulling configured Docker Hub container images..."
)
case ImageSource.DOCKER_HUB:
self.log_header("Scanning and pulling configured Docker Hub container images...")
data = {
"docker": {
"image": {
"auto_pull": "tag", # FIXME: temporary workaround for multiarch
},
"registry": {
"index.docker.io": {
"": "https://registry-1.docker.io",
"type": "docker",
"username": "lablup",
data = {
"docker": {
"image": {
"auto_pull": "tag", # FIXME: temporary workaround for multiarch
},
"registry": {
"index.docker.io": {
"": "https://registry-1.docker.io",
"type": "docker",
"username": "lablup",
},
},
},
},
}
await self.etcd_put_json("config", data)
for ref in self.dist_info.image_refs:
await self.run_manager_cli(["mgr", "image", "rescan", ref])
await self.run_exec(["sudo", "docker", "pull", ref])
case ImageSource.LOCAL_DIR:
self.log_header("Populating local container images...")
for src in self.dist_info.image_sources:
# TODO: Ensure src.ref
await self.run_exec(["sudo", "docker", "load", "-i", str(src.file)])
}
await self.etcd_put_json("config", data)
for ref in self.dist_info.image_refs:
await self.run_manager_cli(["mgr", "image", "rescan", ref])
await self.run_exec([*self.docker_sudo, "docker", "pull", ref])
case ImageSource.LOCAL_DIR:
self.log_header("Populating local container images...")
for src in self.dist_info.image_payloads:
# TODO: Ensure src.ref
await self.run_exec(
[*self.docker_sudo, "docker", "load", "-i", str(src.file)]
)
case ImageSource.LOCAL_REGISTRY:
raise NotImplementedError()


class DevContext(Context):
Expand Down Expand Up @@ -705,6 +721,12 @@ def hydrate_install_info(self) -> InstallInfo:

async def check_prerequisites(self) -> None:
self.os_info = await detect_os(self)
self.log.write(Text.from_markup("Detected OS info: ", end=""))
self.log.write(self.os_info)
if determine_docker_sudo():
self.docker_sudo = ["sudo"]
else:
self.docker_sudo = []
await install_git_lfs(self)
await install_git_hooks(self)
await check_python(self)
Expand Down Expand Up @@ -793,6 +815,12 @@ def hydrate_install_info(self) -> InstallInfo:

async def check_prerequisites(self) -> None:
self.os_info = await detect_os(self)
self.log.write(Text.from_markup("Detected OS info: ", end=""))
self.log.write(self.os_info)
if determine_docker_sudo():
self.docker_sudo = ["sudo"]
else:
self.docker_sudo = []
await check_docker(self)
if self.os_info.distro == "Darwin":
await check_docker_desktop_mount(self)
Expand Down
Loading

0 comments on commit 86ea9ec

Please sign in to comment.