diff --git a/src/docker/assets.ts b/src/docker/assets.ts index 15e39c22..f76c8ba1 100644 --- a/src/docker/assets.ts +++ b/src/docker/assets.ts @@ -176,6 +176,8 @@ disk: 60GiB # This file: Mount the home as read-only, /tmp/lima as writable mounts: - location: "~" +- location: {{toolDir}} + mountPoint: /tool - location: "/tmp/lima" writable: true @@ -221,7 +223,14 @@ provision: EOF fi export DEBIAN_FRONTEND=noninteractive - curl -fsSL https://get.docker.com | sh -s -- --channel {{dockerBinChannel}} --version {{dockerBinVersion}} + if [ {{installSource}} == "archive" ]; then + curl -fsSL https://get.docker.com | sh -s -- --channel {{dockerBinChannel}} --version {{dockerBinVersion}} + if [ {{installSource}} == "image" ]; then + wget https://raw.githubusercontent.com/moby/moby/refs/heads/master/contrib/init/systemd/docker.service -O /etc/systemd/system/docker.service + sed -i 's|^ExecStart=.*|ExecStart=/tool/dockerd|' /etc/systemd/system/docker.service + sed -i 's|containerd.service||' /etc/systemd/system/docker.service + + fi probes: - script: | diff --git a/src/docker/install.ts b/src/docker/install.ts index e6f219f3..5bd056f5 100644 --- a/src/docker/install.ts +++ b/src/docker/install.ts @@ -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; } @@ -192,10 +195,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 +226,14 @@ 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 + dockerBinVersion: srcArchive.version.replace(/^v/, ''), + dockerBinChannel: srcArchive.channel, + toolDir: this.toolDir }); core.info(`Writing lima config to ${path.join(limaDir, 'lima.yaml')}`); fs.writeFileSync(path.join(limaDir, 'lima.yaml'), limaCfg); diff --git a/src/hubRepository.ts b/src/hubRepository.ts index f9617983..96b15ee1 100644 --- a/src/hubRepository.ts +++ b/src/hubRepository.ts @@ -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 { + public async extractImage(tag: string, destDir?: string, osPlatform?: string): Promise { const index = await this.getManifest(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(digest); const paths = manifest.layers.map(async layer => { @@ -115,9 +115,9 @@ export class HubRepository { return 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'; }