hammerkit 2.0.0-next.2 → 2.0.0-next.3

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.
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.evictKeptClaims = exports.sweepKeptClaims = exports.expireKeptClaims = exports.recordClaimState = exports.forgetClaimState = exports.useClaimState = exports.isKeptClaim = exports.getClaimName = exports.EXPIRES_ANNOTATION = exports.STATE_ANNOTATION = exports.KEPT_BY_LABEL = exports.VOLUME_SCOPE_LABEL = void 0;
3
+ exports.evictKeptClaims = exports.sweepKeptClaims = exports.expireKeptClaims = exports.recordClaimState = exports.forgetClaimState = exports.rememberedClaimState = exports.useClaimState = exports.isKeptClaim = exports.getClaimName = exports.EXPIRES_ANNOTATION = exports.STATE_ANNOTATION = exports.KEPT_BY_LABEL = exports.VOLUME_SCOPE_LABEL = void 0;
4
4
  const crypto_1 = require("crypto");
5
5
  const apply_1 = require("./apply");
6
6
  const sleep_1 = require("../utils/sleep");
@@ -98,6 +98,17 @@ async function annotate(instance, namespace, name, annotations) {
98
98
  throw e;
99
99
  }
100
100
  }
101
+ // The state key of the outputs whose folder is whole in the claim of a task of a service run
102
+ // (see getStateFilesDir), null when it names none. The run's namespace is its own, and only
103
+ // the run writes to the claim: it forgets the state before it writes, records it after.
104
+ async function rememberedClaimState(instance, kubernetes, name) {
105
+ const claim = await readClaim(instance, kubernetes.namespace, name);
106
+ if (!claim || claim.metadata?.deletionTimestamp) {
107
+ return null;
108
+ }
109
+ return claim.metadata?.annotations?.[exports.STATE_ANNOTATION] ?? null;
110
+ }
111
+ exports.rememberedClaimState = rememberedClaimState;
101
112
  // Before a task writes to its kept claim: the outputs in it stop being those of a state.
102
113
  // Whether the claim was there, with what an earlier run left in it.
103
114
  function forgetClaimState(instance, kubernetes, name) {
@@ -170,6 +170,9 @@ function kubernetesTaskRuntime(task, kubernetes) {
170
170
  // on a server that keeps them, the task's claim stays after the run with the state of its
171
171
  // outputs, and the next run of the same source mounts them as they are (see kept-claims)
172
172
  const kept = (0, kept_claims_1.isKeptClaim)(task, kubernetes);
173
+ // on a service run, the claim names the last state whose folder is whole (see
174
+ // rememberedClaimState): a wake or a move at that state mounts it without an upload
175
+ const remembers = kept || !!kubernetes.server?.serviceRun;
173
176
  const claim = (0, volumes_1.getVolumeName)(task, kubernetes);
174
177
  return {
175
178
  initialize() {
@@ -182,6 +185,16 @@ function kubernetesTaskRuntime(task, kubernetes) {
182
185
  stateKey &&
183
186
  (await (0, ensure_persistent_data_1.getStateDirsInUse)(instance, kubernetes.namespace, claim)).has((0, volumes_1.getStateFilesDir)(stateKey))) {
184
187
  task.status.write('info', `${task.name}: services of the run use its outputs of this state, they stay`);
188
+ await (0, kept_claims_1.recordClaimState)(instance, kubernetes, claim, stateKey);
189
+ return;
190
+ }
191
+ if (remembers && !kept) {
192
+ // the folder of the state is written now: until it is whole, the claim names no state
193
+ await (0, kept_claims_1.forgetClaimState)(instance, kubernetes, claim);
194
+ await (0, restore_kubernetes_data_1.restoreKubernetesData)(task, kubernetes, instance, environment, path, { stateKey });
195
+ if (stateKey) {
196
+ await (0, kept_claims_1.recordClaimState)(instance, kubernetes, claim, stateKey);
197
+ }
185
198
  return;
186
199
  }
187
200
  if (!kept) {
@@ -231,11 +244,14 @@ function kubernetesTaskRuntime(task, kubernetes) {
231
244
  try {
232
245
  if (files && (await (0, ensure_persistent_data_1.getStateDirsInUse)(instance, kubernetes.namespace, claim)).has(files.dir)) {
233
246
  task.status.write('info', `${task.name}: services of the run use its outputs of this state, they stay`);
247
+ await (0, kept_claims_1.recordClaimState)(instance, kubernetes, claim, options.stateKey);
234
248
  return;
235
249
  }
236
250
  // the task writes to it now: what it holds stops being the outputs of a state, and
237
- // goes, as a new claim would hold nothing
238
- const reset = kept && (await (0, kept_claims_1.forgetClaimState)(instance, kubernetes, claim));
251
+ // goes, as a new claim would hold nothing (on a service run, the folders of other
252
+ // states that no pod mounts go)
253
+ const forgotten = remembers && (await (0, kept_claims_1.forgetClaimState)(instance, kubernetes, claim));
254
+ const reset = kept && forgotten;
239
255
  await (0, ensure_persistent_data_1.ensurePersistentData)(instance, kubernetes, environment, task, persistence, { reset, files });
240
256
  }
241
257
  catch (e) {
@@ -415,7 +431,7 @@ function kubernetesTaskRuntime(task, kubernetes) {
415
431
  }
416
432
  // the finished job stays for its state, the values it read need not
417
433
  await removeTaskSecrets(instance, kubernetes, task);
418
- if (kept) {
434
+ if (remembers) {
419
435
  await (0, kept_claims_1.recordClaimState)(instance, kubernetes, claim, options.stateKey);
420
436
  }
421
437
  }
@@ -471,6 +487,13 @@ function kubernetesTaskRuntime(task, kubernetes) {
471
487
  // the server removes the Jobs of a run at its end, the claim says
472
488
  return (0, kept_claims_1.useClaimState)(instance, kubernetes, claim);
473
489
  }
490
+ if (remembers) {
491
+ // a service run that sleeps loses its Jobs but keeps its claims, the claim says
492
+ const remembered = await (0, kept_claims_1.rememberedClaimState)(instance, kubernetes, claim);
493
+ if (remembered) {
494
+ return remembered;
495
+ }
496
+ }
474
497
  const jobs = await instance.batchApi.listNamespacedJob({
475
498
  namespace: kubernetes.namespace,
476
499
  labelSelector: (0, resources_1.getItemSelector)(task, kubernetes),
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "hammerkit",
3
3
  "description": "Containerized build tool with incremental caching that runs the same build file locally, in Docker and on Kubernetes.",
4
- "version": "2.0.0-next.2",
4
+ "version": "2.0.0-next.3",
5
5
  "keywords": [
6
6
  "build",
7
7
  "build-tool",