mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-08-24 17:36:42 +00:00
fix(mesh): cascade opt-out when a stack is deleted (F-1 / F-14) (#1096)
DELETE /api/stacks/:name now calls MeshService.optOutStack after the DB cleanup so the mesh_stacks row, the override file under <DATA_DIR>/mesh/overrides/<nodeId>/, and any derived aliases do not outlive the deleted stack. Pre-fix, those artifacts leaked and the reconcile loop logged "No compose file found for stack" every tick. optOutStack is idempotent (early return when the stack was never opted in) and already cascades override-regen plus recompose across the rest of the fleet, so peers' /etc/hosts drop the dropped alias. The new cascade call is best-effort relative to the delete itself: mesh cleanup failures warn but never regress the delete contract. New regression test asserts three contracts: cascade on delete, no-op on never-meshed, and 200 + warn when the cascade rejects.
This commit is contained in:
@@ -6,6 +6,7 @@ import { FileSystemService } from '../services/FileSystemService';
|
||||
import { ComposeService, getComposeRollbackInfo } from '../services/ComposeService';
|
||||
import DockerController from '../services/DockerController';
|
||||
import { DatabaseService } from '../services/DatabaseService';
|
||||
import { MeshService } from '../services/MeshService';
|
||||
import { CacheService } from '../services/CacheService';
|
||||
import { UpdatePreviewService } from '../services/UpdatePreviewService';
|
||||
import { GitSourceService, GitSourceError, repoHost as gitRepoHost } from '../services/GitSourceService';
|
||||
@@ -562,6 +563,24 @@ stacksRouter.delete('/:stackName', async (req: Request, res: Response) => {
|
||||
DatabaseService.getInstance().deleteRoleAssignmentsByResource('stack', stackName);
|
||||
DatabaseService.getInstance().deleteGitSource(stackName);
|
||||
|
||||
// Cascade a mesh opt-out so the mesh_stacks row, override file on disk,
|
||||
// and derived aliases do not outlive the stack. optOutStack is idempotent
|
||||
// (no-op when the stack was never opted in). Best-effort: a mesh cleanup
|
||||
// failure must not regress the delete itself.
|
||||
try {
|
||||
await MeshService.getInstance().optOutStack(
|
||||
req.nodeId,
|
||||
stackName,
|
||||
req.user?.username ?? 'system',
|
||||
);
|
||||
} catch (meshErr) {
|
||||
console.warn(
|
||||
'[Stacks] Mesh opt-out cascade failed for %s, continuing delete:',
|
||||
sanitizeForLog(stackName),
|
||||
meshErr,
|
||||
);
|
||||
}
|
||||
|
||||
if (fsErr) throw fsErr;
|
||||
|
||||
invalidateNodeCaches(req.nodeId);
|
||||
|
||||
Reference in New Issue
Block a user