2023-01-31 03:34:51 +01:00
|
|
|
/**
|
|
|
|
|
* Copyright 2023 actions-toolkit authors
|
|
|
|
|
*
|
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
|
*
|
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
*
|
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
|
* limitations under the License.
|
|
|
|
|
*/
|
|
|
|
|
|
2023-01-23 10:07:14 +01:00
|
|
|
import * as exec from '@actions/exec';
|
|
|
|
|
|
|
|
|
|
import {Buildx} from './buildx';
|
2023-01-31 21:13:39 +01:00
|
|
|
import {Context} from '../context';
|
2023-01-23 10:07:14 +01:00
|
|
|
|
2023-01-31 21:13:39 +01:00
|
|
|
import {BuilderInfo, NodeInfo} from '../types/builder';
|
2023-01-23 10:07:14 +01:00
|
|
|
|
|
|
|
|
export interface BuilderOpts {
|
2023-01-30 00:08:45 +01:00
|
|
|
context: Context;
|
2023-01-23 10:07:14 +01:00
|
|
|
buildx?: Buildx;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class Builder {
|
2023-01-30 00:08:45 +01:00
|
|
|
private readonly context: Context;
|
|
|
|
|
private readonly buildx: Buildx;
|
|
|
|
|
|
|
|
|
|
constructor(opts: BuilderOpts) {
|
|
|
|
|
this.context = opts.context;
|
|
|
|
|
this.buildx =
|
|
|
|
|
opts?.buildx ||
|
|
|
|
|
new Buildx({
|
|
|
|
|
context: this.context
|
|
|
|
|
});
|
2023-01-23 10:07:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public async inspect(name: string): Promise<BuilderInfo> {
|
|
|
|
|
const cmd = this.buildx.getCommand(['inspect', name]);
|
|
|
|
|
return await exec
|
|
|
|
|
.getExecOutput(cmd.command, cmd.args, {
|
|
|
|
|
ignoreReturnCode: true,
|
|
|
|
|
silent: true
|
|
|
|
|
})
|
|
|
|
|
.then(res => {
|
|
|
|
|
if (res.stderr.length > 0 && res.exitCode != 0) {
|
|
|
|
|
throw new Error(res.stderr.trim());
|
|
|
|
|
}
|
|
|
|
|
return Builder.parseInspect(res.stdout);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static parseInspect(data: string): BuilderInfo {
|
|
|
|
|
const builder: BuilderInfo = {
|
|
|
|
|
nodes: []
|
|
|
|
|
};
|
|
|
|
|
let node: NodeInfo = {};
|
|
|
|
|
for (const line of data.trim().split(`\n`)) {
|
|
|
|
|
const [key, ...rest] = line.split(':');
|
|
|
|
|
const value = rest.map(v => v.trim()).join(':');
|
|
|
|
|
if (key.length == 0 || value.length == 0) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
switch (key.toLowerCase()) {
|
|
|
|
|
case 'name': {
|
|
|
|
|
if (builder.name == undefined) {
|
|
|
|
|
builder.name = value;
|
|
|
|
|
} else {
|
|
|
|
|
if (Object.keys(node).length > 0) {
|
|
|
|
|
builder.nodes.push(node);
|
|
|
|
|
node = {};
|
|
|
|
|
}
|
|
|
|
|
node.name = value;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 'driver': {
|
|
|
|
|
builder.driver = value;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 'last activity': {
|
|
|
|
|
builder.lastActivity = new Date(value);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 'endpoint': {
|
|
|
|
|
node.endpoint = value;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 'driver options': {
|
|
|
|
|
node.driverOpts = (value.match(/(\w+)="([^"]*)"/g) || []).map(v => v.replace(/^(.*)="(.*)"$/g, '$1=$2'));
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 'status': {
|
|
|
|
|
node.status = value;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 'flags': {
|
|
|
|
|
node.buildkitdFlags = value;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 'buildkit': {
|
|
|
|
|
node.buildkitVersion = value;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 'platforms': {
|
|
|
|
|
let platforms: Array<string> = [];
|
|
|
|
|
// if a preferred platform is being set then use only these
|
|
|
|
|
// https://docs.docker.com/engine/reference/commandline/buildx_inspect/#get-information-about-a-builder-instance
|
|
|
|
|
if (value.includes('*')) {
|
|
|
|
|
for (const platform of value.split(', ')) {
|
|
|
|
|
if (platform.includes('*')) {
|
|
|
|
|
platforms.push(platform.replace('*', ''));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// otherwise set all platforms available
|
|
|
|
|
platforms = value.split(', ');
|
|
|
|
|
}
|
|
|
|
|
node.platforms = platforms.join(',');
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (Object.keys(node).length > 0) {
|
|
|
|
|
builder.nodes.push(node);
|
|
|
|
|
}
|
|
|
|
|
return builder;
|
|
|
|
|
}
|
|
|
|
|
}
|