mirror of
https://github.com/louislam/dockge.git
synced 2025-08-12 12:37:46 +02:00
Compare commits
6 Commits
Author | SHA1 | Date | |
---|---|---|---|
7ed045af05 | |||
7581e61153 | |||
3c137122b6 | |||
e2819afce1 | |||
94ca8a152a | |||
db0add7e4c |
@ -162,9 +162,44 @@ export class TerminalSocketHandler extends SocketHandler {
|
||||
}
|
||||
});
|
||||
|
||||
// TODO: Resize Terminal
|
||||
socket.on("terminalResize", async (rows : unknown) => {
|
||||
// Resize Terminal
|
||||
socket.on(
|
||||
"terminalResize",
|
||||
async (terminalName: unknown, rows: unknown, cols: unknown) => {
|
||||
log.info("terminalResize", `Terminal: ${terminalName}`);
|
||||
try {
|
||||
checkLogin(socket);
|
||||
if (typeof terminalName !== "string") {
|
||||
throw new Error("Terminal name must be a string.");
|
||||
}
|
||||
|
||||
});
|
||||
if (typeof rows !== "number") {
|
||||
throw new Error("Command must be a number.");
|
||||
}
|
||||
if (typeof cols !== "number") {
|
||||
throw new Error("Command must be a number.");
|
||||
}
|
||||
|
||||
let terminal = Terminal.getTerminal(terminalName);
|
||||
|
||||
// log.info("terminal", terminal);
|
||||
if (terminal instanceof Terminal) {
|
||||
//log.debug("terminalInput", "Terminal found, writing to terminal.");
|
||||
terminal.rows = rows;
|
||||
terminal.cols = cols;
|
||||
} else {
|
||||
throw new Error(`${terminalName} Terminal not found.`);
|
||||
}
|
||||
} catch (e) {
|
||||
log.debug(
|
||||
"terminalResize",
|
||||
// Added to prevent the lint error when adding the type
|
||||
// and ts type checker saying type is unknown.
|
||||
// @ts-ignore
|
||||
`Error on ${terminalName}: ${e.message}`
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import yaml from "yaml";
|
||||
import { DockgeSocket, fileExists, ValidationError } from "./util-server";
|
||||
import path from "path";
|
||||
import {
|
||||
acceptedComposeFileNames,
|
||||
COMBINED_TERMINAL_COLS,
|
||||
COMBINED_TERMINAL_ROWS,
|
||||
CREATED_FILE,
|
||||
@ -40,8 +41,7 @@ export class Stack {
|
||||
|
||||
if (!skipFSOperations) {
|
||||
// Check if compose file name is different from compose.yaml
|
||||
const supportedFileNames = [ "compose.yaml", "compose.yml", "docker-compose.yml", "docker-compose.yaml" ];
|
||||
for (const filename of supportedFileNames) {
|
||||
for (const filename of acceptedComposeFileNames) {
|
||||
if (fs.existsSync(path.join(this.path, filename))) {
|
||||
this._composeFileName = filename;
|
||||
break;
|
||||
@ -222,6 +222,26 @@ export class Stack {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a compose file exists in the specified directory.
|
||||
* @async
|
||||
* @static
|
||||
* @param {string} stacksDir - The directory of the stack.
|
||||
* @param {string} filename - The name of the directory to check for the compose file.
|
||||
* @returns {Promise<boolean>} A promise that resolves to a boolean indicating whether any compose file exists.
|
||||
*/
|
||||
static async composeFileExists(stacksDir : string, filename : string) : Promise<boolean> {
|
||||
let filenamePath = path.join(stacksDir, filename);
|
||||
// Check if any compose file exists
|
||||
for (const filename of acceptedComposeFileNames) {
|
||||
let composeFile = path.join(filenamePath, filename);
|
||||
if (await fileExists(composeFile)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static async getStackList(server : DockgeServer, useCacheForManaged = false) : Promise<Map<string, Stack>> {
|
||||
let stacksDir = server.stacksDir;
|
||||
let stackList : Map<string, Stack>;
|
||||
@ -242,6 +262,10 @@ export class Stack {
|
||||
if (!stat.isDirectory()) {
|
||||
continue;
|
||||
}
|
||||
// If no compose file exists, skip it
|
||||
if (!await Stack.composeFileExists(stacksDir, filename)) {
|
||||
continue;
|
||||
}
|
||||
let stack = await this.getStack(server, filename);
|
||||
stack._status = CREATED_FILE;
|
||||
stackList.set(filename, stack);
|
||||
|
@ -67,6 +67,7 @@ export class Terminal {
|
||||
|
||||
set cols(cols : number) {
|
||||
this._cols = cols;
|
||||
log.debug("Terminal", `Terminal cols: ${this._cols}`); // Added to check if cols is being set when changing terminal size.
|
||||
try {
|
||||
this.ptyProcess?.resize(this.cols, this.rows);
|
||||
} catch (e) {
|
||||
|
@ -116,6 +116,13 @@ export const allowedRawKeys = [
|
||||
"\u0003", // Ctrl + C
|
||||
];
|
||||
|
||||
export const acceptedComposeFileNames = [
|
||||
"compose.yaml",
|
||||
"docker-compose.yaml",
|
||||
"docker-compose.yml",
|
||||
"compose.yml",
|
||||
];
|
||||
|
||||
/**
|
||||
* Generate a decimal integer number from a string
|
||||
* @param str Input
|
||||
|
@ -2,6 +2,14 @@
|
||||
FROM node:18.17.1-bookworm-slim
|
||||
ENV PNPM_HOME="/pnpm"
|
||||
ENV PATH="$PNPM_HOME:$PATH"
|
||||
|
||||
|
||||
# TARGETPLATFORM: linux/amd64, linux/arm64, linux/arm/v7
|
||||
ARG TARGETPLATFORM
|
||||
|
||||
# TARGETARCH: amd64, arm64, arm/v7
|
||||
ARG TARGETARCH
|
||||
|
||||
RUN apt update && apt install --yes --no-install-recommends \
|
||||
curl \
|
||||
ca-certificates \
|
||||
@ -18,7 +26,12 @@ RUN apt update && apt install --yes --no-install-recommends \
|
||||
&& apt update \
|
||||
&& apt --yes --no-install-recommends install \
|
||||
docker-ce-cli \
|
||||
docker-compose-plugin \
|
||||
&& rm -rf /var/lib/apt/lists/* \
|
||||
&& npm install pnpm -g \
|
||||
&& pnpm install -g tsx
|
||||
|
||||
# Download docker-compose, as the repo's docker-compose is not up-to-date.
|
||||
COPY ./extra/download-docker-compose.ts ./extra/download-docker-compose.ts
|
||||
ARG DOCKER_COMPOSE_VERSION="2.23.3"
|
||||
RUN tsx ./extra/download-docker-compose.ts ${TARGETPLATFORM} ${DOCKER_COMPOSE_VERSION} \
|
||||
&& docker compose version
|
||||
|
39
extra/download-docker-compose.ts
Normal file
39
extra/download-docker-compose.ts
Normal file
@ -0,0 +1,39 @@
|
||||
import fs from "fs";
|
||||
|
||||
async function main() {
|
||||
// TARGETPLATFORM
|
||||
const targetPlatform = process.argv[2];
|
||||
|
||||
// Docker Compose version
|
||||
const dockerComposeVersion = process.argv[3];
|
||||
|
||||
// Arch
|
||||
let arch = "";
|
||||
|
||||
if (targetPlatform === "linux/amd64") {
|
||||
arch = "x86_64";
|
||||
} else if (targetPlatform === "linux/arm64") {
|
||||
arch = "aarch64";
|
||||
} else if (targetPlatform === "linux/arm/v7") {
|
||||
arch = "armv7";
|
||||
} else {
|
||||
throw new Error(`Unknown target platform: ${targetPlatform}`);
|
||||
}
|
||||
|
||||
// mkdir -p /root/.docker/cli-plugins
|
||||
fs.mkdirSync("/root/.docker/cli-plugins", { recursive: true });
|
||||
|
||||
// Download URL
|
||||
const url = `https://github.com/docker/compose/releases/download/v${dockerComposeVersion}/docker-compose-linux-${arch}`;
|
||||
|
||||
console.log(url);
|
||||
|
||||
// Download docker-compose using fetch api, to "/root/.docker/cli-plugins/docker-compose"
|
||||
const buffer = await (await fetch(url)).arrayBuffer();
|
||||
fs.writeFileSync("/root/.docker/cli-plugins/docker-compose", Buffer.from(buffer));
|
||||
|
||||
// chmod +x /root/.docker/cli-plugins/docker-compose
|
||||
fs.chmodSync("/root/.docker/cli-plugins/docker-compose", 0o111);
|
||||
}
|
||||
|
||||
main();
|
@ -9,17 +9,23 @@ const template = `
|
||||
>
|
||||
|
||||
### 🆕 New Features
|
||||
-
|
||||
|
||||
### ⬆️ Improvements
|
||||
-
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
-
|
||||
|
||||
### 🦎 Translation Contributions
|
||||
-
|
||||
|
||||
### ⬆️ Security Fixes
|
||||
-
|
||||
|
||||
### Others
|
||||
- Other small changes, code refactoring and comment/doc updates in this repo:
|
||||
-
|
||||
|
||||
Please let me know if your username is missing, if your pull request has been merged in this version, or your commit has been included in one of the pull requests.
|
||||
`;
|
||||
|
@ -5,7 +5,8 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Terminal } from "xterm";
|
||||
import { Terminal } from "@xterm/xterm";
|
||||
import { FitAddon } from "@xterm/addon-fit";
|
||||
import { WebLinksAddon } from "xterm-addon-web-links";
|
||||
import { TERMINAL_COLS, TERMINAL_ROWS } from "../../../backend/util-common";
|
||||
|
||||
@ -122,10 +123,12 @@ export default {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Fit the terminal width to the div container size after terminal is created.
|
||||
this.updateTerminalSize();
|
||||
},
|
||||
|
||||
unmounted() {
|
||||
window.removeEventListener("resize", this.onResizeEvent); // Remove the resize event listener from the window object.
|
||||
this.$root.unbindTerminal(this.name);
|
||||
this.terminal.dispose();
|
||||
},
|
||||
@ -208,6 +211,30 @@ export default {
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Update the terminal size to fit the container size.
|
||||
*
|
||||
* If the terminalFitAddOn is not created, creates it, loads it and then fits the terminal to the appropriate size.
|
||||
* It then addes an event listener to the window object to listen for resize events and calls the fit method of the terminalFitAddOn.
|
||||
*/
|
||||
updateTerminalSize() {
|
||||
if (!Object.hasOwn(this, "terminalFitAddOn")) {
|
||||
this.terminalFitAddOn = new FitAddon();
|
||||
this.terminal.loadAddon(this.terminalFitAddOn);
|
||||
window.addEventListener("resize", this.onResizeEvent);
|
||||
}
|
||||
this.terminalFitAddOn.fit();
|
||||
},
|
||||
/**
|
||||
* Handles the resize event of the terminal component.
|
||||
*/
|
||||
onResizeEvent() {
|
||||
this.terminalFitAddOn.fit();
|
||||
let rows = this.terminal.rows;
|
||||
let cols = this.terminal.cols;
|
||||
this.$root.getSocket().emit("terminalResize", this.name, rows, cols);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -10,12 +10,12 @@ import { i18n } from "./i18n";
|
||||
// Dependencies
|
||||
import "bootstrap";
|
||||
import Toast, { POSITION, useToast } from "vue-toastification";
|
||||
import "xterm/lib/xterm.js";
|
||||
import "@xterm/xterm/lib/xterm.js";
|
||||
|
||||
// CSS
|
||||
import "@fontsource/jetbrains-mono";
|
||||
import "vue-toastification/dist/index.css";
|
||||
import "xterm/css/xterm.css";
|
||||
import "@xterm/xterm/css/xterm.css";
|
||||
import "./styles/main.scss";
|
||||
|
||||
// Minxins
|
||||
|
@ -2,7 +2,7 @@ import { io } from "socket.io-client";
|
||||
import { Socket } from "socket.io-client";
|
||||
import { defineComponent } from "vue";
|
||||
import jwtDecode from "jwt-decode";
|
||||
import { Terminal } from "xterm";
|
||||
import { Terminal } from "@xterm/xterm";
|
||||
|
||||
let socket : Socket;
|
||||
|
||||
|
@ -55,8 +55,6 @@
|
||||
"yaml": "~2.3.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"concurrently": "^8.2.2",
|
||||
"wait-on": "^7.2.0",
|
||||
"@actions/github": "^6.0.0",
|
||||
"@fontsource/jetbrains-mono": "^5.0.18",
|
||||
"@fortawesome/fontawesome-svg-core": "6.4.2",
|
||||
@ -71,8 +69,11 @@
|
||||
"@typescript-eslint/eslint-plugin": "~6.8.0",
|
||||
"@typescript-eslint/parser": "~6.8.0",
|
||||
"@vitejs/plugin-vue": "~4.5.2",
|
||||
"@xterm/addon-fit": "beta",
|
||||
"@xterm/xterm": "beta",
|
||||
"bootstrap": "5.3.2",
|
||||
"bootstrap-vue-next": "~0.14.10",
|
||||
"concurrently": "^8.2.2",
|
||||
"cross-env": "~7.0.3",
|
||||
"eslint": "~8.50.0",
|
||||
"eslint-plugin-jsdoc": "~46.8.2",
|
||||
@ -90,7 +91,7 @@
|
||||
"vue-qrcode": "~2.2.0",
|
||||
"vue-router": "~4.2.5",
|
||||
"vue-toastification": "2.0.0-rc.5",
|
||||
"xterm": "5.4.0-beta.37",
|
||||
"wait-on": "^7.2.0",
|
||||
"xterm-addon-web-links": "~0.9.0"
|
||||
}
|
||||
}
|
||||
|
31
pnpm-lock.yaml
generated
31
pnpm-lock.yaml
generated
@ -133,6 +133,12 @@ devDependencies:
|
||||
'@vitejs/plugin-vue':
|
||||
specifier: ~4.5.2
|
||||
version: 4.5.2(vite@5.0.7)(vue@3.3.11)
|
||||
'@xterm/addon-fit':
|
||||
specifier: beta
|
||||
version: 0.9.0-beta.17(@xterm/xterm@5.4.0-beta.17)
|
||||
'@xterm/xterm':
|
||||
specifier: beta
|
||||
version: 5.4.0-beta.17
|
||||
bootstrap:
|
||||
specifier: 5.3.2
|
||||
version: 5.3.2(@popperjs/core@2.11.8)
|
||||
@ -196,12 +202,9 @@ devDependencies:
|
||||
wait-on:
|
||||
specifier: ^7.2.0
|
||||
version: 7.2.0
|
||||
xterm:
|
||||
specifier: 5.4.0-beta.37
|
||||
version: 5.4.0-beta.37
|
||||
xterm-addon-web-links:
|
||||
specifier: ~0.9.0
|
||||
version: 0.9.0(xterm@5.4.0-beta.37)
|
||||
version: 0.9.0(xterm@5.3.0)
|
||||
|
||||
packages:
|
||||
|
||||
@ -1569,6 +1572,18 @@ packages:
|
||||
- vue
|
||||
dev: true
|
||||
|
||||
/@xterm/addon-fit@0.9.0-beta.17(@xterm/xterm@5.4.0-beta.17):
|
||||
resolution: {integrity: sha512-4jYMsbyferF29hF0vCaQj6CQlT2A6ML6DhLZdi6cCZI5qn60mGUXZfDeO/Qoq2nmyK/PBrPyFYSOzWapSy45Zg==}
|
||||
peerDependencies:
|
||||
'@xterm/xterm': ^5.0.0
|
||||
dependencies:
|
||||
'@xterm/xterm': 5.4.0-beta.17
|
||||
dev: true
|
||||
|
||||
/@xterm/xterm@5.4.0-beta.17:
|
||||
resolution: {integrity: sha512-EhQsTHeO7VhCOnYLdrowWAqEbmZKf6k6Z/Rd3GriikB394jivux6OBcJbt7QdewIOAKqFah53d4rNXfz3/6mwQ==}
|
||||
dev: true
|
||||
|
||||
/abbrev@1.1.1:
|
||||
resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==}
|
||||
requiresBuild: true
|
||||
@ -5524,16 +5539,16 @@ packages:
|
||||
engines: {node: '>=0.4.0'}
|
||||
dev: false
|
||||
|
||||
/xterm-addon-web-links@0.9.0(xterm@5.4.0-beta.37):
|
||||
/xterm-addon-web-links@0.9.0(xterm@5.3.0):
|
||||
resolution: {integrity: sha512-LIzi4jBbPlrKMZF3ihoyqayWyTXAwGfu4yprz1aK2p71e9UKXN6RRzVONR0L+Zd+Ik5tPVI9bwp9e8fDTQh49Q==}
|
||||
peerDependencies:
|
||||
xterm: ^5.0.0
|
||||
dependencies:
|
||||
xterm: 5.4.0-beta.37
|
||||
xterm: 5.3.0
|
||||
dev: true
|
||||
|
||||
/xterm@5.4.0-beta.37:
|
||||
resolution: {integrity: sha512-ys+mXqLFrJc7khmYN/MgBnfLv38NgXfkwkEXsCZKHGqn3h2xUBvTvsrSEWO3NQeDPLj4zMr1RwqTblMK9St3BA==}
|
||||
/xterm@5.3.0:
|
||||
resolution: {integrity: sha512-8QqjlekLUFTrU6x7xck1MsPzPA571K5zNqWm0M0oroYEWVOptZ0+ubQSkQ3uxIEhcIHRujJy6emDWX4A7qyFzg==}
|
||||
dev: true
|
||||
|
||||
/y18n@4.0.3:
|
||||
|
Reference in New Issue
Block a user