mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-08-12 11:47:11 +00:00
fix(app-store): handle orphaned stack directories on template deploy (#530)
* fix(app-store): handle orphaned stack directories on template deploy When a stack deployed via the App Store is later removed through Docker Desktop or the CLI (instead of through Sencho), its directory remains on disk without a compose file. The deploy endpoint previously rejected any re-deploy with a 409 if the directory existed, even if empty. Now the endpoint checks for a compose file before rejecting. If the directory exists but contains no compose file, it is treated as an orphaned remnant: cleaned up automatically and the deploy proceeds. Also makes FileSystemService.hasComposeFile public so the deploy endpoint can reuse it instead of duplicating the compose file check. * docs(app-store): document orphaned stack directory cleanup behavior
This commit is contained in:
+11
-4
@@ -5687,10 +5687,17 @@ app.post('/api/templates/deploy', authMiddleware, async (req: Request, res: Resp
|
||||
|
||||
try {
|
||||
await fsPromises.access(stackPath);
|
||||
return res.status(409).json({
|
||||
error: `A stack directory named '${stackName}' already exists. Please choose a different Stack Name.`,
|
||||
rolledBack: false
|
||||
});
|
||||
|
||||
if (await fsService.hasComposeFile(stackPath)) {
|
||||
return res.status(409).json({
|
||||
error: `A stack directory named '${stackName}' already exists. Please choose a different Stack Name.`,
|
||||
rolledBack: false
|
||||
});
|
||||
}
|
||||
|
||||
// Orphaned directory left by external deletion (e.g. Docker Desktop).
|
||||
console.log(`[Templates] Cleaned up orphaned stack directory: ${stackName}`);
|
||||
await fsService.deleteStack(stackName);
|
||||
} catch {
|
||||
// Directory does not exist; proceed with deploy
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ export class FileSystemService {
|
||||
return new FileSystemService(nodeId);
|
||||
}
|
||||
|
||||
private async hasComposeFile(dir: string): Promise<boolean> {
|
||||
async hasComposeFile(dir: string): Promise<boolean> {
|
||||
const composeFiles = ['compose.yaml', 'compose.yml', 'docker-compose.yaml', 'docker-compose.yml'];
|
||||
for (const file of composeFiles) {
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user