docker(install): opt to expose local tcp address
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
This commit is contained in:
@@ -69,6 +69,36 @@ describe('rootless', () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('tcp', () => {
|
||||||
|
// prettier-ignore
|
||||||
|
test.each(getSources(false))(
|
||||||
|
'install %s', async (source) => {
|
||||||
|
await ensureNoSystemContainerd();
|
||||||
|
const install = new Install({
|
||||||
|
source: source,
|
||||||
|
runDir: tmpDir(),
|
||||||
|
contextName: 'foo',
|
||||||
|
daemonConfig: `{"debug":true}`,
|
||||||
|
localTCPPort: 2378
|
||||||
|
});
|
||||||
|
await expect(
|
||||||
|
tryInstall(install, async () => {
|
||||||
|
const out = await Docker.getExecOutput(['info'], {
|
||||||
|
env: Object.assign({}, process.env, {
|
||||||
|
DOCKER_HOST: 'tcp://localhost:2378',
|
||||||
|
DOCKER_CONTENT_TRUST: 'false'
|
||||||
|
}) as {
|
||||||
|
[key: string]: string;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
expect(out.exitCode).toBe(0);
|
||||||
|
})
|
||||||
|
).resolves.not.toThrow();
|
||||||
|
},
|
||||||
|
30 * 60 * 1000
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
async function tryInstall(install: Install, extraCheck?: () => Promise<void>): Promise<void> {
|
async function tryInstall(install: Install, extraCheck?: () => Promise<void>): Promise<void> {
|
||||||
try {
|
try {
|
||||||
await install.download();
|
await install.download();
|
||||||
|
|||||||
@@ -51,7 +51,10 @@ param(
|
|||||||
[string]$RunDir,
|
[string]$RunDir,
|
||||||
|
|
||||||
[Parameter(Mandatory = $true)]
|
[Parameter(Mandatory = $true)]
|
||||||
[string]$DockerHost,
|
[string]$DockerHostSocket,
|
||||||
|
|
||||||
|
[Parameter(Mandatory = $false)]
|
||||||
|
[string]$DockerHostTCP,
|
||||||
|
|
||||||
[Parameter(Mandatory = $false)]
|
[Parameter(Mandatory = $false)]
|
||||||
[string]$DaemonConfig)
|
[string]$DaemonConfig)
|
||||||
@@ -82,7 +85,7 @@ if (Get-Service docker -ErrorAction SilentlyContinue) {
|
|||||||
$env:Path = "$ToolDir;" + [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")
|
$env:Path = "$ToolDir;" + [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")
|
||||||
Write-Host "Path: $env:Path"
|
Write-Host "Path: $env:Path"
|
||||||
|
|
||||||
$env:DOCKER_HOST = $DockerHost
|
$env:DOCKER_HOST = $DockerHostSocket
|
||||||
Write-Host "DOCKER_HOST: $env:DOCKER_HOST"
|
Write-Host "DOCKER_HOST: $env:DOCKER_HOST"
|
||||||
|
|
||||||
if ($DaemonConfig) {
|
if ($DaemonConfig) {
|
||||||
@@ -91,16 +94,21 @@ if ($DaemonConfig) {
|
|||||||
$DaemonConfig | Out-File -FilePath "$env:ProgramData\\Docker\\config\\daemon.json"
|
$DaemonConfig | Out-File -FilePath "$env:ProgramData\\Docker\\config\\daemon.json"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$arguments = @(
|
||||||
|
"--host=$DockerHostSocket",
|
||||||
|
"--data-root=$RunDir\\\\moby-root",
|
||||||
|
"--exec-root=$RunDir\\\\moby-exec",
|
||||||
|
"--pidfile=$RunDir\\\\docker.pid",
|
||||||
|
"--register-service"
|
||||||
|
)
|
||||||
|
if ($DockerHostTCP) {
|
||||||
|
$arguments += "--host=$DockerHostTCP"
|
||||||
|
}
|
||||||
|
|
||||||
Write-Host "Creating service"
|
Write-Host "Creating service"
|
||||||
New-Item -ItemType Directory "$RunDir\\moby-root" -ErrorAction SilentlyContinue | Out-Null
|
New-Item -ItemType Directory "$RunDir\\moby-root" -ErrorAction SilentlyContinue | Out-Null
|
||||||
New-Item -ItemType Directory "$RunDir\\moby-exec" -ErrorAction SilentlyContinue | Out-Null
|
New-Item -ItemType Directory "$RunDir\\moby-exec" -ErrorAction SilentlyContinue | Out-Null
|
||||||
Start-Process -Wait -NoNewWindow "$ToolDir\\dockerd" \`
|
Start-Process -Wait -NoNewWindow "$ToolDir\\dockerd" -ArgumentList $arguments
|
||||||
-ArgumentList \`
|
|
||||||
"--host=$DockerHost", \`
|
|
||||||
"--data-root=$RunDir\\moby-root", \`
|
|
||||||
"--exec-root=$RunDir\\moby-exec", \`
|
|
||||||
"--pidfile=$RunDir\\docker.pid", \`
|
|
||||||
"--register-service"
|
|
||||||
Write-Host "Starting service"
|
Write-Host "Starting service"
|
||||||
Start-Service -Name docker
|
Start-Service -Name docker
|
||||||
Write-Host "Service started successfully!"
|
Write-Host "Service started successfully!"
|
||||||
@@ -231,6 +239,11 @@ provision:
|
|||||||
export DEBIAN_FRONTEND=noninteractive
|
export DEBIAN_FRONTEND=noninteractive
|
||||||
if [ "{{srcType}}" == "archive" ]; then
|
if [ "{{srcType}}" == "archive" ]; then
|
||||||
curl -fsSL https://get.docker.com | sh -s -- --channel {{srcArchiveChannel}} --version {{srcArchiveVersion}}
|
curl -fsSL https://get.docker.com | sh -s -- --channel {{srcArchiveChannel}} --version {{srcArchiveVersion}}
|
||||||
|
sed -i 's|^ExecStart=.*|ExecStart=/usr/bin/dockerd -H fd://{{#if localTCPPort}} -H tcp://0.0.0.0:2375{{/if}} --containerd=/run/containerd/containerd.sock|' /usr/lib/systemd/system/docker.service
|
||||||
|
systemctl daemon-reload
|
||||||
|
systemctl restart docker
|
||||||
|
systemctl status docker.socket || true
|
||||||
|
systemctl status docker.service || true
|
||||||
elif [ "{{srcType}}" == "image" ]; then
|
elif [ "{{srcType}}" == "image" ]; then
|
||||||
arch=$(uname -m)
|
arch=$(uname -m)
|
||||||
case $arch in
|
case $arch in
|
||||||
@@ -250,7 +263,7 @@ provision:
|
|||||||
wget https://raw.githubusercontent.com/moby/moby/{{gitCommit}}/contrib/init/systemd/docker.socket \
|
wget https://raw.githubusercontent.com/moby/moby/{{gitCommit}}/contrib/init/systemd/docker.socket \
|
||||||
-O /etc/systemd/system/docker.socket
|
-O /etc/systemd/system/docker.socket
|
||||||
|
|
||||||
sed -i 's|^ExecStart=.*|ExecStart=/usr/local/bin/dockerd -H fd://|' /etc/systemd/system/docker.service
|
sed -i 's|^ExecStart=.*|ExecStart=/usr/local/bin/dockerd -H fd://{{#if localTCPPort}} -H tcp://0.0.0.0:2375{{/if}}|' /etc/systemd/system/docker.service
|
||||||
sed -i 's|containerd.service||' /etc/systemd/system/docker.service
|
sed -i 's|containerd.service||' /etc/systemd/system/docker.service
|
||||||
if ! getent group docker; then
|
if ! getent group docker; then
|
||||||
groupadd --system docker
|
groupadd --system docker
|
||||||
@@ -285,6 +298,10 @@ hostResolver:
|
|||||||
portForwards:
|
portForwards:
|
||||||
- guestSocket: "/var/run/docker.sock"
|
- guestSocket: "/var/run/docker.sock"
|
||||||
hostSocket: "{{dockerSock}}"
|
hostSocket: "{{dockerSock}}"
|
||||||
|
{{#if localTCPPort}}
|
||||||
|
- guestPort: 2375
|
||||||
|
hostPort: {{localTCPPort}}
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
audio:
|
audio:
|
||||||
# EXPERIMENTAL
|
# EXPERIMENTAL
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ export interface InstallOpts {
|
|||||||
contextName?: string;
|
contextName?: string;
|
||||||
daemonConfig?: string;
|
daemonConfig?: string;
|
||||||
rootless?: boolean;
|
rootless?: boolean;
|
||||||
|
localTCPPort?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface LimaImage {
|
interface LimaImage {
|
||||||
@@ -65,13 +66,15 @@ interface LimaImage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class Install {
|
export class Install {
|
||||||
private runDir: string;
|
private readonly runDir: string;
|
||||||
private readonly source: InstallSource;
|
private readonly source: InstallSource;
|
||||||
private readonly contextName: string;
|
private readonly contextName: string;
|
||||||
private readonly daemonConfig?: string;
|
private readonly daemonConfig?: string;
|
||||||
|
private readonly rootless: boolean;
|
||||||
|
private readonly localTCPPort?: number;
|
||||||
|
|
||||||
private _version: string | undefined;
|
private _version: string | undefined;
|
||||||
private _toolDir: string | undefined;
|
private _toolDir: string | undefined;
|
||||||
private rootless: boolean;
|
|
||||||
|
|
||||||
private gitCommit: string | undefined;
|
private gitCommit: string | undefined;
|
||||||
|
|
||||||
@@ -79,7 +82,6 @@ export class Install {
|
|||||||
|
|
||||||
constructor(opts: InstallOpts) {
|
constructor(opts: InstallOpts) {
|
||||||
this.runDir = opts.runDir;
|
this.runDir = opts.runDir;
|
||||||
this.rootless = opts.rootless || false;
|
|
||||||
this.source = opts.source || {
|
this.source = opts.source || {
|
||||||
type: 'archive',
|
type: 'archive',
|
||||||
version: 'latest',
|
version: 'latest',
|
||||||
@@ -87,6 +89,8 @@ export class Install {
|
|||||||
};
|
};
|
||||||
this.contextName = opts.contextName || 'setup-docker-action';
|
this.contextName = opts.contextName || 'setup-docker-action';
|
||||||
this.daemonConfig = opts.daemonConfig;
|
this.daemonConfig = opts.daemonConfig;
|
||||||
|
this.rootless = opts.rootless || false;
|
||||||
|
this.localTCPPort = opts.localTCPPort;
|
||||||
}
|
}
|
||||||
|
|
||||||
get toolDir(): string {
|
get toolDir(): string {
|
||||||
@@ -268,6 +272,7 @@ export class Install {
|
|||||||
customImages: Install.limaCustomImages(),
|
customImages: Install.limaCustomImages(),
|
||||||
daemonConfig: limaDaemonConfig,
|
daemonConfig: limaDaemonConfig,
|
||||||
dockerSock: `${limaDir}/docker.sock`,
|
dockerSock: `${limaDir}/docker.sock`,
|
||||||
|
localTCPPort: this.localTCPPort,
|
||||||
gitCommit: this.gitCommit,
|
gitCommit: this.gitCommit,
|
||||||
srcType: src.type,
|
srcType: src.type,
|
||||||
srcArchiveVersion: this._version, // Use the resolved version (e.g. latest -> 27.4.0)
|
srcArchiveVersion: this._version, // Use the resolved version (e.g. latest -> 27.4.0)
|
||||||
@@ -376,8 +381,10 @@ export class Install {
|
|||||||
await Exec.exec('sudo', ['sh', '-c', 'echo 0 > /proc/sys/kernel/apparmor_restrict_unprivileged_userns']);
|
await Exec.exec('sudo', ['sh', '-c', 'echo 0 > /proc/sys/kernel/apparmor_restrict_unprivileged_userns']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
let cmd = `${dockerPath} --host="${dockerHost}" --config-file="${daemonConfigPath}" --exec-root="${this.runDir}/execroot" --data-root="${this.runDir}/data" --pidfile="${this.runDir}/docker.pid"`;
|
||||||
const cmd = `${dockerPath} --host="${dockerHost}" --config-file="${daemonConfigPath}" --exec-root="${this.runDir}/execroot" --data-root="${this.runDir}/data" --pidfile="${this.runDir}/docker.pid"`;
|
if (this.localTCPPort) {
|
||||||
|
cmd += ` --host="tcp://127.0.0.1:${this.localTCPPort}"`;
|
||||||
|
}
|
||||||
core.info(`[command] ${cmd}`); // https://github.com/actions/toolkit/blob/3d652d3133965f63309e4b2e1c8852cdbdcb3833/packages/exec/src/toolrunner.ts#L47
|
core.info(`[command] ${cmd}`); // https://github.com/actions/toolkit/blob/3d652d3133965f63309e4b2e1c8852cdbdcb3833/packages/exec/src/toolrunner.ts#L47
|
||||||
let sudo = 'sudo';
|
let sudo = 'sudo';
|
||||||
if (this.rootless) {
|
if (this.rootless) {
|
||||||
@@ -438,7 +445,7 @@ EOF`,
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async installWindows(): Promise<string> {
|
private async installWindows(): Promise<string> {
|
||||||
const dockerHost = 'npipe:////./pipe/setup_docker_action';
|
const dockerHostSocket = 'npipe:////./pipe/setup_docker_action';
|
||||||
|
|
||||||
let daemonConfig = undefined;
|
let daemonConfig = undefined;
|
||||||
const daemonConfigPath = path.join(this.runDir, 'daemon.json');
|
const daemonConfigPath = path.join(this.runDir, 'daemon.json');
|
||||||
@@ -460,24 +467,29 @@ EOF`,
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const params = {
|
||||||
|
ToolDir: this.toolDir,
|
||||||
|
RunDir: this.runDir,
|
||||||
|
DockerHostSocket: dockerHostSocket,
|
||||||
|
DaemonConfig: daemonConfigStr
|
||||||
|
};
|
||||||
|
if (this.localTCPPort) {
|
||||||
|
params['DockerHostTCP'] = `tcp://127.0.0.1:${this.localTCPPort}`;
|
||||||
|
}
|
||||||
|
|
||||||
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(), params);
|
||||||
ToolDir: this.toolDir,
|
|
||||||
RunDir: this.runDir,
|
|
||||||
DockerHost: dockerHost,
|
|
||||||
DaemonConfig: daemonConfigStr
|
|
||||||
});
|
|
||||||
await Exec.exec(setupCmd.command, setupCmd.args);
|
await Exec.exec(setupCmd.command, setupCmd.args);
|
||||||
const logCmd = await Util.powershellCommand(dockerServiceLogsPs1());
|
const logCmd = await Util.powershellCommand(dockerServiceLogsPs1());
|
||||||
await Exec.exec(logCmd.command, logCmd.args);
|
await Exec.exec(logCmd.command, logCmd.args);
|
||||||
});
|
});
|
||||||
|
|
||||||
await core.group('Create Docker context', async () => {
|
await core.group('Create Docker context', async () => {
|
||||||
await Docker.exec(['context', 'create', this.contextName, '--docker', `host=${dockerHost}`]);
|
await Docker.exec(['context', 'create', this.contextName, '--docker', `host=${dockerHostSocket}`]);
|
||||||
await Docker.exec(['context', 'use', this.contextName]);
|
await Docker.exec(['context', 'use', this.contextName]);
|
||||||
});
|
});
|
||||||
|
|
||||||
return dockerHost;
|
return dockerHostSocket;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async tearDown(): Promise<void> {
|
public async tearDown(): Promise<void> {
|
||||||
|
|||||||
Reference in New Issue
Block a user