Skip to content

Commit 062a7b8

Browse files
committed
Add clean --all-fhevm-projects for scoped global fhevm cleanup
1 parent c54e306 commit 062a7b8

File tree

1 file changed

+144
-2
lines changed
  • test-suite/fhevm/scripts/bun

1 file changed

+144
-2
lines changed

test-suite/fhevm/scripts/bun/cli.ts

Lines changed: 144 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ type CleanOptions = {
5959
purgeImages: boolean;
6060
purgeBuildCache: boolean;
6161
purgeNetworks: boolean;
62+
allFhevmProjects: boolean;
6263
};
6364

6465
type TestOptions = {
@@ -129,7 +130,7 @@ function usage(): void {
129130
console.log(` ${COLORS.yellow}unpause${COLORS.reset} ${COLORS.cyan}[CONTRACTS]${COLORS.reset} Unpause specific contracts (host|gateway)`);
130131
console.log(` ${COLORS.yellow}test${COLORS.reset} ${COLORS.cyan}[TYPE]${COLORS.reset} Run tests (${testTypes})`);
131132
console.log(` ${COLORS.yellow}upgrade${COLORS.reset} ${COLORS.cyan}[SERVICE]${COLORS.reset} Upgrade specific service`);
132-
console.log(` ${COLORS.yellow}clean${COLORS.reset} ${COLORS.cyan}[--purge] [--purge-images] [--purge-build-cache] [--purge-networks] [--purge-local-cache]${COLORS.reset} Clean stack resources`);
133+
console.log(` ${COLORS.yellow}clean${COLORS.reset} ${COLORS.cyan}[--purge] [--purge-images] [--purge-build-cache] [--purge-networks] [--purge-local-cache] [--all-fhevm-projects]${COLORS.reset} Clean stack resources`);
133134
console.log(` ${COLORS.yellow}trace${COLORS.reset} ${COLORS.cyan}[up|down|status]${COLORS.reset} Manage local tracing stack (Jaeger + Prometheus)`);
134135
console.log(` ${COLORS.yellow}logs${COLORS.reset} ${COLORS.cyan}[SERVICE]${COLORS.reset} View logs for a specific service`);
135136
console.log(` ${COLORS.yellow}telemetry-smoke${COLORS.reset} Validate Jaeger telemetry services`);
@@ -160,6 +161,7 @@ function usage(): void {
160161
console.log(` ${COLORS.cyan}--purge-build-cache${COLORS.reset} Remove local fhevm Buildx cache directory`);
161162
console.log(` ${COLORS.cyan}--purge-networks${COLORS.reset} Remove networks labeled for the active fhevm compose project only`);
162163
console.log(` ${COLORS.cyan}--purge-local-cache${COLORS.reset} Alias of --purge-build-cache (kept for compatibility)`);
164+
console.log(` ${COLORS.cyan}--all-fhevm-projects${COLORS.reset} Clean every Docker resource prefixed with ${COLORS.green}fhevm-${COLORS.reset}`);
163165
console.log("");
164166
console.log(`${COLORS.bold}${COLORS.lightBlue}Examples:${COLORS.reset}`);
165167
console.log(` ${COLORS.purple}./fhevm-cli up --network testnet${COLORS.reset}`);
@@ -182,6 +184,7 @@ function usage(): void {
182184
console.log(` ${COLORS.purple}./fhevm-cli upgrade coprocessor${COLORS.reset}`);
183185
console.log(` ${COLORS.purple}./fhevm-cli telemetry-smoke${COLORS.reset}`);
184186
console.log(` ${COLORS.purple}./fhevm-cli clean --purge${COLORS.reset}`);
187+
console.log(` ${COLORS.purple}./fhevm-cli clean --all-fhevm-projects${COLORS.reset}`);
185188
console.log(` ${COLORS.purple}./fhevm-cli down --purge${COLORS.reset}`);
186189
console.log(` ${COLORS.purple}./fhevm-cli clean --purge-build-cache${COLORS.reset}`);
187190
console.log(` ${COLORS.purple}./fhevm-cli trace down${COLORS.reset}`);
@@ -3108,6 +3111,7 @@ function parseCleanArgs(args: string[]): CleanOptions {
31083111
purgeImages: false,
31093112
purgeBuildCache: false,
31103113
purgeNetworks: false,
3114+
allFhevmProjects: false,
31113115
};
31123116

31133117
for (const arg of args) {
@@ -3133,16 +3137,154 @@ function parseCleanArgs(args: string[]): CleanOptions {
31333137
options.purgeBuildCache = true;
31343138
continue;
31353139
}
3140+
if (arg === "--all-fhevm-projects") {
3141+
options.allFhevmProjects = true;
3142+
continue;
3143+
}
31363144
usageError(`Unknown option for clean: ${arg}`);
31373145
}
31383146

31393147
return options;
31403148
}
31413149

3150+
function listComposeProjects(): string[] {
3151+
const result = runCommand(["docker", "compose", "ls", "--format", "json"], {
3152+
capture: true,
3153+
check: false,
3154+
allowFailure: true,
3155+
});
3156+
if (result.status !== 0 || !result.stdout.trim()) {
3157+
return [];
3158+
}
3159+
try {
3160+
const parsed = JSON.parse(result.stdout) as Array<{ Name?: string }>;
3161+
if (!Array.isArray(parsed)) {
3162+
return [];
3163+
}
3164+
return parsed
3165+
.map((entry) => entry?.Name?.trim() ?? "")
3166+
.filter((name) => name !== "");
3167+
} catch {
3168+
return [];
3169+
}
3170+
}
3171+
3172+
function removeDockerResourcesByPrefix(prefix: string, removeVolumes: boolean): void {
3173+
const containerNames = runCommand(["docker", "ps", "-a", "--format", "{{.Names}}"], {
3174+
capture: true,
3175+
check: false,
3176+
allowFailure: true,
3177+
}).stdout
3178+
.split("\n")
3179+
.map((line) => line.trim())
3180+
.filter((name) => name.startsWith(prefix));
3181+
if (containerNames.length > 0) {
3182+
runCommand(["docker", "rm", "-f", ...containerNames], {
3183+
check: false,
3184+
allowFailure: true,
3185+
});
3186+
}
3187+
3188+
const networks = runCommand(["docker", "network", "ls", "--format", "{{.Name}}"], {
3189+
capture: true,
3190+
check: false,
3191+
allowFailure: true,
3192+
}).stdout
3193+
.split("\n")
3194+
.map((line) => line.trim())
3195+
.filter((name) => name.startsWith(prefix));
3196+
for (const network of networks) {
3197+
runCommand(["docker", "network", "rm", network], {
3198+
check: false,
3199+
allowFailure: true,
3200+
});
3201+
}
3202+
3203+
if (removeVolumes) {
3204+
const volumes = runCommand(["docker", "volume", "ls", "--format", "{{.Name}}"], {
3205+
capture: true,
3206+
check: false,
3207+
allowFailure: true,
3208+
}).stdout
3209+
.split("\n")
3210+
.map((line) => line.trim())
3211+
.filter((name) => name.startsWith(prefix));
3212+
for (const volume of volumes) {
3213+
runCommand(["docker", "volume", "rm", volume], {
3214+
check: false,
3215+
allowFailure: true,
3216+
});
3217+
}
3218+
}
3219+
}
3220+
3221+
function cleanupAllFhevmProjects(removeVolumes: boolean): void {
3222+
const prefix = "fhevm-";
3223+
const projects = listComposeProjects().filter((name) => name.startsWith(prefix));
3224+
if (projects.length > 0) {
3225+
logInfo(`Cleaning all fhevm compose projects: ${projects.join(", ")}`);
3226+
} else {
3227+
logInfo("No active fhevm compose projects found; cleaning prefixed leftovers.");
3228+
}
3229+
3230+
for (const project of projects) {
3231+
const containerIds = runCommand(
3232+
["docker", "ps", "-a", "--filter", `label=com.docker.compose.project=${project}`, "--format", "{{.ID}}"],
3233+
{ capture: true, check: false, allowFailure: true },
3234+
).stdout
3235+
.split("\n")
3236+
.map((line) => line.trim())
3237+
.filter(Boolean);
3238+
if (containerIds.length > 0) {
3239+
runCommand(["docker", "rm", "-f", ...containerIds], {
3240+
check: false,
3241+
allowFailure: true,
3242+
});
3243+
}
3244+
3245+
const networkIds = runCommand(
3246+
["docker", "network", "ls", "--filter", `label=com.docker.compose.project=${project}`, "--format", "{{.ID}}"],
3247+
{ capture: true, check: false, allowFailure: true },
3248+
).stdout
3249+
.split("\n")
3250+
.map((line) => line.trim())
3251+
.filter(Boolean);
3252+
for (const networkId of networkIds) {
3253+
runCommand(["docker", "network", "rm", networkId], {
3254+
check: false,
3255+
allowFailure: true,
3256+
});
3257+
}
3258+
3259+
if (removeVolumes) {
3260+
const volumeNames = runCommand(
3261+
["docker", "volume", "ls", "--filter", `label=com.docker.compose.project=${project}`, "--format", "{{.Name}}"],
3262+
{ capture: true, check: false, allowFailure: true },
3263+
).stdout
3264+
.split("\n")
3265+
.map((line) => line.trim())
3266+
.filter(Boolean);
3267+
for (const volumeName of volumeNames) {
3268+
runCommand(["docker", "volume", "rm", volumeName], {
3269+
check: false,
3270+
allowFailure: true,
3271+
});
3272+
}
3273+
}
3274+
}
3275+
3276+
// Catch stale leftovers not labeled as compose resources.
3277+
removeDockerResourcesByPrefix(prefix, removeVolumes);
3278+
}
3279+
31423280
function clean(args: string[]): void {
31433281
const options = parseCleanArgs(args);
31443282
console.log(`${COLORS.lightBlue}[CLEAN]${COLORS.reset} ${COLORS.bold}Cleaning up FHEVM stack...${COLORS.reset}`);
3145-
cleanupKnownStack(true);
3283+
if (options.allFhevmProjects) {
3284+
cleanupAllFhevmProjects(true);
3285+
} else {
3286+
cleanupKnownStack(true);
3287+
}
31463288

31473289
if (options.purgeNetworks) {
31483290
const networkList = runCommand(["docker", "network", "ls", "--filter", `label=com.docker.compose.project=${PROJECT}`, "--format", "{{.Name}}"], {

0 commit comments

Comments
 (0)