Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 9 additions & 7 deletions backend/agent-socket-handlers/docker-socket-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ export class DockerSocketHandler extends AgentSocketHandler {
create(socket : DockgeSocket, server : DockgeServer, agentSocket : AgentSocket) {
// Do not call super.create()

agentSocket.on("deployStack", async (name : unknown, composeYAML : unknown, composeENV : unknown, isAdd : unknown, callback) => {
agentSocket.on("deployStack", async (name : unknown, composeYAML : unknown, composeENV : unknown, composeOverrideYAML : unknown, isAdd : unknown, callback) => {
try {
checkLogin(socket);
const stack = await this.saveStack(server, name, composeYAML, composeENV, isAdd);
const stack = await this.saveStack(server, name, composeYAML, composeENV, composeOverrideYAML, isAdd);
await stack.deploy(socket);
server.sendStackList();
callbackResult({
Expand All @@ -25,10 +25,10 @@ export class DockerSocketHandler extends AgentSocketHandler {
}
});

agentSocket.on("saveStack", async (name : unknown, composeYAML : unknown, composeENV : unknown, isAdd : unknown, callback) => {
agentSocket.on("saveStack", async (name : unknown, composeYAML : unknown, composeENV : unknown, composeOverrideYAML : unknown, isAdd : unknown, callback) => {
try {
checkLogin(socket);
await this.saveStack(server, name, composeYAML, composeENV, isAdd);
await this.saveStack(server, name, composeYAML, composeENV, composeOverrideYAML, isAdd);
callbackResult({
ok: true,
msg: "Saved",
Expand Down Expand Up @@ -253,7 +253,7 @@ export class DockerSocketHandler extends AgentSocketHandler {
});
}

async saveStack(server : DockgeServer, name : unknown, composeYAML : unknown, composeENV : unknown, isAdd : unknown) : Promise<Stack> {
async saveStack(server : DockgeServer, name : unknown, composeYAML : unknown, composeENV : unknown, composeOverrideYAML : unknown, isAdd : unknown) : Promise<Stack> {
// Check types
if (typeof(name) !== "string") {
throw new ValidationError("Name must be a string");
Expand All @@ -264,14 +264,16 @@ export class DockerSocketHandler extends AgentSocketHandler {
if (typeof(composeENV) !== "string") {
throw new ValidationError("Compose ENV must be a string");
}
if (typeof(composeOverrideYAML) !== "string") {
throw new ValidationError("Compose Override YAML must be a string");
}
if (typeof(isAdd) !== "boolean") {
throw new ValidationError("isAdd must be a boolean");
}

const stack = new Stack(server, name, composeYAML, composeENV, false);
const stack = new Stack(server, name, composeYAML, composeENV, composeOverrideYAML, false);
await stack.save(isAdd);
return stack;
}

}

41 changes: 39 additions & 2 deletions backend/stack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { DockgeSocket, fileExists, ValidationError } from "./util-server";
import path from "path";
import {
acceptedComposeFileNames,
acceptedComposeOverrideFileNames,
COMBINED_TERMINAL_COLS,
COMBINED_TERMINAL_ROWS,
CREATED_FILE,
Expand All @@ -26,19 +27,22 @@ export class Stack {
protected _status: number = UNKNOWN;
protected _composeYAML?: string;
protected _composeENV?: string;
protected _composeOverrideYAML?: string;
protected _configFilePath?: string;
protected _composeFileName: string = "compose.yaml";
protected _composeOverrideFileName: string = "compose.override.yaml";
protected server: DockgeServer;

protected combinedTerminal? : Terminal;

protected static managedStackList: Map<string, Stack> = new Map();

constructor(server : DockgeServer, name : string, composeYAML? : string, composeENV? : string, skipFSOperations = false) {
constructor(server : DockgeServer, name : string, composeYAML? : string, composeENV? : string, composeOverrideYAML? : string, skipFSOperations = false) {
this.name = name;
this.server = server;
this._composeYAML = composeYAML;
this._composeENV = composeENV;
this._composeOverrideYAML = composeOverrideYAML;

if (!skipFSOperations) {
// Check if compose file name is different from compose.yaml
Expand All @@ -48,6 +52,14 @@ export class Stack {
break;
}
}

// Check if override file exists and determine its name
for (const filename of acceptedComposeOverrideFileNames) {
if (fs.existsSync(path.join(this.path, filename))) {
this._composeOverrideFileName = filename;
break;
}
}
}
}

Expand All @@ -74,6 +86,7 @@ export class Stack {
...obj,
composeYAML: this.composeYAML,
composeENV: this.composeENV,
composeOverrideYAML: this.composeOverrideYAML,
primaryHostname,
};
}
Expand Down Expand Up @@ -120,6 +133,11 @@ export class Stack {
// Check YAML format
yaml.parse(this.composeYAML);

// Check override YAML format if it exists
if (this.composeOverrideYAML && this.composeOverrideYAML.trim() !== "") {
yaml.parse(this.composeOverrideYAML);
}

let lines = this.composeENV.split("\n");

// Check if the .env is able to pass docker-compose
Expand Down Expand Up @@ -152,6 +170,17 @@ export class Stack {
return this._composeENV;
}

get composeOverrideYAML() : string {
if (this._composeOverrideYAML === undefined) {
try {
this._composeOverrideYAML = fs.readFileSync(path.join(this.path, this._composeOverrideFileName), "utf-8");
} catch (e) {
this._composeOverrideYAML = "";
}
}
return this._composeOverrideYAML;
}

get path() : string {
return path.join(this.server.stacksDir, this.name);
}
Expand Down Expand Up @@ -204,6 +233,14 @@ export class Stack {
if (await fileExists(envPath) || this.composeENV.trim() !== "") {
await fsAsync.writeFile(envPath, this.composeENV);
}

const overridePath = path.join(dir, this._composeOverrideFileName);

// Write or overwrite the compose override file
// If override file is not existing and the composeOverrideYAML is empty, we don't need to write it
if (await fileExists(overridePath) || this.composeOverrideYAML.trim() !== "") {
await fsAsync.writeFile(overridePath, this.composeOverrideYAML);
}
}

async deploy(socket : DockgeSocket) : Promise<number> {
Expand Down Expand Up @@ -399,7 +436,7 @@ export class Stack {
if (!skipFSOperations) {
stack = new Stack(server, stackName);
} else {
stack = new Stack(server, stackName, undefined, undefined, true);
stack = new Stack(server, stackName, undefined, undefined, undefined, true);
}

stack._status = UNKNOWN;
Expand Down
8 changes: 7 additions & 1 deletion common/util-common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,13 @@ export const acceptedComposeFileNames = [
"compose.yml",
];

export const acceptedComposeOverrideFileNames = [
"compose.override.yaml",
"compose.override.yml",
"docker-compose.override.yaml",
"docker-compose.override.yml",
];

/**
* Generate a decimal integer number from a string
* @param str Input
Expand Down Expand Up @@ -416,4 +423,3 @@ function traverseYAML(pair : Pair, env : DotenvParseOutput) : void {
pair.value.value = envsubst(pair.value.value, env);
}
}

33 changes: 30 additions & 3 deletions frontend/src/pages/Compose.vue
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,23 @@
</div>
</div>
<div class="col-lg-6">
<!-- Override YAML editor (only show if file exists) -->
<div v-if="stack.composeOverrideYAML && stack.composeOverrideYAML.trim() !== ''">
<h4 class="mb-3">compose.override.yaml</h4>
<div class="shadow-box mb-3 editor-box" :class="{'edit-mode' : isEditMode}">
<prism-editor
ref="overrideEditor"
v-model="stack.composeOverrideYAML"
class="yaml-editor"
:highlight="highlighterYAML"
line-numbers :readonly="!isEditMode"
@input="yamlCodeChange"
@focus="editorFocus = true"
@blur="editorFocus = false"
></prism-editor>
</div>
</div>

<h4 class="mb-3">{{ stack.composeFileName }}</h4>

<!-- YAML editor -->
Expand Down Expand Up @@ -303,7 +320,7 @@ export default {
combinedTerminalRows: COMBINED_TERMINAL_ROWS,
combinedTerminalCols: COMBINED_TERMINAL_COLS,
stack: {

composeOverrideYAML: "",
},
serviceStatusList: {},
isEditMode: false,
Expand Down Expand Up @@ -417,6 +434,16 @@ export default {
deep: true,
},

"stack.composeOverrideYAML": {
handler() {
if (this.editorFocus) {
console.debug("override yaml code changed");
this.yamlCodeChange();
}
},
deep: true,
},

jsonConfig: {
handler() {
if (!this.editorFocus) {
Expand Down Expand Up @@ -580,7 +607,7 @@ export default {

this.bindTerminal();

this.$root.emitAgent(this.stack.endpoint, "deployStack", this.stack.name, this.stack.composeYAML, this.stack.composeENV, this.isAdd, (res) => {
this.$root.emitAgent(this.stack.endpoint, "deployStack", this.stack.name, this.stack.composeYAML, this.stack.composeENV, this.stack.composeOverrideYAML || "", this.isAdd, (res) => {
this.processing = false;
this.$root.toastRes(res);

Expand All @@ -594,7 +621,7 @@ export default {
saveStack() {
this.processing = true;

this.$root.emitAgent(this.stack.endpoint, "saveStack", this.stack.name, this.stack.composeYAML, this.stack.composeENV, this.isAdd, (res) => {
this.$root.emitAgent(this.stack.endpoint, "saveStack", this.stack.name, this.stack.composeYAML, this.stack.composeENV, this.stack.composeOverrideYAML || "", this.isAdd, (res) => {
this.processing = false;
this.$root.toastRes(res);

Expand Down