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 {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<string> {
const release: GitHubRelease = await Install.getRelease(this.version);
async downloadStaticArchive(src: InstallSourceArchive): Promise<string> {
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<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;
if (this.version == 'master') {
core.info(`Downloading from moby/moby-bin`);
const moby = await HubRepository.build('moby/moby-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);
// 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(`Downloading from download.docker.com`);
extractFolder = await this.downloadStaticArchive();
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<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);
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);