typekro 0.27.0 → 0.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.tsbuildinfo +1 -1
- package/dist/core/containers/build.d.ts +2 -46
- package/dist/core/containers/build.d.ts.map +1 -1
- package/dist/core/containers/build.js +219 -134
- package/dist/core/containers/build.js.map +1 -1
- package/dist/core/containers/errors.d.ts +4 -0
- package/dist/core/containers/errors.d.ts.map +1 -1
- package/dist/core/containers/errors.js +14 -1
- package/dist/core/containers/errors.js.map +1 -1
- package/dist/core/containers/exec.d.ts +6 -23
- package/dist/core/containers/exec.d.ts.map +1 -1
- package/dist/core/containers/exec.js +94 -78
- package/dist/core/containers/exec.js.map +1 -1
- package/dist/core/containers/image.d.ts +11 -7
- package/dist/core/containers/image.d.ts.map +1 -1
- package/dist/core/containers/image.js +102 -13
- package/dist/core/containers/image.js.map +1 -1
- package/dist/core/containers/index.d.ts +5 -1
- package/dist/core/containers/index.d.ts.map +1 -1
- package/dist/core/containers/index.js +3 -0
- package/dist/core/containers/index.js.map +1 -1
- package/dist/core/containers/registries/credentials.d.ts +30 -0
- package/dist/core/containers/registries/credentials.d.ts.map +1 -0
- package/dist/core/containers/registries/credentials.js +87 -0
- package/dist/core/containers/registries/credentials.js.map +1 -0
- package/dist/core/containers/registries/docker-session.d.ts +14 -0
- package/dist/core/containers/registries/docker-session.d.ts.map +1 -0
- package/dist/core/containers/registries/docker-session.js +164 -0
- package/dist/core/containers/registries/docker-session.js.map +1 -0
- package/dist/core/containers/registries/ecr.d.ts +2 -3
- package/dist/core/containers/registries/ecr.d.ts.map +1 -1
- package/dist/core/containers/registries/ecr.js +13 -22
- package/dist/core/containers/registries/ecr.js.map +1 -1
- package/dist/core/containers/registries/harbor.d.ts +7 -0
- package/dist/core/containers/registries/harbor.d.ts.map +1 -0
- package/dist/core/containers/registries/harbor.js +9 -0
- package/dist/core/containers/registries/harbor.js.map +1 -0
- package/dist/core/containers/registries/index.d.ts.map +1 -1
- package/dist/core/containers/registries/index.js +5 -0
- package/dist/core/containers/registries/index.js.map +1 -1
- package/dist/core/containers/registries/oci.d.ts +13 -0
- package/dist/core/containers/registries/oci.d.ts.map +1 -0
- package/dist/core/containers/registries/oci.js +68 -0
- package/dist/core/containers/registries/oci.js.map +1 -0
- package/dist/core/containers/registries/orbstack.d.ts +2 -3
- package/dist/core/containers/registries/orbstack.d.ts.map +1 -1
- package/dist/core/containers/registries/orbstack.js +8 -8
- package/dist/core/containers/registries/orbstack.js.map +1 -1
- package/dist/core/containers/registries/types.d.ts +75 -49
- package/dist/core/containers/registries/types.d.ts.map +1 -1
- package/dist/core/containers/registries/types.js +1 -9
- package/dist/core/containers/registries/types.js.map +1 -1
- package/dist/core/deployment/direct-factory.d.ts.map +1 -1
- package/dist/core/deployment/direct-factory.js +15 -8
- package/dist/core/deployment/direct-factory.js.map +1 -1
- package/dist/core/deployment/engine.d.ts.map +1 -1
- package/dist/core/deployment/engine.js +46 -5
- package/dist/core/deployment/engine.js.map +1 -1
- package/dist/core/deployment/kro-factory.d.ts +7 -7
- package/dist/core/deployment/kro-factory.d.ts.map +1 -1
- package/dist/core/deployment/kro-factory.js +148 -60
- package/dist/core/deployment/kro-factory.js.map +1 -1
- package/dist/core/deployment/kro-instance-safety.d.ts +7 -0
- package/dist/core/deployment/kro-instance-safety.d.ts.map +1 -1
- package/dist/core/deployment/kro-instance-safety.js +15 -0
- package/dist/core/deployment/kro-instance-safety.js.map +1 -1
- package/dist/core/deployment/kro-namespace-teardown.d.ts +7 -5
- package/dist/core/deployment/kro-namespace-teardown.d.ts.map +1 -1
- package/dist/core/deployment/kro-namespace-teardown.js +29 -10
- package/dist/core/deployment/kro-namespace-teardown.js.map +1 -1
- package/dist/core/deployment/kro-readiness.d.ts +1 -0
- package/dist/core/deployment/kro-readiness.d.ts.map +1 -1
- package/dist/core/deployment/kro-readiness.js +22 -1
- package/dist/core/deployment/kro-readiness.js.map +1 -1
- package/dist/core/deployment/rollback-manager.d.ts +13 -0
- package/dist/core/deployment/rollback-manager.d.ts.map +1 -1
- package/dist/core/deployment/rollback-manager.js +8 -0
- package/dist/core/deployment/rollback-manager.js.map +1 -1
- package/dist/core/serialization/core.js +3 -1
- package/dist/core/serialization/core.js.map +1 -1
- package/dist/core/serialization/schema.d.ts +2 -2
- package/dist/core/serialization/schema.d.ts.map +1 -1
- package/dist/core/serialization/schema.js +57 -4
- package/dist/core/serialization/schema.js.map +1 -1
- package/dist/core/types/serialization.d.ts +9 -0
- package/dist/core/types/serialization.d.ts.map +1 -1
- package/dist/factories/apisix/types.js +11 -11
- package/dist/factories/apisix/types.js.map +1 -1
- package/dist/factories/caddy/types.js +2 -2
- package/dist/factories/caddy/types.js.map +1 -1
- package/dist/factories/cert-manager/types.js +6 -6
- package/dist/factories/cert-manager/types.js.map +1 -1
- package/dist/factories/cilium/compositions/cilium-bootstrap.js +6 -6
- package/dist/factories/cilium/compositions/cilium-bootstrap.js.map +1 -1
- package/dist/factories/clickhouse/compositions/clickhouse-cluster.js +1 -1
- package/dist/factories/clickhouse/compositions/clickhouse-cluster.js.map +1 -1
- package/dist/factories/clickhouse/types.js +8 -8
- package/dist/factories/clickhouse/types.js.map +1 -1
- package/dist/factories/clickstack/types.js +5 -5
- package/dist/factories/clickstack/types.js.map +1 -1
- package/dist/factories/cnpg/types.js +6 -6
- package/dist/factories/cnpg/types.js.map +1 -1
- package/dist/factories/dagster/types.js +14 -14
- package/dist/factories/dagster/types.js.map +1 -1
- package/dist/factories/external-dns/types.js +3 -3
- package/dist/factories/external-dns/types.js.map +1 -1
- package/dist/factories/harbor/compositions/harbor-installation.d.ts +610 -0
- package/dist/factories/harbor/compositions/harbor-installation.d.ts.map +1 -0
- package/dist/factories/harbor/compositions/harbor-installation.js +348 -0
- package/dist/factories/harbor/compositions/harbor-installation.js.map +1 -0
- package/dist/factories/harbor/compositions/index.d.ts +2 -0
- package/dist/factories/harbor/compositions/index.d.ts.map +1 -0
- package/dist/factories/harbor/compositions/index.js +2 -0
- package/dist/factories/harbor/compositions/index.js.map +1 -0
- package/dist/factories/harbor/index.d.ts +7 -0
- package/dist/factories/harbor/index.d.ts.map +1 -0
- package/dist/factories/harbor/index.js +7 -0
- package/dist/factories/harbor/index.js.map +1 -0
- package/dist/factories/harbor/provider/harbor-api.d.ts +123 -0
- package/dist/factories/harbor/provider/harbor-api.d.ts.map +1 -0
- package/dist/factories/harbor/provider/harbor-api.js +595 -0
- package/dist/factories/harbor/provider/harbor-api.js.map +1 -0
- package/dist/factories/harbor/provider/index.d.ts +4 -0
- package/dist/factories/harbor/provider/index.d.ts.map +1 -0
- package/dist/factories/harbor/provider/index.js +4 -0
- package/dist/factories/harbor/provider/index.js.map +1 -0
- package/dist/factories/harbor/provider/kubernetes-secret-store.d.ts +12 -0
- package/dist/factories/harbor/provider/kubernetes-secret-store.d.ts.map +1 -0
- package/dist/factories/harbor/provider/kubernetes-secret-store.js +81 -0
- package/dist/factories/harbor/provider/kubernetes-secret-store.js.map +1 -0
- package/dist/factories/harbor/provider/rook-s3-binding.d.ts +30 -0
- package/dist/factories/harbor/provider/rook-s3-binding.d.ts.map +1 -0
- package/dist/factories/harbor/provider/rook-s3-binding.js +74 -0
- package/dist/factories/harbor/provider/rook-s3-binding.js.map +1 -0
- package/dist/factories/harbor/resources/helm.d.ts +12 -0
- package/dist/factories/harbor/resources/helm.d.ts.map +1 -0
- package/dist/factories/harbor/resources/helm.js +46 -0
- package/dist/factories/harbor/resources/helm.js.map +1 -0
- package/dist/factories/harbor/resources/index.d.ts +2 -0
- package/dist/factories/harbor/resources/index.d.ts.map +1 -0
- package/dist/factories/harbor/resources/index.js +2 -0
- package/dist/factories/harbor/resources/index.js.map +1 -0
- package/dist/factories/harbor/types.d.ts +319 -0
- package/dist/factories/harbor/types.d.ts.map +1 -0
- package/dist/factories/harbor/types.js +252 -0
- package/dist/factories/harbor/types.js.map +1 -0
- package/dist/factories/harbor/utils/helm-values-mapper.d.ts +8 -0
- package/dist/factories/harbor/utils/helm-values-mapper.d.ts.map +1 -0
- package/dist/factories/harbor/utils/helm-values-mapper.js +322 -0
- package/dist/factories/harbor/utils/helm-values-mapper.js.map +1 -0
- package/dist/factories/harbor/utils/index.d.ts +2 -0
- package/dist/factories/harbor/utils/index.d.ts.map +1 -0
- package/dist/factories/harbor/utils/index.js +2 -0
- package/dist/factories/harbor/utils/index.js.map +1 -0
- package/dist/factories/helm/helm-release.d.ts +10 -0
- package/dist/factories/helm/helm-release.d.ts.map +1 -1
- package/dist/factories/helm/helm-release.js +30 -2
- package/dist/factories/helm/helm-release.js.map +1 -1
- package/dist/factories/helm/readiness-evaluators.d.ts.map +1 -1
- package/dist/factories/helm/readiness-evaluators.js +26 -1
- package/dist/factories/helm/readiness-evaluators.js.map +1 -1
- package/dist/factories/helm/types.d.ts +5 -0
- package/dist/factories/helm/types.d.ts.map +1 -1
- package/dist/factories/index.d.ts +1 -0
- package/dist/factories/index.d.ts.map +1 -1
- package/dist/factories/index.js +4 -0
- package/dist/factories/index.js.map +1 -1
- package/dist/factories/inngest/types.js +8 -8
- package/dist/factories/inngest/types.js.map +1 -1
- package/dist/factories/kubernetes/networking/network-policy.d.ts.map +1 -1
- package/dist/factories/kubernetes/networking/network-policy.js +34 -1
- package/dist/factories/kubernetes/networking/network-policy.js.map +1 -1
- package/dist/factories/ory/types.js +40 -40
- package/dist/factories/ory/types.js.map +1 -1
- package/dist/factories/rook/compositions/index.d.ts +1 -0
- package/dist/factories/rook/compositions/index.d.ts.map +1 -1
- package/dist/factories/rook/compositions/index.js +1 -0
- package/dist/factories/rook/compositions/index.js.map +1 -1
- package/dist/factories/rook/compositions/rook-ceph-operator-installation.d.ts +2 -0
- package/dist/factories/rook/compositions/rook-ceph-operator-installation.d.ts.map +1 -1
- package/dist/factories/rook/compositions/rook-ceph-operator-installation.js +17 -0
- package/dist/factories/rook/compositions/rook-ceph-operator-installation.js.map +1 -1
- package/dist/factories/rook/compositions/rook-ceph-platform.d.ts +181 -0
- package/dist/factories/rook/compositions/rook-ceph-platform.d.ts.map +1 -0
- package/dist/factories/rook/compositions/rook-ceph-platform.js +388 -0
- package/dist/factories/rook/compositions/rook-ceph-platform.js.map +1 -0
- package/dist/factories/rook/resources/bucket-storage-class.d.ts.map +1 -1
- package/dist/factories/rook/resources/bucket-storage-class.js +4 -1
- package/dist/factories/rook/resources/bucket-storage-class.js.map +1 -1
- package/dist/factories/rook/resources/ceph-object-store.d.ts.map +1 -1
- package/dist/factories/rook/resources/ceph-object-store.js +2 -0
- package/dist/factories/rook/resources/ceph-object-store.js.map +1 -1
- package/dist/factories/rook/resources/helm.d.ts +4 -0
- package/dist/factories/rook/resources/helm.d.ts.map +1 -1
- package/dist/factories/rook/resources/helm.js +22 -0
- package/dist/factories/rook/resources/helm.js.map +1 -1
- package/dist/factories/rook/types.d.ts +180 -1
- package/dist/factories/rook/types.d.ts.map +1 -1
- package/dist/factories/rook/types.js +100 -9
- package/dist/factories/rook/types.js.map +1 -1
- package/dist/factories/rook/utils/helm-values-mapper.d.ts +34 -1
- package/dist/factories/rook/utils/helm-values-mapper.d.ts.map +1 -1
- package/dist/factories/rook/utils/helm-values-mapper.js +207 -0
- package/dist/factories/rook/utils/helm-values-mapper.js.map +1 -1
- package/dist/factories/searxng/types.js +2 -2
- package/dist/factories/searxng/types.js.map +1 -1
- package/dist/factories/valkey/types.js +4 -4
- package/dist/factories/valkey/types.js.map +1 -1
- package/dist/factories/webapp/types.js +8 -8
- package/dist/factories/webapp/types.js.map +1 -1
- package/package.json +6 -1
|
@@ -1,108 +1,124 @@
|
|
|
1
|
-
|
|
2
|
-
* Docker CLI Execution Helper
|
|
3
|
-
*
|
|
4
|
-
* Wraps Bun.spawn for Docker commands with streaming output,
|
|
5
|
-
* timeout support, and actionable error messages.
|
|
6
|
-
*/
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
7
2
|
import { getComponentLogger } from '../logging/index.js';
|
|
8
3
|
import { ContainerBuildError } from './errors.js';
|
|
9
4
|
const logger = getComponentLogger('container-exec');
|
|
10
|
-
/** Valid Docker build-arg key pattern. */
|
|
11
5
|
const VALID_BUILD_ARG_KEY = /^[a-zA-Z_][a-zA-Z0-9_]*$/;
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
* Prevents flag injection via malicious keys like "--platform".
|
|
15
|
-
*/
|
|
6
|
+
const MAX_CAPTURED_OUTPUT_CHARS = 1_048_576;
|
|
7
|
+
const FORCE_KILL_GRACE_MS = 1_000;
|
|
16
8
|
export function validateBuildArgs(buildArgs) {
|
|
17
9
|
for (const [key, value] of Object.entries(buildArgs)) {
|
|
18
10
|
if (!VALID_BUILD_ARG_KEY.test(key)) {
|
|
19
|
-
throw new ContainerBuildError(`Invalid build arg key: "${key}". Must match ${VALID_BUILD_ARG_KEY.source}`, 'INVALID_BUILD_ARG', ['Build arg keys must be valid Docker ARG names
|
|
11
|
+
throw new ContainerBuildError(`Invalid build arg key: "${key}". Must match ${VALID_BUILD_ARG_KEY.source}`, 'INVALID_BUILD_ARG', ['Build arg keys must be valid Docker ARG names.']);
|
|
20
12
|
}
|
|
21
|
-
if (
|
|
22
|
-
throw new ContainerBuildError(`Build arg value for "${key}" contains newlines
|
|
13
|
+
if (value.includes('\n')) {
|
|
14
|
+
throw new ContainerBuildError(`Build arg value for "${key}" contains newlines.`, 'INVALID_BUILD_ARG', ['Remove newlines from build arg values.']);
|
|
23
15
|
}
|
|
24
16
|
}
|
|
25
17
|
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
18
|
+
function redact(value, sensitiveValues) {
|
|
19
|
+
return sensitiveValues.reduce((current, sensitive) => (sensitive ? current.split(sensitive).join('***') : current), value);
|
|
20
|
+
}
|
|
21
|
+
function redactedDockerArgs(args) {
|
|
22
|
+
return args.map((arg, index) => {
|
|
23
|
+
if (args[index - 1] === '--build-arg' && arg.includes('=')) {
|
|
24
|
+
return `${arg.slice(0, arg.indexOf('='))}=***`;
|
|
25
|
+
}
|
|
26
|
+
if (args[index - 1] === '--password')
|
|
27
|
+
return '***';
|
|
28
|
+
return arg;
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
function appendBounded(current, chunk) {
|
|
32
|
+
const combined = current + chunk;
|
|
33
|
+
return combined.length <= MAX_CAPTURED_OUTPUT_CHARS
|
|
34
|
+
? combined
|
|
35
|
+
: combined.slice(-MAX_CAPTURED_OUTPUT_CHARS);
|
|
36
|
+
}
|
|
37
|
+
/** Execute Docker through a Node-compatible process boundary with timeout and cancellation. */
|
|
32
38
|
export async function execDocker(args, options = {}) {
|
|
33
|
-
const { stdin, quiet = false, timeout = 300_000 } = options;
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
stderr: 'pipe',
|
|
42
|
-
stdin: stdin ? 'pipe' : undefined,
|
|
39
|
+
const { stdin, quiet = false, timeout = 300_000, signal, environment = {}, sensitiveValues = [], } = options;
|
|
40
|
+
if (signal?.aborted)
|
|
41
|
+
throw ContainerBuildError.cancelled();
|
|
42
|
+
const safeArgs = redactedDockerArgs(args);
|
|
43
|
+
logger.debug('Executing docker command', { args: ['docker', ...safeArgs] });
|
|
44
|
+
const child = spawn('docker', args, {
|
|
45
|
+
env: { ...process.env, ...environment },
|
|
46
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
43
47
|
});
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
const stdoutPromise = new Response(proc.stdout).text().catch(() => '');
|
|
51
|
-
const stderrPromise = new Response(proc.stderr).text().catch(() => '');
|
|
52
|
-
// Race exit against timeout. The timeout promise has a .catch() no-op to
|
|
53
|
-
// prevent unhandled rejections if the timeout fires at the exact moment
|
|
54
|
-
// the process exits (race condition at the boundary).
|
|
55
|
-
let timeoutTimer;
|
|
56
|
-
const timeoutPromise = new Promise((_, reject) => {
|
|
57
|
-
timeoutTimer = setTimeout(() => {
|
|
58
|
-
proc.kill();
|
|
59
|
-
reject(new ContainerBuildError(`Docker command timed out after ${timeout}ms: docker ${redactedArgs.join(' ')}`, 'BUILD_TIMEOUT', ['Increase the timeout option.', 'Check network connectivity for pulls.']));
|
|
60
|
-
}, timeout);
|
|
48
|
+
let stdout = '';
|
|
49
|
+
let stderr = '';
|
|
50
|
+
child.stdout.setEncoding('utf8');
|
|
51
|
+
child.stderr.setEncoding('utf8');
|
|
52
|
+
child.stdout.on('data', (chunk) => {
|
|
53
|
+
stdout = appendBounded(stdout, chunk);
|
|
61
54
|
});
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
if (timeoutTimer !== undefined)
|
|
65
|
-
clearTimeout(timeoutTimer);
|
|
55
|
+
child.stderr.on('data', (chunk) => {
|
|
56
|
+
stderr = appendBounded(stderr, chunk);
|
|
66
57
|
});
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
58
|
+
child.stdin.on('error', (error) => {
|
|
59
|
+
if (error.code !== 'EPIPE')
|
|
60
|
+
logger.debug('Docker stdin closed unexpectedly', { error: error.message });
|
|
61
|
+
});
|
|
62
|
+
if (stdin !== undefined)
|
|
63
|
+
child.stdin.end(stdin);
|
|
64
|
+
else
|
|
65
|
+
child.stdin.end();
|
|
66
|
+
let timedOut = false;
|
|
67
|
+
let cancelled = false;
|
|
68
|
+
let forceKillHandle;
|
|
69
|
+
const terminate = () => {
|
|
70
|
+
child.kill('SIGTERM');
|
|
71
|
+
forceKillHandle ??= setTimeout(() => child.kill('SIGKILL'), FORCE_KILL_GRACE_MS);
|
|
72
|
+
};
|
|
73
|
+
const timeoutHandle = setTimeout(() => {
|
|
74
|
+
timedOut = true;
|
|
75
|
+
terminate();
|
|
76
|
+
}, timeout);
|
|
77
|
+
const abort = () => {
|
|
78
|
+
cancelled = true;
|
|
79
|
+
terminate();
|
|
80
|
+
};
|
|
81
|
+
signal?.addEventListener('abort', abort, { once: true });
|
|
82
|
+
const exitCode = await new Promise((resolve, reject) => {
|
|
83
|
+
child.once('error', reject);
|
|
84
|
+
child.once('close', (code) => resolve(code ?? 1));
|
|
85
|
+
}).finally(() => {
|
|
86
|
+
clearTimeout(timeoutHandle);
|
|
87
|
+
if (forceKillHandle)
|
|
88
|
+
clearTimeout(forceKillHandle);
|
|
89
|
+
signal?.removeEventListener('abort', abort);
|
|
90
|
+
});
|
|
91
|
+
if (cancelled)
|
|
92
|
+
throw ContainerBuildError.cancelled();
|
|
93
|
+
if (timedOut) {
|
|
94
|
+
throw ContainerBuildError.timeout(timeout, `docker ${safeArgs.join(' ')}`);
|
|
95
|
+
}
|
|
96
|
+
const safeStdout = redact(stdout, sensitiveValues);
|
|
97
|
+
const safeStderr = redact(stderr, sensitiveValues);
|
|
98
|
+
if (!quiet && safeStdout.trim()) {
|
|
99
|
+
for (const line of safeStdout.trim().split('\n').slice(-20))
|
|
71
100
|
logger.info(line);
|
|
72
|
-
}
|
|
73
101
|
}
|
|
74
102
|
if (exitCode !== 0) {
|
|
75
103
|
if (!quiet) {
|
|
76
|
-
for (const line of
|
|
104
|
+
for (const line of safeStderr.trim().split('\n').slice(-40))
|
|
77
105
|
logger.error(line);
|
|
78
|
-
}
|
|
79
106
|
}
|
|
80
|
-
throw ContainerBuildError.
|
|
107
|
+
throw ContainerBuildError.commandFailed(exitCode, safeArgs, safeStderr);
|
|
81
108
|
}
|
|
82
|
-
return { exitCode, stdout, stderr };
|
|
109
|
+
return { exitCode, stdout: safeStdout, stderr: safeStderr };
|
|
83
110
|
}
|
|
84
|
-
|
|
85
|
-
* Check if Docker is available and the daemon is running.
|
|
86
|
-
*/
|
|
87
|
-
export async function checkDockerAvailable() {
|
|
111
|
+
export async function checkDockerAvailable(signal) {
|
|
88
112
|
try {
|
|
89
|
-
const
|
|
90
|
-
|
|
91
|
-
|
|
113
|
+
const result = await execDocker(['version', '--format', '{{.Server.Version}}'], {
|
|
114
|
+
quiet: true,
|
|
115
|
+
timeout: 15_000,
|
|
116
|
+
...(signal ? { signal } : {}),
|
|
92
117
|
});
|
|
93
|
-
|
|
94
|
-
const stdoutPromise = new Response(proc.stdout).text().catch(() => '');
|
|
95
|
-
const stderrPromise = new Response(proc.stderr).text().catch(() => '');
|
|
96
|
-
const exitCode = await proc.exited;
|
|
97
|
-
const stdout = await stdoutPromise;
|
|
98
|
-
const stderr = await stderrPromise;
|
|
99
|
-
if (exitCode !== 0) {
|
|
100
|
-
throw ContainerBuildError.dockerNotAvailable(stderr.trim());
|
|
101
|
-
}
|
|
102
|
-
logger.debug('Docker available', { version: stdout.trim() });
|
|
118
|
+
logger.debug('Docker available', { version: result.stdout.trim() });
|
|
103
119
|
}
|
|
104
120
|
catch (error) {
|
|
105
|
-
if (error instanceof ContainerBuildError)
|
|
121
|
+
if (error instanceof ContainerBuildError && error.code === 'BUILD_CANCELLED')
|
|
106
122
|
throw error;
|
|
107
123
|
throw ContainerBuildError.dockerNotAvailable(error instanceof Error ? error.message : String(error));
|
|
108
124
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"exec.js","sourceRoot":"","sources":["../../../src/core/containers/exec.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"exec.js","sourceRoot":"","sources":["../../../src/core/containers/exec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAE3C,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAElD,MAAM,MAAM,GAAG,kBAAkB,CAAC,gBAAgB,CAAC,CAAC;AACpD,MAAM,mBAAmB,GAAG,0BAA0B,CAAC;AACvD,MAAM,yBAAyB,GAAG,SAAS,CAAC;AAC5C,MAAM,mBAAmB,GAAG,KAAK,CAAC;AAkBlC,MAAM,UAAU,iBAAiB,CAAC,SAAiC;IACjE,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;QACrD,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YACnC,MAAM,IAAI,mBAAmB,CAC3B,2BAA2B,GAAG,iBAAiB,mBAAmB,CAAC,MAAM,EAAE,EAC3E,mBAAmB,EACnB,CAAC,gDAAgD,CAAC,CACnD,CAAC;QACJ,CAAC;QACD,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YACzB,MAAM,IAAI,mBAAmB,CAC3B,wBAAwB,GAAG,sBAAsB,EACjD,mBAAmB,EACnB,CAAC,wCAAwC,CAAC,CAC3C,CAAC;QACJ,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,MAAM,CAAC,KAAa,EAAE,eAAkC;IAC/D,OAAO,eAAe,CAAC,MAAM,CAC3B,CAAC,OAAO,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EACpF,KAAK,CACN,CAAC;AACJ,CAAC;AAED,SAAS,kBAAkB,CAAC,IAAuB;IACjD,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE;QAC7B,IAAI,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,aAAa,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YAC3D,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC;QACjD,CAAC;QACD,IAAI,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,YAAY;YAAE,OAAO,KAAK,CAAC;QACnD,OAAO,GAAG,CAAC;IACb,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,aAAa,CAAC,OAAe,EAAE,KAAa;IACnD,MAAM,QAAQ,GAAG,OAAO,GAAG,KAAK,CAAC;IACjC,OAAO,QAAQ,CAAC,MAAM,IAAI,yBAAyB;QACjD,CAAC,CAAC,QAAQ;QACV,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,yBAAyB,CAAC,CAAC;AACjD,CAAC;AAED,+FAA+F;AAC/F,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,IAAc,EACd,UAA6B,EAAE;IAE/B,MAAM,EACJ,KAAK,EACL,KAAK,GAAG,KAAK,EACb,OAAO,GAAG,OAAO,EACjB,MAAM,EACN,WAAW,GAAG,EAAE,EAChB,eAAe,GAAG,EAAE,GACrB,GAAG,OAAO,CAAC;IACZ,IAAI,MAAM,EAAE,OAAO;QAAE,MAAM,mBAAmB,CAAC,SAAS,EAAE,CAAC;IAE3D,MAAM,QAAQ,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC;IAC1C,MAAM,CAAC,KAAK,CAAC,0BAA0B,EAAE,EAAE,IAAI,EAAE,CAAC,QAAQ,EAAE,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC;IAE5E,MAAM,KAAK,GAAG,KAAK,CAAC,QAAQ,EAAE,IAAI,EAAE;QAClC,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,GAAG,WAAW,EAAE;QACvC,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;KAChC,CAAC,CAAC;IACH,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IACjC,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IACjC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;QACxC,MAAM,GAAG,aAAa,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IACH,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;QACxC,MAAM,GAAG,aAAa,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IACH,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAA4B,EAAE,EAAE;QACvD,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO;YACxB,MAAM,CAAC,KAAK,CAAC,kCAAkC,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IAC/E,CAAC,CAAC,CAAC;IACH,IAAI,KAAK,KAAK,SAAS;QAAE,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;;QAC3C,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;IAEvB,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,IAAI,SAAS,GAAG,KAAK,CAAC;IACtB,IAAI,eAA0D,CAAC;IAC/D,MAAM,SAAS,GAAG,GAAG,EAAE;QACrB,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACtB,eAAe,KAAK,UAAU,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,mBAAmB,CAAC,CAAC;IACnF,CAAC,CAAC;IACF,MAAM,aAAa,GAAG,UAAU,CAAC,GAAG,EAAE;QACpC,QAAQ,GAAG,IAAI,CAAC;QAChB,SAAS,EAAE,CAAC;IACd,CAAC,EAAE,OAAO,CAAC,CAAC;IACZ,MAAM,KAAK,GAAG,GAAG,EAAE;QACjB,SAAS,GAAG,IAAI,CAAC;QACjB,SAAS,EAAE,CAAC;IACd,CAAC,CAAC;IACF,MAAM,EAAE,gBAAgB,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IAEzD,MAAM,QAAQ,GAAG,MAAM,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC7D,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC5B,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE;QACd,YAAY,CAAC,aAAa,CAAC,CAAC;QAC5B,IAAI,eAAe;YAAE,YAAY,CAAC,eAAe,CAAC,CAAC;QACnD,MAAM,EAAE,mBAAmB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;IAEH,IAAI,SAAS;QAAE,MAAM,mBAAmB,CAAC,SAAS,EAAE,CAAC;IACrD,IAAI,QAAQ,EAAE,CAAC;QACb,MAAM,mBAAmB,CAAC,OAAO,CAAC,OAAO,EAAE,UAAU,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC7E,CAAC;IAED,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IACnD,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IACnD,IAAI,CAAC,KAAK,IAAI,UAAU,CAAC,IAAI,EAAE,EAAE,CAAC;QAChC,KAAK,MAAM,IAAI,IAAI,UAAU,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;YAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjF,CAAC;IACD,IAAI,QAAQ,KAAK,CAAC,EAAE,CAAC;QACnB,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,KAAK,MAAM,IAAI,IAAI,UAAU,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;gBAAE,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAClF,CAAC;QACD,MAAM,mBAAmB,CAAC,aAAa,CAAC,QAAQ,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;IAC1E,CAAC;IACD,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;AAC9D,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,MAAoB;IAC7D,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,CAAC,SAAS,EAAE,UAAU,EAAE,qBAAqB,CAAC,EAAE;YAC9E,KAAK,EAAE,IAAI;YACX,OAAO,EAAE,MAAM;YACf,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC9B,CAAC,CAAC;QACH,MAAM,CAAC,KAAK,CAAC,kBAAkB,EAAE,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IACtE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,mBAAmB,IAAI,KAAK,CAAC,IAAI,KAAK,iBAAiB;YAAE,MAAM,KAAK,CAAC;QAC1F,MAAM,mBAAmB,CAAC,kBAAkB,CAC1C,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CACvD,CAAC;IACJ,CAAC;AACH,CAAC"}
|
|
@@ -10,8 +10,9 @@
|
|
|
10
10
|
* that: you `await` it. It is NOT a deferred reference — resolve images in (async) setup code before
|
|
11
11
|
* composing, then feed the resulting literals into resources or chart values.
|
|
12
12
|
*
|
|
13
|
-
* Memoization: the build is keyed by
|
|
14
|
-
* the same container many times
|
|
13
|
+
* Memoization: the build is keyed by the effective content, target, registry, and build options, so
|
|
14
|
+
* awaiting the same container many times builds it once while a changed context or registry cannot
|
|
15
|
+
* accidentally reuse a different image.
|
|
15
16
|
*
|
|
16
17
|
* @example
|
|
17
18
|
* ```typescript
|
|
@@ -28,16 +29,19 @@
|
|
|
28
29
|
import type { ContainerBuildOptions, ContainerBuildResult } from './registries/types.js';
|
|
29
30
|
/** A built container image, resolved to a literal — both the full URI and its split parts. */
|
|
30
31
|
export interface ContainerImage {
|
|
31
|
-
/**
|
|
32
|
+
/** Immutable digest URI for remote images, or the local tagged URI. */
|
|
32
33
|
readonly imageUri: string;
|
|
33
|
-
/**
|
|
34
|
+
/** Human-readable tagged URI retained for inspection and retention policy. */
|
|
35
|
+
readonly taggedImageUri: string;
|
|
34
36
|
readonly repository: string;
|
|
35
|
-
/** The tag, e.g. `sha-abc`. */
|
|
36
37
|
readonly tag: string;
|
|
38
|
+
/** Registry-verified digest. Omitted for local, non-pushed images. */
|
|
39
|
+
readonly digest?: string;
|
|
40
|
+
readonly platforms: readonly string[];
|
|
37
41
|
}
|
|
38
|
-
/** Options for {@link container}: the {@link ContainerBuildOptions} plus an optional
|
|
42
|
+
/** Options for {@link container}: the {@link ContainerBuildOptions} plus an optional diagnostic identity. */
|
|
39
43
|
export interface ContainerOptions extends ContainerBuildOptions {
|
|
40
|
-
/** Stable identity
|
|
44
|
+
/** Stable diagnostic identity included in, but never substituted for, the complete cache key. */
|
|
41
45
|
id?: string;
|
|
42
46
|
}
|
|
43
47
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"image.d.ts","sourceRoot":"","sources":["../../../src/core/containers/image.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"image.d.ts","sourceRoot":"","sources":["../../../src/core/containers/image.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAOH,OAAO,KAAK,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAEzF,8FAA8F;AAC9F,MAAM,WAAW,cAAc;IAC7B,uEAAuE;IACvE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,8EAA8E;IAC9E,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,sEAAsE;IACtE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;CACvC;AAED,6GAA6G;AAC7G,MAAM,WAAW,gBAAiB,SAAQ,qBAAqB;IAC7D,iGAAiG;IACjG,EAAE,CAAC,EAAE,MAAM,CAAC;CACb;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAQ9E;AAOD,uGAAuG;AACvG,KAAK,OAAO,GAAG,CAAC,OAAO,EAAE,qBAAqB,KAAK,OAAO,CAAC,oBAAoB,CAAC,CAAC;AAiGjF;;;;GAIG;AACH,wBAAgB,SAAS,CACvB,OAAO,EAAE,gBAAgB,EACzB,KAAK,GAAE,OAAwB,GAC9B,OAAO,CAAC,cAAc,CAAC,CAazB;AAED,sGAAsG;AACtG,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C"}
|
|
@@ -10,8 +10,9 @@
|
|
|
10
10
|
* that: you `await` it. It is NOT a deferred reference — resolve images in (async) setup code before
|
|
11
11
|
* composing, then feed the resulting literals into resources or chart values.
|
|
12
12
|
*
|
|
13
|
-
* Memoization: the build is keyed by
|
|
14
|
-
* the same container many times
|
|
13
|
+
* Memoization: the build is keyed by the effective content, target, registry, and build options, so
|
|
14
|
+
* awaiting the same container many times builds it once while a changed context or registry cannot
|
|
15
|
+
* accidentally reuse a different image.
|
|
15
16
|
*
|
|
16
17
|
* @example
|
|
17
18
|
* ```typescript
|
|
@@ -25,7 +26,10 @@
|
|
|
25
26
|
* // or for a Helm chart's split image values: { repository: img.repository, tag: img.tag }
|
|
26
27
|
* ```
|
|
27
28
|
*/
|
|
28
|
-
import {
|
|
29
|
+
import { createHash } from 'node:crypto';
|
|
30
|
+
import { existsSync } from 'node:fs';
|
|
31
|
+
import { join, resolve } from 'node:path';
|
|
32
|
+
import { buildContainer, computeContentHash } from './build.js';
|
|
29
33
|
/**
|
|
30
34
|
* Split a full image URI into `{ repository, tag }`. Handles digest form (`repo@sha256:…`) and tag
|
|
31
35
|
* form (`repo:tag`), registry-port-colon aware (a colon in `host:port/...` is not the tag separator).
|
|
@@ -40,13 +44,92 @@ export function splitImageUri(uri) {
|
|
|
40
44
|
? { repository: uri.slice(0, colon), tag: uri.slice(colon + 1) }
|
|
41
45
|
: { repository: uri, tag: 'latest' };
|
|
42
46
|
}
|
|
43
|
-
/** Build memoization, keyed by
|
|
47
|
+
/** Build memoization, keyed by effective content/options — builds each exact image once. */
|
|
44
48
|
const buildCache = new Map();
|
|
49
|
+
const objectIdentities = new WeakMap();
|
|
50
|
+
let nextObjectIdentity = 1;
|
|
45
51
|
async function buildAndShape(options, build) {
|
|
46
52
|
const { id: _id, ...buildOptions } = options;
|
|
47
53
|
const result = await build({ ...buildOptions, tag: buildOptions.tag ?? 'content-hash' });
|
|
48
|
-
|
|
49
|
-
|
|
54
|
+
return {
|
|
55
|
+
imageUri: result.imageUri,
|
|
56
|
+
taggedImageUri: result.taggedImageUri,
|
|
57
|
+
repository: result.repository,
|
|
58
|
+
tag: result.tag,
|
|
59
|
+
...(result.digest ? { digest: result.digest } : {}),
|
|
60
|
+
platforms: result.platforms,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
function objectIdentity(value) {
|
|
64
|
+
if (!value)
|
|
65
|
+
return undefined;
|
|
66
|
+
let identity = objectIdentities.get(value);
|
|
67
|
+
if (!identity) {
|
|
68
|
+
identity = nextObjectIdentity++;
|
|
69
|
+
objectIdentities.set(value, identity);
|
|
70
|
+
}
|
|
71
|
+
return identity;
|
|
72
|
+
}
|
|
73
|
+
function sortedRecord(value) {
|
|
74
|
+
return value
|
|
75
|
+
? Object.fromEntries(Object.entries(value).sort(([left], [right]) => left.localeCompare(right)))
|
|
76
|
+
: undefined;
|
|
77
|
+
}
|
|
78
|
+
function registryIdentity(registry) {
|
|
79
|
+
switch (registry.type) {
|
|
80
|
+
case 'oci':
|
|
81
|
+
return {
|
|
82
|
+
type: registry.type,
|
|
83
|
+
registry: registry.registry,
|
|
84
|
+
repositoryPrefix: registry.repositoryPrefix,
|
|
85
|
+
dockerConfigPath: registry.dockerConfigPath,
|
|
86
|
+
tls: registry.tls,
|
|
87
|
+
credentialProvider: objectIdentity(registry.credentialProvider),
|
|
88
|
+
};
|
|
89
|
+
case 'ecr':
|
|
90
|
+
return {
|
|
91
|
+
type: registry.type,
|
|
92
|
+
accountId: registry.accountId,
|
|
93
|
+
region: registry.region,
|
|
94
|
+
createRepository: registry.createRepository,
|
|
95
|
+
credentials: objectIdentity(registry.credentials),
|
|
96
|
+
};
|
|
97
|
+
case 'custom':
|
|
98
|
+
return { type: registry.type, handler: objectIdentity(registry.handler) };
|
|
99
|
+
default:
|
|
100
|
+
return registry;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
async function resolvedBuildOptions(options, build) {
|
|
104
|
+
const context = resolve(options.context);
|
|
105
|
+
const dockerfile = options.dockerfile ?? 'Dockerfile';
|
|
106
|
+
let tag = options.tag ?? 'content-hash';
|
|
107
|
+
if (tag === 'content-hash' &&
|
|
108
|
+
build === buildContainer &&
|
|
109
|
+
existsSync(context) &&
|
|
110
|
+
existsSync(join(context, dockerfile))) {
|
|
111
|
+
tag = await computeContentHash(context, join(context, dockerfile));
|
|
112
|
+
}
|
|
113
|
+
return { ...options, context, dockerfile, tag };
|
|
114
|
+
}
|
|
115
|
+
function buildCacheKey(options, build) {
|
|
116
|
+
const identity = {
|
|
117
|
+
id: options.id,
|
|
118
|
+
context: options.context,
|
|
119
|
+
dockerfile: options.dockerfile,
|
|
120
|
+
imageName: options.imageName,
|
|
121
|
+
tag: options.tag,
|
|
122
|
+
platform: options.platform,
|
|
123
|
+
platforms: options.platforms ? [...options.platforms] : undefined,
|
|
124
|
+
buildArgs: sortedRecord(options.buildArgs),
|
|
125
|
+
target: options.target,
|
|
126
|
+
timeout: options.timeout,
|
|
127
|
+
signal: objectIdentity(options.signal),
|
|
128
|
+
extraDockerArgs: options.extraDockerArgs ? [...options.extraDockerArgs] : undefined,
|
|
129
|
+
registry: registryIdentity(options.registry),
|
|
130
|
+
builder: objectIdentity(build),
|
|
131
|
+
};
|
|
132
|
+
return createHash('sha256').update(JSON.stringify(identity)).digest('hex');
|
|
50
133
|
}
|
|
51
134
|
/**
|
|
52
135
|
* Build a container image (delegating to {@link buildContainer}) and resolve to its shaped result.
|
|
@@ -54,13 +137,19 @@ async function buildAndShape(options, build) {
|
|
|
54
137
|
* pass only `options`.
|
|
55
138
|
*/
|
|
56
139
|
export function container(options, build = buildContainer) {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
140
|
+
return resolvedBuildOptions(options, build).then((resolved) => {
|
|
141
|
+
const key = buildCacheKey(resolved, build);
|
|
142
|
+
let pending = buildCache.get(key);
|
|
143
|
+
if (!pending) {
|
|
144
|
+
pending = buildAndShape(resolved, build);
|
|
145
|
+
buildCache.set(key, pending);
|
|
146
|
+
pending.catch(() => {
|
|
147
|
+
if (buildCache.get(key) === pending)
|
|
148
|
+
buildCache.delete(key);
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
return pending;
|
|
152
|
+
});
|
|
64
153
|
}
|
|
65
154
|
/** Clear the build memoization cache. Intended for tests/long-lived processes that need a rebuild. */
|
|
66
155
|
export function clearContainerCache() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"image.js","sourceRoot":"","sources":["../../../src/core/containers/image.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"image.js","sourceRoot":"","sources":["../../../src/core/containers/image.ts"],"names":[],"mappings":"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"}
|
|
@@ -21,5 +21,9 @@
|
|
|
21
21
|
export { buildContainer } from './build.js';
|
|
22
22
|
export { ContainerBuildError } from './errors.js';
|
|
23
23
|
export { type ContainerImage, type ContainerOptions, clearContainerCache, container, splitImageUri, } from './image.js';
|
|
24
|
-
export type { ContainerBuildOptions, ContainerBuildResult, EcrRegistryConfig, OrbstackRegistryConfig, RegistryConfig, } from './registries/types.js';
|
|
24
|
+
export type { ContainerBuildProgress, ContainerBuildOptions, ContainerBuildResult, CustomRegistryConfig, EcrRegistryConfig, HarborRegistryConfig, OciRegistryConfig, OciRegistryCredential, OciRegistryCredentialProvider, OciRegistryTlsConfig, OrbstackRegistryConfig, RegistryConfig, RegistryHandler, RegistrySession, } from './registries/types.js';
|
|
25
|
+
export { kubernetesSecretRegistryCredentials } from './registries/credentials.js';
|
|
26
|
+
export type { KubernetesRegistrySecretReader, KubernetesSecretRegistryCredentialOptions, } from './registries/credentials.js';
|
|
27
|
+
export { harbor } from './registries/harbor.js';
|
|
28
|
+
export { ociRegistry } from './registries/oci.js';
|
|
25
29
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/containers/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,mBAAmB,EACnB,SAAS,EACT,aAAa,GACd,MAAM,YAAY,CAAC;AACpB,YAAY,EACV,qBAAqB,EACrB,oBAAoB,EACpB,iBAAiB,EACjB,sBAAsB,EACtB,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/containers/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,mBAAmB,EACnB,SAAS,EACT,aAAa,GACd,MAAM,YAAY,CAAC;AACpB,YAAY,EACV,sBAAsB,EACtB,qBAAqB,EACrB,oBAAoB,EACpB,oBAAoB,EACpB,iBAAiB,EACjB,oBAAoB,EACpB,iBAAiB,EACjB,qBAAqB,EACrB,6BAA6B,EAC7B,oBAAoB,EACpB,sBAAsB,EACtB,cAAc,EACd,eAAe,EACf,eAAe,GAChB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,mCAAmC,EAAE,MAAM,6BAA6B,CAAC;AAClF,YAAY,EACV,8BAA8B,EAC9B,yCAAyC,GAC1C,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC"}
|
|
@@ -21,4 +21,7 @@
|
|
|
21
21
|
export { buildContainer } from './build.js';
|
|
22
22
|
export { ContainerBuildError } from './errors.js';
|
|
23
23
|
export { clearContainerCache, container, splitImageUri, } from './image.js';
|
|
24
|
+
export { kubernetesSecretRegistryCredentials } from './registries/credentials.js';
|
|
25
|
+
export { harbor } from './registries/harbor.js';
|
|
26
|
+
export { ociRegistry } from './registries/oci.js';
|
|
24
27
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/containers/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAGL,mBAAmB,EACnB,SAAS,EACT,aAAa,GACd,MAAM,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/containers/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAGL,mBAAmB,EACnB,SAAS,EACT,aAAa,GACd,MAAM,YAAY,CAAC;AAiBpB,OAAO,EAAE,mCAAmC,EAAE,MAAM,6BAA6B,CAAC;AAKlF,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { OciRegistryCredentialProvider } from './types.js';
|
|
2
|
+
export interface KubernetesSecretRegistryCredentialOptions {
|
|
3
|
+
namespace: string;
|
|
4
|
+
name: string;
|
|
5
|
+
/** Registry host used when resolving a kubernetes.io/dockerconfigjson entry. */
|
|
6
|
+
registry?: string;
|
|
7
|
+
/** Non-secret username paired with passwordKey. Mutually exclusive with usernameKey. */
|
|
8
|
+
username?: string;
|
|
9
|
+
usernameKey?: string;
|
|
10
|
+
passwordKey?: string;
|
|
11
|
+
dockerConfigJsonKey?: string;
|
|
12
|
+
context?: string;
|
|
13
|
+
kubeconfigPath?: string;
|
|
14
|
+
/** Optional embedding/test seam. Production defaults to the selected Kubernetes client. */
|
|
15
|
+
secretReader?: KubernetesRegistrySecretReader;
|
|
16
|
+
}
|
|
17
|
+
export type KubernetesRegistrySecretReader = (request: {
|
|
18
|
+
readonly namespace: string;
|
|
19
|
+
readonly name: string;
|
|
20
|
+
readonly context?: string;
|
|
21
|
+
readonly kubeconfigPath?: string;
|
|
22
|
+
}) => Promise<Readonly<Record<string, string>>>;
|
|
23
|
+
/**
|
|
24
|
+
* Resolve an OCI credential from a selected Kubernetes Secret at execution time.
|
|
25
|
+
*
|
|
26
|
+
* The returned closure retains only Secret coordinates; decoded values exist only during the
|
|
27
|
+
* registry session and are never written to TypeKro state or generated resources.
|
|
28
|
+
*/
|
|
29
|
+
export declare function kubernetesSecretRegistryCredentials(options: KubernetesSecretRegistryCredentialOptions): OciRegistryCredentialProvider;
|
|
30
|
+
//# sourceMappingURL=credentials.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../../../../src/core/containers/registries/credentials.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAyB,6BAA6B,EAAE,MAAM,YAAY,CAAC;AAEvF,MAAM,WAAW,yCAAyC;IACxD,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,gFAAgF;IAChF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wFAAwF;IACxF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,2FAA2F;IAC3F,YAAY,CAAC,EAAE,8BAA8B,CAAC;CAC/C;AAED,MAAM,MAAM,8BAA8B,GAAG,CAAC,OAAO,EAAE;IACrD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;CAClC,KAAK,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;AAoDhD;;;;;GAKG;AACH,wBAAgB,mCAAmC,CACjD,OAAO,EAAE,yCAAyC,GACjD,6BAA6B,CAwC/B"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { Buffer } from 'node:buffer';
|
|
2
|
+
import { createKubernetesClientProvider, } from '../../kubernetes/client-provider.js';
|
|
3
|
+
import { ContainerBuildError } from '../errors.js';
|
|
4
|
+
function decodeSecretValue(value, key) {
|
|
5
|
+
if (!value) {
|
|
6
|
+
throw new ContainerBuildError(`Registry credential Secret is missing key "${key}".`, 'REGISTRY_SECRET_INVALID', ['Verify the Secret name, namespace, and configured key names.']);
|
|
7
|
+
}
|
|
8
|
+
return Buffer.from(value, 'base64').toString('utf8');
|
|
9
|
+
}
|
|
10
|
+
function registryHost(value) {
|
|
11
|
+
const withScheme = value.includes('://') ? value : `https://${value}`;
|
|
12
|
+
return new URL(withScheme).host;
|
|
13
|
+
}
|
|
14
|
+
function credentialFromDockerConfig(encodedConfig, registry) {
|
|
15
|
+
const decoded = Buffer.from(encodedConfig, 'base64').toString('utf8');
|
|
16
|
+
const parsed = JSON.parse(decoded);
|
|
17
|
+
const entries = Object.entries(parsed.auths ?? {});
|
|
18
|
+
const selected = registry
|
|
19
|
+
? entries.find(([name]) => registryHost(name) === registryHost(registry))
|
|
20
|
+
: entries.length === 1
|
|
21
|
+
? entries[0]
|
|
22
|
+
: undefined;
|
|
23
|
+
if (!selected) {
|
|
24
|
+
throw new ContainerBuildError('Docker config Secret does not contain an unambiguous credential for the registry.', 'REGISTRY_SECRET_INVALID', ['Set the registry option or use explicit usernameKey and passwordKey values.']);
|
|
25
|
+
}
|
|
26
|
+
const entry = selected[1];
|
|
27
|
+
if (entry.username && entry.password)
|
|
28
|
+
return entry;
|
|
29
|
+
const auth = entry.auth ? Buffer.from(entry.auth, 'base64').toString('utf8') : '';
|
|
30
|
+
const separator = auth.indexOf(':');
|
|
31
|
+
if (separator <= 0) {
|
|
32
|
+
throw new ContainerBuildError('Docker config Secret credential is missing username/password material.', 'REGISTRY_SECRET_INVALID');
|
|
33
|
+
}
|
|
34
|
+
return { username: auth.slice(0, separator), password: auth.slice(separator + 1) };
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Resolve an OCI credential from a selected Kubernetes Secret at execution time.
|
|
38
|
+
*
|
|
39
|
+
* The returned closure retains only Secret coordinates; decoded values exist only during the
|
|
40
|
+
* registry session and are never written to TypeKro state or generated resources.
|
|
41
|
+
*/
|
|
42
|
+
export function kubernetesSecretRegistryCredentials(options) {
|
|
43
|
+
if (options.username !== undefined && options.usernameKey !== undefined) {
|
|
44
|
+
throw new ContainerBuildError('Registry credential options must select either username or usernameKey, not both.', 'REGISTRY_SECRET_INVALID');
|
|
45
|
+
}
|
|
46
|
+
if (options.username !== undefined && options.username.trim().length === 0) {
|
|
47
|
+
throw new ContainerBuildError('Registry credential username must not be empty.', 'REGISTRY_SECRET_INVALID');
|
|
48
|
+
}
|
|
49
|
+
return async (signal) => {
|
|
50
|
+
if (signal?.aborted)
|
|
51
|
+
throw ContainerBuildError.cancelled();
|
|
52
|
+
const request = {
|
|
53
|
+
namespace: options.namespace,
|
|
54
|
+
name: options.name,
|
|
55
|
+
...(options.context ? { context: options.context } : {}),
|
|
56
|
+
...(options.kubeconfigPath ? { kubeconfigPath: options.kubeconfigPath } : {}),
|
|
57
|
+
};
|
|
58
|
+
const data = options.secretReader
|
|
59
|
+
? await options.secretReader(request)
|
|
60
|
+
: await readKubernetesSecret(request);
|
|
61
|
+
if (signal?.aborted)
|
|
62
|
+
throw ContainerBuildError.cancelled();
|
|
63
|
+
const dockerConfigKey = options.dockerConfigJsonKey ?? '.dockerconfigjson';
|
|
64
|
+
if (data[dockerConfigKey]) {
|
|
65
|
+
return credentialFromDockerConfig(data[dockerConfigKey], options.registry);
|
|
66
|
+
}
|
|
67
|
+
const passwordKey = options.passwordKey ?? 'password';
|
|
68
|
+
return {
|
|
69
|
+
username: options.username ??
|
|
70
|
+
decodeSecretValue(data[options.usernameKey ?? 'username'], options.usernameKey ?? 'username'),
|
|
71
|
+
password: decodeSecretValue(data[passwordKey], passwordKey),
|
|
72
|
+
};
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
async function readKubernetesSecret(request) {
|
|
76
|
+
const config = {
|
|
77
|
+
...(request.context ? { context: request.context } : {}),
|
|
78
|
+
...(request.kubeconfigPath ? { kubeconfigPath: request.kubeconfigPath } : {}),
|
|
79
|
+
};
|
|
80
|
+
const provider = createKubernetesClientProvider(config);
|
|
81
|
+
const secret = await provider.getCoreV1Api().readNamespacedSecret({
|
|
82
|
+
namespace: request.namespace,
|
|
83
|
+
name: request.name,
|
|
84
|
+
});
|
|
85
|
+
return secret.data ?? {};
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=credentials.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credentials.js","sourceRoot":"","sources":["../../../../src/core/containers/registries/credentials.ts"],"names":[],"mappings":"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"}
|