mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-07-26 11:49:16 +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 {
|
||||
|
||||
@@ -74,6 +74,8 @@ Below the template variables, an **Add Custom Variable** section lets you define
|
||||
|
||||
A toast notification confirms success or shows the error message. Large images may take a few minutes to pull.
|
||||
|
||||
If a previous stack with the same name was removed outside of Sencho (for example, through the Docker CLI or Docker Desktop), the leftover directory is cleaned up automatically and the deploy proceeds as normal.
|
||||
|
||||
<Note>
|
||||
Deploying a template requires the `stack:create` permission. Users without this permission will see the Deploy button disabled.
|
||||
</Note>
|
||||
|
||||
Reference in New Issue
Block a user