hammerkit 1.26.0 → 1.27.0-next.10
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/build.schema.json +62 -1
- package/dist/cache/backends/local-cache-backend.js +10 -2
- package/dist/cache/backends/registry-cache-backend.js +2 -2
- package/dist/cache/explain.js +13 -11
- package/dist/cli.js +3 -0
- package/dist/docker/item-network.js +471 -0
- package/dist/docker/pull.js +4 -2
- package/dist/docker/remove-orphaned-containers.js +13 -6
- package/dist/environment/replace-env-variables.js +8 -6
- package/dist/executer/await-completed-dependencies.js +2 -1
- package/dist/executer/check-readiness.js +2 -2
- package/dist/executer/docker-service.js +24 -13
- package/dist/executer/docker-task.js +18 -29
- package/dist/executer/event-cache.js +24 -2
- package/dist/executer/execute-command.js +18 -5
- package/dist/executer/execute-docker.js +4 -1
- package/dist/executer/execution-steps.js +33 -7
- package/dist/executer/get-docker-executor.js +14 -7
- package/dist/executer/scheduler/enqueue-next.js +17 -3
- package/dist/executer/watch-loop.js +2 -2
- package/dist/executer/watch-state-key.js +1 -1
- package/dist/file/within-root.js +42 -0
- package/dist/harness/connect.js +99 -0
- package/dist/harness/format.js +73 -0
- package/dist/harness/mcp-command.js +59 -0
- package/dist/harness/mcp.js +432 -0
- package/dist/harness/opencode.js +492 -0
- package/dist/harness/pi.js +217 -0
- package/dist/harness/sandbox-client.js +411 -0
- package/dist/index.js +33 -36
- package/dist/kubernetes/apply.js +42 -1
- package/dist/kubernetes/await-running-state.js +33 -1
- package/dist/kubernetes/claim-layout.js +71 -0
- package/dist/kubernetes/ensure-http-route.js +1 -1
- package/dist/kubernetes/ensure-kubernetes-deployment-exists.js +46 -28
- package/dist/kubernetes/ensure-kubernetes-persistent-volume-claim-exists.js +132 -5
- package/dist/kubernetes/ensure-kubernetes-service-exists.js +27 -11
- package/dist/kubernetes/ensure-persistent-data.js +75 -24
- package/dist/kubernetes/get-service-ip.js +16 -2
- package/dist/kubernetes/job-placement.js +99 -0
- package/dist/kubernetes/job-secrets.js +320 -0
- package/dist/kubernetes/kept-claims.js +203 -0
- package/dist/kubernetes/kubernetes-instance.js +10 -2
- package/dist/kubernetes/network-gate.js +71 -0
- package/dist/kubernetes/network-policy.js +583 -0
- package/dist/kubernetes/remove-persistent-data.js +3 -1
- package/dist/kubernetes/resources.js +37 -4
- package/dist/kubernetes/restore-kubernetes-data.js +28 -7
- package/dist/kubernetes/secrets.js +7 -9
- package/dist/kubernetes/store-kubernetes-data.js +1 -1
- package/dist/kubernetes/volumes.js +104 -12
- package/dist/log.js +1 -1
- package/dist/main.js +41 -0
- package/dist/network/egress-proxy.js +407 -0
- package/dist/network/port-relay.js +35 -0
- package/dist/optimizer/get-work-cache-stats.js +16 -0
- package/dist/optimizer/work-task-cache-description.js +5 -2
- package/dist/planner/service-definition.js +5 -0
- package/dist/planner/utils/append-work-dependencies.js +5 -2
- package/dist/planner/utils/append-work-environment.js +2 -0
- package/dist/planner/utils/append-work-service.js +5 -0
- package/dist/planner/utils/append-work-task.js +20 -1
- package/dist/planner/utils/assert-item-paths.js +50 -0
- package/dist/planner/utils/hosted-volumes.js +35 -0
- package/dist/planner/utils/task-arguments.js +3 -0
- package/dist/planner/work-network.js +193 -0
- package/dist/planner/work-runtime-docker.js +43 -1
- package/dist/planner/work-runtime-kubernetes.js +370 -111
- package/dist/planner/work-runtime-local.js +2 -1
- package/dist/program.js +33 -5
- package/dist/remote/annotations.js +115 -0
- package/dist/remote/bundle-text.js +24 -0
- package/dist/remote/bundle.js +9 -1
- package/dist/remote/remote-commands.js +15 -3
- package/dist/remote/remote-work-commands.js +272 -71
- package/dist/remote/server-client.js +18 -5
- package/dist/remote/source-manifest.js +15 -2
- package/dist/remote/token-source.js +67 -0
- package/dist/schema/build-file-base-task-schema.js +7 -0
- package/dist/schema/build-file-container-service-schema.js +8 -0
- package/dist/schema/build-file-container-task-schema.js +3 -0
- package/dist/schema/build-file-environment-schema.js +9 -0
- package/dist/schema/network-schema.js +78 -0
- package/dist/schema/reference-parser.js +2 -0
- package/dist/schema/schema-parser.js +16 -3
- package/dist/schema/work-scope-parser.js +5 -0
- package/dist/secrets/command-secret-provider.js +73 -10
- package/dist/secrets/github-app-token-command.js +26 -0
- package/dist/secrets/github-app-token.js +191 -0
- package/dist/server/accounts-api.js +9 -2
- package/dist/server/definitions-api.js +69 -47
- package/dist/server/definitions.js +76 -51
- package/dist/server/executor.js +156 -41
- package/dist/server/git-checkout.js +72 -8
- package/dist/server/kubernetes-backend.js +603 -0
- package/dist/server/kubernetes-sandbox-storage.js +997 -0
- package/dist/server/oauth.js +12 -0
- package/dist/server/plan.js +88 -2
- package/dist/server/policy.js +104 -15
- package/dist/server/proposals-api.js +24 -40
- package/dist/server/proposals.js +12 -25
- package/dist/server/repo-access.js +37 -6
- package/dist/server/run-logs.js +217 -0
- package/dist/server/run-plan.js +48 -2
- package/dist/server/run-request.js +29 -10
- package/dist/server/run-store.js +5 -0
- package/dist/server/run-worker-command.js +13 -1
- package/dist/server/run-worker.js +121 -24
- package/dist/server/runs.js +191 -10
- package/dist/server/sandbox-docker.js +62 -0
- package/dist/server/sandbox-files-api.js +269 -0
- package/dist/server/sandbox-files.js +1054 -0
- package/dist/server/sandbox-patch.js +481 -0
- package/dist/server/sandbox-pod-command.js +15 -0
- package/dist/server/sandbox-pod.js +146 -0
- package/dist/server/sandbox-storage.js +462 -0
- package/dist/server/sandboxes-api.js +216 -0
- package/dist/server/sandboxes.js +519 -0
- package/dist/server/server-command.js +39 -20
- package/dist/server/server-config.js +443 -22
- package/dist/server/server.js +219 -40
- package/dist/utils/abort-on-signals.js +46 -6
- package/dist/utils/run-id.js +12 -0
- package/dist/utils/tar.js +25 -0
- package/harness/opencode.ts +11 -0
- package/harness/pi.ts +7 -0
- package/package.json +8 -2
- package/dist/remote/text-diff.js +0 -89
|
@@ -1,21 +1,38 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.restoreKubernetesData = void 0;
|
|
3
|
+
exports.restoreKubernetesData = exports.getRestoreTarget = void 0;
|
|
4
4
|
const event_cache_1 = require("../executer/event-cache");
|
|
5
5
|
const log_1 = require("../log");
|
|
6
|
-
const path_1 = require("path");
|
|
7
6
|
const volumes_1 = require("./volumes");
|
|
8
7
|
const ensure_persistent_data_1 = require("./ensure-persistent-data");
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
const claim_layout_1 = require("./claim-layout");
|
|
9
|
+
// Where the upload pod (which mounts the work's claim at /dev/hammerkit/<id>) unpacks the
|
|
10
|
+
// archive of an output: the output's place in the claim, which its mount reads
|
|
11
|
+
function getRestoreTarget(work, path) {
|
|
12
|
+
return `/dev/hammerkit/${work.id()}/${(0, claim_layout_1.getClaimSubPath)(work, path)}`;
|
|
13
|
+
}
|
|
14
|
+
exports.getRestoreTarget = getRestoreTarget;
|
|
15
|
+
async function restoreKubernetesData(work, kubernetes, instance, environment, path,
|
|
16
|
+
// the kept claim of the work holds what an earlier run left, which goes first
|
|
17
|
+
options = {}) {
|
|
18
|
+
const persistence = await (0, volumes_1.getKubernetesPersistence)(work, kubernetes);
|
|
11
19
|
await (0, ensure_persistent_data_1.getPodForPersistence)(instance, kubernetes, work, persistence, 'write', async (name) => {
|
|
20
|
+
if (options.reset) {
|
|
21
|
+
await (0, ensure_persistent_data_1.clearClaim)(instance, kubernetes, work, name);
|
|
22
|
+
}
|
|
12
23
|
for (const generatedArchive of (0, event_cache_1.getArchivePaths)(work.data, path)) {
|
|
13
24
|
if (!(await environment.file.exists(generatedArchive.filename))) {
|
|
14
25
|
continue;
|
|
15
26
|
}
|
|
16
|
-
const targetPath =
|
|
17
|
-
|
|
18
|
-
|
|
27
|
+
const targetPath = getRestoreTarget(work, generatedArchive.path);
|
|
28
|
+
// a claim made for this run (a server removes the claims of a run when it
|
|
29
|
+
// ends) does not have the directory of the output yet
|
|
30
|
+
let failure = null;
|
|
31
|
+
const res = await instance.exec.exec(kubernetes.namespace, name, 'volume', ['sh', '-c', 'mkdir -p "$1" && tar xzf - -C "$1"', 'sh', targetPath], process.stdout, process.stderr, environment.file.readStream(generatedArchive.filename), false, (status) => {
|
|
32
|
+
work.status.write('debug', `upload ${generatedArchive.filename} to ${name}: ${status.status}`);
|
|
33
|
+
if (status.status !== 'Success') {
|
|
34
|
+
failure = status.message ?? status.reason ?? 'unknown';
|
|
35
|
+
}
|
|
19
36
|
});
|
|
20
37
|
await new Promise((resolve, reject) => {
|
|
21
38
|
try {
|
|
@@ -27,6 +44,10 @@ async function restoreKubernetesData(work, kubernetes, instance, environment, pa
|
|
|
27
44
|
reject(err);
|
|
28
45
|
});
|
|
29
46
|
res.on('close', () => {
|
|
47
|
+
if (failure) {
|
|
48
|
+
reject(new Error(`unable to restore ${generatedArchive.path} into ${name}: ${failure}`));
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
30
51
|
work.status.write('debug', `uploaded ${generatedArchive.filename} to ${name}:${targetPath}`);
|
|
31
52
|
resolve();
|
|
32
53
|
});
|
|
@@ -6,17 +6,17 @@ const apply_1 = require("./apply");
|
|
|
6
6
|
const resources_1 = require("./resources");
|
|
7
7
|
const version_1 = require("../version");
|
|
8
8
|
const SECRET_VOLUME_NAME = 'hammerkit-secrets';
|
|
9
|
-
function getSecretResourceName(item) {
|
|
10
|
-
return (0, resources_1.getResourceName)(item, '-secrets');
|
|
9
|
+
function getSecretResourceName(item, kubernetes) {
|
|
10
|
+
return (0, resources_1.getResourceName)(item, kubernetes, '-secrets');
|
|
11
11
|
}
|
|
12
12
|
exports.getSecretResourceName = getSecretResourceName;
|
|
13
13
|
// The values go into a Secret of the item; the pod only references it, so no
|
|
14
14
|
// value is part of a Job or Deployment spec.
|
|
15
|
-
function getKubernetesSecretRefs(item, secrets) {
|
|
15
|
+
function getKubernetesSecretRefs(item, kubernetes, secrets) {
|
|
16
16
|
if (secrets.length === 0) {
|
|
17
17
|
return { env: [], mounts: [], volumes: [] };
|
|
18
18
|
}
|
|
19
|
-
const secretName = getSecretResourceName(item);
|
|
19
|
+
const secretName = getSecretResourceName(item, kubernetes);
|
|
20
20
|
const refs = {
|
|
21
21
|
env: [],
|
|
22
22
|
mounts: [],
|
|
@@ -49,13 +49,11 @@ async function ensureKubernetesSecret(instance, kubernetes, item, secrets, envir
|
|
|
49
49
|
apiVersion: 'v1',
|
|
50
50
|
metadata: {
|
|
51
51
|
namespace: kubernetes.namespace,
|
|
52
|
-
name: getSecretResourceName(item),
|
|
52
|
+
name: getSecretResourceName(item, kubernetes),
|
|
53
53
|
annotations: {
|
|
54
54
|
'hammerkit.dev/version': (0, version_1.getVersion)(),
|
|
55
55
|
},
|
|
56
|
-
labels:
|
|
57
|
-
'hammerkit.dev/id': item.id(),
|
|
58
|
-
},
|
|
56
|
+
labels: (0, resources_1.getItemLabels)(item, kubernetes),
|
|
59
57
|
},
|
|
60
58
|
type: 'Opaque',
|
|
61
59
|
stringData,
|
|
@@ -66,7 +64,7 @@ exports.ensureKubernetesSecret = ensureKubernetesSecret;
|
|
|
66
64
|
async function removeKubernetesSecret(instance, kubernetes, item) {
|
|
67
65
|
try {
|
|
68
66
|
await instance.coreApi.deleteNamespacedSecret({
|
|
69
|
-
name: getSecretResourceName(item),
|
|
67
|
+
name: getSecretResourceName(item, kubernetes),
|
|
70
68
|
namespace: kubernetes.namespace,
|
|
71
69
|
});
|
|
72
70
|
}
|
|
@@ -6,7 +6,7 @@ const event_cache_1 = require("../executer/event-cache");
|
|
|
6
6
|
const volumes_1 = require("./volumes");
|
|
7
7
|
const ensure_persistent_data_1 = require("./ensure-persistent-data");
|
|
8
8
|
async function storeKubernetesData(work, kubernetes, instance, environment, path) {
|
|
9
|
-
const persistence = await (0, volumes_1.getKubernetesPersistence)(work);
|
|
9
|
+
const persistence = await (0, volumes_1.getKubernetesPersistence)(work, kubernetes);
|
|
10
10
|
await (0, ensure_persistent_data_1.getPodForPersistence)(instance, kubernetes, work, persistence, 'read', async (name) => {
|
|
11
11
|
for (const generatedArchive of (0, event_cache_1.getArchivePaths)(work.data, path)) {
|
|
12
12
|
const writerStream = environment.file.createWriteStream(generatedArchive.filename);
|
|
@@ -1,37 +1,90 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.appendVolume = exports.getKubernetesPersistence = exports.getVolumeName = void 0;
|
|
3
|
+
exports.getSandboxAffinity = exports.SANDBOX_LABEL = exports.getWorkspacePodSpec = exports.appendVolume = exports.getKubernetesPersistence = exports.getVolumeName = void 0;
|
|
4
4
|
const path_1 = require("path");
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
const fs_1 = require("fs");
|
|
6
|
+
const kept_claims_1 = require("./kept-claims");
|
|
7
|
+
const claim_layout_1 = require("./claim-layout");
|
|
8
|
+
function getVolumeName(service, kubernetes) {
|
|
9
|
+
return (0, kept_claims_1.getClaimName)(service, kubernetes);
|
|
7
10
|
}
|
|
8
11
|
exports.getVolumeName = getVolumeName;
|
|
9
|
-
|
|
10
|
-
|
|
12
|
+
const WORKSPACE_VOLUME = 'hammerkit-sandbox';
|
|
13
|
+
// The path of `path` below the root of a sandbox's files, or undefined when it is not
|
|
14
|
+
// below it
|
|
15
|
+
function workspacePath(workspace, path) {
|
|
16
|
+
const rel = (0, path_1.relative)(workspace.root, path);
|
|
17
|
+
if (rel.startsWith('..') || (0, path_1.isAbsolute)(rel)) {
|
|
18
|
+
return undefined;
|
|
19
|
+
}
|
|
20
|
+
return [workspace.subPath, ...rel.split(path_1.sep).filter((part) => part.length > 0)].join('/');
|
|
21
|
+
}
|
|
22
|
+
// A path of a sandbox is mounted from its claim, read and write as on a host's docker,
|
|
23
|
+
// so what the task writes is in the sandbox afterwards. A path that is not in the
|
|
24
|
+
// sandbox is left out: Kubernetes would make a directory of it in the claim.
|
|
25
|
+
function appendWorkspaceMount(workspace, persistence, containerPath, localPath, isFile, readOnly) {
|
|
26
|
+
const subPath = workspacePath(workspace, localPath);
|
|
27
|
+
if (subPath === undefined) {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
if (!(0, fs_1.existsSync)(localPath)) {
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
33
|
+
if (persistence.workspace.length === 0) {
|
|
34
|
+
persistence.workspace.push({ name: WORKSPACE_VOLUME, persistentVolumeClaim: { claimName: workspace.claim } });
|
|
35
|
+
}
|
|
36
|
+
persistence.mounts.push({
|
|
37
|
+
mount: { readOnly, mountPath: containerPath, name: WORKSPACE_VOLUME, subPath },
|
|
38
|
+
uploadPath: '',
|
|
39
|
+
cwd: isFile ? (0, path_1.dirname)(containerPath) : containerPath,
|
|
40
|
+
workspace: true,
|
|
41
|
+
});
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
async function getKubernetesPersistence(work, kubernetes) {
|
|
45
|
+
const persistence = {
|
|
46
|
+
volumes: [],
|
|
47
|
+
sizes: {},
|
|
48
|
+
kept: [],
|
|
49
|
+
workspace: [],
|
|
50
|
+
sources: [],
|
|
51
|
+
mounts: [],
|
|
52
|
+
initCommands: [],
|
|
53
|
+
};
|
|
54
|
+
const workspace = kubernetes.server?.workspace;
|
|
11
55
|
for (const mount of work.data.mounts) {
|
|
12
|
-
|
|
56
|
+
if (workspace &&
|
|
57
|
+
appendWorkspaceMount(workspace, persistence, mount.containerPath, mount.localPath, mount.isFile, mount.readOnly)) {
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
appendVolume(work, persistence, mount.containerPath, mount.localPath, mount.isFile, true, kubernetes);
|
|
13
61
|
}
|
|
14
62
|
for (const src of work.data.src) {
|
|
15
63
|
if (src.inherited) {
|
|
16
64
|
continue;
|
|
17
65
|
}
|
|
18
|
-
|
|
66
|
+
if (workspace &&
|
|
67
|
+
appendWorkspaceMount(workspace, persistence, src.absolutePath, src.absolutePath, src.isFile, false)) {
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
appendVolume(work, persistence, src.absolutePath, src.absolutePath, src.isFile, true, kubernetes); // TODO matcher
|
|
19
71
|
}
|
|
20
72
|
if (work.data.type === 'container-task') {
|
|
21
73
|
for (const generate of work.data.generates) {
|
|
22
|
-
appendVolume(generate.inherited ?? work, persistence, generate.path, null, false, !!generate.inherited);
|
|
74
|
+
appendVolume(generate.inherited ?? work, persistence, generate.path, null, false, !!generate.inherited, kubernetes);
|
|
23
75
|
}
|
|
24
76
|
}
|
|
25
77
|
else {
|
|
26
78
|
for (const volume of work.data.volumes) {
|
|
27
|
-
appendVolume(volume.inherited ?? work, persistence, volume.containerPath, null, false, !!volume.inherited || volume.readOnly);
|
|
79
|
+
appendVolume(volume.inherited ?? work, persistence, volume.containerPath, null, false, !!volume.inherited || volume.readOnly, kubernetes);
|
|
28
80
|
}
|
|
29
81
|
}
|
|
30
82
|
return persistence;
|
|
31
83
|
}
|
|
32
84
|
exports.getKubernetesPersistence = getKubernetesPersistence;
|
|
33
|
-
function appendVolume(sourceWork, persistence, containerPath, localPath, isFile, readOnly) {
|
|
34
|
-
const volumeName = getVolumeName(sourceWork);
|
|
85
|
+
function appendVolume(sourceWork, persistence, containerPath, localPath, isFile, readOnly, kubernetes) {
|
|
86
|
+
const volumeName = getVolumeName(sourceWork, kubernetes);
|
|
87
|
+
const subPath = (0, claim_layout_1.getClaimSubPath)(sourceWork, containerPath);
|
|
35
88
|
const existVolume = persistence.volumes.some((v) => v.name === volumeName);
|
|
36
89
|
if (!existVolume) {
|
|
37
90
|
persistence.volumes.push({
|
|
@@ -40,13 +93,17 @@ function appendVolume(sourceWork, persistence, containerPath, localPath, isFile,
|
|
|
40
93
|
claimName: volumeName,
|
|
41
94
|
},
|
|
42
95
|
});
|
|
96
|
+
persistence.sizes[volumeName] = 'volumeSize' in sourceWork.data ? sourceWork.data.volumeSize : null;
|
|
97
|
+
if ((0, kept_claims_1.isKeptClaim)(sourceWork, kubernetes)) {
|
|
98
|
+
persistence.kept.push(volumeName);
|
|
99
|
+
}
|
|
43
100
|
}
|
|
44
101
|
persistence.mounts.push({
|
|
45
102
|
mount: {
|
|
46
103
|
readOnly,
|
|
47
104
|
mountPath: containerPath,
|
|
48
105
|
name: volumeName,
|
|
49
|
-
subPath
|
|
106
|
+
subPath,
|
|
50
107
|
},
|
|
51
108
|
uploadPath: `/dev/hammerkit/${sourceWork.id()}`,
|
|
52
109
|
cwd: isFile ? (0, path_1.dirname)(containerPath) : containerPath,
|
|
@@ -56,9 +113,44 @@ function appendVolume(sourceWork, persistence, containerPath, localPath, isFile,
|
|
|
56
113
|
localPath: localPath,
|
|
57
114
|
matcher: () => true, // TODO
|
|
58
115
|
containerPath,
|
|
116
|
+
subPath,
|
|
59
117
|
stateKey: '', // TODO
|
|
60
118
|
});
|
|
61
119
|
}
|
|
62
120
|
}
|
|
63
121
|
exports.appendVolume = appendVolume;
|
|
122
|
+
/**
|
|
123
|
+
* What a pod that mounts the claim of a sandbox needs: its label, and to go where the
|
|
124
|
+
* other pods that mount it run. A claim is usually `ReadWriteOnce`, which several pods
|
|
125
|
+
* share only on one node; the first pod (no other one runs) goes anywhere. The pod of the
|
|
126
|
+
* sandbox's files runs on the first pool while a run works, so a task on another pool
|
|
127
|
+
* would never start: it is refused.
|
|
128
|
+
*/
|
|
129
|
+
function getWorkspacePodSpec(kubernetes, persistence, task) {
|
|
130
|
+
const workspace = kubernetes.server?.workspace;
|
|
131
|
+
if (!workspace || persistence.workspace.length === 0) {
|
|
132
|
+
return { labels: {} };
|
|
133
|
+
}
|
|
134
|
+
const first = kubernetes.server?.pools[0]?.name;
|
|
135
|
+
if (task?.pool && first && task.pool !== first) {
|
|
136
|
+
throw new Error(`task ${task.name}: runs on the pool ${task.pool}, and the tasks of a run on a sandbox run on the first pool, ${first}, where its files are`);
|
|
137
|
+
}
|
|
138
|
+
return {
|
|
139
|
+
labels: { [exports.SANDBOX_LABEL]: workspace.label },
|
|
140
|
+
affinity: getSandboxAffinity(workspace.label),
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
exports.getWorkspacePodSpec = getWorkspacePodSpec;
|
|
144
|
+
// the label of the pods that mount the claim of a sandbox
|
|
145
|
+
exports.SANDBOX_LABEL = 'hammerkit.dev/sandbox';
|
|
146
|
+
function getSandboxAffinity(label) {
|
|
147
|
+
return {
|
|
148
|
+
podAffinity: {
|
|
149
|
+
requiredDuringSchedulingIgnoredDuringExecution: [
|
|
150
|
+
{ labelSelector: { matchLabels: { [exports.SANDBOX_LABEL]: label } }, topologyKey: 'kubernetes.io/hostname' },
|
|
151
|
+
],
|
|
152
|
+
},
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
exports.getSandboxAffinity = getSandboxAffinity;
|
|
64
156
|
//# sourceMappingURL=volumes.js.map
|
package/dist/log.js
CHANGED
|
@@ -216,7 +216,7 @@ function writeWorkItemLogToConsole(env, log, maxNodeNameLength) {
|
|
|
216
216
|
exports.writeWorkItemLogToConsole = writeWorkItemLogToConsole;
|
|
217
217
|
function formatDate(date) {
|
|
218
218
|
return colors_1.default.grey(`[${date.getFullYear()}-${(date.getMonth() + 1).toString().padStart(2, '0')}-${date
|
|
219
|
-
.
|
|
219
|
+
.getDate()
|
|
220
220
|
.toString()
|
|
221
221
|
.padStart(2, '0')} ${date.getHours().toString().padStart(2, '0')}:${date
|
|
222
222
|
.getMinutes()
|
package/dist/main.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
// The CLI: what `hammerkit` runs, for all but the command of a sandbox's pod (see index.ts).
|
|
4
|
+
const log_1 = require("./log");
|
|
5
|
+
const get_file_context_1 = require("./file/get-file-context");
|
|
6
|
+
const work_item_status_1 = require("./planner/work-item-status");
|
|
7
|
+
const redact_1 = require("./utils/redact");
|
|
8
|
+
const empty_writable_1 = require("./utils/empty-writable");
|
|
9
|
+
const run_program_1 = require("./run-program");
|
|
10
|
+
const abort_on_signals_1 = require("./utils/abort-on-signals");
|
|
11
|
+
const abortCtrl = new AbortController();
|
|
12
|
+
(0, abort_on_signals_1.abortOnSignals)(process, abortCtrl);
|
|
13
|
+
let settled = false;
|
|
14
|
+
// A run that never settles (a task waiting on something that can't happen)
|
|
15
|
+
// lets the event loop drain, and Node then exits 0: CI would report success
|
|
16
|
+
// for a build that never finished. Fail loudly instead.
|
|
17
|
+
process.on('beforeExit', () => {
|
|
18
|
+
if (!settled) {
|
|
19
|
+
process.stderr.write('hammerkit stopped before the run finished\n');
|
|
20
|
+
process.exitCode = 1;
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
const secrets = (0, redact_1.createSecretRegistry)();
|
|
24
|
+
(0, run_program_1.runProgram)({
|
|
25
|
+
cwd: process.cwd(),
|
|
26
|
+
abortCtrl,
|
|
27
|
+
processEnvs: process.env,
|
|
28
|
+
file: (0, get_file_context_1.getFileContext)(process.cwd()),
|
|
29
|
+
console: (0, log_1.consoleContext)(process.stdout),
|
|
30
|
+
status: (0, work_item_status_1.statusConsole)((0, empty_writable_1.emptyWritable)(), secrets),
|
|
31
|
+
secrets,
|
|
32
|
+
stdout: process.stdout,
|
|
33
|
+
stderr: process.stderr,
|
|
34
|
+
stdoutColumns: process.stdout.columns,
|
|
35
|
+
}, process.argv, false).then(() => {
|
|
36
|
+
settled = true;
|
|
37
|
+
}, () => {
|
|
38
|
+
settled = true;
|
|
39
|
+
process.exit(1);
|
|
40
|
+
});
|
|
41
|
+
//# sourceMappingURL=main.js.map
|