Merge pull request #62 from crazy-max/docker-custom-context
docker: allow custom context name on install
This commit is contained in:
@@ -21,19 +21,23 @@ import {Install} from '../../src/docker/install';
|
|||||||
import {Docker} from '../../src/docker/docker';
|
import {Docker} from '../../src/docker/docker';
|
||||||
|
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
const tmpDir = path.join(process.env.TEMP || '/tmp', 'buildx-jest');
|
const tmpDir = path.join(process.env.TEMP || '/tmp', 'docker-install-jest');
|
||||||
|
|
||||||
describe('install', () => {
|
describe('install', () => {
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
test.each(['23.0.0'])(
|
test.each(['23.0.0'])(
|
||||||
'install docker %s', async (version) => {
|
'install docker %s', async (version) => {
|
||||||
await expect((async () => {
|
await expect((async () => {
|
||||||
const install = new Install();
|
const install = new Install({
|
||||||
const toolPath = await install.download(version);
|
version: version,
|
||||||
await install.install(toolPath, tmpDir, version);
|
runDir: tmpDir,
|
||||||
|
contextName: 'foo'
|
||||||
|
});
|
||||||
|
await install.download();
|
||||||
|
await install.install();
|
||||||
await Docker.printVersion();
|
await Docker.printVersion();
|
||||||
await Docker.printInfo();
|
await Docker.printInfo();
|
||||||
await install.tearDown(tmpDir);
|
await install.tearDown();
|
||||||
})()).resolves.not.toThrow();
|
})()).resolves.not.toThrow();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ import osm = require('os');
|
|||||||
import {Install} from '../../src/docker/install';
|
import {Install} from '../../src/docker/install';
|
||||||
|
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
const tmpDir = path.join(process.env.TEMP || '/tmp', 'buildx-jest');
|
const tmpDir = path.join(process.env.TEMP || '/tmp', 'docker-install-jest');
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
jest.clearAllMocks();
|
jest.clearAllMocks();
|
||||||
@@ -43,8 +43,11 @@ describe('download', () => {
|
|||||||
])(
|
])(
|
||||||
'acquires %p of docker (%s)', async (version, platformOS) => {
|
'acquires %p of docker (%s)', async (version, platformOS) => {
|
||||||
jest.spyOn(osm, 'platform').mockImplementation(() => platformOS);
|
jest.spyOn(osm, 'platform').mockImplementation(() => platformOS);
|
||||||
const install = new Install();
|
const install = new Install({
|
||||||
const toolPath = await install.download(version);
|
version: version,
|
||||||
|
runDir: tmpDir,
|
||||||
|
});
|
||||||
|
const toolPath = await install.download();
|
||||||
expect(fs.existsSync(toolPath)).toBe(true);
|
expect(fs.existsSync(toolPath)).toBe(true);
|
||||||
}, 100000);
|
}, 100000);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -25,14 +25,38 @@ import * as core from '@actions/core';
|
|||||||
import * as io from '@actions/io';
|
import * as io from '@actions/io';
|
||||||
import * as tc from '@actions/tool-cache';
|
import * as tc from '@actions/tool-cache';
|
||||||
|
|
||||||
|
import {Context} from '../context';
|
||||||
import {Exec} from '../exec';
|
import {Exec} from '../exec';
|
||||||
import {Util} from '../util';
|
import {Util} from '../util';
|
||||||
import {colimaYamlData, dockerServiceLogsPs1, setupDockerLinuxSh, setupDockerWinPs1} from './assets';
|
import {colimaYamlData, dockerServiceLogsPs1, setupDockerLinuxSh, setupDockerWinPs1} from './assets';
|
||||||
|
|
||||||
|
export interface InstallOpts {
|
||||||
|
version: string;
|
||||||
|
channel?: string;
|
||||||
|
runDir: string;
|
||||||
|
contextName?: string;
|
||||||
|
}
|
||||||
|
|
||||||
export class Install {
|
export class Install {
|
||||||
public async download(version: string, channel?: string): Promise<string> {
|
private readonly version: string;
|
||||||
channel = channel || 'stable';
|
private readonly channel: string;
|
||||||
const downloadURL = this.downloadURL(version, channel);
|
private readonly runDir: string;
|
||||||
|
private readonly contextName: string;
|
||||||
|
private _toolDir: string | undefined;
|
||||||
|
|
||||||
|
constructor(opts: InstallOpts) {
|
||||||
|
this.version = opts.version;
|
||||||
|
this.channel = opts.channel || 'stable';
|
||||||
|
this.runDir = opts.runDir;
|
||||||
|
this.contextName = opts.contextName || 'setup-docker-action';
|
||||||
|
}
|
||||||
|
|
||||||
|
get toolDir(): string {
|
||||||
|
return this._toolDir || Context.tmpDir();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async download(): Promise<string> {
|
||||||
|
const downloadURL = this.downloadURL(this.version, this.channel);
|
||||||
|
|
||||||
core.info(`Downloading ${downloadURL}`);
|
core.info(`Downloading ${downloadURL}`);
|
||||||
const downloadPath = await tc.downloadTool(downloadURL);
|
const downloadPath = await tc.downloadTool(downloadURL);
|
||||||
@@ -60,31 +84,32 @@ export class Install {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
const tooldir = await tc.cacheDir(extractFolder, `docker-${channel}`, version.replace(/(0+)([1-9]+)/, '$2'));
|
const tooldir = await tc.cacheDir(extractFolder, `docker-${this.channel}`, 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');
|
||||||
|
|
||||||
|
this._toolDir = tooldir;
|
||||||
return tooldir;
|
return tooldir;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async install(toolDir: string, runDir: string, version: string, channel?: string): Promise<void> {
|
public async install(): Promise<void> {
|
||||||
if (toolDir.length == 0) {
|
if (!this.toolDir) {
|
||||||
throw new Error('toolDir must be set');
|
throw new Error('toolDir must be set. Run download first.');
|
||||||
}
|
}
|
||||||
if (runDir.length == 0) {
|
if (!this.runDir) {
|
||||||
throw new Error('runDir must be set');
|
throw new Error('runDir must be set');
|
||||||
}
|
}
|
||||||
channel = channel || 'stable';
|
|
||||||
switch (os.platform()) {
|
switch (os.platform()) {
|
||||||
case 'darwin': {
|
case 'darwin': {
|
||||||
await this.installDarwin(toolDir, version, channel);
|
await this.installDarwin();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'linux': {
|
case 'linux': {
|
||||||
await this.installLinux(toolDir, runDir);
|
await this.installLinux();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'win32': {
|
case 'win32': {
|
||||||
await this.installWindows(toolDir, runDir);
|
await this.installWindows();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
@@ -93,7 +118,7 @@ export class Install {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async installDarwin(toolDir: string, version: string, channel?: string): Promise<void> {
|
private async installDarwin(): Promise<void> {
|
||||||
const colimaDir = path.join(os.homedir(), '.colima', 'default'); // TODO: create a custom colima profile to avoid overlap with other actions
|
const colimaDir = path.join(os.homedir(), '.colima', 'default'); // TODO: create a custom colima profile to avoid overlap with other actions
|
||||||
await io.mkdirP(colimaDir);
|
await io.mkdirP(colimaDir);
|
||||||
const dockerHost = `unix://${colimaDir}/docker.sock`;
|
const dockerHost = `unix://${colimaDir}/docker.sock`;
|
||||||
@@ -107,8 +132,8 @@ export class Install {
|
|||||||
await core.group('Creating colima config', async () => {
|
await core.group('Creating colima config', async () => {
|
||||||
const colimaCfg = handlebars.compile(colimaYamlData)({
|
const colimaCfg = handlebars.compile(colimaYamlData)({
|
||||||
hostArch: Install.platformArch(),
|
hostArch: Install.platformArch(),
|
||||||
dockerVersion: version,
|
dockerVersion: this.version,
|
||||||
dockerChannel: channel
|
dockerChannel: this.channel
|
||||||
});
|
});
|
||||||
core.info(`Writing colima config to ${path.join(colimaDir, 'colima.yaml')}`);
|
core.info(`Writing colima config to ${path.join(colimaDir, 'colima.yaml')}`);
|
||||||
fs.writeFileSync(path.join(colimaDir, 'colima.yaml'), colimaCfg);
|
fs.writeFileSync(path.join(colimaDir, 'colima.yaml'), colimaCfg);
|
||||||
@@ -118,7 +143,7 @@ export class Install {
|
|||||||
// colima is already started on the runner so env var added in download
|
// colima is already started on the runner so env var added in download
|
||||||
// method is not expanded to the running process.
|
// method is not expanded to the running process.
|
||||||
const envs = Object.assign({}, process.env, {
|
const envs = Object.assign({}, process.env, {
|
||||||
PATH: `${toolDir}:${process.env.PATH}`
|
PATH: `${this.toolDir}:${process.env.PATH}`
|
||||||
}) as {
|
}) as {
|
||||||
[key: string]: string;
|
[key: string]: string;
|
||||||
};
|
};
|
||||||
@@ -127,14 +152,14 @@ export class Install {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await core.group('Create Docker context', async () => {
|
await core.group('Create Docker context', async () => {
|
||||||
await Exec.exec('docker', ['context', 'create', 'setup-docker-action', '--docker', `host=${dockerHost}`]);
|
await Exec.exec('docker', ['context', 'create', this.contextName, '--docker', `host=${dockerHost}`]);
|
||||||
await Exec.exec('docker', ['context', 'use', 'setup-docker-action']);
|
await Exec.exec('docker', ['context', 'use', this.contextName]);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private async installLinux(toolDir: string, runDir: string): Promise<void> {
|
private async installLinux(): Promise<void> {
|
||||||
const dockerHost = `unix://${path.join(runDir, 'docker.sock')}`;
|
const dockerHost = `unix://${path.join(this.runDir, 'docker.sock')}`;
|
||||||
await io.mkdirP(runDir);
|
await io.mkdirP(this.runDir);
|
||||||
|
|
||||||
await core.group('Start Docker daemon', async () => {
|
await core.group('Start Docker daemon', async () => {
|
||||||
const bashPath: string = await io.which('bash', true);
|
const bashPath: string = await io.which('bash', true);
|
||||||
@@ -143,8 +168,8 @@ export class Install {
|
|||||||
shell: true,
|
shell: true,
|
||||||
stdio: ['ignore', process.stdout, process.stderr],
|
stdio: ['ignore', process.stdout, process.stderr],
|
||||||
env: Object.assign({}, process.env, {
|
env: Object.assign({}, process.env, {
|
||||||
TOOLDIR: toolDir,
|
TOOLDIR: this.toolDir,
|
||||||
RUNDIR: runDir,
|
RUNDIR: this.runDir,
|
||||||
DOCKER_HOST: dockerHost
|
DOCKER_HOST: dockerHost
|
||||||
}) as {
|
}) as {
|
||||||
[key: string]: string;
|
[key: string]: string;
|
||||||
@@ -182,18 +207,18 @@ export class Install {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await core.group('Create Docker context', async () => {
|
await core.group('Create Docker context', async () => {
|
||||||
await Exec.exec('docker', ['context', 'create', 'setup-docker-action', '--docker', `host=${dockerHost}`]);
|
await Exec.exec('docker', ['context', 'create', this.contextName, '--docker', `host=${dockerHost}`]);
|
||||||
await Exec.exec('docker', ['context', 'use', 'setup-docker-action']);
|
await Exec.exec('docker', ['context', 'use', this.contextName]);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private async installWindows(toolDir: string, runDir: string): Promise<void> {
|
private async installWindows(): Promise<void> {
|
||||||
const dockerHost = 'npipe:////./pipe/setup_docker_action';
|
const dockerHost = 'npipe:////./pipe/setup_docker_action';
|
||||||
|
|
||||||
await core.group('Install Docker daemon service', async () => {
|
await core.group('Install Docker daemon service', async () => {
|
||||||
const setupCmd = await Util.powershellCommand(setupDockerWinPs1(), {
|
const setupCmd = await Util.powershellCommand(setupDockerWinPs1(), {
|
||||||
ToolDir: toolDir,
|
ToolDir: this.toolDir,
|
||||||
RunDir: runDir,
|
RunDir: this.runDir,
|
||||||
DockerHost: dockerHost
|
DockerHost: dockerHost
|
||||||
});
|
});
|
||||||
await Exec.exec(setupCmd.command, setupCmd.args);
|
await Exec.exec(setupCmd.command, setupCmd.args);
|
||||||
@@ -202,19 +227,22 @@ export class Install {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await core.group('Create Docker context', async () => {
|
await core.group('Create Docker context', async () => {
|
||||||
await Exec.exec('docker', ['context', 'create', 'setup-docker-action', '--docker', `host=${dockerHost}`]);
|
await Exec.exec('docker', ['context', 'create', this.contextName, '--docker', `host=${dockerHost}`]);
|
||||||
await Exec.exec('docker', ['context', 'use', 'setup-docker-action']);
|
await Exec.exec('docker', ['context', 'use', this.contextName]);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public async tearDown(runDir: string): Promise<void> {
|
public async tearDown(): Promise<void> {
|
||||||
|
if (!this.runDir) {
|
||||||
|
throw new Error('runDir must be set');
|
||||||
|
}
|
||||||
switch (os.platform()) {
|
switch (os.platform()) {
|
||||||
case 'darwin': {
|
case 'darwin': {
|
||||||
await this.tearDownDarwin(runDir);
|
await this.tearDownDarwin();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'linux': {
|
case 'linux': {
|
||||||
await this.tearDownLinux(runDir);
|
await this.tearDownLinux();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'win32': {
|
case 'win32': {
|
||||||
@@ -227,7 +255,7 @@ export class Install {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async tearDownDarwin(runDir: string): Promise<void> {
|
private async tearDownDarwin(): Promise<void> {
|
||||||
await core.group('Docker daemon logs', async () => {
|
await core.group('Docker daemon logs', async () => {
|
||||||
await Exec.exec('colima', ['exec', '--', 'cat', '/var/log/docker.log']);
|
await Exec.exec('colima', ['exec', '--', 'cat', '/var/log/docker.log']);
|
||||||
});
|
});
|
||||||
@@ -235,25 +263,25 @@ export class Install {
|
|||||||
await Exec.exec('colima', ['stop', '--very-verbose']);
|
await Exec.exec('colima', ['stop', '--very-verbose']);
|
||||||
});
|
});
|
||||||
await core.group('Removing Docker context', async () => {
|
await core.group('Removing Docker context', async () => {
|
||||||
await Exec.exec('docker', ['context', 'rm', '-f', 'setup-docker-action']);
|
await Exec.exec('docker', ['context', 'rm', '-f', this.contextName]);
|
||||||
});
|
});
|
||||||
await core.group(`Cleaning up runDir`, async () => {
|
await core.group(`Cleaning up runDir`, async () => {
|
||||||
await Exec.exec('sudo', ['rm', '-rf', runDir]);
|
await Exec.exec('sudo', ['rm', '-rf', this.runDir]);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private async tearDownLinux(runDir: string): Promise<void> {
|
private async tearDownLinux(): Promise<void> {
|
||||||
await core.group('Docker daemon logs', async () => {
|
await core.group('Docker daemon logs', async () => {
|
||||||
core.info(fs.readFileSync(path.join(runDir, 'dockerd.log'), {encoding: 'utf8'}));
|
core.info(fs.readFileSync(path.join(this.runDir, 'dockerd.log'), {encoding: 'utf8'}));
|
||||||
});
|
});
|
||||||
await core.group('Stopping Docker daemon', async () => {
|
await core.group('Stopping Docker daemon', async () => {
|
||||||
await Exec.exec('sudo', ['kill', fs.readFileSync(path.join(runDir, 'docker.pid')).toString().trim()]);
|
await Exec.exec('sudo', ['kill', fs.readFileSync(path.join(this.runDir, 'docker.pid')).toString().trim()]);
|
||||||
});
|
});
|
||||||
await core.group('Removing Docker context', async () => {
|
await core.group('Removing Docker context', async () => {
|
||||||
await Exec.exec('docker', ['context', 'rm', '-f', 'setup-docker-action']);
|
await Exec.exec('docker', ['context', 'rm', '-f', this.contextName]);
|
||||||
});
|
});
|
||||||
await core.group(`Cleaning up runDir`, async () => {
|
await core.group(`Cleaning up runDir`, async () => {
|
||||||
await Exec.exec('sudo', ['rm', '-rf', runDir]);
|
await Exec.exec('sudo', ['rm', '-rf', this.runDir]);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -263,7 +291,7 @@ export class Install {
|
|||||||
await Exec.exec(logCmd.command, logCmd.args);
|
await Exec.exec(logCmd.command, logCmd.args);
|
||||||
});
|
});
|
||||||
await core.group('Removing Docker context', async () => {
|
await core.group('Removing Docker context', async () => {
|
||||||
await Exec.exec('docker', ['context', 'rm', '-f', 'setup-docker-action']);
|
await Exec.exec('docker', ['context', 'rm', '-f', this.contextName]);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user