Added other script files
parent
2e6d6d748f
commit
492f80447a
|
@ -0,0 +1,16 @@
|
|||
DB_USER=$1
|
||||
DB_PASSWORD=$2
|
||||
DB_HOST=$3
|
||||
ADMIN_PASSWORD=$(pwgen 10 1)
|
||||
MYSQL=$(which mysql)
|
||||
JEM=$(which jem)
|
||||
cmd="CREATE USER '${DB_USER}'@'localhost' IDENTIFIED BY '${DB_PASSWORD}'; CREATE USER '${DB_USER}'@'%' IDENTIFIED BY '${DB_PASSWORD}'; GRANT ALL PRIVILEGES ON *.* TO '${DB_USER}'@'localhost' WITH GRANT OPTION; GRANT ALL PRIVILEGES ON *.* TO '${DB_USER}'@'%' WITH GRANT OPTION; FLUSH PRIVILEGES;"
|
||||
unset resp;
|
||||
resp=$($MYSQL -u${DB_USER} -p${DB_PASSWORD} -h ${DB_HOST} --execute="SHOW DATABASES;")
|
||||
[ -z "$resp" ] && {
|
||||
echo "Creating the DB user for application"
|
||||
$JEM passwd set -p ${ADMIN_PASSWORD}
|
||||
$MYSQL -uroot -p${ADMIN_PASSWORD} -h ${DB_HOST} --execute="$cmd"
|
||||
} || {
|
||||
echo "[Info] User ${DB_USER} already exists."
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
/var/log/backup_addon.log {
|
||||
weekly
|
||||
rotate 52
|
||||
missingok
|
||||
notifempty
|
||||
compress
|
||||
copytruncate
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
//@auth
|
||||
|
||||
var action = getParam("action", "backup"),
|
||||
baseUrl = "${baseUrl}";
|
||||
|
||||
function run() {
|
||||
var BackupManager = use("scripts/mb-backup-manager.js", {
|
||||
session : session,
|
||||
baseUrl : baseUrl,
|
||||
uid : user.uid,
|
||||
cronTime : "${cronTime}",
|
||||
scriptName : "${scriptName}",
|
||||
envName : "${envName}",
|
||||
envAppid : "${envAppid}",
|
||||
storageNodeId : "${storageNodeId}",
|
||||
backupExecNode : "${backupExecNode}",
|
||||
backupCount : "${backupCount}",
|
||||
storageEnv : "${storageEnv}"
|
||||
});
|
||||
|
||||
api.local.ReturnResult(
|
||||
BackupManager.invoke(action)
|
||||
);
|
||||
}
|
||||
|
||||
function use(script, config) {
|
||||
var Transport = com.hivext.api.core.utils.Transport,
|
||||
body = new Transport().get(baseUrl + "/" + script + "?_r=" + Math.random());
|
||||
var debug = baseUrl + "/" + script + "?_r=" + Math.random();
|
||||
|
||||
return new (new Function("return " + body)())(config);
|
||||
}
|
||||
|
||||
try {
|
||||
run();
|
||||
} catch (ex) {
|
||||
var resp = {
|
||||
result : com.hivext.api.Response.ERROR_UNKNOWN,
|
||||
error: "Error: " + toJSON(ex)
|
||||
};
|
||||
|
||||
api.marketplace.console.WriteLog(appid, signature, "ERROR: " + resp);
|
||||
api.local.ReturnResult(resp);
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
var resp = api.env.control.GetEnvs();
|
||||
if (resp.result !== 0) return resp;
|
||||
var envs = [];
|
||||
var nodes = {};
|
||||
for (var i = 0, envInfo, env; envInfo = resp.infos[i]; i++) {
|
||||
if (envInfo.envGroups.includes("WP Backup") || envInfo.envGroups.includes("Backup storage nodes")) {
|
||||
env = envInfo.env
|
||||
if (env.status == 1) {
|
||||
for (var j = 0, node; node = envInfo.nodes[j]; j++) {
|
||||
nodes[env.envName] = nodes[env.envName] || [];
|
||||
nodes[env.envName].groups = nodes[env.envName].groups || {};
|
||||
if (!nodes[env.envName].groups[node.nodeGroup]) nodes[env.envName].push({
|
||||
value: node.nodeGroup,
|
||||
caption: (node.displayName || node.name) + ' (' + node.nodeGroup + ')'
|
||||
});
|
||||
nodes[env.envName].groups[node.nodeGroup] = true;
|
||||
}
|
||||
if (nodes[env.envName] && nodes[env.envName].length > 0) {
|
||||
envs.push({
|
||||
value: env.envName,
|
||||
caption: (env.displayName + " (" + env.envName + ")" || env.envName)
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (envs.length > 0) {
|
||||
jps.settings.main.fields[1].values = envs;
|
||||
jps.settings.main.fields[1].default = envs[0].value;
|
||||
}
|
||||
|
||||
import java.util.TimeZone;
|
||||
var zones = toNative(TimeZone.getAvailableIDs());
|
||||
var values = {};
|
||||
|
||||
for (var i = 0, n = zones.length; i < n; i++) {
|
||||
var offset = TimeZone.getTimeZone(zones[i]).getRawOffset()/3600000;
|
||||
var m = offset % 1;
|
||||
if (m != 0) m = Math.abs(m * 60);
|
||||
if (m < 10) m = "0" + m;
|
||||
var h = Math.floor(offset);
|
||||
if (Math.abs(h) < 10) h = h < 0 ? "-0" + Math.abs(h) : "+0" + h; else if (h >= 0) h = "+" + h;
|
||||
values[zones[i]] = zones[i] + (zones[i] == "GMT" ? "" : " (GMT" + h + ":" + m + ")");
|
||||
}
|
||||
|
||||
jps.settings.main.fields[0].showIf[2][2].values = values;
|
||||
jps.settings.main.fields[0].showIf[2][2].value = "GMT0";
|
||||
|
||||
return {
|
||||
result: 0,
|
||||
settings: jps.settings
|
||||
};
|
|
@ -0,0 +1,11 @@
|
|||
#!/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
|
|
@ -0,0 +1,11 @@
|
|||
#!/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
|
|
@ -0,0 +1,138 @@
|
|||
var storage_unavailable_markup = "";
|
||||
var resp = api.env.control.GetEnvs();
|
||||
if (resp.result !== 0) return resp;
|
||||
var envs = [];
|
||||
var nodes = {};
|
||||
var currentStorageExists = false;
|
||||
var scheduleType = '${settings.scheduleType}';
|
||||
for (var i = 0, envInfo, env; envInfo = resp.infos[i]; i++) {
|
||||
if (envInfo.envGroups.includes("WP Backup") || envInfo.envGroups.includes("Backup storage nodes")) {
|
||||
env = envInfo.env
|
||||
if (env.status == 1) {
|
||||
for (var j = 0, node; node = envInfo.nodes[j]; j++) {
|
||||
nodes[env.envName] = nodes[env.envName] || [];
|
||||
nodes[env.envName].groups = nodes[env.envName].groups || {};
|
||||
if (!nodes[env.envName].groups[node.nodeGroup]) nodes[env.envName].push({
|
||||
value: node.nodeGroup,
|
||||
caption: (node.displayName || node.name) + ' (' + node.nodeGroup + ')'
|
||||
});
|
||||
nodes[env.envName].groups[node.nodeGroup] = true;
|
||||
if ( env.envName == '${settings.storageName}' ) {
|
||||
currentStorageExists = true;
|
||||
}
|
||||
}
|
||||
if (nodes[env.envName] && nodes[env.envName].length > 0) {
|
||||
envs.push({
|
||||
value: env.envName,
|
||||
caption: (env.displayName + " (" + env.envName + ")" || env.envName)
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
jps.settings.main.fields[1].values = envs;
|
||||
jps.settings.main.fields[1].default = "";
|
||||
if (envs.length > 0) {
|
||||
if (currentStorageExists == true) {
|
||||
jps.settings.main.fields[1].default = '${settings.storageName}';
|
||||
} else {
|
||||
jps.settings.main.fields[1].default = envs[0].value;
|
||||
}
|
||||
} else {
|
||||
storage_unavailable_markup = "There are no available backup storages on current account."
|
||||
}
|
||||
|
||||
import java.util.TimeZone;
|
||||
var zones = toNative(TimeZone.getAvailableIDs());
|
||||
var values = {};
|
||||
|
||||
for (var i = 0, n = zones.length; i < n; i++) {
|
||||
var offset = TimeZone.getTimeZone(zones[i]).getRawOffset()/3600000;
|
||||
var m = offset % 1;
|
||||
if (m != 0) m = Math.abs(m * 60);
|
||||
if (m < 10) m = "0" + m;
|
||||
var h = Math.floor(offset);
|
||||
if (Math.abs(h) < 10) h = h < 0 ? "-0" + Math.abs(h) : "+0" + h; else if (h >= 0) h = "+" + h;
|
||||
values[zones[i]] = zones[i] + (zones[i] == "GMT" ? "" : " (GMT" + h + ":" + m + ")");
|
||||
}
|
||||
|
||||
jps.settings.main.fields[0].default = '${settings.scheduleType}';
|
||||
|
||||
if (scheduleType == '1') {
|
||||
jps.settings.main.fields[0].showIf[1][0].default = '${settings.cronTime}';
|
||||
} else if (scheduleType == '2') {
|
||||
jps.settings.main.fields[0].showIf[2][0].default = '${settings.backupTime}';
|
||||
var sun = ('${settings.sun}' === 'true'),
|
||||
mon = ('${settings.mon}' === 'true'),
|
||||
tue = ('${settings.tue}' === 'true'),
|
||||
wed = ('${settings.wed}' === 'true'),
|
||||
thu = ('${settings.thu}' === 'true'),
|
||||
fri = ('${settings.fri}' === 'true'),
|
||||
sat = ('${settings.sat}' === 'true');
|
||||
var selectedDays = {
|
||||
"caption": "Days",
|
||||
"type": "compositefield",
|
||||
"name": "days",
|
||||
"defaultMargins": "0 12 0 0",
|
||||
"items": [
|
||||
{
|
||||
"name": "sun",
|
||||
"value": sun,
|
||||
"type": "checkbox",
|
||||
"caption": "Su"
|
||||
},
|
||||
{
|
||||
"name": "mon",
|
||||
"value": mon,
|
||||
"type": "checkbox",
|
||||
"caption": "Mo"
|
||||
},
|
||||
{
|
||||
"name": "tue",
|
||||
"value": tue,
|
||||
"type": "checkbox",
|
||||
"caption": "Tu"
|
||||
},
|
||||
{
|
||||
"name": "wed",
|
||||
"value": wed,
|
||||
"type": "checkbox",
|
||||
"caption": "We"
|
||||
},
|
||||
{
|
||||
"name": "thu",
|
||||
"value": thu,
|
||||
"type": "checkbox",
|
||||
"caption": "Th"
|
||||
},
|
||||
{
|
||||
"name": "fri",
|
||||
"value": fri,
|
||||
"type": "checkbox",
|
||||
"caption": "Fr"
|
||||
},
|
||||
{
|
||||
"name": "sat",
|
||||
"value": sat,
|
||||
"type": "checkbox",
|
||||
"caption": "Sa"
|
||||
}
|
||||
]
|
||||
};
|
||||
jps.settings.main.fields[0].showIf[2][1] = selectedDays;
|
||||
jps.settings.main.fields[0].showIf[2][2].values = values;
|
||||
jps.settings.main.fields[0].showIf[2][2].value = '${settings.tz}';
|
||||
} else {
|
||||
jps.settings.main.fields[0].showIf[3][0].default = '${settings.cronTime}';
|
||||
}
|
||||
|
||||
jps.settings.main.fields[2].default = '${settings.backupCount}';
|
||||
|
||||
if (storage_unavailable_markup.length > 0) {
|
||||
jps.settings.main.fields.push(
|
||||
{"type": "displayfield", "cls": "warning", "height": 30, "hideLabel": true, "markup": storage_unavailable_markup}
|
||||
)
|
||||
}
|
||||
|
||||
return settings;
|
|
@ -0,0 +1,13 @@
|
|||
#!/bin/bash
|
||||
|
||||
if [ $# -eq 0 ]; then
|
||||
ENV_LIST=$(ls -Qm /data);
|
||||
OUTPUT_JSON="{\"result\": 0, \"envs\": [${ENV_LIST}"
|
||||
else
|
||||
ENV_NAME=$1
|
||||
[ -d "/data/$1" ] && BACKUP_LIST=$(RESTIC_PASSWORD="$1" restic -r /data/$1 snapshots|awk '{print $5}'|grep -o [0-9_-]*|awk '{print "\""$1"\""}'|tr '\n' ',')
|
||||
OUTPUT_JSON="{\"result\": 0, \"backups\": [${BACKUP_LIST}"
|
||||
[ -n "${BACKUP_LIST}" ] && OUTPUT_JSON=${OUTPUT_JSON::-1}
|
||||
fi
|
||||
|
||||
echo $OUTPUT_JSON]}
|
|
@ -0,0 +1,10 @@
|
|||
var storageEnv = '${settings.storageName}'
|
||||
var storageEnvShortName = storageEnv.split(".")[0]
|
||||
var resp = api.environment.control.GetEnvInfo(storageEnvShortName, session)
|
||||
if (resp.result != 0) return resp
|
||||
for (var i = 0; resp.nodes; i++) {
|
||||
var node = resp.nodes[i]
|
||||
if (node.nodeGroup == 'storage' && node.ismaster) {
|
||||
return { result: 0, storageCtid : node.id, storageEnvShortName : storageEnvShortName};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
var storageEnv = '${settings.storageName}'
|
||||
var storageEnvShortName = storageEnv.split(".")[0]
|
||||
var resp = api.environment.control.GetEnvInfo(storageEnvShortName, session)
|
||||
if (resp.result != 0) return resp
|
||||
for (var i = 0; resp.nodes; i++) {
|
||||
var node = resp.nodes[i]
|
||||
if (node.nodeGroup == 'storage' && node.ismaster) {
|
||||
return { result: 0, storageCtid : node.id, storageEnvShortName : storageEnvShortName};
|
||||
}
|
||||
}
|
|
@ -37,7 +37,7 @@ function BackupManager(config) {
|
|||
};
|
||||
|
||||
me.backupMediaFiles = function() {
|
||||
var backupName = me.getBackupName(BACKUP_TYPES.MEDIA);
|
||||
var backupName = me.getBackupName(BACKUP_TYPES.ME DIA);
|
||||
// Placeholder for media files backup logic
|
||||
Logger.info("Media files backup completed: " + backupName);
|
||||
};
|
||||
|
@ -87,7 +87,3 @@ function BackupManager(config) {
|
|||
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.
|
||||
|
|
|
@ -0,0 +1,90 @@
|
|||
import org.json.JSONObject;
|
||||
var Response = com.hivext.api.Response;
|
||||
var storage_unavailable_markup = "";
|
||||
var storageInfo = getStorageNodeid();
|
||||
var storageEnvDomain = storageInfo.storageEnvShortName;
|
||||
var storageEnvMasterId = storageInfo.storageCtid;
|
||||
|
||||
resp = api.env.control.GetEnvInfo(storageEnvDomain, session);
|
||||
if (resp.result != 0 && resp.result != 11) return resp;
|
||||
if (resp.result == 11) {
|
||||
storage_unavailable_markup = "Storage environment " + "${settings.storageName}" + " is deleted.";
|
||||
} else if (resp.env.status == 1) {
|
||||
var respUpdate = api.env.control.ExecCmdById(storageEnvDomain, session, storageEnvMasterId, toJSON([{"command": "/usr/bin/restic self-update 2>&1", "params": ""}]), false);
|
||||
if (respUpdate.result != 0) return resp;
|
||||
var backups = api.env.control.ExecCmdById(storageEnvDomain, session, storageEnvMasterId, toJSON([{"command": "/root/getBackupsAllEnvs.sh", "params": ""}]), false);
|
||||
if (backups.result != 0) return resp;
|
||||
var backupList = toNative(new JSONObject(String(backups.responses[0].out)));
|
||||
var envs = prepareEnvs(backupList.envs);
|
||||
var backups = prepareBackups(backupList.backups);
|
||||
} else {
|
||||
storage_unavailable_markup = "Storage environment " + storageEnvDomain + " is unavailable (stopped/sleeping).";
|
||||
}
|
||||
|
||||
function getStorageNodeid(){
|
||||
let storageEnv = '${settings.storageName}';
|
||||
var storageEnvShortName = storageEnv.split(".")[0];
|
||||
let resp = api.environment.control.GetEnvInfo({ envName: storageEnvShortName });
|
||||
if (resp.result != 0) return resp;
|
||||
|
||||
let storageNode = resp.nodes.filter(node => (node.nodeGroup == 'storage' && node.ismaster))[0];
|
||||
if (!storageNode) return { result: Response.OBJECT_NOT_EXIST, error: "storage node not found" };
|
||||
|
||||
return { result: 0, storageCtid : storageNode.id, storageEnvShortName: storageEnvShortName };
|
||||
}
|
||||
|
||||
function prepareEnvs(values) {
|
||||
var aResultValues = [];
|
||||
|
||||
values = values || [];
|
||||
|
||||
for (var i = 0, n = values.length; i < n; i++) {
|
||||
aResultValues.push({ caption: values[i], value: values[i] });
|
||||
}
|
||||
|
||||
return aResultValues;
|
||||
}
|
||||
|
||||
function prepareBackups(backups) {
|
||||
var oResultBackups = {};
|
||||
var aValues;
|
||||
|
||||
for (var envName in backups) {
|
||||
if (Object.prototype.hasOwnProperty.call(backups, envName)) {
|
||||
aValues = [];
|
||||
|
||||
for (var i = 0, n = backups[envName].length; i < n; i++) {
|
||||
aValues.push({ caption: backups[envName][i], value: backups[envName][i] });
|
||||
}
|
||||
|
||||
oResultBackups[envName] = aValues;
|
||||
}
|
||||
}
|
||||
|
||||
return oResultBackups;
|
||||
}
|
||||
|
||||
if (storage_unavailable_markup === "") {
|
||||
settings.fields.push({
|
||||
"caption": "Restore from",
|
||||
"type": "list",
|
||||
"name": "backupedEnvName",
|
||||
"required": true,
|
||||
"values": envs
|
||||
}, {
|
||||
"caption": "Backup",
|
||||
"type": "list",
|
||||
"name": "backupDir",
|
||||
"required": true,
|
||||
"tooltip": "Select the time stamp for which you want to restore the DB dump",
|
||||
"dependsOn": {
|
||||
"backupedEnvName" : backups
|
||||
}
|
||||
})
|
||||
} else {
|
||||
settings.fields.push(
|
||||
{"type": "displayfield", "cls": "warning", "height": 30, "hideLabel": true, "markup": storage_unavailable_markup}
|
||||
)
|
||||
}
|
||||
|
||||
return settings;
|
|
@ -0,0 +1,62 @@
|
|||
import org.json.JSONObject;
|
||||
var Response = com.hivext.api.Response;
|
||||
var storage_unavailable_markup = "";
|
||||
var storageInfo = getStorageNodeid();
|
||||
var storageEnvDomain = storageInfo.storageEnvShortName;
|
||||
var storageEnvMasterId = storageInfo.storageCtid;
|
||||
var backupedEnvDomain = '${env.envName}';
|
||||
|
||||
resp = api.env.control.GetEnvInfo(storageEnvDomain, session);
|
||||
if (resp.result != 0 && resp.result != 11) return resp;
|
||||
if (resp.result == 11) {
|
||||
storage_unavailable_markup = "Storage environment " + "${settings.storageName}" + " is deleted.";
|
||||
} else if (resp.env.status == 1) {
|
||||
var respUpdate = api.env.control.ExecCmdById(storageEnvDomain, session, storageEnvMasterId, toJSON([{"command": "/usr/bin/restic self-update 2>&1", "params": ""}]), false);
|
||||
if (respUpdate.result != 0) return resp;
|
||||
var backups = api.env.control.ExecCmdById(storageEnvDomain, session, storageEnvMasterId, toJSON([{"command": "/root/getBackups.sh", "params": backupedEnvDomain}]), false).responses[0].out;
|
||||
var backupList = toNative(new JSONObject(String(backups))).backups;
|
||||
var backupListPrepared = prepareBackups(backupList);
|
||||
} else {
|
||||
storage_unavailable_markup = "Storage environment " + storageEnvDomain + " is unavailable (stopped/sleeping).";
|
||||
}
|
||||
|
||||
function getStorageNodeid(){
|
||||
let storageEnv = '${settings.storageName}'
|
||||
var storageEnvShortName = storageEnv.split(".")[0]
|
||||
let resp = api.environment.control.GetEnvInfo({ envName: storageEnvShortName })
|
||||
if (resp.result != 0) return resp
|
||||
|
||||
let storageNode = resp.nodes.filter(node => (node.nodeGroup == 'storage' && node.ismaster))[0];
|
||||
if (!storageNode) return { result: Response.OBJECT_NOT_EXIST, error: "storage node not found" };
|
||||
|
||||
return { result: 0, storageCtid : storageNode.id, storageEnvShortName: storageEnvShortName };
|
||||
}
|
||||
|
||||
function prepareBackups(values) {
|
||||
var aResultValues = [];
|
||||
values = values || [];
|
||||
for (var i = 0, n = values.length; i < n; i++) {
|
||||
aResultValues.push({
|
||||
caption: values[i],
|
||||
value: values[i]
|
||||
});
|
||||
}
|
||||
return aResultValues;
|
||||
}
|
||||
|
||||
if (storage_unavailable_markup === "") {
|
||||
settings.fields.push({
|
||||
"caption": "Backup",
|
||||
"type": "list",
|
||||
"tooltip": "Select the time stamp for which you want to restore the contents of the web site",
|
||||
"name": "backupDir",
|
||||
"required": true,
|
||||
"values": backupListPrepared
|
||||
})
|
||||
} else {
|
||||
settings.fields.push(
|
||||
{"type": "displayfield", "cls": "warning", "height": 30, "hideLabel": true, "markup": storage_unavailable_markup}
|
||||
)
|
||||
}
|
||||
|
||||
return settings;
|
Loading…
Reference in New Issue