mirror of
https://github.com/CyberL1/dlinux-dashboard.git
synced 2025-01-22 01:19:18 -05:00
remove not needded files
This commit is contained in:
parent
d7dcabc3da
commit
81bf5fb6af
@ -1,4 +0,0 @@
|
|||||||
PORT=3000
|
|
||||||
HOST="0.0.0.0"
|
|
||||||
|
|
||||||
PROXY_DOMAIN="localhost"
|
|
24
.gitignore
vendored
24
.gitignore
vendored
@ -1,2 +1,24 @@
|
|||||||
.env
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
pnpm-debug.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
|
||||||
node_modules
|
node_modules
|
||||||
|
dist
|
||||||
|
dist-ssr
|
||||||
|
*.local
|
||||||
|
|
||||||
|
# Editor directories and files
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/extensions.json
|
||||||
|
.idea
|
||||||
|
.DS_Store
|
||||||
|
*.suo
|
||||||
|
*.ntvs*
|
||||||
|
*.njsproj
|
||||||
|
*.sln
|
||||||
|
*.sw?
|
||||||
|
@ -1,5 +0,0 @@
|
|||||||
FROM node:alpine
|
|
||||||
COPY . .
|
|
||||||
|
|
||||||
RUN npm i
|
|
||||||
ENTRYPOINT ["npm", "start"]
|
|
147
biome.json
147
biome.json
@ -1,77 +1,74 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://biomejs.dev/schemas/1.8.0/schema.json",
|
"linter": {
|
||||||
"organizeImports": {
|
"rules": {
|
||||||
"enabled": true
|
"recommended": false,
|
||||||
},
|
"complexity": {
|
||||||
"linter": {
|
"noBannedTypes": "error",
|
||||||
"enabled": true,
|
"noExtraBooleanCast": "error",
|
||||||
"rules": {
|
"noMultipleSpacesInRegularExpressionLiterals": "error",
|
||||||
"recommended": false,
|
"noUselessCatch": "error",
|
||||||
"complexity": {
|
"noUselessTypeConstraint": "error",
|
||||||
"noExtraBooleanCast": "error",
|
"noWith": "error"
|
||||||
"noMultipleSpacesInRegularExpressionLiterals": "error",
|
},
|
||||||
"noUselessCatch": "error",
|
"correctness": {
|
||||||
"noWith": "error"
|
"noConstAssign": "error",
|
||||||
},
|
"noConstantCondition": "error",
|
||||||
"correctness": {
|
"noEmptyCharacterClassInRegex": "error",
|
||||||
"noConstAssign": "error",
|
"noEmptyPattern": "error",
|
||||||
"noConstantCondition": "error",
|
"noGlobalObjectCalls": "error",
|
||||||
"noEmptyCharacterClassInRegex": "error",
|
"noInnerDeclarations": "error",
|
||||||
"noEmptyPattern": "error",
|
"noInvalidConstructorSuper": "error",
|
||||||
"noGlobalObjectCalls": "error",
|
"noNewSymbol": "error",
|
||||||
"noInnerDeclarations": "error",
|
"noNonoctalDecimalEscape": "error",
|
||||||
"noInvalidConstructorSuper": "error",
|
"noPrecisionLoss": "error",
|
||||||
"noNewSymbol": "error",
|
"noSelfAssign": "error",
|
||||||
"noNonoctalDecimalEscape": "error",
|
"noSetterReturn": "error",
|
||||||
"noPrecisionLoss": "error",
|
"noSwitchDeclarations": "error",
|
||||||
"noSelfAssign": "error",
|
"noUndeclaredVariables": "error",
|
||||||
"noSetterReturn": "error",
|
"noUnreachable": "error",
|
||||||
"noSwitchDeclarations": "error",
|
"noUnreachableSuper": "error",
|
||||||
"noUndeclaredVariables": "error",
|
"noUnsafeFinally": "error",
|
||||||
"noUnreachable": "error",
|
"noUnsafeOptionalChaining": "error",
|
||||||
"noUnreachableSuper": "error",
|
"noUnusedLabels": "error",
|
||||||
"noUnsafeFinally": "error",
|
"noUnusedVariables": "error",
|
||||||
"noUnsafeOptionalChaining": "error",
|
"useArrayLiterals": "off",
|
||||||
"noUnusedLabels": "error",
|
"useExhaustiveDependencies": "warn",
|
||||||
"noUnusedVariables": "error",
|
"useHookAtTopLevel": "error",
|
||||||
"useIsNan": "error",
|
"useIsNan": "error",
|
||||||
"useValidForDirection": "error",
|
"useValidForDirection": "error",
|
||||||
"useYield": "error"
|
"useYield": "error"
|
||||||
},
|
},
|
||||||
"style": {
|
"style": { "noNamespace": "error", "useAsConstAssertion": "error" },
|
||||||
"noVar": "error",
|
"suspicious": {
|
||||||
"useBlockStatements": "error",
|
"noAsyncPromiseExecutor": "error",
|
||||||
"useCollapsedElseIf": "error",
|
"noCatchAssign": "error",
|
||||||
"useConst": "error"
|
"noClassAssign": "error",
|
||||||
},
|
"noCompareNegZero": "error",
|
||||||
"suspicious": {
|
"noControlCharactersInRegex": "error",
|
||||||
"noAsyncPromiseExecutor": "error",
|
"noDebugger": "error",
|
||||||
"noCatchAssign": "error",
|
"noDuplicateCase": "error",
|
||||||
"noClassAssign": "error",
|
"noDuplicateClassMembers": "error",
|
||||||
"noCompareNegZero": "error",
|
"noDuplicateObjectKeys": "error",
|
||||||
"noControlCharactersInRegex": "error",
|
"noDuplicateParameters": "error",
|
||||||
"noDebugger": "error",
|
"noEmptyBlockStatements": "error",
|
||||||
"noDuplicateCase": "error",
|
"noExplicitAny": "error",
|
||||||
"noDuplicateClassMembers": "error",
|
"noExtraNonNullAssertion": "error",
|
||||||
"noDuplicateObjectKeys": "error",
|
"noFallthroughSwitchClause": "error",
|
||||||
"noDuplicateParameters": "error",
|
"noFunctionAssign": "error",
|
||||||
"noEmptyBlockStatements": "error",
|
"noGlobalAssign": "error",
|
||||||
"noFallthroughSwitchClause": "error",
|
"noImportAssign": "error",
|
||||||
"noFunctionAssign": "error",
|
"noMisleadingCharacterClass": "error",
|
||||||
"noGlobalAssign": "error",
|
"noMisleadingInstantiator": "error",
|
||||||
"noImportAssign": "error",
|
"noPrototypeBuiltins": "error",
|
||||||
"noMisleadingCharacterClass": "error",
|
"noRedeclare": "error",
|
||||||
"noPrototypeBuiltins": "error",
|
"noShadowRestrictedNames": "error",
|
||||||
"noRedeclare": "error",
|
"noSparseArray": "error",
|
||||||
"noShadowRestrictedNames": "error",
|
"noUnsafeDeclarationMerging": "error",
|
||||||
"noUnsafeNegation": "error",
|
"noUnsafeNegation": "error",
|
||||||
"useGetterReturn": "error",
|
"useGetterReturn": "error",
|
||||||
"useValidTypeof": "error"
|
"useValidTypeof": "error"
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
},
|
"ignore": ["**/dist"]
|
||||||
"formatter": {
|
}
|
||||||
"indentStyle": "space",
|
|
||||||
"indentWidth": 2
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,22 +0,0 @@
|
|||||||
name: code-containers
|
|
||||||
|
|
||||||
services:
|
|
||||||
server:
|
|
||||||
build: ..
|
|
||||||
env_file: ../.env
|
|
||||||
ports:
|
|
||||||
- 3000:3000
|
|
||||||
volumes:
|
|
||||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
|
||||||
proxy:
|
|
||||||
build: ../proxy
|
|
||||||
env_file: ../.env
|
|
||||||
ports:
|
|
||||||
- 80:80
|
|
||||||
network_mode: host
|
|
||||||
frontend:
|
|
||||||
image: nginx:alpine
|
|
||||||
ports:
|
|
||||||
- 5173:80
|
|
||||||
volumes:
|
|
||||||
- ../frontend/dist:/usr/share/nginx/html
|
|
24
frontend/.gitignore
vendored
24
frontend/.gitignore
vendored
@ -1,24 +0,0 @@
|
|||||||
# Logs
|
|
||||||
logs
|
|
||||||
*.log
|
|
||||||
npm-debug.log*
|
|
||||||
yarn-debug.log*
|
|
||||||
yarn-error.log*
|
|
||||||
pnpm-debug.log*
|
|
||||||
lerna-debug.log*
|
|
||||||
|
|
||||||
node_modules
|
|
||||||
dist
|
|
||||||
dist-ssr
|
|
||||||
*.local
|
|
||||||
|
|
||||||
# Editor directories and files
|
|
||||||
.vscode/*
|
|
||||||
!.vscode/extensions.json
|
|
||||||
.idea
|
|
||||||
.DS_Store
|
|
||||||
*.suo
|
|
||||||
*.ntvs*
|
|
||||||
*.njsproj
|
|
||||||
*.sln
|
|
||||||
*.sw?
|
|
@ -1,74 +0,0 @@
|
|||||||
{
|
|
||||||
"linter": {
|
|
||||||
"rules": {
|
|
||||||
"recommended": false,
|
|
||||||
"complexity": {
|
|
||||||
"noBannedTypes": "error",
|
|
||||||
"noExtraBooleanCast": "error",
|
|
||||||
"noMultipleSpacesInRegularExpressionLiterals": "error",
|
|
||||||
"noUselessCatch": "error",
|
|
||||||
"noUselessTypeConstraint": "error",
|
|
||||||
"noWith": "error"
|
|
||||||
},
|
|
||||||
"correctness": {
|
|
||||||
"noConstAssign": "error",
|
|
||||||
"noConstantCondition": "error",
|
|
||||||
"noEmptyCharacterClassInRegex": "error",
|
|
||||||
"noEmptyPattern": "error",
|
|
||||||
"noGlobalObjectCalls": "error",
|
|
||||||
"noInnerDeclarations": "error",
|
|
||||||
"noInvalidConstructorSuper": "error",
|
|
||||||
"noNewSymbol": "error",
|
|
||||||
"noNonoctalDecimalEscape": "error",
|
|
||||||
"noPrecisionLoss": "error",
|
|
||||||
"noSelfAssign": "error",
|
|
||||||
"noSetterReturn": "error",
|
|
||||||
"noSwitchDeclarations": "error",
|
|
||||||
"noUndeclaredVariables": "error",
|
|
||||||
"noUnreachable": "error",
|
|
||||||
"noUnreachableSuper": "error",
|
|
||||||
"noUnsafeFinally": "error",
|
|
||||||
"noUnsafeOptionalChaining": "error",
|
|
||||||
"noUnusedLabels": "error",
|
|
||||||
"noUnusedVariables": "error",
|
|
||||||
"useArrayLiterals": "off",
|
|
||||||
"useExhaustiveDependencies": "warn",
|
|
||||||
"useHookAtTopLevel": "error",
|
|
||||||
"useIsNan": "error",
|
|
||||||
"useValidForDirection": "error",
|
|
||||||
"useYield": "error"
|
|
||||||
},
|
|
||||||
"style": { "noNamespace": "error", "useAsConstAssertion": "error" },
|
|
||||||
"suspicious": {
|
|
||||||
"noAsyncPromiseExecutor": "error",
|
|
||||||
"noCatchAssign": "error",
|
|
||||||
"noClassAssign": "error",
|
|
||||||
"noCompareNegZero": "error",
|
|
||||||
"noControlCharactersInRegex": "error",
|
|
||||||
"noDebugger": "error",
|
|
||||||
"noDuplicateCase": "error",
|
|
||||||
"noDuplicateClassMembers": "error",
|
|
||||||
"noDuplicateObjectKeys": "error",
|
|
||||||
"noDuplicateParameters": "error",
|
|
||||||
"noEmptyBlockStatements": "error",
|
|
||||||
"noExplicitAny": "error",
|
|
||||||
"noExtraNonNullAssertion": "error",
|
|
||||||
"noFallthroughSwitchClause": "error",
|
|
||||||
"noFunctionAssign": "error",
|
|
||||||
"noGlobalAssign": "error",
|
|
||||||
"noImportAssign": "error",
|
|
||||||
"noMisleadingCharacterClass": "error",
|
|
||||||
"noMisleadingInstantiator": "error",
|
|
||||||
"noPrototypeBuiltins": "error",
|
|
||||||
"noRedeclare": "error",
|
|
||||||
"noShadowRestrictedNames": "error",
|
|
||||||
"noSparseArray": "error",
|
|
||||||
"noUnsafeDeclarationMerging": "error",
|
|
||||||
"noUnsafeNegation": "error",
|
|
||||||
"useGetterReturn": "error",
|
|
||||||
"useValidTypeof": "error"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"ignore": ["**/dist"]
|
|
||||||
}
|
|
||||||
}
|
|
4543
frontend/package-lock.json
generated
4543
frontend/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -1,38 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "notifier-frontend",
|
|
||||||
"private": true,
|
|
||||||
"version": "0.0.0",
|
|
||||||
"type": "module",
|
|
||||||
"scripts": {
|
|
||||||
"dev": "vite",
|
|
||||||
"build": "tsc && vite build",
|
|
||||||
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
|
|
||||||
"preview": "vite preview"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"@emotion/react": "^11.13.5",
|
|
||||||
"@emotion/styled": "^11.13.5",
|
|
||||||
"@fontsource/roboto": "^5.1.0",
|
|
||||||
"@mui/icons-material": "^6.1.8",
|
|
||||||
"@mui/lab": "^6.0.0-beta.23",
|
|
||||||
"@mui/material": "^6.1.8",
|
|
||||||
"@xterm/addon-attach": "^0.11.0",
|
|
||||||
"@xterm/addon-fit": "^0.10.0",
|
|
||||||
"@xterm/xterm": "^5.5.0",
|
|
||||||
"react": "^18.2.0",
|
|
||||||
"react-dom": "^18.2.0",
|
|
||||||
"react-router": "^7.0.1"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@biomejs/biome": "^1.9.4",
|
|
||||||
"@types/dockerode": "^3.3.34",
|
|
||||||
"@types/node": "^22.9.3",
|
|
||||||
"@types/react": "^18.2.66",
|
|
||||||
"@types/react-dom": "^18.2.22",
|
|
||||||
"@typescript-eslint/eslint-plugin": "^7.2.0",
|
|
||||||
"@typescript-eslint/parser": "^7.2.0",
|
|
||||||
"@vitejs/plugin-react": "^4.2.1",
|
|
||||||
"typescript": "^5.2.2",
|
|
||||||
"vite": "^5.2.0"
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,16 +0,0 @@
|
|||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
"module": "ESNext",
|
|
||||||
"target": "ES2024",
|
|
||||||
"lib": [
|
|
||||||
"ES2024"
|
|
||||||
],
|
|
||||||
"moduleResolution": "bundler",
|
|
||||||
"allowImportingTsExtensions": true,
|
|
||||||
"paths": {
|
|
||||||
"#src/*": [
|
|
||||||
"./src/*"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
4876
package-lock.json
generated
4876
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
45
package.json
45
package.json
@ -1,27 +1,38 @@
|
|||||||
{
|
{
|
||||||
"name": "code-containers",
|
"name": "notifier-frontend",
|
||||||
"version": "1.0.0",
|
"private": true,
|
||||||
"main": "src/index.ts",
|
"version": "0.0.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "node --experimental-strip-types .",
|
"dev": "vite",
|
||||||
"dev": "node --experimental-strip-types --watch ."
|
"build": "tsc && vite build",
|
||||||
|
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
|
||||||
|
"preview": "vite preview"
|
||||||
},
|
},
|
||||||
"imports": {
|
|
||||||
"#src/*": "./src/*"
|
|
||||||
},
|
|
||||||
"keywords": [],
|
|
||||||
"author": "",
|
|
||||||
"license": "ISC",
|
|
||||||
"description": "",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fastify/websocket": "^11.0.2",
|
"@emotion/react": "^11.13.5",
|
||||||
|
"@emotion/styled": "^11.13.5",
|
||||||
|
"@fontsource/roboto": "^5.1.0",
|
||||||
|
"@mui/icons-material": "^6.1.8",
|
||||||
|
"@mui/lab": "^6.0.0-beta.23",
|
||||||
|
"@mui/material": "^6.1.8",
|
||||||
|
"@xterm/addon-attach": "^0.11.0",
|
||||||
"@xterm/addon-fit": "^0.10.0",
|
"@xterm/addon-fit": "^0.10.0",
|
||||||
"dockerode": "^4.0.3",
|
"@xterm/xterm": "^5.5.0",
|
||||||
"dotenv": "^16.4.7",
|
"react": "^18.2.0",
|
||||||
"fastify": "^5.2.1"
|
"react-dom": "^18.2.0",
|
||||||
|
"react-router": "^7.0.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@biomejs/biome": "^1.9.4"
|
"@biomejs/biome": "^1.9.4",
|
||||||
|
"@types/dockerode": "^3.3.34",
|
||||||
|
"@types/node": "^22.9.3",
|
||||||
|
"@types/react": "^18.2.66",
|
||||||
|
"@types/react-dom": "^18.2.22",
|
||||||
|
"@typescript-eslint/eslint-plugin": "^7.2.0",
|
||||||
|
"@typescript-eslint/parser": "^7.2.0",
|
||||||
|
"@vitejs/plugin-react": "^4.2.1",
|
||||||
|
"typescript": "^5.2.2",
|
||||||
|
"vite": "^5.2.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +0,0 @@
|
|||||||
FROM openresty/openresty:alpine
|
|
||||||
|
|
||||||
RUN wget -O /usr/local/openresty/lualib/resty/http.lua https://github.com/ledgetech/lua-resty-http/raw/refs/heads/master/lib/resty/http.lua
|
|
||||||
RUN wget -O /usr/local/openresty/lualib/resty/http_connect.lua https://github.com/ledgetech/lua-resty-http/raw/refs/heads/master/lib/resty/http_connect.lua
|
|
||||||
RUN wget -O /usr/local/openresty/lualib/resty/http_headers.lua https://github.com/ledgetech/lua-resty-http/raw/refs/heads/master/lib/resty/http_headers.lua
|
|
||||||
|
|
||||||
COPY proxy.conf etc/nginx/conf.d/proxy.conf
|
|
||||||
ENTRYPOINT ["/bin/sh", "-c", "sed -i \"s/{PROXY_DOMAIN}/$PROXY_DOMAIN/\" etc/nginx/conf.d/proxy.conf && nginx -g 'daemon off;'"]
|
|
@ -1,40 +0,0 @@
|
|||||||
server {
|
|
||||||
listen 80;
|
|
||||||
listen [::]:80;
|
|
||||||
|
|
||||||
server_name {PROXY_DOMAIN};
|
|
||||||
|
|
||||||
location / {
|
|
||||||
proxy_pass http://127.0.0.1:5173;
|
|
||||||
}
|
|
||||||
|
|
||||||
location /api/ {
|
|
||||||
proxy_pass http://127.0.0.1:3000/;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
server {
|
|
||||||
listen 80;
|
|
||||||
listen [::]:80;
|
|
||||||
|
|
||||||
server_name "~^(port-(?<port>.+)\.)?(?<container>.*)\.{PROXY_DOMAIN}";
|
|
||||||
|
|
||||||
location / {
|
|
||||||
if ($port = "") {
|
|
||||||
set $port "80";
|
|
||||||
}
|
|
||||||
|
|
||||||
set $ip '';
|
|
||||||
rewrite_by_lua_block {
|
|
||||||
local http = require("resty.http").new()
|
|
||||||
|
|
||||||
local res = http:request_uri("http://127.0.0.1:3000/containers/" .. ngx.var.container .. "/ip")
|
|
||||||
ngx.var.ip = res.body
|
|
||||||
}
|
|
||||||
|
|
||||||
proxy_pass http://$ip:$port;
|
|
||||||
proxy_http_version 1.1;
|
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
|
||||||
proxy_set_header Connection "upgrade";
|
|
||||||
}
|
|
||||||
}
|
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 4.0 KiB |
35
src/index.ts
35
src/index.ts
@ -1,35 +0,0 @@
|
|||||||
import fastifyWebsocket from "@fastify/websocket";
|
|
||||||
import "dotenv/config";
|
|
||||||
import fastify from "fastify";
|
|
||||||
import { readdirSync } from "fs";
|
|
||||||
|
|
||||||
const app = fastify();
|
|
||||||
app.register(fastifyWebsocket);
|
|
||||||
|
|
||||||
const routes = readdirSync(`${import.meta.dirname}/routes`, {
|
|
||||||
recursive: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
for (let file of routes) {
|
|
||||||
if (typeof file === "string") {
|
|
||||||
if (!file.endsWith(".ts")) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
file = file.replaceAll("\\", "/");
|
|
||||||
|
|
||||||
let route = `/${file.split(".").slice(0, -1).join(".")}`;
|
|
||||||
route = route.replaceAll("_", ":");
|
|
||||||
|
|
||||||
const routePath = route.endsWith("/index") ? route.slice(0, -6) : route;
|
|
||||||
console.log(`Loading route: ${routePath}`);
|
|
||||||
|
|
||||||
app.register((await import(`./routes/${file}`)).default, {
|
|
||||||
prefix: routePath,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
await app.listen({ port: Number(process.env.PORT), host: process.env.HOST });
|
|
||||||
|
|
||||||
console.log("App ready on", `http://${process.env.HOST}:${process.env.PORT}`);
|
|
@ -1,29 +0,0 @@
|
|||||||
import type {
|
|
||||||
Container,
|
|
||||||
RemoveContainerParams,
|
|
||||||
RemoveContainerQuery,
|
|
||||||
} from "#src/types/Container.ts";
|
|
||||||
import { getContainer, getContainerResponse } from "#src/utils/containers.ts";
|
|
||||||
import type { FastifyInstance, FastifyRequest } from "fastify";
|
|
||||||
|
|
||||||
export default (fastify: FastifyInstance) => {
|
|
||||||
fastify.get("/", (req: FastifyRequest<{ Params: Container }>) => {
|
|
||||||
const container = getContainer(req.params.id);
|
|
||||||
return getContainerResponse(container);
|
|
||||||
});
|
|
||||||
|
|
||||||
fastify.delete(
|
|
||||||
"/",
|
|
||||||
async (
|
|
||||||
req: FastifyRequest<{
|
|
||||||
Params: RemoveContainerParams;
|
|
||||||
Querystring: RemoveContainerQuery;
|
|
||||||
}>,
|
|
||||||
) => {
|
|
||||||
const container = getContainer(req.params.id);
|
|
||||||
|
|
||||||
await container.remove({ force: req.query.force === "true" });
|
|
||||||
return getContainerResponse(container);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
};
|
|
@ -1,12 +0,0 @@
|
|||||||
import type { Container } from "#src/types/Container.ts";
|
|
||||||
import { getContainer } from "#src/utils/containers.ts";
|
|
||||||
import type { FastifyInstance, FastifyRequest } from "fastify";
|
|
||||||
|
|
||||||
export default (fastify: FastifyInstance) => {
|
|
||||||
fastify.get("/", async (req: FastifyRequest<{ Params: Container }>) => {
|
|
||||||
const container = getContainer(req.params.id);
|
|
||||||
|
|
||||||
const { NetworkSettings } = await container.inspect();
|
|
||||||
return NetworkSettings.IPAddress;
|
|
||||||
});
|
|
||||||
};
|
|
@ -1,45 +0,0 @@
|
|||||||
import type {
|
|
||||||
CreateContainerBody,
|
|
||||||
RemoveContainerParams,
|
|
||||||
RemoveContainerQuery,
|
|
||||||
} from "#src/types/Container.ts";
|
|
||||||
import {
|
|
||||||
createContainer,
|
|
||||||
getContainer,
|
|
||||||
getContainerResponse,
|
|
||||||
} from "#src/utils/containers.ts";
|
|
||||||
import { getImage } from "#src/utils/images.ts";
|
|
||||||
import type { FastifyInstance, FastifyRequest } from "fastify";
|
|
||||||
|
|
||||||
export default (fastify: FastifyInstance) => {
|
|
||||||
fastify.post(
|
|
||||||
"/",
|
|
||||||
async (
|
|
||||||
req: FastifyRequest<{
|
|
||||||
Params: RemoveContainerParams;
|
|
||||||
Querystring: RemoveContainerQuery;
|
|
||||||
Body: CreateContainerBody;
|
|
||||||
}>,
|
|
||||||
) => {
|
|
||||||
if (req.body) {
|
|
||||||
if (!(await getImage(req.body?.image).inspect()).Id) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const oldContainer = getContainer(req.params.id);
|
|
||||||
const name = (await oldContainer.inspect()).Name;
|
|
||||||
|
|
||||||
const image =
|
|
||||||
req.body?.image ||
|
|
||||||
(await oldContainer.inspect()).Config.Labels["code-containers.image"];
|
|
||||||
|
|
||||||
await oldContainer.remove({ force: req.query.force === "true" });
|
|
||||||
|
|
||||||
const newContainer = await createContainer({ name, image });
|
|
||||||
await newContainer.start();
|
|
||||||
|
|
||||||
return getContainerResponse(newContainer);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
};
|
|
@ -1,12 +0,0 @@
|
|||||||
import type { Container } from "#src/types/Container.ts";
|
|
||||||
import { getContainer, getContainerResponse } from "#src/utils/containers.ts";
|
|
||||||
import type { FastifyInstance, FastifyRequest } from "fastify";
|
|
||||||
|
|
||||||
export default (fastify: FastifyInstance) => {
|
|
||||||
fastify.put("/", async (req: FastifyRequest<{ Params: Container }>) => {
|
|
||||||
const container = getContainer(req.params.id);
|
|
||||||
|
|
||||||
await container.restart();
|
|
||||||
return getContainerResponse(container);
|
|
||||||
});
|
|
||||||
};
|
|
@ -1,12 +0,0 @@
|
|||||||
import type { Container } from "#src/types/Container.ts";
|
|
||||||
import { getContainer, getContainerResponse } from "#src/utils/containers.ts";
|
|
||||||
import type { FastifyInstance, FastifyRequest } from "fastify";
|
|
||||||
|
|
||||||
export default (fastify: FastifyInstance) => {
|
|
||||||
fastify.put("/", async (req: FastifyRequest<{ Params: Container }>) => {
|
|
||||||
const container = getContainer(req.params.id);
|
|
||||||
|
|
||||||
await container.start();
|
|
||||||
return getContainerResponse(container);
|
|
||||||
});
|
|
||||||
};
|
|
@ -1,29 +0,0 @@
|
|||||||
import type { Container } from "#src/types/Container.ts";
|
|
||||||
import { getContainer } from "#src/utils/containers.ts";
|
|
||||||
import type { FastifyInstance, FastifyRequest } from "fastify";
|
|
||||||
|
|
||||||
export default (fastify: FastifyInstance) => {
|
|
||||||
fastify.get(
|
|
||||||
"/",
|
|
||||||
async (req: FastifyRequest<{ Params: Container }>, reply) => {
|
|
||||||
const container = getContainer(req.params.id);
|
|
||||||
|
|
||||||
reply.header("Content-Type", "text/event-stream");
|
|
||||||
reply.header("Cache-Control", "no-cache");
|
|
||||||
reply.header("Connection", "keep-alive");
|
|
||||||
|
|
||||||
const stream = await container.stats({ stream: true });
|
|
||||||
|
|
||||||
if (!stream) {
|
|
||||||
reply.status(500).send("Error fetching stats");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
stream.on("data", (chunk) => {
|
|
||||||
reply.raw.write(`data: ${chunk.toString()}\n\n`);
|
|
||||||
});
|
|
||||||
|
|
||||||
stream.on("end", () => reply.raw.end());
|
|
||||||
return stream;
|
|
||||||
},
|
|
||||||
);
|
|
||||||
};
|
|
@ -1,12 +0,0 @@
|
|||||||
import type { Container } from "#src/types/Container.ts";
|
|
||||||
import { getContainer, getContainerResponse } from "#src/utils/containers.ts";
|
|
||||||
import type { FastifyInstance, FastifyRequest } from "fastify";
|
|
||||||
|
|
||||||
export default (fastify: FastifyInstance) => {
|
|
||||||
fastify.put("/", async (req: FastifyRequest<{ Params: Container }>) => {
|
|
||||||
const container = getContainer(req.params.id);
|
|
||||||
|
|
||||||
await container.stop();
|
|
||||||
return getContainerResponse(container);
|
|
||||||
});
|
|
||||||
};
|
|
@ -1,52 +0,0 @@
|
|||||||
import type { Container } from "#src/types/Container.ts";
|
|
||||||
import { getContainer } from "#src/utils/containers.ts";
|
|
||||||
import type { FastifyInstance, FastifyRequest } from "fastify";
|
|
||||||
import { PassThrough } from "stream";
|
|
||||||
|
|
||||||
export default (fastify: FastifyInstance) => {
|
|
||||||
fastify.get(
|
|
||||||
"/",
|
|
||||||
{ websocket: true },
|
|
||||||
async (connection, req: FastifyRequest<{ Params: Container }>) => {
|
|
||||||
const container = getContainer(req.params.id);
|
|
||||||
|
|
||||||
const exec = await container.exec({
|
|
||||||
Cmd: ["/bin/bash"],
|
|
||||||
AttachStdin: true,
|
|
||||||
AttachStdout: true,
|
|
||||||
AttachStderr: true,
|
|
||||||
Tty: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
const stream = await exec.start({ hijack: true, stdin: true });
|
|
||||||
|
|
||||||
const stdout = new PassThrough();
|
|
||||||
const stderr = new PassThrough();
|
|
||||||
|
|
||||||
container.modem.demuxStream(stream, stdout, stderr);
|
|
||||||
|
|
||||||
connection.on("message", (data: Buffer) => {
|
|
||||||
console.log(new TextDecoder().decode(data));
|
|
||||||
|
|
||||||
if (new TextDecoder().decode(data).startsWith("{")) {
|
|
||||||
const parsed = JSON.parse(data.toString());
|
|
||||||
|
|
||||||
exec.resize({
|
|
||||||
h: parsed.rows,
|
|
||||||
w: parsed.cols,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
stream.write(data);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
stdout.on("data", (chunk) => {
|
|
||||||
connection.send(chunk.toString());
|
|
||||||
});
|
|
||||||
|
|
||||||
stderr.on("data", (chunk) => {
|
|
||||||
connection.send(chunk.toString());
|
|
||||||
});
|
|
||||||
},
|
|
||||||
);
|
|
||||||
};
|
|
@ -1,39 +0,0 @@
|
|||||||
import createContainerSchema from "#src/schemas/createContainerSchema.ts";
|
|
||||||
import type { CreateContainerBody, Container } from "#src/types/Container.ts";
|
|
||||||
import {
|
|
||||||
createContainer,
|
|
||||||
getContainerResponse,
|
|
||||||
getContainers,
|
|
||||||
} from "#src/utils/containers.ts";
|
|
||||||
import type { FastifyInstance, FastifyRequest } from "fastify";
|
|
||||||
|
|
||||||
export default (fastify: FastifyInstance) => {
|
|
||||||
fastify.get("/", async () => {
|
|
||||||
const containers = await getContainers();
|
|
||||||
const containersResponse = [];
|
|
||||||
|
|
||||||
for (const container of containers) {
|
|
||||||
const response = {
|
|
||||||
id: container.Id,
|
|
||||||
name: container.Names[0].slice(1),
|
|
||||||
image: container.Image,
|
|
||||||
status: container.State,
|
|
||||||
} as Omit<Container, "ip">;
|
|
||||||
|
|
||||||
containersResponse.push(response);
|
|
||||||
}
|
|
||||||
|
|
||||||
return containersResponse;
|
|
||||||
});
|
|
||||||
|
|
||||||
fastify.post(
|
|
||||||
"/",
|
|
||||||
{ schema: createContainerSchema },
|
|
||||||
async (req: FastifyRequest<{ Body: CreateContainerBody }>) => {
|
|
||||||
const container = await createContainer({ image: req.body.image });
|
|
||||||
await container.start();
|
|
||||||
|
|
||||||
return getContainerResponse(container);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
};
|
|
@ -1,10 +0,0 @@
|
|||||||
import type { Image } from "#src/types/Image.ts";
|
|
||||||
import { getImage } from "#src/utils/images.ts";
|
|
||||||
import type { FastifyInstance, FastifyRequest } from "fastify";
|
|
||||||
|
|
||||||
export default (fastify: FastifyInstance) => {
|
|
||||||
fastify.get("/", (req: FastifyRequest<{ Params: Image }>) => {
|
|
||||||
const image = getImage(req.params.name);
|
|
||||||
return image.inspect();
|
|
||||||
});
|
|
||||||
};
|
|
@ -1,8 +0,0 @@
|
|||||||
import { getImages } from "#src/utils/images.ts";
|
|
||||||
import type { FastifyInstance, FastifyRequest } from "fastify";
|
|
||||||
|
|
||||||
export default (fastify: FastifyInstance) => {
|
|
||||||
fastify.get("/", () => {
|
|
||||||
return getImages();
|
|
||||||
});
|
|
||||||
};
|
|
@ -1,7 +0,0 @@
|
|||||||
import type { FastifyInstance } from "fastify";
|
|
||||||
|
|
||||||
export default (fastify: FastifyInstance) => {
|
|
||||||
fastify.get("/", () => {
|
|
||||||
return { appName: "code-containers" };
|
|
||||||
});
|
|
||||||
};
|
|
@ -1,13 +0,0 @@
|
|||||||
import type { FastifySchema } from "fastify";
|
|
||||||
|
|
||||||
const createContainerSchema: FastifySchema = {
|
|
||||||
body: {
|
|
||||||
type: "object",
|
|
||||||
properties: {
|
|
||||||
image: { type: "string", minLength: 1 },
|
|
||||||
},
|
|
||||||
required: ["image"],
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export default createContainerSchema;
|
|
@ -1,20 +0,0 @@
|
|||||||
export interface Container {
|
|
||||||
id: string;
|
|
||||||
name: string;
|
|
||||||
image: string;
|
|
||||||
status: string;
|
|
||||||
ip: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface CreateContainerBody {
|
|
||||||
name: string;
|
|
||||||
image: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface RemoveContainerParams {
|
|
||||||
id: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface RemoveContainerQuery {
|
|
||||||
force: string;
|
|
||||||
}
|
|
@ -1,3 +0,0 @@
|
|||||||
export interface Image {
|
|
||||||
name: string;
|
|
||||||
}
|
|
@ -1,44 +0,0 @@
|
|||||||
import type { Container, CreateContainerBody } from "#src/types/Container.ts";
|
|
||||||
import Dockerode from "dockerode";
|
|
||||||
|
|
||||||
const dockerode = new Dockerode();
|
|
||||||
|
|
||||||
export const getContainers = () => {
|
|
||||||
const containers = dockerode.listContainers({
|
|
||||||
filters: { label: ["code-containers.image"] },
|
|
||||||
all: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
return containers;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getContainer = (id: string) => {
|
|
||||||
const container = dockerode.getContainer(id);
|
|
||||||
return container;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const createContainer = ({ name, image }: CreateContainerBody) => {
|
|
||||||
const container = dockerode.createContainer({
|
|
||||||
name,
|
|
||||||
Image: `code-containers/${image}`,
|
|
||||||
Labels: {
|
|
||||||
"code-containers.image": image,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
return container;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getContainerResponse = async (container: Dockerode.Container) => {
|
|
||||||
const inspect = await container.inspect();
|
|
||||||
|
|
||||||
const response = {
|
|
||||||
id: inspect.Id,
|
|
||||||
name: inspect.Name.slice(1),
|
|
||||||
image: inspect.Config.Image,
|
|
||||||
status: inspect.State.Status,
|
|
||||||
ip: inspect.NetworkSettings.Networks.bridge.IPAddress,
|
|
||||||
} as Container;
|
|
||||||
|
|
||||||
return response;
|
|
||||||
};
|
|
@ -1,16 +0,0 @@
|
|||||||
import Dockerode from "dockerode";
|
|
||||||
|
|
||||||
const dockerode = new Dockerode();
|
|
||||||
|
|
||||||
export const getImages = () => {
|
|
||||||
const images = dockerode.listImages({
|
|
||||||
filters: { reference: ["code-containers/*"] },
|
|
||||||
});
|
|
||||||
|
|
||||||
return images;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getImage = (name: string) => {
|
|
||||||
const image = dockerode.getImage(`code-containers/${name}`);
|
|
||||||
return image;
|
|
||||||
};
|
|
Loading…
x
Reference in New Issue
Block a user