Skip to content

Commit

Permalink
Support image source on darwin
Browse files Browse the repository at this point in the history
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
  • Loading branch information
vvoland committed Oct 17, 2024
1 parent b143889 commit a74c891
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 20 deletions.
3 changes: 2 additions & 1 deletion __tests__/docker/install.test.itg.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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')) {
Expand Down
29 changes: 24 additions & 5 deletions src/docker/assets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -221,16 +221,35 @@ 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
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
mkdir -p /usr/local/bin
cp /tmp/lima/* /usr/local/bin/
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
if ! systemctl enable --now docker; then
systemctl status docker.socket
systemctl status docker.service
fi
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
Expand Down
32 changes: 22 additions & 10 deletions src/docker/install.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,13 +127,16 @@ 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)) {
if (['win32', 'linux', 'darwin'].includes(platform)) {
core.info(`Downloading dockerd from moby/moby-bin:${tag}`);
const moby = await HubRepository.build('moby/moby-bin');
await moby.extractImage(tag, extractFolder);

// On macOS, we extract the Linux version of dockerd which will be run in a lima VM.
const extractPlatform = platform == 'darwin' ? 'linux' : undefined;

await moby.extractImage(tag, extractFolder, extractPlatform);
} else {
core.info(`dockerd not supported on ${platform}`);
core.warning(`dockerd not supported on ${platform}, only the Docker cli will be available`);
}
break;
}
Expand Down Expand Up @@ -192,14 +195,19 @@ export class Install {
}

private async installDarwin(): Promise<string> {
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`;

// this.toolDir is a very long path which causes trouble when mounting it in lima.
// Copy it to a shorter path.
const limaToolsDir = '/tmp/lima';

await core.group('Copy tools', async () => {
await Exec.exec('cp', ['-rv', this.toolDir, limaToolsDir]);
});

// avoid brew to auto update and upgrade unrelated packages.
let envs = Object.assign({}, process.env, {
HOMEBREW_NO_AUTO_UPDATE: '1',
Expand All @@ -226,12 +234,16 @@ 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,
toolDir: limaToolsDir
});
core.info(`Writing lima config to ${path.join(limaDir, 'lima.yaml')}`);
fs.writeFileSync(path.join(limaDir, 'lima.yaml'), limaCfg);
Expand Down
8 changes: 4 additions & 4 deletions src/hubRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,12 @@ export class HubRepository {

// Unpacks the image layers and returns the path to the extracted image.
// Only OCI indexes/manifest list are supported for now.
public async extractImage(tag: string, destDir?: string): Promise<string> {
public async extractImage(tag: string, destDir?: string, osPlatform?: string): Promise<string> {
const index = await this.getManifest<Index>(tag);
if (index.mediaType != MEDIATYPE_IMAGE_INDEX_V1 && index.mediaType != MEDIATYPE_IMAGE_MANIFEST_LIST_V2) {
throw new Error(`Unsupported image media type: ${index.mediaType}`);
}
const digest = HubRepository.getPlatformManifestDigest(index);
const digest = HubRepository.getPlatformManifestDigest(index, osPlatform);
const manifest = await this.getManifest<Manifest>(digest);

const paths = manifest.layers.map(async layer => {
Expand Down Expand Up @@ -115,9 +115,9 @@ export class HubRepository {
return <T>JSON.parse(body);
}

private static getPlatformManifestDigest(index: Index): string {
private static getPlatformManifestDigest(index: Index, osPlatform?: string): string {
// This doesn't handle all possible platforms normalizations, but it's good enough for now.
let pos: string = os.platform();
let pos: string = osPlatform || os.platform();
if (pos == 'win32') {
pos = 'windows';
}
Expand Down

0 comments on commit a74c891

Please sign in to comment.