Support image source on darwin

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 <pawel.gronowski@docker.com>
This commit is contained in:
Paweł Gronowski 2024-10-16 10:42:54 +02:00
parent b143889d3e
commit e3d0e4e199
No known key found for this signature in database
GPG Key ID: B85EFCFE26DEF92A
3 changed files with 58 additions and 22 deletions

View File

@ -41,8 +41,9 @@ aarch64:https://cloud.debian.org/images/cloud/bookworm/20231013-1532/debian-12-g
}); });
// prettier-ignore // prettier-ignore
test.each([ test.each([
{type: 'archive', version: 'v26.1.4', channel: 'stable'} as InstallSourceArchive,
{type: 'image', tag: '27.3.1'} as InstallSourceImage, {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) => { 'install docker %s', async (source) => {
if (process.env.ImageOS && process.env.ImageOS.startsWith('ubuntu')) { 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 () => { 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.download();
await install.install(); await install.install();
await Docker.printVersion(); await Docker.printVersion();
await Docker.printInfo(); await Docker.printInfo();
})().finally(async () => {
await install.tearDown(); await install.tearDown();
})()).resolves.not.toThrow(); })).resolves.not.toThrow();
}, 1200000); }, 30 * 60 * 1000);
}); });

View File

@ -221,16 +221,49 @@ provision:
EOF EOF
fi fi
export DEBIAN_FRONTEND=noninteractive 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: probes:
- script: | - script: |
#!/bin/bash #!/bin/bash
set -eux -o pipefail set -eux -o pipefail
if ! timeout 30s bash -c "until command -v docker >/dev/null 2>&1; do sleep 3; done"; then # Don't check for docker CLI as it's not installed in the VM (only on the host)
echo >&2 "docker is not installed yet"
exit 1
fi
if ! timeout 30s bash -c "until pgrep dockerd; do sleep 3; done"; then if ! timeout 30s bash -c "until pgrep dockerd; do sleep 3; done"; then
echo >&2 "dockerd is not running" echo >&2 "dockerd is not running"
exit 1 exit 1

View File

@ -127,13 +127,14 @@ export class Install {
const cli = await HubRepository.build('dockereng/cli-bin'); const cli = await HubRepository.build('dockereng/cli-bin');
extractFolder = await cli.extractImage(tag); extractFolder = await cli.extractImage(tag);
// Daemon is only available for Windows and Linux
if (['win32', 'linux'].includes(platform)) { if (['win32', 'linux'].includes(platform)) {
core.info(`Downloading dockerd from moby/moby-bin:${tag}`); core.info(`Downloading dockerd from moby/moby-bin:${tag}`);
const moby = await HubRepository.build('moby/moby-bin'); const moby = await HubRepository.build('moby/moby-bin');
await moby.extractImage(tag, extractFolder); await moby.extractImage(tag, extractFolder);
} else if (platform == 'darwin') {
// On macOS, the docker daemon binary will be downloaded inside the lima VM
} else { } else {
core.info(`dockerd not supported on ${platform}`); core.warning(`dockerd not supported on ${platform}, only the Docker cli will be available`);
} }
break; break;
} }
@ -192,10 +193,7 @@ export class Install {
} }
private async installDarwin(): Promise<string> { private async installDarwin(): Promise<string> {
if (this.source.type !== 'archive') { const src = this.source;
throw new Error('Only archive source is supported on macOS');
}
const src = this.source as InstallSourceArchive;
const limaDir = path.join(os.homedir(), '.lima', this.limaInstanceName); const limaDir = path.join(os.homedir(), '.lima', this.limaInstanceName);
await io.mkdirP(limaDir); await io.mkdirP(limaDir);
const dockerHost = `unix://${limaDir}/docker.sock`; const dockerHost = `unix://${limaDir}/docker.sock`;
@ -226,12 +224,15 @@ export class Install {
handlebars.registerHelper('stringify', function (obj) { handlebars.registerHelper('stringify', function (obj) {
return new handlebars.SafeString(JSON.stringify(obj)); return new handlebars.SafeString(JSON.stringify(obj));
}); });
const srcArchive = src as InstallSourceArchive;
const limaCfg = handlebars.compile(limaYamlData)({ const limaCfg = handlebars.compile(limaYamlData)({
customImages: Install.limaCustomImages(), customImages: Install.limaCustomImages(),
daemonConfig: limaDaemonConfig, daemonConfig: limaDaemonConfig,
dockerSock: `${limaDir}/docker.sock`, dockerSock: `${limaDir}/docker.sock`,
dockerBinVersion: src.version.replace(/^v/, ''), srcType: src.type,
dockerBinChannel: src.channel srcArchiveVersion: srcArchive.version?.replace(/^v/, ''),
srcArchiveChannel: srcArchive.channel,
srcImageTag: (src as InstallSourceImage).tag
}); });
core.info(`Writing lima config to ${path.join(limaDir, 'lima.yaml')}`); core.info(`Writing lima config to ${path.join(limaDir, 'lima.yaml')}`);
fs.writeFileSync(path.join(limaDir, 'lima.yaml'), limaCfg); fs.writeFileSync(path.join(limaDir, 'lima.yaml'), limaCfg);