Merge branch 'develop' into feat/system-metrics
# Conflicts: # pages/index.vue
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { exec } from "node:child_process"
|
||||
import { execFile } from "node:child_process"
|
||||
import scripts from "../config/backup-script.json"
|
||||
|
||||
type BackupScript = {
|
||||
@@ -6,11 +6,12 @@ type BackupScript = {
|
||||
label: string
|
||||
downloadFolders?: string[]
|
||||
command: string
|
||||
args?: string[]
|
||||
}
|
||||
|
||||
function runCommand(command: string): Promise<string> {
|
||||
function runCommand(command: string, args: string[] = []): Promise<string> {
|
||||
return new Promise((resolve, reject) => {
|
||||
exec(command, { timeout: 10 * 60 * 1000 }, (error, stdout, stderr) => {
|
||||
execFile(command, args, { timeout: 10 * 60 * 1000 }, (error, stdout, stderr) => {
|
||||
if (error) {
|
||||
reject(stderr || error.message)
|
||||
return
|
||||
@@ -40,7 +41,7 @@ export default defineEventHandler(async (event) => {
|
||||
}
|
||||
|
||||
try {
|
||||
const output = await runCommand(script.command)
|
||||
const output = await runCommand(script.command, script.args || [])
|
||||
return {
|
||||
ok: true,
|
||||
key: script.key,
|
||||
@@ -49,9 +50,11 @@ export default defineEventHandler(async (event) => {
|
||||
output: output.trim()
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Erreur execution script:", error)
|
||||
|
||||
throw createError({
|
||||
statusCode: 500,
|
||||
statusMessage: `Erreur execution script: ${String(error)}`
|
||||
statusMessage: "Erreur lors de l'opération"
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { execFile } from "node:child_process"
|
||||
import folderMap from "../config/backup-folders.json"
|
||||
|
||||
const REMOTE_HOST = process.env.BACKUPS_REMOTE_HOST || "malio-b"
|
||||
const REMOTE_ROOT = process.env.BACKUPS_REMOTE_ROOT || "/home/malio-b/backups"
|
||||
const MAX_FILES_PER_FOLDER = Number(process.env.BACKUPS_MAX_FILES || "200")
|
||||
const REMOTE_HOST = process.env.BACKUPS_REMOTE_HOST
|
||||
const REMOTE_ROOT = process.env.BACKUPS_REMOTE_ROOT
|
||||
const MAX_FILES_PER_FOLDER = Number(process.env.BACKUPS_MAX_FILES)
|
||||
const isSafeFolder = (value: string) => /^[a-zA-Z0-9._-]+$/.test(value)
|
||||
const shellQuote = (value: string) => `'${value.replace(/'/g, `'\\''`)}'`
|
||||
const FOLDER_MAP = folderMap as Record<string, string>
|
||||
@@ -31,9 +31,11 @@ function isMissingPathError(error: unknown): boolean {
|
||||
}
|
||||
|
||||
function toServerError(error: unknown) {
|
||||
console.error("Erreur backups:", error)
|
||||
|
||||
return createError({
|
||||
statusCode: 500,
|
||||
statusMessage: `Erreur SSH backups: ${String(error)}`
|
||||
statusMessage: "Erreur lors de l'opération"
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -1,15 +1,31 @@
|
||||
export default defineEventHandler(async () => {
|
||||
const token = process.env.DISCORD_BOT_TOKEN
|
||||
const channel = process.env.DISCORD_CHANNEL_ID
|
||||
const token = process.env.DISCORD_BOT_TOKEN
|
||||
const channel = process.env.DISCORD_CHANNEL_ID
|
||||
|
||||
if (!token || !channel) {
|
||||
throw createError({
|
||||
statusCode: 503,
|
||||
statusMessage: "Service indisponible"
|
||||
})
|
||||
}
|
||||
|
||||
try {
|
||||
const messages = await $fetch(
|
||||
`https://discord.com/api/v10/channels/${channel}/messages?limit=20`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bot ${token}`
|
||||
}
|
||||
`https://discord.com/api/v10/channels/${channel}/messages?limit=20`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bot ${token}`
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
return messages
|
||||
})
|
||||
} catch (error) {
|
||||
console.error("Erreur Discord messages:", error)
|
||||
|
||||
throw createError({
|
||||
statusCode: 500,
|
||||
statusMessage: "Erreur lors de l'opération"
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1,21 +1,34 @@
|
||||
import { exec } from "child_process"
|
||||
import { exec, execFile } from "child_process"
|
||||
import diskSources from "../config/disk-commands.json"
|
||||
|
||||
type DiskSource = {
|
||||
key: string
|
||||
label: string
|
||||
command: string
|
||||
args?: string[]
|
||||
}
|
||||
|
||||
function getCommand(source: DiskSource) {
|
||||
function getEnvCommand(source: DiskSource) {
|
||||
const envKey = `DISK_COMMAND_${source.key.toUpperCase()}`
|
||||
const legacyEnvKey =
|
||||
source.key === "remote" ? "DISK_REMOTE_COMMAND" : source.key === "local" ? "DISK_LOCAL_COMMAND" : ""
|
||||
|
||||
return process.env[envKey] || (legacyEnvKey ? process.env[legacyEnvKey] : undefined) || source.command
|
||||
return process.env[envKey] || (legacyEnvKey ? process.env[legacyEnvKey] : undefined) || null
|
||||
}
|
||||
|
||||
function runCommand(command: string): Promise<string> {
|
||||
function runCommand(command: string, args: string[] = []): Promise<string> {
|
||||
return new Promise((resolve, reject) => {
|
||||
execFile(command, args, (error, stdout, stderr) => {
|
||||
if (error) {
|
||||
reject(stderr || error.message)
|
||||
return
|
||||
}
|
||||
resolve(stdout)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function runShellCommand(command: string): Promise<string> {
|
||||
return new Promise((resolve, reject) => {
|
||||
exec(command, (error, stdout, stderr) => {
|
||||
if (error) {
|
||||
@@ -31,7 +44,10 @@ export default defineEventHandler(async () => {
|
||||
const results = await Promise.all(
|
||||
(diskSources as DiskSource[]).map(async (source) => {
|
||||
try {
|
||||
const output = await runCommand(getCommand(source))
|
||||
const envCommand = getEnvCommand(source)
|
||||
const output = envCommand
|
||||
? await runShellCommand(envCommand)
|
||||
: await runCommand(source.command, source.args || [])
|
||||
return {
|
||||
key: source.key,
|
||||
label: source.label,
|
||||
@@ -39,11 +55,12 @@ export default defineEventHandler(async () => {
|
||||
output
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`Erreur disk source ${source.key}:`, error)
|
||||
return {
|
||||
key: source.key,
|
||||
label: source.label,
|
||||
ok: false,
|
||||
output: `Erreur: ${String(error)}`
|
||||
output: "Erreur lors de l'opération"
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@@ -7,7 +7,7 @@ const REMOTE_ROOT = process.env.BACKUPS_REMOTE_ROOT || "/home/malio-b/backups"
|
||||
const FOLDER_MAP = folderMap as Record<string, string>
|
||||
|
||||
const isSafeFolder = (value: string) => /^[a-zA-Z0-9._-]+$/.test(value)
|
||||
const isSafeFile = (value: string) => /^[^/\\]+$/.test(value)
|
||||
const isSafeFile = (value: string) => /^[a-zA-Z0-9._-]+$/.test(value)
|
||||
const shellQuote = (value: string) => `'${value.replace(/'/g, `'\\''`)}'`
|
||||
|
||||
function runSsh(command: string): Promise<string> {
|
||||
@@ -56,7 +56,7 @@ function buildContentDisposition(fileName: string) {
|
||||
return `attachment; filename="${asciiName}"; filename*=UTF-8''${encodeURIComponent(fileName)}`
|
||||
}
|
||||
|
||||
function speedtestStream(event: any) {
|
||||
function speedtestStream(event: H3Event) {
|
||||
const size = 128 * 1024 * 1024
|
||||
let sent = 0
|
||||
|
||||
|
||||
Reference in New Issue
Block a user