Skip to content

Commit f25d254

Browse files
committed
draft support for nested stacks directory
1 parent 0190620 commit f25d254

File tree

1 file changed

+30
-70
lines changed

1 file changed

+30
-70
lines changed

backend/stack.ts

Lines changed: 30 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ export class Stack {
104104
}
105105

106106
get isManagedByDockge() : boolean {
107-
return fs.existsSync(this.path) && fs.statSync(this.path).isDirectory();
107+
return !!this._configFilePath && this._configFilePath.startsWith(this.server.stacksDir);
108108
}
109109

110110
get status() : number {
@@ -153,7 +153,7 @@ export class Stack {
153153
}
154154

155155
get path() : string {
156-
return path.join(this.server.stacksDir, this.name);
156+
return this._configFilePath || "";
157157
}
158158

159159
get fullPath() : string {
@@ -263,41 +263,12 @@ export class Stack {
263263
}
264264

265265
static async getStackList(server : DockgeServer, useCacheForManaged = false) : Promise<Map<string, Stack>> {
266-
let stacksDir = server.stacksDir;
267-
let stackList : Map<string, Stack>;
266+
let stackList : Map<string, Stack> = new Map<string, Stack>();
268267

269268
// Use cached stack list?
270269
if (useCacheForManaged && this.managedStackList.size > 0) {
271270
stackList = this.managedStackList;
272-
} else {
273-
stackList = new Map<string, Stack>();
274-
275-
// Scan the stacks directory, and get the stack list
276-
let filenameList = await fsAsync.readdir(stacksDir);
277-
278-
for (let filename of filenameList) {
279-
try {
280-
// Check if it is a directory
281-
let stat = await fsAsync.stat(path.join(stacksDir, filename));
282-
if (!stat.isDirectory()) {
283-
continue;
284-
}
285-
// If no compose file exists, skip it
286-
if (!await Stack.composeFileExists(stacksDir, filename)) {
287-
continue;
288-
}
289-
let stack = await this.getStack(server, filename);
290-
stack._status = CREATED_FILE;
291-
stackList.set(filename, stack);
292-
} catch (e) {
293-
if (e instanceof Error) {
294-
log.warn("getStackList", `Failed to get stack ${filename}, error: ${e.message}`);
295-
}
296-
}
297-
}
298-
299-
// Cache by copying
300-
this.managedStackList = new Map(stackList);
271+
return stackList;
301272
}
302273

303274
// Get status from docker compose ls
@@ -306,28 +277,29 @@ export class Stack {
306277
});
307278

308279
if (!res.stdout) {
280+
log.warn("getStackList", "No response from docker compose daemon when attempting to retrieve list of stacks");
309281
return stackList;
310282
}
311283

312284
let composeList = JSON.parse(res.stdout.toString());
313285

314286
for (let composeStack of composeList) {
315-
let stack = stackList.get(composeStack.Name);
287+
try {
288+
let stack = new Stack(server, composeStack.Name);
289+
stack._status = this.statusConvert(composeStack.Status);
316290

317-
// This stack probably is not managed by Dockge, but we still want to show it
318-
if (!stack) {
319-
// Skip the dockge stack if it is not managed by Dockge
320-
if (composeStack.Name === "dockge") {
321-
continue;
322-
}
323-
stack = new Stack(server, composeStack.Name);
291+
let composeFiles = composeStack.ConfigFiles.split(","); // it is possible for a project to have more than one config file
292+
stack._configFilePath = path.dirname(composeFiles[0]);
293+
stack._composeFileName = path.basename(composeFiles[0]);
324294
stackList.set(composeStack.Name, stack);
295+
} catch (e) {
296+
if (e instanceof Error) {
297+
log.warn("getStackList", `Failed to get stack ${composeStack.Name}, error: ${e.message}`);
298+
}
325299
}
326-
327-
stack._status = this.statusConvert(composeStack.Status);
328-
stack._configFilePath = composeStack.ConfigFiles;
329300
}
330301

302+
this.managedStackList = stackList;
331303
return stackList;
332304
}
333305

@@ -375,35 +347,24 @@ export class Stack {
375347
}
376348

377349
static async getStack(server: DockgeServer, stackName: string, skipFSOperations = false) : Promise<Stack> {
378-
let dir = path.join(server.stacksDir, stackName);
379-
350+
let stack: Stack | undefined;
380351
if (!skipFSOperations) {
381-
if (!await fileExists(dir) || !(await fsAsync.stat(dir)).isDirectory()) {
382-
// Maybe it is a stack managed by docker compose directly
383-
let stackList = await this.getStackList(server, true);
384-
let stack = stackList.get(stackName);
385-
386-
if (stack) {
387-
return stack;
388-
} else {
389-
// Really not found
390-
throw new ValidationError("Stack not found");
391-
}
352+
let stackList = await this.getStackList(server, true);
353+
stack = stackList.get(stackName);
354+
if (!stack || !await fileExists(stack.path) || !(await fsAsync.stat(stack.path)).isDirectory() ) {
355+
throw new ValidationError("getStack; Stack not found");
392356
}
393357
} else {
394-
//log.debug("getStack", "Skip FS operations");
395-
}
396-
397-
let stack : Stack;
398-
399-
if (!skipFSOperations) {
400-
stack = new Stack(server, stackName);
401-
} else {
402-
stack = new Stack(server, stackName, undefined, undefined, true);
358+
// search for known stack with this name
359+
if (this.managedStackList) {
360+
stack = this.managedStackList.get(stackName);
361+
}
362+
if (!this.managedStackList || !stack) {
363+
stack = new Stack(server, stackName, undefined, undefined, true);
364+
stack._status = UNKNOWN;
365+
stack._configFilePath = path.resolve(server.stacksDir, stackName);
366+
}
403367
}
404-
405-
stack._status = UNKNOWN;
406-
stack._configFilePath = path.resolve(dir);
407368
return stack;
408369
}
409370

@@ -522,7 +483,6 @@ export class Stack {
522483
} catch (e) {
523484
}
524485
}
525-
526486
return statusList;
527487
} catch (e) {
528488
log.error("getServiceStatusList", e);

0 commit comments

Comments
 (0)