Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ import { z } from "zod";
export const devPlanHoldMilliseconds = 30_000;
const api = "https://api.system.01.cf.eu01.stackit.cloud";
const origin = "https://lzc-dev-configurator.apps.01.cf.eu01.stackit.cloud";
// The fixed STACKIT foundation emits shortened Diego instance IDs, not RFC UUIDs.
const liveInstance = z
.string()
.regex(
/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-(?:[a-f0-9]{4}|[a-f0-9]{12})$/,
);
const configuration = z.strictObject({
version: z.literal(1),
instanceId: z.uuid(),
Expand Down Expand Up @@ -41,7 +47,7 @@ export function devPlanHoldConfiguration(
job.origin !== origin ||
(job.purpose !== undefined && job.purpose !== "standard") ||
!env.LZC_RECOVERY_PLAN_HOLD ||
!z.uuid().safeParse(env.CF_INSTANCE_GUID).success
!liveInstance.safeParse(env.CF_INSTANCE_GUID).success
)
return undefined;
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,44 @@ it("requires explicit short-lived exact-instance opt-in in the route-free Dev wa
}),
).toBeUndefined();
});
it("accepts the observed STACKIT short instance format without relaxing app, space or process bindings", () => {
const env = make();
for (const value of [
"11111111-1111-4111-8111-1111",
"41653aa4-3a3a-486a-4431-ef258b39f042",
])
expect(
devPlanHoldConfiguration(job, { ...env, CF_INSTANCE_GUID: value }),
).toBeDefined();
for (const value of [
"",
"instance",
"11111111-1111-4111-8111",
"11111111-1111-4111-8111-11111",
"11111111-1111-4111-8111-1111\n",
"11111111-1111-4111-8111-gggg",
])
expect(
devPlanHoldConfiguration(job, { ...env, CF_INSTANCE_GUID: value }),
).toBeUndefined();
const short = { ...env, CF_INSTANCE_GUID: "11111111-1111-4111-8111-1111" };
for (const changes of [
{ application_id: randomUUID() },
{ space_id: randomUUID() },
{ process_type: "task" },
{ process_type: undefined },
])
expect(
devPlanHoldConfiguration(job, {
...short,
VCAP_APPLICATION: JSON.stringify({
...JSON.parse(env.VCAP_APPLICATION),
...changes,
}),
}),
).toBeUndefined();
});

it("does not signal any process without opt-in, a safe child PID and remaining deadline", () => {
const kill = vi.spyOn(process, "kill");
const disabled = createDevPlanHold(undefined, vi.fn());
Expand Down
7 changes: 6 additions & 1 deletion landing-zone-configurator/infra/recovery-lab/README.de.md
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,12 @@ Ausführung und andere Instanzen können den Wartepunkt nicht aktivieren. Beim
ersten nativen Versionsereignis sendet er `SIGSTOP` nur an seine eigene gestartete
Prozessgruppe, prüft den von Linux gemeldeten Halt sowohl des Shell-Gruppenleiters
als auch seines echten nativen `tofu plan` in derselben Gruppe und meldet
`native-plan-held`. Nach 30 Sekunden oder beim Aufräumen des Befehls setzt
`native-plan-held`. Die Foundation liefert verkürzte `CF_INSTANCE_GUID`-Werte
im Hexadezimalformat `8-4-4-4-4`. Diese Laufzeit-Instanzprüfung akzeptiert auch
vollständige GUIDs im Format `8-4-4-4-12`; App-, Space- und Bestell-IDs müssen
weiter UUIDs sein und `VCAP_APPLICATION.process_type` muss `web` bleiben.
Task-Metadaten können den Wartepunkt nicht aktivieren.
Nach 30 Sekunden oder beim Aufräumen des Befehls setzt
er automatisch fort. Frei einstellbare Verzögerungen oder Shell-Befehle werden
nicht angenommen. Siehe die offiziellen
[CF-Laufzeitmetadaten](https://docs.cloudfoundry.org/devguide/deploy-apps/environment-variable.html).
Expand Down
4 changes: 4 additions & 0 deletions landing-zone-configurator/infra/recovery-lab/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,10 @@ destroy, local execution and foreign instances cannot activate it. At the first
native version observation it sends `SIGSTOP` only to its spawned process group,
checks Linux reports both the shell leader and its actual native `tofu plan`
process stopped in that group, and emits `native-plan-held`.
The foundation uses shortened `CF_INSTANCE_GUID` values in hexadecimal
`8-4-4-4-4` format. This runtime-instance check also accepts full `8-4-4-4-12`
GUIDs; app, space and order IDs still require UUIDs, and `VCAP_APPLICATION.process_type`
must still be `web`. Task metadata cannot activate the hold.
It resumes automatically after 30 seconds or when command cleanup runs. No
operator-set arbitrary delay or shell command is accepted. See the official
[CF runtime metadata](https://docs.cloudfoundry.org/devguide/deploy-apps/environment-variable.html).
Expand Down
Loading