@porosys/pss
Version:
Porosys Server Setup (pss): General-purpose server setup and automation tool (including Netdata management)
90 lines (79 loc) • 2.89 kB
text/typescript
import path from 'path';
import fsExtra from 'fs-extra';
import { execa } from 'execa';
import { input } from '@inquirer/prompts';
import { isCronJobPresent } from '../../../../utils/is-cron-job-present.util';
import { isBinaryInstalled } from '../../../../utils/is-binary-installed.util';
import { installBinary } from '../../../../utils/install-binary.util';
import { isDependencyCustom } from '../../../../types';
import { SetupAlertArgs } from './setup-alert.type';
const { writeFileSync, mkdirSync, existsSync, readFileSync } = fsExtra;
export async function setupAlert({
alertName,
dependencies,
templates,
cronScriptPath,
healthdPath,
healthScriptsPath,
checkFiles,
}: SetupAlertArgs) {
try {
if (!healthdPath || !healthScriptsPath) {
throw new Error(
'healthdPath and healthScriptsPath must be set in config before calling setupAlert.',
);
}
const isAlertSetup = async (): Promise<boolean> =>
checkFiles.every((file) => existsSync(file)) &&
isCronJobPresent(cronScriptPath);
for (const dep of dependencies) {
if (isDependencyCustom(dep)) {
await dep.install();
} else if (!(await isBinaryInstalled(dep.binary))) {
await installBinary(dep.binary, dep.packageName);
}
}
if (await isAlertSetup()) {
const shouldResetupInput = await input({
message: `⚠️ ${alertName} alert is already set up. Do you want to re-setup it? (y/N): `,
});
const shouldResetup = /^y(es)?$/i.test(shouldResetupInput.trim());
if (!shouldResetup) {
console.log('❌ Setup cancelled by user.');
process.exit(0);
}
}
// Ensure directories exist
templates.forEach(({ destinationPath }) => {
mkdirSync(path.dirname(destinationPath), { recursive: true });
});
mkdirSync(healthdPath, { recursive: true });
// Write all templates
for (const {
templatePath,
destinationPath,
replacements,
mode,
} of templates) {
let content = readFileSync(templatePath, 'utf-8');
for (const [key, value] of Object.entries(replacements)) {
content = content.replace(new RegExp(key, 'g'), value);
}
writeFileSync(destinationPath, content, mode ? { mode } : undefined);
}
console.log(`✅ ${alertName} alert setup completed.`);
if (!(await isCronJobPresent(cronScriptPath))) {
const cronJob = `* * * * * ${cronScriptPath}`; // every minute
await execa(`(crontab -l 2>/dev/null; echo "${cronJob}") | crontab -`, {
shell: true,
stdio: 'inherit',
});
console.log(`✅ Cron job for ${alertName} setup successfully.`);
} else {
console.log(`ℹ️ Cron job for ${alertName} already exists.`);
}
} catch (err) {
console.error(`❌ Failed to set up ${alertName} alert:`, err);
process.exit(1);
}
}