fix: repin semver compose tags during fleet self-update (#1587)

* fix: repin semver compose tags during fleet self-update

Fleet updates failed when docker-compose.yml pinned a semver tag because recreate reused the on-disk pin. Pull the target image first, rewrite semver pins via the update helper, and block digest or unresolved pins with fast 409s.

* fix: update OFFLINE_META shape in capability and node-registry meta tests
This commit is contained in:
Anso
2026-07-07 14:40:50 -04:00
committed by GitHub
parent dbe230eef3
commit e12602091a
31 changed files with 1460 additions and 74 deletions
+29
View File
@@ -0,0 +1,29 @@
import type { Request, Response } from 'express';
import semver from 'semver';
import { isValidVersion } from '../services/CapabilityRegistry';
/** The semver compare target when valid, otherwise undefined (legacy pull-current). */
export function pickCompareTarget(compareVersion: string | null, compareValid: boolean): string | undefined {
if (!compareValid || !isValidVersion(compareVersion)) return undefined;
return compareVersion;
}
/**
* Parse an optional `targetVersion` from a self-update request body.
*
* - Omitted or null -> returns undefined (the caller chooses the default).
* - Present and a valid semver -> returns the normalized version.
* - Present but not a valid semver -> writes a 400 and returns null so the
* caller early-returns. We never silently fall back on a supplied-but-bad
* value, because that would hide a client bug and update to the wrong target.
*/
export function parseRequestedTargetVersion(req: Request, res: Response): string | null | undefined {
const raw = (req.body ?? {})?.targetVersion;
if (raw === undefined || raw === null) return undefined;
const normalized = typeof raw === 'string' ? semver.valid(raw) : null;
if (!normalized || !isValidVersion(normalized) || raw.length > 64) {
res.status(400).json({ error: 'Invalid target version' });
return null;
}
return normalized;
}