Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: Remove shelljs from more appsmithctl commands #37383

Merged
merged 2 commits into from
Nov 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 8 additions & 15 deletions deploy/docker/fs/opt/appsmith/utils/bin/backup.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,7 @@ async function run() {
let backupRootPath, archivePath, encryptionPassword;
let encryptArchive = false;

try {
await utils.execCommandSilent(["/usr/bin/supervisorctl"]);
} catch (e) {
console.error('Supervisor is not running, exiting.');
process.exitCode = 1;
return;
}
await utils.ensureSupervisorIsRunning();

try {
console.log('Available free space at /appsmith-stacks');
Expand All @@ -31,7 +25,7 @@ async function run() {

checkAvailableBackupSpace(availSpaceInBytes);

const backupRootPath = await generateBackupRootPath();
backupRootPath = await generateBackupRootPath();
const backupContentsPath = getBackupContentsPath(backupRootPath, timestamp);

await fsPromises.mkdir(backupContentsPath);
Expand All @@ -51,17 +45,17 @@ async function run() {
}
await exportDockerEnvFile(backupContentsPath, encryptArchive);

const archivePath = await createFinalArchive(backupRootPath, timestamp);
archivePath = await createFinalArchive(backupRootPath, timestamp);
// shell.exec("openssl enc -aes-256-cbc -pbkdf2 -iter 100000 -in " + archivePath + " -out " + archivePath + ".enc");
if (encryptArchive){
const encryptedArchivePath = await encryptBackupArchive(archivePath,encryptionPassword);
logger.backup_info('Finished creating an encrypted a backup archive at ' + encryptedArchivePath);
await logger.backup_info('Finished creating an encrypted a backup archive at ' + encryptedArchivePath);
if (archivePath != null) {
await fsPromises.rm(archivePath, { recursive: true, force: true });
}
}
else {
logger.backup_info('Finished creating a backup archive at ' + archivePath);
await logger.backup_info('Finished creating a backup archive at ' + archivePath);
console.log('********************************************************* IMPORTANT!!! *************************************************************');
console.log('*** Please ensure you have saved the APPSMITH_ENCRYPTION_SALT and APPSMITH_ENCRYPTION_PASSWORD variables from the docker.env file **')
console.log('*** These values are not included in the backup export. **');
Expand All @@ -70,7 +64,7 @@ async function run() {

await fsPromises.rm(backupRootPath, { recursive: true, force: true });

logger.backup_info('Finished taking a backup at ' + archivePath);
await logger.backup_info('Finished taking a backup at ' + archivePath);

} catch (err) {
errorCode = 1;
Expand Down Expand Up @@ -194,9 +188,8 @@ function getGitRoot(gitRoot) {
return gitRoot
}

async function generateBackupRootPath() {
const backupRootPath = await fsPromises.mkdtemp(path.join(os.tmpdir(), 'appsmithctl-backup-'));
return backupRootPath
function generateBackupRootPath() {
return fsPromises.mkdtemp(path.join(os.tmpdir(), 'appsmithctl-backup-'));
}

function getBackupContentsPath(backupRootPath, timestamp) {
Expand Down
1 change: 0 additions & 1 deletion deploy/docker/fs/opt/appsmith/utils/bin/backup.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ it('Should not hould throw Error when the available size is >= MIN_REQUIRED_DISK
it('Generates t', async () => {
os.tmpdir = jest.fn().mockReturnValue('temp/dir');
fsPromises.mkdtemp = jest.fn().mockImplementation((a) => a);
backup.generateBackupRootPath().then((response)=>{console.log(response)})
const res = await backup.generateBackupRootPath()
expect(res).toBe('temp/dir/appsmithctl-backup-')
});
Expand Down
73 changes: 28 additions & 45 deletions deploy/docker/fs/opt/appsmith/utils/bin/export_db.js
Original file line number Diff line number Diff line change
@@ -1,66 +1,49 @@
// Init function export mongodb
const shell = require('shelljs');
const fsPromises = require("fs/promises");
const Constants = require('./constants');
const utils = require('./utils');

function export_database() {
async function exportDatabase() {
console.log('export_database ....');
dbUrl = utils.getDburl();
shell.mkdir('-p', [Constants.BACKUP_PATH]);
const cmd = `mongodump --uri='${dbUrl}' --archive='${Constants.BACKUP_PATH}/${Constants.DUMP_FILE_NAME}' --gzip`;
shell.exec(cmd);
const dbUrl = utils.getDburl();
await fsPromises.mkdir(Constants.BACKUP_PATH, { recursive: true });
await utils.execCommand([
"mongodump",
"--uri=" + dbUrl,
`--archive=${Constants.BACKUP_PATH}/${Constants.DUMP_FILE_NAME}`,
"--gzip",
])
console.log('export_database done');
}

function stop_application() {
console.log('stop_application ....');
shell.exec('/usr/bin/supervisorctl stop backend rts');
console.log('stop_application done');
}
async function run() {
let errorCode = 0;

function start_application() {
console.log('start_application ....');
shell.exec('/usr/bin/supervisorctl start backend rts');
console.log('start_application done');
}
await utils.ensureSupervisorIsRunning();

// Main application workflow
function run() {
let errorCode = 0;
try {
check_supervisord_status_cmd = '/usr/bin/supervisorctl >/dev/null 2>&1 ';
shell.exec(check_supervisord_status_cmd, function (code) {
if (code > 0) {
shell.echo('application is not running, starting supervisord');
shell.exec('/usr/bin/supervisord');
}
});

shell.echo('stop backend & rts application before export database');
stop_application();
export_database();
shell.echo('start backend & rts application after export database');
shell.echo();
shell.echo('\033[0;33m++++++++++++++++++++ NOTE ++++++++++++++++++++');
shell.echo();
shell.echo(
console.log('stop backend & rts application before export database');
await utils.stop(["backend", "rts"]);
await exportDatabase();
console.log('start backend & rts application after export database');
console.log();
console.log('\033[0;33m++++++++++++++++++++ NOTE ++++++++++++++++++++');
console.log();
console.log(
'Please remember to also copy APPSMITH_ENCRYPTION_SALT and APPSMITH_ENCRYPTION_PASSWORD variables from the docker.env file to the target instance where you intend to import this database dump.',
);
shell.echo();
shell.echo('++++++++++++++++++++++++++++++++++++++++++++++\033[0m');
shell.echo();
console.log();
console.log('++++++++++++++++++++++++++++++++++++++++++++++\033[0m');
console.log();
} catch (err) {
shell.echo(err);
console.log(err);
errorCode = 1;
} finally {
start_application();
await utils.start(["backend", "rts"]);
process.exit(errorCode);
}
}

module.exports = {
run,
exportDatabase: export_database,
stopApplication: stop_application,
startApplication: start_application,
};
exportDatabase,
};
18 changes: 9 additions & 9 deletions deploy/docker/fs/opt/appsmith/utils/bin/import_db.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@ const main = (forceOption) => {
check_supervisord_status_cmd = '/usr/bin/supervisorctl'
shell.exec(check_supervisord_status_cmd, function (code) {
if (code > 0) {
shell.echo('application is not running, starting supervisord')
console.log('application is not running, starting supervisord')
shell.exec('/usr/bin/supervisord')
}
})

shell.echo('stop backend & rts application before import database')
console.log('stop backend & rts application before import database')
stop_application()
const shellCmdResult = shell.exec(`mongo ${process.env.APPSMITH_DB_URL} --quiet --eval "db.getCollectionNames().length"`)
const collectionsLen = parseInt(shellCmdResult.stdout.toString().trimEnd())
Expand All @@ -44,9 +44,9 @@ const main = (forceOption) => {
import_database()
return
}
shell.echo()
shell.echo('**************************** WARNING ****************************')
shell.echo(`Your target database is not empty, it has data in ${collectionsLen} collections.`)
console.log()
console.log('**************************** WARNING ****************************')
console.log(`Your target database is not empty, it has data in ${collectionsLen} collections.`)
const input = readlineSync.question('Importing this DB will erase this data. Are you sure you want to proceed?[Yes/No] ')
const answer = input && input.toLocaleUpperCase()
if (answer === 'Y' || answer === 'YES') {
Expand All @@ -55,22 +55,22 @@ const main = (forceOption) => {
} else if (answer === 'N' || answer === 'NO') {
return
}
shell.echo(`Your input is invalid. Please try to run import command again.`)
console.log(`Your input is invalid. Please try to run import command again.`)
return
} else {
import_database()
return
}
} catch (err) {
shell.echo(err)
console.log(err)
errorCode = 1
} finally {
shell.echo('start backend & rts application after import database')
console.log('start backend & rts application after import database')
start_application()
process.exit(errorCode)
}
Comment on lines +65 to 71
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Improve error handling in finally block

The error handling and application restart logic could be more robust.

   } catch (err) {
-    console.log(err)
+    console.error('Import failed:', err)
     errorCode = 1
   } finally {
-    console.log('start backend & rts application after import database')
-    start_application()
-    process.exit(errorCode)
+    try {
+      console.log('Restarting applications...')
+      start_application()
+      console.log('Applications restarted successfully')
+    } catch (error) {
+      console.error('Failed to restart applications:', error)
+      errorCode = 1
+    } finally {
+      process.exit(errorCode)
+    }
   }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
console.log(err)
errorCode = 1
} finally {
shell.echo('start backend & rts application after import database')
console.log('start backend & rts application after import database')
start_application()
process.exit(errorCode)
}
console.error('Import failed:', err)
errorCode = 1
} finally {
try {
console.log('Restarting applications...')
start_application()
console.log('Applications restarted successfully')
} catch (error) {
console.error('Failed to restart applications:', error)
errorCode = 1
} finally {
process.exit(errorCode)
}
}

}

module.exports = {
runImportDatabase: main,
}
}
6 changes: 1 addition & 5 deletions deploy/docker/fs/opt/appsmith/utils/bin/mailer.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
const nodemailer = require('nodemailer');
const shell = require('shelljs');


const Constants = require('./constants');
const utils = require('./utils');
const logger = require('./logger');
Expand Down Expand Up @@ -66,10 +63,9 @@ async function sendBackupErrorToAdmins(err, backupTimestamp) {
}
} catch (err) {
await logger.backup_error(err.stack);
return;
}
}

module.exports = {
sendBackupErrorToAdmins,
};
};
16 changes: 5 additions & 11 deletions deploy/docker/fs/opt/appsmith/utils/bin/restore.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ const path = require('path');
const os = require('os');
const readlineSync = require('readline-sync');

const shell = require('shelljs');

const utils = require('./utils');
const Constants = require('./constants');
const command_args = process.argv.slice(3);
Expand Down Expand Up @@ -174,14 +172,10 @@ async function run() {
let cleanupArchive = false;
let overwriteEncryptionKeys = true;
let backupFilePath;
try {
shell.exec('/usr/bin/supervisorctl >/dev/null 2>&1', function (code) {
if (code > 0) {
shell.echo('application is not running, starting supervisord');
shell.exec('/usr/bin/supervisord');
}
});

await utils.ensureSupervisorIsRunning();

try {
let backupFileName = await getBackupFileName();
if (backupFileName == null) {
process.exit(errorCode);
Expand Down Expand Up @@ -209,7 +203,7 @@ async function run() {

console.log('****************************************************************');
console.log('Restoring Appsmith instance from the backup at ' + backupFilePath);
utils.stop(['backend', 'rts']);
await utils.stop(["backend", "rts"]);
await restoreDatabase(restoreContentsPath, utils.getDburl());
await restoreDockerEnvFile(restoreContentsPath, backupName, overwriteEncryptionKeys);
await restoreGitStorageArchive(restoreContentsPath, backupName);
Expand All @@ -224,7 +218,7 @@ async function run() {
if (cleanupArchive){
await fsPromises.rm(backupFilePath, { force: true });
}
utils.start(['backend', 'rts']);
await utils.start(["backend", "rts"]);
process.exit(errorCode);

}
Expand Down
31 changes: 19 additions & 12 deletions deploy/docker/fs/opt/appsmith/utils/bin/utils.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
const shell = require("shelljs");
const fsPromises = require("fs/promises");
const Constants = require("./constants");
const childProcess = require("child_process");
Expand All @@ -18,18 +17,25 @@ function showHelp() {
console.log("\t--help\t\t\t" + "Show help.");
}

function stop(apps) {
const appsStr = apps.join(" ");
console.log("Stopping " + appsStr);
shell.exec("/usr/bin/supervisorctl stop " + appsStr);
console.log("Stopped " + appsStr);
async function ensureSupervisorIsRunning() {
try {
await execCommandSilent(["/usr/bin/supervisorctl"]);
} catch (e) {
console.error('Supervisor is not running, exiting.');
throw e;
}
}

async function stop(apps) {
console.log("Stopping", apps);
await execCommand(["/usr/bin/supervisorctl", "stop", ...apps]);
console.log("Stopped", apps);
}

function start(apps) {
const appsStr = apps.join(" ");
console.log("Starting " + appsStr);
shell.exec("/usr/bin/supervisorctl start " + appsStr);
console.log("Started " + appsStr);
async function start(apps) {
console.log("Starting", apps);
await execCommand(["/usr/bin/supervisorctl", "start", ...apps]);
console.log("Started", apps);
}

function getDburl() {
Expand Down Expand Up @@ -186,6 +192,7 @@ function getDatabaseNameFromMongoURI(uri) {

module.exports = {
showHelp,
ensureSupervisorIsRunning,
start,
stop,
execCommand,
Expand All @@ -196,5 +203,5 @@ module.exports = {
preprocessMongoDBURI,
execCommandSilent,
getDatabaseNameFromMongoURI,
getDburl
getDburl,
};
Loading