@atolis-hq/wake 0.2.12 → 0.2.13
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.
|
@@ -57,6 +57,9 @@ function buildRunArgs(input) {
|
|
|
57
57
|
}
|
|
58
58
|
export function createDockerCli(deps) {
|
|
59
59
|
return {
|
|
60
|
+
async inspectContainerImage(containerName) {
|
|
61
|
+
return (await deps.inspectContainerImage?.(containerName)) ?? null;
|
|
62
|
+
},
|
|
60
63
|
async build(input) {
|
|
61
64
|
const buildArgFlags = Object.entries(input.buildArgs ?? {}).flatMap(([key, value]) => [
|
|
62
65
|
'--build-arg',
|
|
@@ -12,6 +12,13 @@ const START_PROCESS_CHECK = [
|
|
|
12
12
|
'tr "\\0" " " < "/proc/$pid/cmdline" | grep -F "node /app/dist/src/main.js start --wake-root /wake" >/dev/null',
|
|
13
13
|
].join(' && '),
|
|
14
14
|
];
|
|
15
|
+
function tagFromImage(imageRepository, image) {
|
|
16
|
+
if (image === null) {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
const prefix = `${imageRepository}:`;
|
|
20
|
+
return image.startsWith(prefix) ? image.slice(prefix.length) : null;
|
|
21
|
+
}
|
|
15
22
|
function readFlag(name, args) {
|
|
16
23
|
const index = args.indexOf(name);
|
|
17
24
|
return index === -1 ? undefined : args[index + 1];
|
|
@@ -69,6 +76,13 @@ export async function runSelfUpdateCommand(input) {
|
|
|
69
76
|
logger: input.logger,
|
|
70
77
|
});
|
|
71
78
|
const newImage = `${input.imageRepository}:${tag}`;
|
|
79
|
+
const previousImage = (await input.docker.inspectContainerImage?.(input.containerName)) ?? null;
|
|
80
|
+
const previousImageTag = tagFromImage(input.imageRepository, previousImage);
|
|
81
|
+
const rollbackImage = previousImage ??
|
|
82
|
+
(ledger.lastKnownGoodTag !== null
|
|
83
|
+
? `${input.imageRepository}:${ledger.lastKnownGoodTag}`
|
|
84
|
+
: null);
|
|
85
|
+
const rollbackTag = previousImageTag ?? ledger.lastKnownGoodTag;
|
|
72
86
|
const updateInput = {
|
|
73
87
|
containerName: input.containerName,
|
|
74
88
|
wakeRoot: input.wakeRoot,
|
|
@@ -106,9 +120,10 @@ export async function runSelfUpdateCommand(input) {
|
|
|
106
120
|
catch (error) {
|
|
107
121
|
const reason = error instanceof Error ? error.message : String(error);
|
|
108
122
|
input.logger.error(`[self-update] rollout of ${tag} failed: ${reason}`);
|
|
109
|
-
if (
|
|
110
|
-
|
|
111
|
-
|
|
123
|
+
if (rollbackImage !== null) {
|
|
124
|
+
if (rollbackTag !== null) {
|
|
125
|
+
await input.git.checkoutTag(rollbackTag);
|
|
126
|
+
}
|
|
112
127
|
await input.docker.update({ ...updateInput, image: rollbackImage });
|
|
113
128
|
input.logger.info('[self-update] recreated rollback container; entrypoint will keep wake start running');
|
|
114
129
|
await verifyResidentStart({
|
|
@@ -119,21 +134,21 @@ export async function runSelfUpdateCommand(input) {
|
|
|
119
134
|
sleep: input.sleep,
|
|
120
135
|
context: 'rollback',
|
|
121
136
|
});
|
|
122
|
-
input.logger.info(`[self-update] rolled back to ${
|
|
137
|
+
input.logger.info(`[self-update] rolled back to ${rollbackTag ?? rollbackImage}`);
|
|
123
138
|
}
|
|
124
139
|
else {
|
|
125
140
|
input.logger.error('[self-update] no previous known-good tag to roll back to');
|
|
126
141
|
}
|
|
127
142
|
await input.writeLedger({
|
|
128
|
-
lastAppliedTag:
|
|
129
|
-
lastKnownGoodTag:
|
|
143
|
+
lastAppliedTag: rollbackTag,
|
|
144
|
+
lastKnownGoodTag: rollbackTag,
|
|
130
145
|
badTags: [...ledger.badTags, { tag, reason, recordedAt: new Date().toISOString() }],
|
|
131
146
|
});
|
|
132
147
|
try {
|
|
133
148
|
await input.issueReporter.createIssue({
|
|
134
149
|
title: `Self-update to ${tag} failed and was rolled back`,
|
|
135
150
|
body: [
|
|
136
|
-
`Automated update to \`${tag}\` failed during rollout and was rolled back to \`${
|
|
151
|
+
`Automated update to \`${tag}\` failed during rollout and was rolled back to \`${rollbackTag ?? rollbackImage ?? 'unknown'}\`.`,
|
|
137
152
|
'',
|
|
138
153
|
'```',
|
|
139
154
|
reason,
|
package/dist/src/main.js
CHANGED
|
@@ -346,6 +346,28 @@ async function inspectDockerContainer(containerName) {
|
|
|
346
346
|
});
|
|
347
347
|
});
|
|
348
348
|
}
|
|
349
|
+
async function inspectDockerContainerImage(containerName) {
|
|
350
|
+
return await new Promise((resolveInspect, reject) => {
|
|
351
|
+
const child = spawn('docker', ['container', 'inspect', '-f', '{{.Config.Image}}', containerName], {
|
|
352
|
+
cwd: process.cwd(),
|
|
353
|
+
env: process.env,
|
|
354
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
355
|
+
});
|
|
356
|
+
let stdout = '';
|
|
357
|
+
child.stdout.on('data', (chunk) => {
|
|
358
|
+
stdout += chunk.toString();
|
|
359
|
+
});
|
|
360
|
+
child.on('error', reject);
|
|
361
|
+
child.on('close', (exitCode) => {
|
|
362
|
+
if (exitCode !== 0) {
|
|
363
|
+
resolveInspect(null);
|
|
364
|
+
return;
|
|
365
|
+
}
|
|
366
|
+
const image = stdout.trim();
|
|
367
|
+
resolveInspect(image.length > 0 ? image : null);
|
|
368
|
+
});
|
|
369
|
+
});
|
|
370
|
+
}
|
|
349
371
|
async function dockerDaemonReachable() {
|
|
350
372
|
return await new Promise((resolveReachable) => {
|
|
351
373
|
const child = spawn('docker', ['info'], {
|
|
@@ -370,6 +392,7 @@ function createHostDockerCli() {
|
|
|
370
392
|
run: (dockerArgs) => runCommand('docker', dockerArgs, { ...process.env, DOCKER_BUILDKIT: '1' }),
|
|
371
393
|
inspectImage: inspectDockerImage,
|
|
372
394
|
inspectContainer: inspectDockerContainer,
|
|
395
|
+
inspectContainerImage: inspectDockerContainerImage,
|
|
373
396
|
spawnExec: (dockerArgs) => {
|
|
374
397
|
const child = spawn('docker', dockerArgs, {
|
|
375
398
|
cwd: process.cwd(),
|
package/dist/src/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const wakeVersion = "0.2.
|
|
1
|
+
export const wakeVersion = "0.2.13+g3da36d3";
|