Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions __tests__/docker/install.test.itg.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,14 @@ describe('install', () => {
jest.resetModules();
process.env = {
...originalEnv,
LIMA_START_ARGS: '--cpus 4 --memory 8',
LIMA_IMAGES: `x86_64:https://cloud.debian.org/images/cloud/bookworm/20231013-1532/debian-12-genericcloud-amd64-20231013-1532.qcow2@sha512:6b55e88b027c14da1b55c85a25a9f7069d4560a8fdb2d948c986a585db469728a06d2c528303e34bb62d8b2984def38fd9ddfc00965846ff6e05b01d6e883bfe
aarch64:https://cloud.debian.org/images/cloud/bookworm/20231013-1532/debian-12-genericcloud-arm64-20231013-1532.qcow2`
LIMA_START_ARGS: '--cpus 4 --memory 8'
};
});
afterEach(() => {
process.env = originalEnv;
});
// prettier-ignore
test.each(['v26.1.4'])(
test.each(['v27.2.1'])(
'install docker %s', async (version) => {
if (process.env.ImageOS && process.env.ImageOS.startsWith('ubuntu')) {
// Remove containerd first on ubuntu runners to make sure it takes
Expand Down
18 changes: 12 additions & 6 deletions src/docker/assets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,11 +132,13 @@ Get-WinEvent -ea SilentlyContinue \`
`;

export const limaYamlData = `
# Source: https://github.com/lima-vm/lima/blob/master/examples/docker-rootful.yaml

# VM type: "qemu" or "vz" (on macOS 13 and later).
# The vmType can be specified only on creating the instance.
# The vmType of existing instances cannot be changed.
# Builtin default: "qemu"
vmType: qemu
vmType: {{vmType}}

# OS: "Linux".
# Builtin default: "Linux"
Expand All @@ -152,12 +154,16 @@ images:
arch: "{{arch}}"
digest: "{{digest}}"
{{/each}}
- location: "https://cloud-images.ubuntu.com/releases/22.04/release-20231026/ubuntu-22.04-server-cloudimg-amd64.img"
- location: "https://cloud-images.ubuntu.com/releases/24.04/release-20240821/ubuntu-24.04-server-cloudimg-amd64.img"
arch: "x86_64"
digest: "sha256:0e25ca6ee9f08ec5d4f9910054b66ae7163c6152e81a3e67689d89bd6e4dfa69"
- location: "https://cloud-images.ubuntu.com/releases/24.04/release-20240821/ubuntu-24.04-server-cloudimg-arm64.img"
arch: "aarch64"
digest: "sha256:5ecac6447be66a164626744a87a27fd4e6c6606dc683e0a233870af63df4276a"
- location: "https://cloud-images.ubuntu.com/releases/24.04/release/ubuntu-24.04-server-cloudimg-amd64.img"
arch: "x86_64"
digest: "sha256:054db2d88c454bb0ad8dfd8883955e3946b57d2b0bf0d023f3ade3c93cdd14e5"
- location: "https://cloud-images.ubuntu.com/releases/22.04/release-20231026/ubuntu-22.04-server-cloudimg-arm64.img"
- location: "https://cloud-images.ubuntu.com/releases/24.04/release/ubuntu-24.04-server-cloudimg-arm64.img"
arch: "aarch64"
digest: "sha256:eafa7742ce5ff109222ea313d31ea366d587b4e89b900b11d8285ae775dfe8c3"

# CPUs
# Builtin default: min(4, host CPU cores)
Expand All @@ -182,7 +188,7 @@ mounts:
# Mount type for above mounts, such as "reverse-sshfs" (from sshocker), "9p" (EXPERIMENTAL, from QEMU’s virtio-9p-pci, aka virtfs),
# or "virtiofs" (EXPERIMENTAL, needs \`vmType: vz\`)
# Builtin default: "reverse-sshfs" (for QEMU), "virtiofs" (for vz)
mountType: null
mountType: {{mountType}}

containerd:
system: false
Expand Down
59 changes: 58 additions & 1 deletion src/docker/install.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import os from 'os';
import path from 'path';
import retry from 'async-retry';
import * as handlebars from 'handlebars';
import * as semver from 'semver';
import * as util from 'util';
import * as core from '@actions/core';
import * as httpm from '@actions/http-client';
Expand Down Expand Up @@ -140,6 +141,22 @@ export class Install {
await io.mkdirP(limaDir);
const dockerHost = `unix://${limaDir}/docker.sock`;

// fallback to a version requiring QEMU with colima
let macosVersion = '12.0.0';
await core.group('macOS version', async () => {
macosVersion = await Exec.getExecOutput(`sw_vers`, ['-productVersion'], {
ignoreReturnCode: true,
silent: true
}).then(res => {
if (res.exitCode == 0 && res.stdout.length > 0) {
return res.stdout.trim();
}
core.info(`sw_vers failed to get macOS version. Using ${macosVersion} as fallback.`);
return macosVersion;
});
core.info(macosVersion);
});

// avoid brew to auto update and upgrade unrelated packages.
let envs = Object.assign({}, process.env, {
HOMEBREW_NO_AUTO_UPDATE: '1',
Expand All @@ -158,6 +175,13 @@ export class Install {
await Exec.exec('lima', ['--version'], {env: envs});
});

let limaVmType = 'vz';
let limaMountType = 'virtiofs';
if (semver.satisfies(macosVersion, '<13.0.0')) {
limaVmType = 'qemu';
limaMountType = '9p';
}

await core.group('Creating lima config', async () => {
let limaDaemonConfig = {};
if (this.daemonConfig) {
Expand All @@ -167,7 +191,9 @@ export class Install {
return new handlebars.SafeString(JSON.stringify(obj));
});
const limaCfg = handlebars.compile(limaYamlData)({
vmType: limaVmType,
customImages: Install.limaCustomImages(),
mountType: limaMountType,
daemonConfig: limaDaemonConfig,
dockerSock: `${limaDir}/docker.sock`,
dockerBinVersion: this._version,
Expand All @@ -192,13 +218,43 @@ export class Install {
};

await core.group('Starting lima instance', async () => {
const limaStartTimeout = process.env.LIMA_START_TIMEOUT ? parseInt(process.env.LIMA_START_TIMEOUT) : 2 * 60 * 1000;
const limaStartArgs = ['start', `--name=${this.limaInstanceName}`];
if (process.env.LIMA_START_ARGS) {
limaStartArgs.push(process.env.LIMA_START_ARGS);
}
try {
await Exec.exec(`limactl ${limaStartArgs.join(' ')}`, [], {env: envs});
const startPromise = new Promise<void>((resolve, reject) => {
core.info(`Executing: limactl ${limaStartArgs.join(' ')}`);
const proc = child_process.spawn(`limactl ${limaStartArgs.join(' ')}`, {
env: envs
});
proc.on('close', code => {
if (code === 0) {
core.info('limactl command completed successfully');
resolve();
} else {
core.error(`limactl command failed with code ${code}`);
reject(new Error(`limactl command failed with code ${code}`));
}
});

proc.on('error', err => {
core.error(`limactl command error: ${err.message}`);
reject(err);
});
});

const timeoutPromise = new Promise<void>((_, reject) => {
setTimeout(() => {
core.error('Timeout reached');
reject(new Error('Timeout reached'));
}, limaStartTimeout);
});

await Promise.race([startPromise, timeoutPromise]);
} catch (e) {
core.error(`Error starting lima instance: ${e.message}`);
fsp
.readdir(limaDir)
.then(files => {
Expand All @@ -215,6 +271,7 @@ export class Install {
.catch(() => {
// ignore
});
await Exec.exec(`limactl delete ${this.limaInstanceName}`, [], {env: envs});
throw e;
}
});
Expand Down
Loading