hammerkit 2.0.0-next.3 → 2.0.0-next.4
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.ensurePersistentData = exports.packSource = exports.restoreLiveFiles = exports.syncLiveFiles = exports.SYNC_FILES = exports.getStateDirsInUse = exports.REMOVE_OTHER_STATES = exports.execInPod = exports.clearClaim = exports.getPodForPersistence = void 0;
|
|
3
|
+
exports.ensurePersistentData = exports.packSource = exports.clearStateFiles = exports.restoreLiveFiles = exports.syncLiveFiles = exports.SYNC_FILES = exports.getStateDirsInUse = exports.REMOVE_OTHER_STATES = exports.execInPod = exports.clearClaim = exports.getPodForPersistence = void 0;
|
|
4
4
|
const volumes_1 = require("./volumes");
|
|
5
5
|
const apply_1 = require("./apply");
|
|
6
6
|
const path_1 = require("path");
|
|
@@ -282,6 +282,31 @@ exports.restoreLiveFiles = restoreLiveFiles;
|
|
|
282
282
|
// Returns whether the upload is needed.
|
|
283
283
|
async function prepareStateFiles(instance, env, work, pod, dir, inUse) {
|
|
284
284
|
const targetPath = `/dev/hammerkit/${work.id()}`;
|
|
285
|
+
await removeOtherStates(instance, env, pod, targetPath, dir, inUse);
|
|
286
|
+
if (inUse.has(dir) && !(await execInPod(instance, env, pod, ['test', '-e', `${targetPath}/${dir}/${UPLOADED}`]))) {
|
|
287
|
+
work.status.write('info', `the files of ${work.name} are there already`);
|
|
288
|
+
return false;
|
|
289
|
+
}
|
|
290
|
+
await clearStateDir(instance, env, pod, `${targetPath}/${dir}`);
|
|
291
|
+
return true;
|
|
292
|
+
}
|
|
293
|
+
// what a failed upload, restore or task left: tar does not remove files the commit does not have
|
|
294
|
+
async function clearStateDir(instance, env, pod, path) {
|
|
295
|
+
const cleared = await execInPod(instance, env, pod, ['rm', '-rf', path]);
|
|
296
|
+
if (cleared) {
|
|
297
|
+
throw new Error(`unable to clear ${path}: ${cleared}`);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
// Before a restore of a service run into the folder `dir` of the claim of `work` (in its upload
|
|
301
|
+
// pod `pod`): the folders of the other states go but those of `inUse`, which pods of the run
|
|
302
|
+
// mount, and `dir` is emptied. A claim that took only restores holds one state, as after a Job.
|
|
303
|
+
async function clearStateFiles(instance, env, work, pod, dir, inUse) {
|
|
304
|
+
const targetPath = `/dev/hammerkit/${work.id()}`;
|
|
305
|
+
await removeOtherStates(instance, env, pod, targetPath, dir, inUse);
|
|
306
|
+
await clearStateDir(instance, env, pod, `${targetPath}/${dir}`);
|
|
307
|
+
}
|
|
308
|
+
exports.clearStateFiles = clearStateFiles;
|
|
309
|
+
async function removeOtherStates(instance, env, pod, targetPath, dir, inUse) {
|
|
285
310
|
const removed = await execInPod(instance, env, pod, [
|
|
286
311
|
'sh',
|
|
287
312
|
'-c',
|
|
@@ -294,16 +319,6 @@ async function prepareStateFiles(instance, env, work, pod, dir, inUse) {
|
|
|
294
319
|
if (removed) {
|
|
295
320
|
throw new Error(`unable to remove the files of other commits in ${targetPath}: ${removed}`);
|
|
296
321
|
}
|
|
297
|
-
if (inUse.has(dir) && !(await execInPod(instance, env, pod, ['test', '-e', `${targetPath}/${dir}/${UPLOADED}`]))) {
|
|
298
|
-
work.status.write('info', `the files of ${work.name} are there already`);
|
|
299
|
-
return false;
|
|
300
|
-
}
|
|
301
|
-
// what a failed upload or task left: tar does not remove files the commit does not have
|
|
302
|
-
const cleared = await execInPod(instance, env, pod, ['rm', '-rf', `${targetPath}/${dir}`]);
|
|
303
|
-
if (cleared) {
|
|
304
|
-
throw new Error(`unable to clear ${targetPath}/${dir}: ${cleared}`);
|
|
305
|
-
}
|
|
306
|
-
return true;
|
|
307
322
|
}
|
|
308
323
|
// The archive that uploads a source into the claim: its file or directory, at its place in
|
|
309
324
|
// the claim (see getClaimSubPath) instead of under its own name
|
|
@@ -99,11 +99,15 @@ async function annotate(instance, namespace, name, annotations) {
|
|
|
99
99
|
}
|
|
100
100
|
}
|
|
101
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
|
|
103
|
-
//
|
|
102
|
+
// (see getStateFilesDir), null when it names none (also while the claim is being removed),
|
|
103
|
+
// undefined when there is no claim. The run's namespace is its own, and only the run writes
|
|
104
|
+
// to the claim: it forgets the state before it writes, records it after.
|
|
104
105
|
async function rememberedClaimState(instance, kubernetes, name) {
|
|
105
106
|
const claim = await readClaim(instance, kubernetes.namespace, name);
|
|
106
|
-
if (!claim
|
|
107
|
+
if (!claim) {
|
|
108
|
+
return undefined;
|
|
109
|
+
}
|
|
110
|
+
if (claim.metadata?.deletionTimestamp) {
|
|
107
111
|
return null;
|
|
108
112
|
}
|
|
109
113
|
return claim.metadata?.annotations?.[exports.STATE_ANNOTATION] ?? null;
|
|
@@ -16,7 +16,9 @@ stateDir) {
|
|
|
16
16
|
exports.getRestoreTarget = getRestoreTarget;
|
|
17
17
|
async function restoreKubernetesData(work, kubernetes, instance, environment, path,
|
|
18
18
|
// the kept claim of the work holds what an earlier run left, which goes first; on a
|
|
19
|
-
// service run, the outputs go into the folder of `stateKey` (see getStateFilesDir)
|
|
19
|
+
// service run, the outputs go into the folder of `stateKey` (see getStateFilesDir);
|
|
20
|
+
// `otherStates`: the folders of the other states go but these (the ones pods of the run
|
|
21
|
+
// mount), and the folder of `stateKey` is emptied first
|
|
20
22
|
options = {}) {
|
|
21
23
|
const persistence = await (0, volumes_1.getKubernetesPersistence)(work, kubernetes, options.stateKey);
|
|
22
24
|
const stateDir = kubernetes.server?.serviceRun ? (0, volumes_1.getItemFilesDir)(work, options.stateKey) : undefined;
|
|
@@ -24,6 +26,9 @@ options = {}) {
|
|
|
24
26
|
if (options.reset) {
|
|
25
27
|
await (0, ensure_persistent_data_1.clearClaim)(instance, kubernetes, work, name);
|
|
26
28
|
}
|
|
29
|
+
if (stateDir && options.otherStates) {
|
|
30
|
+
await (0, ensure_persistent_data_1.clearStateFiles)(instance, kubernetes, work, name, stateDir, options.otherStates);
|
|
31
|
+
}
|
|
27
32
|
for (const generatedArchive of (0, event_cache_1.getArchivePaths)(work.data, path)) {
|
|
28
33
|
if (!(await environment.file.exists(generatedArchive.filename))) {
|
|
29
34
|
continue;
|
|
@@ -190,8 +190,13 @@ function kubernetesTaskRuntime(task, kubernetes) {
|
|
|
190
190
|
}
|
|
191
191
|
if (remembers && !kept) {
|
|
192
192
|
// the folder of the state is written now: until it is whole, the claim names no state
|
|
193
|
+
// (a restore without a state key says none, and the next run uploads again)
|
|
193
194
|
await (0, kept_claims_1.forgetClaimState)(instance, kubernetes, claim);
|
|
194
|
-
await (0, restore_kubernetes_data_1.restoreKubernetesData)(task, kubernetes, instance, environment, path, {
|
|
195
|
+
await (0, restore_kubernetes_data_1.restoreKubernetesData)(task, kubernetes, instance, environment, path, {
|
|
196
|
+
stateKey,
|
|
197
|
+
// the folders of other states no pod of the run mounts go, as before a Job
|
|
198
|
+
...(stateKey ? { otherStates: await (0, ensure_persistent_data_1.getStateDirsInUse)(instance, kubernetes.namespace, claim) } : {}),
|
|
199
|
+
});
|
|
195
200
|
if (stateKey) {
|
|
196
201
|
await (0, kept_claims_1.recordClaimState)(instance, kubernetes, claim, stateKey);
|
|
197
202
|
}
|
|
@@ -488,9 +493,11 @@ function kubernetesTaskRuntime(task, kubernetes) {
|
|
|
488
493
|
return (0, kept_claims_1.useClaimState)(instance, kubernetes, claim);
|
|
489
494
|
}
|
|
490
495
|
if (remembers) {
|
|
491
|
-
// a service run that sleeps loses its Jobs but keeps its claims, the claim says
|
|
496
|
+
// a service run that sleeps loses its Jobs but keeps its claims, the claim says. One
|
|
497
|
+
// that names no state is being written (or was, and that failed): the folder of the
|
|
498
|
+
// state of an earlier Job may be gone. Only a task without a claim goes by its Jobs.
|
|
492
499
|
const remembered = await (0, kept_claims_1.rememberedClaimState)(instance, kubernetes, claim);
|
|
493
|
-
if (remembered) {
|
|
500
|
+
if (remembered !== undefined) {
|
|
494
501
|
return remembered;
|
|
495
502
|
}
|
|
496
503
|
}
|
package/package.json
CHANGED