libretime/easypanel/update.js
Cesar Jhoanny Mendivil Rubio 697b7cc288
Some checks are pending
Container / meta (analyzer) (push) Waiting to run
Container / meta (api) (push) Waiting to run
Container / meta (legacy) (push) Waiting to run
Container / meta (nginx) (push) Waiting to run
Container / meta (playout) (push) Waiting to run
Container / meta (worker) (push) Waiting to run
Container / build (push) Blocked by required conditions
Project / pre-commit (push) Waiting to run
Project / test-tools (push) Waiting to run
Release-Please / release-please (push) Waiting to run
feat(easypanel): actualizar configuración y scripts de EasyPanel, incluyendo mejoras en la generación de contraseñas, sincronización de herramientas y gestión de configuraciones
2025-10-01 17:41:20 -07:00

115 lines
3.9 KiB
JavaScript
Executable File

#!/usr/bin/env node
"use strict";
// update.js - script de utilidad para EasyPanel
// Copia docker-compose.easypanel.yml a ./code/docker-compose.yml y elimina
// container_name y ports para que EasyPanel gestione nombres y puertos.
const fs = require('fs');
const path = require('path');
const SRC = path.resolve(__dirname, '../docker-compose.easypanel.yml');
const DEST_DIR = path.resolve(__dirname, './code');
const DEST = path.join(DEST_DIR, 'docker-compose.yml');
// Variables secret requeridas para evitar despliegues con valores vacíos
const REQUIRED_SECRETS = ['POSTGRES_PASSWORD', 'RABBITMQ_DEFAULT_PASS'];
function parseEnvFile(filePath) {
const out = {};
if (!fs.existsSync(filePath)) return out;
const raw = fs.readFileSync(filePath, 'utf8');
raw.split(/\n/).forEach(line => {
line = line.trim();
if (!line || line.startsWith('#')) return;
const m = line.match(/^([A-Za-z_][A-Za-z0-9_]*)=(.*)$/);
if (m) {
let val = m[2];
// strip optional quotes
if ((val.startsWith("\'") && val.endsWith("\'")) || (val.startsWith('"') && val.endsWith('"'))) {
val = val.slice(1, -1);
}
out[m[1]] = val;
}
});
return out;
}
function validateRequiredSecrets() {
const envFilePath = path.join(__dirname, 'service.env');
const fileEnv = parseEnvFile(envFilePath);
const missing = [];
REQUIRED_SECRETS.forEach(k => {
const v = (process.env[k] || '').trim() || (fileEnv[k] || '').trim();
// treat obvious placeholders as missing
if (!v || /^\s*(CAMBIA|pon_aqui|tu_|CHANGE|REPLACE)/i.test(v)) {
missing.push(k);
}
});
if (missing.length) {
console.error('ERROR: faltan valores seguros para las siguientes variables:', missing.join(', '));
console.error('Asegúrate de definirlas en la sección Environment/Secrets de EasyPanel o en', envFilePath);
console.error('Variables requeridas:', REQUIRED_SECRETS.join(', '));
process.exit(2);
}
}
function removeContainerNamesAndPorts(content) {
// Eliminar container_name: <valor> líneas
content = content.replace(/^[ \t]*container_name:[^\n]*\n/gm, '');
// Eliminar version: ... para evitar advertencias en EasyPanel
content = content.replace(/^[ \t]*version:[^\n]*\n/gm, '');
// Eliminar bloques de ports:
// ports:\n - "..."\n - ...
content = content.replace(/^[ \t]*ports:[^\n]*\n(?:^[ \t]+-.*\n)*/gim, '');
return content;
}
async function main() {
// Validar secretos antes de generar el compose final
validateRequiredSecrets();
if (!fs.existsSync(SRC)) {
console.error('ERROR: no se encuentra', SRC);
process.exit(2);
}
if (!fs.existsSync(DEST_DIR)) fs.mkdirSync(DEST_DIR, { recursive: true });
const raw = fs.readFileSync(SRC, 'utf8');
const sanitized = removeContainerNamesAndPorts(raw);
fs.writeFileSync(DEST, sanitized, 'utf8');
// Copy tools/ into code/ so relative mounts like ./tools work in the generated compose
const toolsSrc = path.resolve(__dirname, '../tools');
const toolsDest = path.resolve(DEST_DIR, 'tools');
try {
if (fs.existsSync(toolsSrc)) {
// remove existing dest if any
if (fs.existsSync(toolsDest)) {
fs.rmSync(toolsDest, { recursive: true, force: true });
}
// copy recursively
const { spawnSync } = require('child_process');
const res = spawnSync('cp', ['-a', toolsSrc, toolsDest]);
if (res.status !== 0) {
console.warn('warning: failed to copy tools directory to code/:', res.stderr && res.stderr.toString());
}
}
} catch (err) {
console.warn('warning copying tools:', err && err.message);
}
// Asegurar permisos ejecutables para scripts .sh dentro de code/tools
try {
const { spawnSync } = require('child_process');
spawnSync('find', [path.join(DEST_DIR, 'tools'), '-type', 'f', '-iname', '*.sh', '-exec', 'chmod', '0755', '{}', ';']);
} catch (e) {
// ignore
}
console.log('Preparado', DEST);
}
main().catch(err => {
console.error(err);
process.exit(1);
});