From e3d0e4e199e204233f4a542401cf922a0225a8c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Gronowski?= Date: Wed, 16 Oct 2024 10:42:54 +0200 Subject: [PATCH] Support image source on darwin MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use undock inside lima to pull the image content. We could mount the downloaded binaries from the host, but for some reason lima mounts are not always mounted when the provisioning script is run. Signed-off-by: Paweł Gronowski --- __tests__/docker/install.test.itg.ts | 20 +++++++------ src/docker/assets.ts | 43 ++++++++++++++++++++++++---- src/docker/install.ts | 17 +++++------ 3 files changed, 58 insertions(+), 22 deletions(-) diff --git a/__tests__/docker/install.test.itg.ts b/__tests__/docker/install.test.itg.ts index c061afb..822da61 100644 --- a/__tests__/docker/install.test.itg.ts +++ b/__tests__/docker/install.test.itg.ts @@ -41,8 +41,9 @@ aarch64:https://cloud.debian.org/images/cloud/bookworm/20231013-1532/debian-12-g }); // prettier-ignore test.each([ - {type: 'archive', version: 'v26.1.4', channel: 'stable'} as InstallSourceArchive, {type: 'image', tag: '27.3.1'} as InstallSourceImage, + {type: 'image', tag: 'master'} as InstallSourceImage, + {type: 'archive', version: 'v26.1.4', channel: 'stable'} as InstallSourceArchive, ])( 'install docker %s', async (source) => { if (process.env.ImageOS && process.env.ImageOS.startsWith('ubuntu')) { @@ -56,18 +57,19 @@ aarch64:https://cloud.debian.org/images/cloud/bookworm/20231013-1532/debian-12-g } }); } + const install = new Install({ + source: source, + runDir: tmpDir, + contextName: 'foo', + daemonConfig: `{"debug":true,"features":{"containerd-snapshotter":true}}` + }); await expect((async () => { - const install = new Install({ - source: source, - runDir: tmpDir, - contextName: 'foo', - daemonConfig: `{"debug":true,"features":{"containerd-snapshotter":true}}` - }); await install.download(); await install.install(); await Docker.printVersion(); await Docker.printInfo(); + })().finally(async () => { await install.tearDown(); - })()).resolves.not.toThrow(); - }, 1200000); + })).resolves.not.toThrow(); + }, 30 * 60 * 1000); }); diff --git a/src/docker/assets.ts b/src/docker/assets.ts index 15e39c2..00f7332 100644 --- a/src/docker/assets.ts +++ b/src/docker/assets.ts @@ -221,16 +221,49 @@ provision: EOF fi export DEBIAN_FRONTEND=noninteractive - curl -fsSL https://get.docker.com | sh -s -- --channel {{dockerBinChannel}} --version {{dockerBinVersion}} + if [ "{{srcType}}" == "archive" ]; then + curl -fsSL https://get.docker.com | sh -s -- --channel {{srcArchiveChannel}} --version {{srcArchiveVersion}} + elif [ "{{srcType}}" == "image" ]; then + arch=$(uname -m) + case $arch in + x86_64) arch=amd64;; + aarch64) arch=arm64;; + esac + url="https://github.com/crazy-max/undock/releases/download/v0.8.0/undock_0.8.0_linux_$arch.tar.gz" + + wget "$url" -O /tmp/undock.tar.gz + tar -C /usr/local/bin -xvf /tmp/undock.tar.gz + undock --version + + HOME=/tmp undock moby/moby-bin:{{srcImageTag}} /usr/local/bin + + wget https://raw.githubusercontent.com/moby/moby/{{srcImageTag}}/contrib/init/systemd/docker.service \ + https://raw.githubusercontent.com/moby/moby/v{{srcImageTag}}/contrib/init/systemd/docker.service \ + -O /etc/systemd/system/docker.service || true + wget https://raw.githubusercontent.com/moby/moby/{{srcImageTag}}/contrib/init/systemd/docker.socket \ + https://raw.githubusercontent.com/moby/moby/v{{srcImageTag}}/contrib/init/systemd/docker.socket \ + -O /etc/systemd/system/docker.socket || true + + sed -i 's|^ExecStart=.*|ExecStart=/usr/local/bin/dockerd -H fd://|' /etc/systemd/system/docker.service + sed -i 's|containerd.service||' /etc/systemd/system/docker.service + if ! getent group docker; then + groupadd --system docker + fi + systemctl daemon-reload + fail=0 + if ! systemctl enable --now docker; then + fail=1 + fi + systemctl status docker.socket || true + systemctl status docker.service || true + exit $fail + fi probes: - script: | #!/bin/bash set -eux -o pipefail - if ! timeout 30s bash -c "until command -v docker >/dev/null 2>&1; do sleep 3; done"; then - echo >&2 "docker is not installed yet" - exit 1 - fi + # Don't check for docker CLI as it's not installed in the VM (only on the host) if ! timeout 30s bash -c "until pgrep dockerd; do sleep 3; done"; then echo >&2 "dockerd is not running" exit 1 diff --git a/src/docker/install.ts b/src/docker/install.ts index e6f219f..d2c89a3 100644 --- a/src/docker/install.ts +++ b/src/docker/install.ts @@ -127,13 +127,14 @@ export class Install { const cli = await HubRepository.build('dockereng/cli-bin'); extractFolder = await cli.extractImage(tag); - // Daemon is only available for Windows and Linux if (['win32', 'linux'].includes(platform)) { core.info(`Downloading dockerd from moby/moby-bin:${tag}`); const moby = await HubRepository.build('moby/moby-bin'); await moby.extractImage(tag, extractFolder); + } else if (platform == 'darwin') { + // On macOS, the docker daemon binary will be downloaded inside the lima VM } else { - core.info(`dockerd not supported on ${platform}`); + core.warning(`dockerd not supported on ${platform}, only the Docker cli will be available`); } break; } @@ -192,10 +193,7 @@ export class Install { } private async installDarwin(): Promise { - if (this.source.type !== 'archive') { - throw new Error('Only archive source is supported on macOS'); - } - const src = this.source as InstallSourceArchive; + const src = this.source; const limaDir = path.join(os.homedir(), '.lima', this.limaInstanceName); await io.mkdirP(limaDir); const dockerHost = `unix://${limaDir}/docker.sock`; @@ -226,12 +224,15 @@ export class Install { handlebars.registerHelper('stringify', function (obj) { return new handlebars.SafeString(JSON.stringify(obj)); }); + const srcArchive = src as InstallSourceArchive; const limaCfg = handlebars.compile(limaYamlData)({ customImages: Install.limaCustomImages(), daemonConfig: limaDaemonConfig, dockerSock: `${limaDir}/docker.sock`, - dockerBinVersion: src.version.replace(/^v/, ''), - dockerBinChannel: src.channel + srcType: src.type, + srcArchiveVersion: srcArchive.version?.replace(/^v/, ''), + srcArchiveChannel: srcArchive.channel, + srcImageTag: (src as InstallSourceImage).tag }); core.info(`Writing lima config to ${path.join(limaDir, 'lima.yaml')}`); fs.writeFileSync(path.join(limaDir, 'lima.yaml'), limaCfg);