Files
actions-toolkit/src/buildx/builder.ts
CrazyMax 35a8193474 Exec class
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2023-02-20 09:18:53 +01:00

123 lines
3.5 KiB
TypeScript

/**
* 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.
*/
import {Buildx} from './buildx';
import {Exec} from '../exec';
import {BuilderInfo, NodeInfo} from '../types/builder';
export interface BuilderOpts {
buildx?: Buildx;
}
export class Builder {
private readonly buildx: Buildx;
constructor(opts?: BuilderOpts) {
this.buildx = opts?.buildx || new Buildx();
}
public async inspect(name: string): Promise<BuilderInfo> {
const cmd = await 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;
}
}