diff --git a/manage-amis.ts b/manage-amis.ts index 7c2716e..7af323f 100644 --- a/manage-amis.ts +++ b/manage-amis.ts @@ -22,7 +22,7 @@ Options: --name AMI project tag (default: nixos-zfs-ec2) --architecture Filter by architecture --runtime-state-bucket S3 bucket with qx-deploy registry objects - --force Delete even when registry deployments reference the AMI + --force Delete even when active registry deployments reference the AMI -h, --help Show this help `; @@ -211,6 +211,11 @@ const deploymentRegistry = (state) => { return records; }; +const deploymentReferenceLabel = (record) => + `${record.id}${record.status ? `:${record.status}` : ""}`; + +const isDestroyedDeployment = (record) => record.status === "destroyed"; + const listArtifacts = (state) => { const registry = deploymentRegistry(state); const references = new Map(); @@ -220,7 +225,7 @@ const listArtifacts = (state) => { continue; } const entries = references.get(amiId) ?? []; - entries.push(record.id); + entries.push(deploymentReferenceLabel(record)); references.set(amiId, entries); } @@ -246,11 +251,12 @@ const deleteArtifact = (state) => { } const registry = deploymentRegistry(state); - const refs = registry + const activeRefs = registry .filter((record) => record.config?.amiId === state.amiId) - .map((record) => record.id); - if (refs.length > 0 && !state.force) { - throw new Error(`Refusing to delete ${state.amiId}; referenced by deployments: ${refs.join(", ")}\nPass --force after those deployments are destroyed or intentionally orphaned.`); + .filter((record) => !isDestroyedDeployment(record)) + .map(deploymentReferenceLabel); + if (activeRefs.length > 0 && !state.force) { + throw new Error(`Refusing to delete ${state.amiId}; referenced by active deployments: ${activeRefs.join(", ")}\nDestroy those deployments first, or pass --force if they are intentionally orphaned.`); } const result = awsJson([