docker/install: Install source

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
This commit is contained in:
Paweł Gronowski 2024-09-09 13:27:10 +02:00
parent 1335f081af
commit 10424facaf
No known key found for this signature in database
GPG Key ID: B85EFCFE26DEF92A

View File

@ -35,9 +35,30 @@ import {limaYamlData, dockerServiceLogsPs1, setupDockerWinPs1} from './assets';
import {GitHubRelease} from '../types/github'; import {GitHubRelease} from '../types/github';
import {HubRepository} from '../hubRepository'; 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 { export interface InstallOpts {
source?: InstallSource;
// @deprecated
// Use `source = InstallSourceTypeArchive{version: ..., channel: ...}` instead
version?: string; version?: string;
// @deprecated
// Use `source = InstallSourceTypeArchive{version: ..., channel: ...}` instead
channel?: string; channel?: string;
// ...
runDir: string; runDir: string;
contextName?: string; contextName?: string;
daemonConfig?: string; daemonConfig?: string;
@ -51,8 +72,7 @@ interface LimaImage {
export class Install { export class Install {
private readonly runDir: string; private readonly runDir: string;
private readonly version: string; private readonly source: InstallSource;
private readonly channel: string;
private readonly contextName: string; private readonly contextName: string;
private readonly daemonConfig?: string; private readonly daemonConfig?: string;
private _version: string | undefined; private _version: string | undefined;
@ -62,8 +82,11 @@ export class Install {
constructor(opts: InstallOpts) { constructor(opts: InstallOpts) {
this.runDir = opts.runDir; this.runDir = opts.runDir;
this.version = opts.version || 'latest'; this.source = opts.source || {
this.channel = opts.channel || 'stable'; type: 'archive',
version: opts.version || 'latest',
channel: opts.channel || 'stable'
};
this.contextName = opts.contextName || 'setup-docker-action'; this.contextName = opts.contextName || 'setup-docker-action';
this.daemonConfig = opts.daemonConfig; this.daemonConfig = opts.daemonConfig;
} }
@ -72,12 +95,12 @@ export class Install {
return this._toolDir || Context.tmpDir(); return this._toolDir || Context.tmpDir();
} }
async downloadStaticArchive(): Promise<string> { async downloadStaticArchive(src: InstallSourceArchive): Promise<string> {
const release: GitHubRelease = await Install.getRelease(this.version); const release: GitHubRelease = await Install.getRelease(src.version);
this._version = release.tag_name.replace(/^v+|v+$/g, ''); this._version = release.tag_name.replace(/^v+|v+$/g, '');
core.debug(`docker.Install.download version: ${this._version}`); 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}`); core.info(`Downloading ${downloadURL}`);
const downloadPath = await tc.downloadTool(downloadURL); const downloadPath = await tc.downloadTool(downloadURL);
@ -98,20 +121,39 @@ export class Install {
public async download(): Promise<string> { public async download(): Promise<string> {
let extractFolder: string; 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; core.info(`Downloading docker cli from dockereng/cli-bin:${tag}`);
if (this.version == 'master') { const cli = await HubRepository.build('dockereng/cli-bin');
core.info(`Downloading from moby/moby-bin`); extractFolder = await cli.extractImage(tag);
const moby = await HubRepository.build('moby/moby-bin');
const cli = await HubRepository.build('dockereng/cli-bin');
extractFolder = await moby.extractImage(this.version); // Daemon is only available for Windows and Linux
await cli.extractImage(this.version, extractFolder); if (['win32', 'linux'].includes(platform)) {
} else { core.info(`Downloading dockerd from moby/moby-bin:${tag}`);
core.info(`Downloading from download.docker.com`); const moby = await HubRepository.build('moby/moby-bin');
extractFolder = await this.downloadStaticArchive(); 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'); 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.addPath(tooldir);
core.info('Added Docker to PATH'); core.info('Added Docker to PATH');
@ -157,6 +199,10 @@ export class Install {
} }
private async installDarwin(): Promise<string> { 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 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`;
@ -191,8 +237,8 @@ export class Install {
customImages: Install.limaCustomImages(), customImages: Install.limaCustomImages(),
daemonConfig: limaDaemonConfig, daemonConfig: limaDaemonConfig,
dockerSock: `${limaDir}/docker.sock`, dockerSock: `${limaDir}/docker.sock`,
dockerBinVersion: this._version, dockerBinVersion: src.version.replace(/^v/, ''),
dockerBinChannel: this.channel dockerBinChannel: src.channel
}); });
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);