Feature/ssh cmd (#94)

* feat: Add SSH remote script support -  before and after rsync

* fix: remove __dirname

* feat: add sshCmdArgs option

* Add promise instead of callback

* fix: improve logs

* fix: Add simple command exists instead of a plugin

* add non interactive install

* feat: add onStderr and onStdout logs

* Improve reject messages

* feat: Add RSYNC_STDOUT env variable

* emoji updates

* fix: update workflow actions
This commit is contained in:
Dragan Filipović
2023-01-02 21:06:33 +01:00
committed by GitHub
parent a5d8edb941
commit ec9347f8c6
17 changed files with 373 additions and 242 deletions

View File

@@ -1,46 +1,76 @@
const { sync: commandExists } = require("command-exists");
const { exec, execSync } = require("child_process");
const { execSync } = require('child_process');
const nodeRsync = require('rsyncwrapper');
const validateRsync = (callback = () => {}) => {
const rsyncCli = commandExists("rsync");
if (rsyncCli) {
console.log('⚠️ [CLI] Rsync exists');
const rsyncVersion = execSync("rsync --version", { stdio: 'inherit' });
return callback();
const nodeRsyncPromise = async (config) => new Promise((resolve, reject) => {
try {
nodeRsync(config, (error, stdout, stderr, cmd) => {
if (error) {
console.error('❌ [Rsync] error: ');
console.error(error);
console.error('❌ [Rsync] stderr: ');
console.error(stderr);
console.error('❌️ [Rsync] stdout: ');
console.error(stdout);
console.error('❌ [Rsync] cmd: ', cmd);
reject(new Error(`${error.message}\n\n${stderr}`));
} else {
resolve(stdout);
}
});
} catch (error) {
console.error('❌ [Rsync] command error: ', error.message, error.stack);
reject(error);
}
});
const validateRsync = async () => {
try {
execSync('rsync --version', { stdio: 'inherit' });
console.log('✅️ [CLI] Rsync exists');
return;
} catch (error) {
console.warn('⚠️ [CLI] Rsync doesn\'t exists', error.message);
}
console.log('⚠️ [CLI] Rsync doesn\'t exists. Start installation with "apt-get" \n');
console.log('[CLI] Start rsync installation with "apt-get" \n');
try {
execSync('sudo DEBIAN_FRONTEND=noninteractive apt-get -y update && sudo DEBIAN_FRONTEND=noninteractive apt-get --no-install-recommends -y install rsync', { stdio: 'inherit' });
console.log('✅ [CLI] Rsync installed. \n');
} catch (error) {
throw new Error(`⚠️ [CLI] Rsync installation failed. Aborting ... error: ${error.message}`);
}
};
exec("sudo apt-get update && sudo apt-get --no-install-recommends install rsync", (err, data, stderr) => {
if (err) {
console.log("⚠️ [CLI] Rsync installation failed. Aborting ... ", err.message);
process.abort();
} else {
console.log("✅ [CLI] Rsync installed. \n", data, stderr);
callback();
}
const rsyncCli = async ({
source, rsyncServer, exclude, remotePort,
privateKeyPath, args, sshCmdArgs
}) => {
console.log(`[Rsync] Starting Rsync Action: ${source} to ${rsyncServer}`);
if (exclude) console.log(`[Rsync] excluding folders ${exclude}`);
const defaultOptions = {
ssh: true,
recursive: true
};
// RSYNC COMMAND
/* eslint-disable object-property-newline */
return nodeRsyncPromise({
...defaultOptions,
src: source, dest: rsyncServer, excludeFirst: exclude, port: remotePort,
privateKey: privateKeyPath, args, sshCmdArgs,
onStdout: (data) => console.log(data), onStderr: (data) => console.error(data)
});
};
const validateInputs = (inputs) => {
const inputKeys = Object.keys(inputs);
const validInputs = inputKeys.filter((inputKey) => {
const inputValue = inputs[inputKey];
if (!inputValue) {
console.error(`⚠️ [INPUTS] ${inputKey} is mandatory`);
}
return inputValue;
});
if (validInputs.length !== inputKeys.length) {
console.error("⚠️ [INPUTS] Inputs not valid, aborting ...");
process.abort();
}
const sshDeploy = async (params) => {
await validateRsync();
const stdout = await rsyncCli(params);
console.log('✅ [Rsync] finished.', stdout);
process.env.RSYNC_STDOUT = `${stdout}`;
return stdout;
};
module.exports = {
validateRsync,
validateInputs,
sshDeploy
};