mirror of
https://github.com/louislam/dockge.git
synced 2025-02-21 19:15:56 +00:00
Closes #694
This commit is contained in:
parent
d451e06e84
commit
74b60c6f61
5 changed files with 10483 additions and 6 deletions
|
@ -67,6 +67,25 @@ export class DockerSocketHandler extends AgentSocketHandler {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
agentSocket.on("forceDeleteStack", async (name : unknown, callback) => {
|
||||||
|
try {
|
||||||
|
checkLogin(socket);
|
||||||
|
if (typeof(name) !== "string") {
|
||||||
|
throw new ValidationError("Name must be a string");
|
||||||
|
}
|
||||||
|
const stack = await Stack.getStack(server, name);
|
||||||
|
await stack.forceDelete(socket);
|
||||||
|
server.sendStackList();
|
||||||
|
callbackResult({
|
||||||
|
ok: true,
|
||||||
|
msg: "Deleted",
|
||||||
|
msgi18n: true,
|
||||||
|
}, callback);
|
||||||
|
} catch (e) {
|
||||||
|
callbackError(e, callback);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
agentSocket.on("getStack", async (stackName : unknown, callback) => {
|
agentSocket.on("getStack", async (stackName : unknown, callback) => {
|
||||||
try {
|
try {
|
||||||
checkLogin(socket);
|
checkLogin(socket);
|
||||||
|
|
|
@ -208,7 +208,7 @@ export class Stack {
|
||||||
|
|
||||||
async deploy(socket : DockgeSocket) : Promise<number> {
|
async deploy(socket : DockgeSocket) : Promise<number> {
|
||||||
const terminalName = getComposeTerminalName(socket.endpoint, this.name);
|
const terminalName = getComposeTerminalName(socket.endpoint, this.name);
|
||||||
let exitCode = await Terminal.exec(this.server, socket, terminalName, "docker", [ "compose", "up", "-d", "--remove-orphans" ], this.path);
|
let exitCode = await Terminal.exec(this.server, socket, terminalName, "docker", ["compose", "up", "-d", "--remove-orphans"], this.path);
|
||||||
if (exitCode !== 0) {
|
if (exitCode !== 0) {
|
||||||
throw new Error("Failed to deploy, please check the terminal output for more information.");
|
throw new Error("Failed to deploy, please check the terminal output for more information.");
|
||||||
}
|
}
|
||||||
|
@ -217,9 +217,9 @@ export class Stack {
|
||||||
|
|
||||||
async delete(socket: DockgeSocket) : Promise<number> {
|
async delete(socket: DockgeSocket) : Promise<number> {
|
||||||
const terminalName = getComposeTerminalName(socket.endpoint, this.name);
|
const terminalName = getComposeTerminalName(socket.endpoint, this.name);
|
||||||
let exitCode = await Terminal.exec(this.server, socket, terminalName, "docker", [ "compose", "down", "--remove-orphans" ], this.path);
|
let exitCode = await Terminal.exec(this.server, socket, terminalName, "docker", ["compose", "down", "--remove-orphans"], this.path);
|
||||||
if (exitCode !== 0) {
|
if (exitCode !== 0) {
|
||||||
throw new Error("Failed to delete, please check the terminal output for more information.");
|
throw new Error(`Failed to delete ${this.name}, please check the terminal output for more information.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove the stack folder
|
// Remove the stack folder
|
||||||
|
@ -231,6 +231,19 @@ export class Stack {
|
||||||
return exitCode;
|
return exitCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async forceDelete(socket: DockgeSocket): Promise<number> {
|
||||||
|
const terminalName = getComposeTerminalName(socket.endpoint, this.name);
|
||||||
|
let exitCode = await Terminal.exec(this.server, socket, terminalName, "docker", ["compose", "down", "-v", "--remove-orphans"], this.path);
|
||||||
|
|
||||||
|
// Remove the stack folder
|
||||||
|
await fsAsync.rm(this.path, {
|
||||||
|
recursive: true,
|
||||||
|
force: true
|
||||||
|
});
|
||||||
|
|
||||||
|
return exitCode;
|
||||||
|
}
|
||||||
|
|
||||||
async updateStatus() {
|
async updateStatus() {
|
||||||
let statusList = await Stack.getStatusList();
|
let statusList = await Stack.getStatusList();
|
||||||
let status = statusList.get(this.name);
|
let status = statusList.get(this.name);
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
"stackName": "Stack Name",
|
"stackName": "Stack Name",
|
||||||
"deployStack": "Deploy",
|
"deployStack": "Deploy",
|
||||||
"deleteStack": "Delete",
|
"deleteStack": "Delete",
|
||||||
|
"forceDeleteStack": "Force Delete",
|
||||||
"stopStack": "Stop",
|
"stopStack": "Stop",
|
||||||
"restartStack": "Restart",
|
"restartStack": "Restart",
|
||||||
"updateStack": "Update",
|
"updateStack": "Update",
|
||||||
|
@ -25,6 +26,7 @@
|
||||||
"saveStackDraft": "Save",
|
"saveStackDraft": "Save",
|
||||||
"notAvailableShort": "N/A",
|
"notAvailableShort": "N/A",
|
||||||
"deleteStackMsg": "Are you sure you want to delete this stack?",
|
"deleteStackMsg": "Are you sure you want to delete this stack?",
|
||||||
|
"forceDeleteStackMsg": "Force deleting may leave behind some files or configuration. Are you sure you want to force delete this stack?",
|
||||||
"stackNotManagedByDockgeMsg": "This stack is not managed by Dockge.",
|
"stackNotManagedByDockgeMsg": "This stack is not managed by Dockge.",
|
||||||
"primaryHostname": "Primary Hostname",
|
"primaryHostname": "Primary Hostname",
|
||||||
"general": "General",
|
"general": "General",
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<transition name="slide-fade" appear>
|
<transition name="slide-fade" appear>
|
||||||
<div>
|
<div>
|
||||||
<h1 v-if="isAdd" class="mb-3">{{$t("compose")}}</h1>
|
<h1 v-if="isAdd" class="mb-3">{{ $t("compose") }}</h1>
|
||||||
<h1 v-else class="mb-3">
|
<h1 v-else class="mb-3">
|
||||||
<Uptime :stack="globalStack" :pill="true" /> {{ stack.name }}
|
<Uptime :stack="globalStack" :pill="true" /> {{ stack.name }}
|
||||||
<span v-if="$root.agentCount > 1" class="agent-name">
|
<span v-if="$root.agentCount > 1" class="agent-name">
|
||||||
|
@ -55,10 +55,14 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button v-if="isEditMode && !isAdd" class="btn btn-normal" :disabled="processing" @click="discardStack">{{ $t("discardStack") }}</button>
|
<button v-if="isEditMode && !isAdd" class="btn btn-normal" :disabled="processing" @click="discardStack">{{ $t("discardStack") }}</button>
|
||||||
<button v-if="!isEditMode" class="btn btn-danger" :disabled="processing" @click="showDeleteDialog = !showDeleteDialog">
|
<button v-if="!isEditMode && !errorDelete" class="btn btn-danger" :disabled="processing" @click="showDeleteDialog = !showDeleteDialog">
|
||||||
<font-awesome-icon icon="trash" class="me-1" />
|
<font-awesome-icon icon="trash" class="me-1" />
|
||||||
{{ $t("deleteStack") }}
|
{{ $t("deleteStack") }}
|
||||||
</button>
|
</button>
|
||||||
|
<button v-if="errorDelete" class="btn btn-danger" :disabled="processing" @click="showForceDeleteDialog = !showForceDeleteDialog">
|
||||||
|
<font-awesome-icon icon="trash" class="me-1" />
|
||||||
|
{{ $t("forceDeleteStack") }}
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- URLs -->
|
<!-- URLs -->
|
||||||
|
@ -150,7 +154,7 @@
|
||||||
|
|
||||||
<!-- Combined Terminal Output -->
|
<!-- Combined Terminal Output -->
|
||||||
<div v-show="!isEditMode">
|
<div v-show="!isEditMode">
|
||||||
<h4 class="mb-3">{{$t("terminal")}}</h4>
|
<h4 class="mb-3">{{ $t("terminal") }}</h4>
|
||||||
<Terminal
|
<Terminal
|
||||||
ref="combinedTerminal"
|
ref="combinedTerminal"
|
||||||
class="mb-3 terminal"
|
class="mb-3 terminal"
|
||||||
|
@ -232,6 +236,11 @@
|
||||||
<BModal v-model="showDeleteDialog" :okTitle="$t('deleteStack')" okVariant="danger" @ok="deleteDialog">
|
<BModal v-model="showDeleteDialog" :okTitle="$t('deleteStack')" okVariant="danger" @ok="deleteDialog">
|
||||||
{{ $t("deleteStackMsg") }}
|
{{ $t("deleteStackMsg") }}
|
||||||
</BModal>
|
</BModal>
|
||||||
|
|
||||||
|
<!-- Force Delete Dialog -->
|
||||||
|
<BModal v-model="showForceDeleteDialog" :okTitle="$t('forceDeleteStack')" okVariant="danger" @ok="forceDeleteDialog">
|
||||||
|
{{ $t("forceDeleteStackMsg") }}
|
||||||
|
</BModal>
|
||||||
</div>
|
</div>
|
||||||
</transition>
|
</transition>
|
||||||
</template>
|
</template>
|
||||||
|
@ -307,8 +316,10 @@ export default {
|
||||||
},
|
},
|
||||||
serviceStatusList: {},
|
serviceStatusList: {},
|
||||||
isEditMode: false,
|
isEditMode: false,
|
||||||
|
errorDelete: false,
|
||||||
submitted: false,
|
submitted: false,
|
||||||
showDeleteDialog: false,
|
showDeleteDialog: false,
|
||||||
|
showForceDeleteDialog: false,
|
||||||
newContainerName: "",
|
newContainerName: "",
|
||||||
stopServiceStatusTimeout: false,
|
stopServiceStatusTimeout: false,
|
||||||
};
|
};
|
||||||
|
@ -647,6 +658,17 @@ export default {
|
||||||
|
|
||||||
deleteDialog() {
|
deleteDialog() {
|
||||||
this.$root.emitAgent(this.endpoint, "deleteStack", this.stack.name, (res) => {
|
this.$root.emitAgent(this.endpoint, "deleteStack", this.stack.name, (res) => {
|
||||||
|
this.$root.toastRes(res);
|
||||||
|
if (res.ok) {
|
||||||
|
this.$router.push("/");
|
||||||
|
} else {
|
||||||
|
this.errorDelete = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
forceDeleteDialog() {
|
||||||
|
this.$root.emitAgent(this.endpoint, "forceDeleteStack", this.stack.name, (res) => {
|
||||||
this.$root.toastRes(res);
|
this.$root.toastRes(res);
|
||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
this.$router.push("/");
|
this.$router.push("/");
|
||||||
|
|
10421
package-lock.json
generated
Normal file
10421
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Reference in a new issue