@or3/cloud 0.1.87 → 0.1.90

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.
@@ -973,6 +973,9 @@ export function validStartInput(input) {
973
973
  async function main() {
974
974
  await mkdir(dirname(socketPath), { recursive: true, mode: 0o700 });
975
975
  await rm(socketPath, { force: true });
976
+ // Kept separate from the legacy update protocol and bundled by this exact CLI.
977
+ let lifecycle;
978
+ const getLifecycle = () => lifecycle ??= import('./dashboard-lifecycle.mjs').then(module => module.createManagedLifecycle(deploymentDirectory));
976
979
 
977
980
  const server = createServer(async (request, response) => {
978
981
  // Protocol 2 is additive: the versioned routes are the same handlers with a
@@ -982,6 +985,13 @@ async function main() {
982
985
  const route = isV2 ? request.url.slice(3) : request.url;
983
986
  const reply = (statusCode, payload) => send(response, statusCode, isV2 ? { protocolVersion: currentProtocolVersion, ...payload } : payload);
984
987
  try {
988
+ if ((request.url || '').startsWith('/lifecycle/v1/')) {
989
+ if (updateClaimed) return send(response, 409, { code: 'update_in_progress' });
990
+ try {
991
+ const service = await getLifecycle();
992
+ if (await service.handle(service.controller, request, response)) return;
993
+ } catch { return send(response, 503, { code: 'controller_unavailable' }); }
994
+ }
985
995
  if (request.method === 'GET' && route === '/status') return reply(200, await status(isV2));
986
996
  if (request.method === 'POST' && route === '/check') {
987
997
  if (!consumeRateLimit(checkAttempts, Date.now(), 30, 60_000)) {
@@ -1008,6 +1018,9 @@ async function main() {
1008
1018
  }
1009
1019
  updateClaimed = true;
1010
1020
  try {
1021
+ const service = await getLifecycle();
1022
+ const restart = (await service.controller.status()).operation;
1023
+ if (restart && !['succeeded', 'cancelled', 'failed'].includes(restart.phase)) throw new Error('A dashboard restart is unresolved. Reconcile it before updating.');
1011
1024
  await assertHandoffReady();
1012
1025
  const checked = await check(isV2);
1013
1026
  if (!checked.updateAvailable) {
@@ -1073,6 +1086,7 @@ async function main() {
1073
1086
  reply(503, { message: error instanceof Error ? error.message : 'The update operator is unavailable.' });
1074
1087
  }
1075
1088
  });
1089
+ server.requestTimeout = 5_000;
1076
1090
 
1077
1091
  server.listen(socketPath, () => {
1078
1092
  // The read-only app bind mount needs to connect as a distinct container UID.