Compare commits

...

2 Commits

Author SHA1 Message Date
Anthony 2e6d6d748f Created main JPS 2024-03-05 01:31:33 +08:00
Anthony 443f0deb85 Update Install Restic Checks 2024-02-29 21:35:12 +08:00
2 changed files with 301 additions and 74 deletions

View File

@ -14,39 +14,70 @@ targetNodes:
- llsmp
settings:
backup:
main:
fields:
- type: checkbox
name: enableScheduledBackup
caption: Enable Scheduled Backup
default: false
- type: list
name: backupSchedule
caption: Backup Schedule
required: true
dependsOn: enableScheduledBackup:true
- type: radio-fieldset
name: scheduleType
hidden: false
default: '1'
values:
- value: daily
caption: Daily
- value: weekly
caption: Weekly
- value: monthly
caption: Monthly
- value: custom
caption: Custom
showIf: enableScheduledBackup:true
- type: string
name: customCron
caption: Custom Cron Schedule
dependsOn: backupSchedule:custom
showIf: backupSchedule:custom
- value: 1
caption: Pre-defined
showIf:
1:
- name: cronTime
caption: Backup schedule
type: list
editable: false
values:
- value: 0 * * * *
caption: "Hourly (at minute 0)"
- value: 0 0 * * *
caption: "Daily (at 00:00)"
- value: 0 0 * * 0
caption: "Weekly (at 00:00 on Sunday)"
- value: 0 0 1 * *
caption: "Monthly (at 00:00 on day 1)"
default: 0 0 * * *
- caption: Backup storage
type: list
tooltip: "The environment with backup storage to be used for backups creation. Presence of this environment is obligatory."
name: storageName
dependsOn: region
required: true
- type: spinner
name: backupRetentionCount
caption: Number of Backups to Retain
default: 5
name: backupCount
caption: Number of backups
tooltip: "The number of newest backups to be kept during rotation."
min: 1
max: 30
tooltip: "The number of newest backups to be kept during rotation."
default: 5
onBeforeInit: scripts/configOnBeforeInit.js
restore:
fields: []
onBeforeInit: scripts/multipleRestoreOnBeforeInit.js
onBeforeInit: scripts/backupOnBeforeInit.js
buttons:
- caption: Backup Now
action: backup
loadingText: Backing up...
confirmText: Do you want to initiate the backup process?
successText: The backup process has been finished successfully.
- caption: Restore
action: restore
loadingText: Restoring...
settings: restore
successText: The backup have been successfully restored.
title: Restore Backup
submitButtonText: Restore
confirmText: You are going to restore from a backup, which will override all your existing data. This action cannot be canceled or reverted. Do you want to proceed?
globals:
scriptSufix: wp-backup
onInstall:
- checkApplication
@ -54,19 +85,50 @@ onInstall:
- installRestic
- setSchedule
onUninstall:
- callScript: uninstall
- removeScript
onBeforeDelete:
- callScript: uninstall
- removeScript
onAfterRedeployContainer[cp]:
- installRestic
onAfterClone:
- script: return {result:0, jps:MANIFEST};
- install: ${response.jps}
nodeGroup: ${targetNodes.nodeGroup:cp}
envName: ${event.response.env.envName}
settings:
scheduleType: ${settings.scheduleType}
storageName: ${settings.storageName}
cronTime: ${settings.cronTime}
backupTime: ${settings.backupTime}
sun: ${settings.sun}
mon: ${settings.mon}
tue: ${settings.tue}
wed: ${settings.wed}
thu: ${settings.thu}
fri: ${settings.fri}
sat: ${settings.sat}
tz: ${settings.tz}
backupCount: ${settings.backupCount}
onAfterConfirmTransfer: setSchedule
actions:
checkApplication:
cmd[${nodes.cp.master.id}]: |-
#!/bin/bash
if [ -e /var/www/webroot/ROOT/wp-config.php ]; then
echo "$(date) trying to install the backup add-on" >> /var/log/backup_addon.log
if [ -e /home/jelastic/bin/wp ]; then
/home/jelastic/bin/wp --info >> /var/log/backup_addon.log
fi
else
echo "$(date) The application deployed to WEBROOT cannot be backuped by Jelastic backup add-on" >> /var/log/backup_addon.log
echo "Non-supported"
fi
- cmd[${nodes.cp.master.id}]: |-
[ -f /root/check_app.sh ] && rm -f /root/check_app.sh;
wget -O /root/check_app.sh ${baseUrl}/scripts/check_app.sh;
bash /root/check_app.sh;
user: root
- if (response.out == "Non-supported"):
- stopEvent:
type: warning
message: Deployed application is not supported by Backup add-on.
checkAddons:
- script: |-
@ -80,7 +142,7 @@ actions:
if (resp.result != 0) return resp;
glbs["alreadyInstalled"] = false;
for (let i = 0, n = resp.apps.length; i < n; i++) {
if (resp.apps[i].isInstalled) {
if (resp.apps[i].isInstalled) {
if (resp.apps[i].app_id == 'db-backup') {
glbs["alreadyInstalled"] = true;
break;
@ -107,18 +169,6 @@ actions:
fi
user: root
setSchedule:
- setGlobals:
storageEnv: ${settings.storageName}
- if ("${settings.scheduleType}" == 2):
- convert
- else:
- setGlobals:
cron: ${settings.cronTime}
- installScript:
cronTime: ${globals.cron}
backupCount: ${settings.backupCount}
installScript:
- removeScript
- getStorageCtid
@ -133,30 +183,114 @@ actions:
backupExecNode: ${nodes.cp.master.id}
storageEnv: ${response.storageEnvShortName}
globals:
scriptSufix: mb-backup-manager
callScript:
script: |-
var resp = api.dev.scripting.Eval(appid, session, '${env.envName}-${globals.scriptSufix}', {action:"${this}"});
if (resp.result === 1702 && "${this}" == "uninstall") {
return { result: 0, out: "script not found" };
} else {
return resp.response || resp;
}
removeScript:
script: |-
var resp = api.dev.scripting.GetScript(appid, session, '${env.envName}-${globals.scriptSufix}');
if (resp.result === 0) {
var resp = api.dev.scripting.DeleteScript(appid, session, '${env.envName}-${globals.scriptSufix}');
return resp.response || resp;
}
return { result: 0 };
backup:
- callScript: backup
restore:
- cmd[cp]: |-
echo "${settings.backupedEnvName}" > /root/.backupedenv
echo "${settings.backupDir}" > /root/.backupid
user: root
- callScript: restore
configure:
- setSchedule
getStorageCtid:
- script: scripts/getStorageCtid.js
convert:
- script: |
var resp = {result:0, onAfterReturn: {setGlobals:{cron: ""}}}, offset = java.util.TimeZone.getTimeZone("${settings.tz}").getRawOffset(),
setGlobals = resp.onAfterReturn.setGlobals;
var time = "${settings.backupTime}".split(":"),
d1 = new Date(2020, 1, 10, parseInt(time[0],10), parseInt(time[1],10)),
d2 = new Date(d1.getTime() - offset),
dd = d2.getDate() - d1.getDate(),
days = getDays([${settings.sun:0}, ${settings.mon:0}, ${settings.tue:0}, ${settings.wed:0}, ${settings.thu:0}, ${settings.fri:0}, ${settings.sat:0}], dd);
setGlobals.cron = d2.getMinutes() + " " + d2.getHours() + " * * " + days.join(",");
function getDays(settings, dd) {
var days = [];
for (var i = 0, n = settings.length; i < n; i++) {
if (settings[i]) {
var day = i + dd;
if (day < 0) day +=7; else if (day > 6) day -=7;
days.push(day);
}
}
days.sort();
return days;
}
return resp;
setSchedule:
- setGlobals:
storageEnv: ${settings.storageName}
- if ("${settings.scheduleType}" == 2):
- convert
- else:
- setGlobals:
cron: ${settings.cronTime}
- installScript:
cronTime: ${globals.cron}
backupCount: ${settings.backupCount}
actions:
backupAllNow:
cmd[${nodes.cp.master.id}]: scripts/backupAll.sh
- script: ${baseUrl}/scripts/backupAllNow.js
backupDatabaseOnly:
cmd[${nodes.cp.master.id}]: scripts/backupDatabase.sh
backupWordPressCoreFilesOnly:
cmd[${nodes.cp.master.id}]: scripts/backupWordPressCore.sh
- script: ${baseUrl}/scripts/backupDatabaseOnly.js
backupWordPressCoreOnly:
- script: ${baseUrl}/scripts/backupWordPressCoreOnly.js
backupMediaFilesOnly:
cmd[${nodes.cp.master.id}]: scripts/backupMediaFiles.sh
restoreAll:
cmd[${nodes.cp.master.id}]: scripts/restoreAll.sh
- script: ${baseUrl}/scripts/backupMediaFilesOnly.js
restoreAllOnSpecific:
- script: ${baseUrl}/scripts/restoreAllOnSpecific.js
restoreDatabaseOnly:
cmd[${nodes.cp.master.id}]: scripts/restoreDatabase.sh
- script: ${baseUrl}/scripts/restoreDatabaseOnly.js
restoreMediaFilesOnly:
cmd[${nodes.cp.master.id}]: scripts/restoreMediaFiles.sh
restoreWordPressCoreFilesOnly:
cmd[${nodes.cp.master.id}]: scripts/restoreWordPressCore.sh
configureBackupSchedule:
script: scripts/configureSchedule.js
manageBackupRetention:
script: scripts/manageRetention.js
- script: ${baseUrl}/scripts/restoreMediaFilesOnly.js
restoreWordPressCoreOnly:
- script: ${baseUrl}/scripts/restoreWordPressCoreOnly.js
menu:
items:
- caption: "Backup All Now"
action: backupAllNow
- caption: "Backup Database Only"
action: backupDatabaseOnly
- caption: "Backup WordPress Core Files Only"
action: backupWordPressCoreOnly
- caption: "Backup Media Files Only"
action: backupMediaFilesOnly
- caption: "Restore ALL on specific backup"
action: restoreAllOnSpecific
- caption: "Restore Database Only (specific backup)"
action: restoreDatabaseOnly
- caption: "Restore Media Files Only (specific backup)"
action: restoreMediaFilesOnly
- caption: "Restore WordPress Core Files Only (specific backup)"
action: restoreWordPressCoreOnly
onUninstall:
- cmd[${nodes.cp.master.id}]: scripts/uninstallRestic.sh

View File

@ -0,0 +1,93 @@
function BackupManager(config) {
var Response = com.hivext.api.Response,
Transport = com.hivext.api.core.utils.Transport,
Logger = org.slf4j.LoggerFactory.getLogger("backup-addon:" + config.envName);
var me = this;
var BACKUP_TYPES = {
CORE: "core",
MEDIA: "media",
DATABASE: "db"
};
me.invoke = function(action) {
var actions = {
"backup": me.backup,
"restore": me.restore
};
return actions[action] ? actions[action].call(me) : {
result: Response.ERROR_UNKNOWN,
error: "Unknown action: " + action
};
};
me.backup = function() {
// Sequentially perform all backups
me.backupCoreFiles();
me.backupMediaFiles();
me.backupDatabase();
Logger.info("All backups completed successfully.");
};
me.backupCoreFiles = function() {
var backupName = me.getBackupName(BACKUP_TYPES.CORE);
// Placeholder for core files backup logic
Logger.info("Core files backup completed: " + backupName);
};
me.backupMediaFiles = function() {
var backupName = me.getBackupName(BACKUP_TYPES.MEDIA);
// Placeholder for media files backup logic
Logger.info("Media files backup completed: " + backupName);
};
me.backupDatabase = function() {
var backupName = me.getBackupName(BACKUP_TYPES.DATABASE);
// Placeholder for database backup logic
Logger.info("Database backup completed: " + backupName);
};
me.restore = function(backupName) {
// Determine type from backupName and call the respective restore function
var type = backupName.split("_")[1]; // Assumes naming convention is used
switch(type) {
case BACKUP_TYPES.CORE:
me.restoreCoreFiles(backupName);
break;
case BACKUP_TYPES.MEDIA:
me.restoreMediaFiles(backupName);
break;
case BACKUP_TYPES.DATABASE:
me.restoreDatabase(backupName);
break;
default:
Logger.error("Unknown backup type for restoration: " + backupName);
}
};
me.restoreCoreFiles = function(backupName) {
// Placeholder for core files restore logic
Logger.info("Core files restoration completed: " + backupName);
};
me.restoreMediaFiles = function(backupName) {
// Placeholder for media files restore logic
Logger.info("Media files restoration completed: " + backupName);
};
me.restoreDatabase = function(backupName) {
// Placeholder for database restore logic
Logger.info("Database restoration completed: " + backupName);
};
me.getBackupName = function(type) {
var dateFormat = new java.text.SimpleDateFormat("yyyyMMddHHmmss");
var dateStr = dateFormat.format(new java.util.Date());
return config.envName + "_" + type + "_" + dateStr;
};
}
// Note: This code assumes the existence of several placeholders where actual backup and restore logic should be implemented.
// Depending on the storage and execution environment, this could involve executing shell commands, interacting with APIs,
// or using tools like Restic for actual data handling.