diff --git a/__tests__/.fixtures/inspect12.txt b/__tests__/.fixtures/inspect12.txt new file mode 100644 index 0000000..f7d63bb --- /dev/null +++ b/__tests__/.fixtures/inspect12.txt @@ -0,0 +1,55 @@ +Name: nvidia +Driver: docker-container +Last Activity: 2025-02-14 15:57:45 +0000 UTC + +Nodes: +Name: nvidia0 +Endpoint: unix:///var/run/docker.sock +Driver Options: image="moby/buildkit:local" +Status: running +BuildKit daemon flags: --allow-insecure-entitlement=network.host +BuildKit version: v0.20.0-rc2-4-gd30d8e22c.m +Platforms: linux/amd64, linux/amd64/v2, linux/amd64/v3, linux/arm64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/arm/v7, linux/arm/v6 +Features: + Cache export: true + Docker exporter: true + Multi-platform build: true + OCI exporter: true +Labels: + org.mobyproject.buildkit.worker.executor: oci + org.mobyproject.buildkit.worker.hostname: 76ac9a510d96 + org.mobyproject.buildkit.worker.network: host + org.mobyproject.buildkit.worker.oci.process-mode: sandbox + org.mobyproject.buildkit.worker.selinux.enabled: false + org.mobyproject.buildkit.worker.snapshotter: overlayfs +Devices: + Name: nvidia.com/gpu=all + Automatically allowed: true + Annotations: + foo: bar + org.mobyproject.buildkit.device.autoallow: true + Name: docker.com/gpu=venus + Automatically allowed: false + Annotations: + bar: baz +GC Policy rule#0: + All: false + Filters: type==source.local,type==exec.cachemount,type==source.git.checkout + Keep Duration: 48h0m0s + Max Used Space: 488.3MiB +GC Policy rule#1: + All: false + Keep Duration: 1440h0m0s + Reserved Space: 9.313GiB + Max Used Space: 93.13GiB + Min Free Space: 188.1GiB +GC Policy rule#2: + All: false + Reserved Space: 9.313GiB + Max Used Space: 93.13GiB + Min Free Space: 188.1GiB +GC Policy rule#3: + All: true + Reserved Space: 9.313GiB + Max Used Space: 93.13GiB + Min Free Space: 188.1GiB diff --git a/__tests__/buildx/builder.test.ts b/__tests__/buildx/builder.test.ts index 011a33f..b888505 100644 --- a/__tests__/buildx/builder.test.ts +++ b/__tests__/buildx/builder.test.ts @@ -466,6 +466,89 @@ baz = qux ] } ], + [ + 'inspect12.txt', + { + "name": "nvidia", + "driver": "docker-container", + "lastActivity": new Date("2025-02-14T15:57:45.000Z"), + "nodes": [ + { + "buildkit": "v0.20.0-rc2-4-gd30d8e22c.m", + "buildkitd-flags": "--allow-insecure-entitlement=network.host", + "driver-opts": [ + "image=moby/buildkit:local", + ], + "endpoint": "unix:///var/run/docker.sock", + "name": "nvidia0", + "platforms": "linux/amd64,linux/amd64/v2,linux/amd64/v3,linux/arm64,linux/riscv64,linux/ppc64le,linux/s390x,linux/386,linux/arm/v7,linux/arm/v6", + "status": "running", + "features": { + "Cache export": true, + "Docker exporter": true, + "Multi-platform build": true, + "OCI exporter": true, + }, + "labels": { + "org.mobyproject.buildkit.worker.executor": "oci", + "org.mobyproject.buildkit.worker.hostname": "76ac9a510d96", + "org.mobyproject.buildkit.worker.network": "host", + "org.mobyproject.buildkit.worker.oci.process-mode": "sandbox", + "org.mobyproject.buildkit.worker.selinux.enabled": "false", + "org.mobyproject.buildkit.worker.snapshotter": "overlayfs", + }, + "devices": [ + { + "annotations": { + "foo": "bar", + "org.mobyproject.buildkit.device.autoallow": "true" + }, + "autoAllow": true, + "name": "nvidia.com/gpu=all" + }, + { + "annotations": { + "bar": "baz" + }, + "autoAllow": false, + "name": "docker.com/gpu=venus" + } + ], + "gcPolicy": [ + { + "all": false, + "filter": [ + "type==source.local", + "type==exec.cachemount", + "type==source.git.checkout" + ], + "keepDuration": "48h0m0s", + "maxUsedSpace": "488.3MiB", + }, + { + "all": false, + "keepDuration": "1440h0m0s", + "maxUsedSpace": "93.13GiB", + "minFreeSpace": "188.1GiB", + "reservedSpace": "9.313GiB", + }, + { + "all": false, + "maxUsedSpace": "93.13GiB", + "minFreeSpace": "188.1GiB", + "reservedSpace": "9.313GiB", + }, + { + "all": true, + "maxUsedSpace": "93.13GiB", + "minFreeSpace": "188.1GiB", + "reservedSpace": "9.313GiB", + } + ] + } + ] + } + ], ])('given %p', async (inspectFile, expected) => { expect(await Builder.parseInspect(fs.readFileSync(path.join(fixturesDir, inspectFile)).toString())).toEqual(expected); }); diff --git a/src/buildx/builder.ts b/src/buildx/builder.ts index 578d697..2e54e8e 100644 --- a/src/buildx/builder.ts +++ b/src/buildx/builder.ts @@ -19,7 +19,7 @@ import * as core from '@actions/core'; import {Buildx} from './buildx'; import {Exec} from '../exec'; -import {BuilderInfo, GCPolicy, NodeInfo} from '../types/buildx/builder'; +import {BuilderInfo, Device, GCPolicy, NodeInfo} from '../types/buildx/builder'; export interface BuilderOpts { buildx?: Buildx; @@ -89,6 +89,7 @@ export class Builder { let parsingType: string | undefined; let currentNode: NodeInfo = {}; let currentGCPolicy: GCPolicy | undefined; + let currentDevice: Device | undefined; let currentFile: string | undefined; for (const line of data.trim().split(`\n`)) { const [key, ...rest] = line.split(':'); @@ -172,6 +173,10 @@ export class Builder { parsingType = 'label'; currentNode.labels = {}; break; + case lkey == 'devices': + parsingType = 'devices'; + currentNode.devices = currentNode.devices || []; + break; case lkey.startsWith('gc policy rule#'): parsingType = 'gcpolicy'; if (currentNode.gcPolicy && currentGCPolicy) { @@ -186,6 +191,10 @@ export class Builder { currentNode.files[currentFile] = ''; break; default: { + if (parsingType && parsingType !== 'devices' && currentNode.devices && currentDevice) { + currentNode.devices.push(currentDevice); + currentDevice = undefined; + } switch (parsingType || '') { case 'features': { currentNode.features = currentNode.features || {}; @@ -197,6 +206,42 @@ export class Builder { currentNode.labels[key.trim()] = value; break; } + case 'devices': { + switch (lkey.trim()) { + case 'name': { + if (currentNode.devices && currentDevice) { + currentNode.devices.push(currentDevice); + } + currentDevice = {}; + currentDevice.name = value; + break; + } + case 'on-demand': { + if (currentDevice && value) { + currentDevice.onDemand = value == 'true'; + } + break; + } + case 'automatically allowed': { + if (currentDevice && value) { + currentDevice.autoAllow = value == 'true'; + } + break; + } + case 'annotations': { + if (currentDevice) { + currentDevice.annotations = currentDevice.annotations || {}; + } + break; + } + default: { + if (currentDevice && currentDevice.annotations) { + currentDevice.annotations[key.trim()] = value; + } + } + } + break; + } case 'gcpolicy': { currentNode.gcPolicy = currentNode.gcPolicy || []; currentGCPolicy = currentGCPolicy || {}; @@ -219,6 +264,18 @@ export class Builder { currentGCPolicy.keepBytes = value; break; } + case 'reserved space': { + currentGCPolicy.reservedSpace = value; + break; + } + case 'max used space': { + currentGCPolicy.maxUsedSpace = value; + break; + } + case 'min free space': { + currentGCPolicy.minFreeSpace = value; + break; + } } break; } @@ -235,6 +292,9 @@ export class Builder { } } } + if (currentDevice && currentNode.devices) { + currentNode.devices.push(currentDevice); + } if (currentGCPolicy && currentNode.gcPolicy) { currentNode.gcPolicy.push(currentGCPolicy); } diff --git a/src/types/buildx/builder.ts b/src/types/buildx/builder.ts index b319d40..f4f2cc1 100644 --- a/src/types/buildx/builder.ts +++ b/src/types/buildx/builder.ts @@ -34,13 +34,24 @@ export interface NodeInfo extends Node { buildkit?: string; features?: Record; labels?: Record; + devices?: Array; gcPolicy?: Array; files?: Record; } +export interface Device { + name?: string; + annotations?: Record; + autoAllow?: boolean; + onDemand?: boolean; +} + export interface GCPolicy { all?: boolean; filter?: string[]; keepDuration?: string; - keepBytes?: string; + keepBytes?: string; // deprecated, use reservedSpace instead + reservedSpace?: string; + maxUsedSpace?: string; + minFreeSpace?: string; }