From 10424facafc5938c6f88e91450a0383596e196a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Gronowski?= Date: Mon, 9 Sep 2024 13:27:10 +0200 Subject: [PATCH] docker/install: Install source MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Paweł Gronowski --- src/docker/install.ts | 88 ++++++++++++++++++++++++++++++++----------- 1 file changed, 67 insertions(+), 21 deletions(-) diff --git a/src/docker/install.ts b/src/docker/install.ts index 80dbab4..7664972 100644 --- a/src/docker/install.ts +++ b/src/docker/install.ts @@ -35,9 +35,30 @@ import {limaYamlData, dockerServiceLogsPs1, setupDockerWinPs1} from './assets'; import {GitHubRelease} from '../types/github'; import {HubRepository} from '../hubRepository'; +export interface InstallSourceImage { + type: 'image'; + tag: string; +} + +export interface InstallSourceArchive { + type: 'archive'; + version: string; + channel: string; +} + +export type InstallSource = InstallSourceImage | InstallSourceArchive; + export interface InstallOpts { + source?: InstallSource; + + // @deprecated + // Use `source = InstallSourceTypeArchive{version: ..., channel: ...}` instead version?: string; + // @deprecated + // Use `source = InstallSourceTypeArchive{version: ..., channel: ...}` instead channel?: string; + + // ... runDir: string; contextName?: string; daemonConfig?: string; @@ -51,8 +72,7 @@ interface LimaImage { export class Install { private readonly runDir: string; - private readonly version: string; - private readonly channel: string; + private readonly source: InstallSource; private readonly contextName: string; private readonly daemonConfig?: string; private _version: string | undefined; @@ -62,8 +82,11 @@ export class Install { constructor(opts: InstallOpts) { this.runDir = opts.runDir; - this.version = opts.version || 'latest'; - this.channel = opts.channel || 'stable'; + this.source = opts.source || { + type: 'archive', + version: opts.version || 'latest', + channel: opts.channel || 'stable' + }; this.contextName = opts.contextName || 'setup-docker-action'; this.daemonConfig = opts.daemonConfig; } @@ -72,12 +95,12 @@ export class Install { return this._toolDir || Context.tmpDir(); } - async downloadStaticArchive(): Promise { - const release: GitHubRelease = await Install.getRelease(this.version); + async downloadStaticArchive(src: InstallSourceArchive): Promise { + const release: GitHubRelease = await Install.getRelease(src.version); this._version = release.tag_name.replace(/^v+|v+$/g, ''); core.debug(`docker.Install.download version: ${this._version}`); - const downloadURL = this.downloadURL(this._version, this.channel); + const downloadURL = this.downloadURL(this._version, src.channel); core.info(`Downloading ${downloadURL}`); const downloadPath = await tc.downloadTool(downloadURL); @@ -98,20 +121,39 @@ export class Install { public async download(): Promise { let extractFolder: string; + let cacheKey: string; + const platform = os.platform(); - core.info(`Downloading Docker ${this.version} from ${this.channel}`); + switch (this.source.type) { + case 'image': { + const tag = this.source.tag; + this._version = tag; + cacheKey = `docker-image`; - this._version = this.version; - if (this.version == 'master') { - core.info(`Downloading from moby/moby-bin`); - const moby = await HubRepository.build('moby/moby-bin'); - const cli = await HubRepository.build('dockereng/cli-bin'); + core.info(`Downloading docker cli from dockereng/cli-bin:${tag}`); + const cli = await HubRepository.build('dockereng/cli-bin'); + extractFolder = await cli.extractImage(tag); - extractFolder = await moby.extractImage(this.version); - await cli.extractImage(this.version, extractFolder); - } else { - core.info(`Downloading from download.docker.com`); - extractFolder = await this.downloadStaticArchive(); + // 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 { + core.info(`dockerd not supported on ${platform}`); + } + break; + } + case 'archive': { + const version = this.source.version; + const channel = this.source.channel; + cacheKey = `docker-archive-${channel}`; + this._version = version; + + core.info(`Downloading Docker ${version} from ${this.source.channel} at download.docker.com`); + extractFolder = await this.downloadStaticArchive(this.source); + break; + } } core.info('Fixing perms'); @@ -125,7 +167,7 @@ export class Install { }); }); - const tooldir = await tc.cacheDir(extractFolder, `docker-${this.channel}`, this._version.replace(/(0+)([1-9]+)/, '$2')); + const tooldir = await tc.cacheDir(extractFolder, cacheKey, this._version.replace(/(0+)([1-9]+)/, '$2')); core.addPath(tooldir); core.info('Added Docker to PATH'); @@ -157,6 +199,10 @@ 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 limaDir = path.join(os.homedir(), '.lima', this.limaInstanceName); await io.mkdirP(limaDir); const dockerHost = `unix://${limaDir}/docker.sock`; @@ -191,8 +237,8 @@ export class Install { customImages: Install.limaCustomImages(), daemonConfig: limaDaemonConfig, dockerSock: `${limaDir}/docker.sock`, - dockerBinVersion: this._version, - dockerBinChannel: this.channel + dockerBinVersion: src.version.replace(/^v/, ''), + dockerBinChannel: src.channel }); core.info(`Writing lima config to ${path.join(limaDir, 'lima.yaml')}`); fs.writeFileSync(path.join(limaDir, 'lima.yaml'), limaCfg);