diff --git a/backup-module/backup_controller.php b/backup-module/backup_controller.php
index c4c6094..02266ee 100644
--- a/backup-module/backup_controller.php
+++ b/backup-module/backup_controller.php
@@ -92,7 +92,7 @@ function backup_controller()
if ($route->action == "download") {
header("Content-type: application/zip");
- $backup_filename="emoncms-backup-".date("Y-m-d").".tar.gz";
+ $backup_filename="emoncms-backup-".gethostname()."-".date("Y-m-d").".tar.gz";
header("Content-Disposition: attachment; filename=$backup_filename");
header("Pragma: no-cache");
header("Expires: 0");
@@ -120,7 +120,7 @@ function backup_controller()
if ((move_uploaded_file($_FILES['file']['tmp_name'], $target_path)) && ($uploadOk == 1)) {
$redis->rpush("service-runner","$import_script $import_flag>$import_logfile");
- header('Location: '.$path.'backup#import');
+ header('Location: '.$path.'backup#import-archive');
} else {
return "
Error: Import archive not selected
";
}
diff --git a/backup-module/backup_view.php b/backup-module/backup_view.php
index e80c52b..c2d2788 100644
--- a/backup-module/backup_view.php
+++ b/backup-module/backup_view.php
@@ -74,7 +74,7 @@
Right Click > Download:
'.$backup_filename.'';
}
@@ -161,7 +161,7 @@ function export_log_update() {
$("#export-log").html(result);
document.getElementById("export-log-bound").scrollTop = document.getElementById("export-log-bound").scrollHeight
- if (result.indexOf("=== Emoncms export complete! ===")!=-1) {
+ if (result.indexOf("=== Emoncms export complete! ===")!=-1 || result.indexOf("=== Emoncms export completed with ERRORS! ===")!=-1) {
clearInterval(export_updater);
}
}
diff --git a/emoncms-export.sh b/emoncms-export.sh
index 883e77c..0b20192 100755
--- a/emoncms-export.sh
+++ b/emoncms-export.sh
@@ -1,47 +1,79 @@
#!/bin/bash
-script_location="`dirname $0`"
-date=$(date +"%Y-%m-%d")
+# Set the shell to trigger errors when commands within a pipe have a non-zero return code
+set -o pipefail
+
+# The errors variable is set when error_handler() is called, the variable is used by the finish() function for success or failure messages
+errors=false
+
+# This error handler function display information of what happened and where, but does NOT stop the script execution
+error_handler() {
+ echo "Error: RC=$1 occurred on line $2"
+ errors=true
+}
+
+# Set trap for ERR to pass the return code and line number to error_handler()
+trap 'error_handler $? $LINENO' ERR
+
+# Exit handler used to ensure the exit message AJAX expects is found, whilst summarising if errors were found
+# This also picks up the natural exit when reaching end of script
+
+function finish() {
+ if [[ "${errors}" == "false" && $? == 0 ]]; then
+ echo "=== Emoncms export complete! ==="
+# The strings output are identified in the interface to stop ongoing AJAX calls, please ammend in interface if changed here
+ else
+ echo "=== Emoncms export completed with ERRORS! ==="
+# The strings output are identified in the interface to stop ongoing AJAX calls, please ammend in interface if changed here
+ fi
+}
+
+# Set trap for whenever EXIT is called to call finish()
+trap finish EXIT
+
+declare -a included not_found
+script_location="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
+config_location=${script_location}/config.cfg
echo "=== Emoncms export start ==="
date
echo "Backup module version:"
-cat $script_location/backup-module/module.json | grep version
+grep version "${script_location}/module.json"
echo "EUID: $EUID"
-echo "Reading $script_location/config.cfg...."
-if [ -f "$script_location/config.cfg" ]
+echo "Reading ${config_location}...."
+
+if [ ! -f "${config_location}" ]
then
- source "$script_location/config.cfg"
- echo "Location of databases: $database_path"
- echo "Location of emonhub.conf: $emonhub_config_path"
- echo "Location of Emoncms: $emoncms_location"
- echo "Backup destination: $backup_location"
-else
- echo "ERROR: Backup $script_location/backup/config.cfg file does not exist"
+ echo "ERROR: Backup config file ${config_location} does not exist"
exit 1
- sudo systemctl start feedwriter > /dev/null
fi
+source "${config_location}"
+echo "Location of databases: $database_path"
+echo "Location of emonhub.conf: $emonhub_config_path"
+echo "Location of Emoncms: $emoncms_location"
+echo "Backup destination: $backup_location"
+
+tar_filename="${backup_location}/emoncms-backup-$(hostname)-$(date +"%Y-%m-%d").tar"
+
module_location="${emoncms_location}/Modules/backup"
echo "emoncms backup module location $module_location"
#-----------------------------------------------------------------------------------------------
# Remove Old backup files
#-----------------------------------------------------------------------------------------------
-if [ -f $backup_location/emoncms.sql ]
-then
- sudo rm $backup_location/emoncms.sql
-fi
-
-if [ -f $backup_location/emoncms-backup-$date.tar ]
-then
- sudo rm $backup_location/emoncms-backup-$date.tar
-fi
+for file in "${backup_location}/emoncms.sql" "${tar_filename}"
+do
+ if [ -f "${file}" ]
+ then
+ sudo rm "${file}"
+ fi
+done
#-----------------------------------------------------------------------------------------------
# Check emonPi / emonBase image version
#-----------------------------------------------------------------------------------------------
-image_version=$(ls /boot | grep emonSD)
+image_version=$(cd /boot && echo *emonSD* )
# Check first 16 characters of filename
image_date=${image_version:0:16}
@@ -63,8 +95,8 @@ fi
sudo systemctl stop feedwriter
# Get MYSQL authentication details from settings.php
-if [ -f $script_location/get_emoncms_mysql_auth.php ]; then
- auth=$(echo $emoncms_location | php $script_location/get_emoncms_mysql_auth.php php)
+if [ -f "${script_location}/get_emoncms_mysql_auth.php" ]; then
+ auth=$(echo "${emoncms_location}" | php "${script_location}/get_emoncms_mysql_auth.php" php)
IFS=":" read username password database <<< "$auth"
else
echo "Error: cannot read MYSQL authentication details from Emoncms $script_location/get_emoncms_mysql_auth.php php & settings.php"
@@ -75,7 +107,7 @@ fi
# MYSQL Dump Emoncms database
if [ -n "$username" ]; then # if username string is not empty
- mysqldump -u$username -p$password $database > $backup_location/emoncms.sql
+ mysqldump -u"${username}" -p"${password}" "${database}" > "${backup_location}/emoncms.sql"
if [ $? -ne 0 ]; then
echo "Error: failed to export mysql data"
echo "emoncms export failed"
@@ -88,85 +120,53 @@ else
exit 1
fi
-if [ -f $backup_location/emoncms.sql ]
-then
- echo "-- adding $backup_location/emoncms.sql to archive --"
- tar -c --file=$backup_location/emoncms-backup-$date.tar $backup_location/emoncms.sql --transform 's?.*/??g' 2>&1
-else
- echo "no file $backup_location/emoncms.sql"
-fi
-
-if [ -f $emonhub_config_path/emonhub.conf ]
-then
- echo "-- adding $emonhub_config_path/emonhub.conf to archive --"
- tar -vr --file=$backup_location/emoncms-backup-$date.tar $emonhub_config_path/emonhub.conf --transform 's?.*/??g' 2>&1
-else
- echo "no file $emonhub_config_path/emonhub.conf"
-fi
-
-if [ -f $emoncms_location/settings.ini ]
-then
- echo "-- adding $emoncms_location/settings.ini to archive --"
- tar -vr --file=$backup_location/emoncms-backup-$date.tar $emoncms_location/settings.ini --transform 's?.*/??g' 2>&1
-else
- echo "no file $emoncms_location/settings.ini"
-fi
-
-if [ -f $emoncms_location/settings.php ]
-then
- echo "-- adding $emoncms_location/settings.php to archive --"
- tar -vr --file=$backup_location/emoncms-backup-$date.tar $emoncms_location/settings.php --transform 's?.*/??g' 2>&1
-else
- echo "no file $emoncms_location/settings.php"
-fi
+#
+for file in "${backup_location}/emoncms.sql" "${emonhub_config_path}/emonhub.conf" "${emoncms_location}/settings.ini" "${emoncms_location}/settings.php"
+do
+ if [ -f "${file}" ]
+ then
+ echo "-- adding ${file} to archive --"
+ tar -vr --file="${tar_filename}" "${file}" --transform 's?.*/??g' 2>&1
+ included+=("${file}")
+ else
+ echo "no ${file} to backup"
+ not_found+=("${file}")
+ fi
+done
# Append database folder to the archive with absolute path
-if [ -d $database_path/phpfina ]
-then
- echo "-- adding $database_path/phpfina to archive --"
- tar -vr --file=$backup_location/emoncms-backup-$date.tar -C $database_path phpfina 2>&1
- if [ $? -ne 0 ]; then
- echo "Error: failed to tar phpfina"
- fi
-else
- echo "no phpfina directory"
-fi
-
-if [ -d $database_path/phpfiwa ]
-then
- echo "-- adding $database_path/phpfiwa to archive --"
- tar -vr --file=$backup_location/emoncms-backup-$date.tar -C $database_path phpfiwa 2>&1
- if [ $? -ne 0 ]; then
- echo "Error: failed to tar phpfiwa"
- fi
-else
- echo "no phpfiwa directory"
-fi
+for dir in phpfina phpfiwa phptimeseries
+do
+ if [ -d "${database_path}/${dir}" ]
+ then
+ echo "-- adding ${database_path}/${dir} to archive --"
+ tar -vr --file="${tar_filename}" -C "${database_path}" "${dir}" 2>&1
+ if [ $? -ne 0 ]; then
+ echo "Error: failed to tar ${dir}"
+ fi
+ included+=("${dir}")
+ else
+ echo "no ${database_path}/${dir} directory to backup"
+ not_found+=("${dir}")
+ fi
+done
-if [ -d $database_path/phptimeseries ]
-then
- echo "-- adding $database_path/phptimeseries to archive --"
- tar -vr --file=$backup_location/emoncms-backup-$date.tar -C $database_path phptimeseries 2>&1
- if [ $? -ne 0 ]; then
- echo "Error: failed to tar phptimeseries"
- fi
-else
- echo "no phptimeseries directory $database_path/phptimeseries"
-fi
+sudo systemctl start feedwriter > /dev/null
# Compress backup
echo "Compressing archive..."
-gzip -fv $backup_location/emoncms-backup-$date.tar 2>&1
+gzip -fv "${tar_filename}" 2>&1
if [ $? -ne 0 ]; then
echo "Error: failed to compress tar file"
echo "emoncms export failed"
- sudo systemctl start feedwriter > /dev/null
exit 1
fi
-sudo systemctl start feedwriter > /dev/null
-
-echo "Backup saved: $backup_location/emoncms-backup-$date.tar.gz"
+echo "Backup saved: ${tar_filename}.gz"
date
+echo -e "\nBackup included components: ${included[*]}"
+echo -e "INFO: These components couldn't be found to backup: ${not_found[*]}\n"
+
echo "Export finished...refresh page to view download link"
-echo "=== Emoncms export complete! ===" # This string is identified in the interface to stop ongoing AJAX calls, please ammend in interface if changed here
+
+# The exit trap will pickup the natural exit and display the string to stop ongoing AJAX calls
diff --git a/emoncms-import.sh b/emoncms-import.sh
index abfc04a..a5ba544 100755
--- a/emoncms-import.sh
+++ b/emoncms-import.sh
@@ -1,23 +1,24 @@
#!/bin/bash
-script_location="`dirname $0`"
+script_location="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
+config_location=${script_location}/config.cfg
echo "=== Emoncms import start ==="
date +"%Y-%m-%d-%T"
echo "Backup module version:"
-cat $script_location/backup/module.json | grep version
+grep version "${script_location}/module.json"
echo "EUID: $EUID"
-echo "Reading $script_location/config.cfg...."
-if [ -f "$script_location/config.cfg" ]
+echo "Reading ${config_location}...."
+if [ -f "${config_location}" ]
then
- source "$script_location/config.cfg"
+ source "${config_location}"
echo "Location of data databases: $database_path"
echo "Location of emonhub.conf: $emonhub_config_path"
echo "Location of Emoncms: $emoncms_location"
echo "Backup destination: $backup_location"
echo "Backup source path: $backup_source_path"
else
- echo "ERROR: Backup $script_location/backup/config.cfg file does not exist"
+ echo "ERROR: Backup config file ${config_location} does not exist"
exit 1
fi
@@ -52,24 +53,24 @@ fi
# Get latest backup filename
-if [ ! -d $backup_source_path ]; then
- echo "Error: $backup_source_path does not exist, nothing to import"
+if [ ! -d "${backup_source_path}" ]; then
+ echo "Error: ${backup_source_path} does not exist, nothing to import"
exit 1
fi
-backup_filename=$((cd $backup_source_path && ls -t *.tar.gz) | head -1)
-if [[ -z "$backup_filename" ]] #if backup does not exist (empty filename string)
+backup_filename=$(ls -t "${backup_source_path}"/*.tar.gz | head -1)
+if [[ -z "${backup_filename}" ]] #if backup does not exist (empty filename string)
then
echo "Error: cannot find backup, stopping import"
exit 1
fi
# if backup exists
-echo "Backup found: $backup_filename starting import.."
+echo "Backup found: ${backup_filename} starting import.."
echo "Read MYSQL authentication details from settings.php"
-if [ -f $script_location/get_emoncms_mysql_auth.php ]; then
- auth=$(echo $emoncms_location | php $script_location/get_emoncms_mysql_auth.php php)
+if [ -f "${script_location}/get_emoncms_mysql_auth.php" ]; then
+ auth=$(echo "${emoncms_location}" | php "${script_location}/get_emoncms_mysql_auth.php" php)
IFS=":" read username password database <<< "$auth"
else
echo "Error: cannot read MYSQL authentication details from Emoncms settings.php"
@@ -79,27 +80,31 @@ fi
echo "Decompressing backup.."
-if [ ! -d $backup_location/import ]; then
- mkdir $backup_location/import
- sudo chown $user $backup_location/import -R
+import_location="${backup_location}/import"
+if [ -d "${import_location}" ]; then
+ sudo rm -rf "${import_location}"
+ # Belt and braces cleanup in case any '.' prefixed files exist
fi
-tar xfzv $backup_source_path/$backup_filename -C $backup_location/import 2>&1
+mkdir "${import_location}"
+sudo chown "${user}" "${import_location}"
+
+tar xfzv "${backup_filename}" -C "${import_location}" 2>&1
if [ $? -ne 0 ]; then
echo "Error: failed to decompress backup"
- echo "$backup_source_path/$backup_filename has not been removed for diagnotics"
- echo "Removing files in $backup_location/import"
- sudo rm -Rf $backup_location/import/*
+ echo "${backup_filename} has not been removed for diagnotics"
+ echo "Removing files in ${import_location}"
+ sudo rm -Rf "${import_location}/*"
echo "Import failed"
exit 1
fi
echo "Removing compressed backup to save disk space.."
-sudo rm $backup_source_path/$backup_filename
+sudo rm "${backup_filename}"
if [ -n "$password" ]
then # if username sring is not empty
- if [ -f $backup_location/import/emoncms.sql ]; then
+ if [ -f "${import_location}/emoncms.sql" ]; then
echo "Stopping services.."
if [[ $emonhub == "loaded" ]]; then
sudo systemctl stop emonhub
@@ -114,7 +119,7 @@ then # if username sring is not empty
sudo systemctl stop emoncms_mqtt
fi
echo "Emoncms MYSQL database import..."
- mysql -u$username -p$password $database < $backup_location/import/emoncms.sql
+ mysql -u"${username}" -p"${password}" "${database}" < "${import_location}/emoncms.sql"
if [ $? -ne 0 ]; then
echo "Error: failed to import mysql data"
echo "Import failed"
@@ -130,27 +135,31 @@ else
fi
echo "Import feed meta data.."
-sudo rm -rf $database_path/{phpfina,phptimeseries} 2> /dev/null
+sudo rm -rf "${database_path}"/{phpfina,phptimeseries} 2> /dev/null
echo "Restore phpfina and phptimeseries data folders..."
-if [ -d $backup_location/import/phpfina ]; then
- sudo mv $backup_location/import/phpfina $database_path
- sudo chown -R www-data:root $database_path/phpfina
+if [ -d "${import_location}/phpfina" ]; then
+ sudo mv "${import_location}/phpfina" "${database_path}"
+ sudo chown -R www-data:root "${database_path}/phpfina"
fi
-if [ -d $backup_location/import/phptimeseries ]; then
- sudo mv $backup_location/import/phptimeseries $database_path
- sudo chown -R www-data:root $database_path/phptimeseries
+if [ -d "${import_location}/phptimeseries" ]; then
+ sudo mv "${import_location}/phptimeseries" "${database_path}"
+ sudo chown -R www-data:root "${database_path}/phptimeseries"
fi
# cleanup
-sudo rm $backup_location/import/emoncms.sql
+sudo rm "${import_location}/emoncms.sql"
# Save previous config settings as old.emonhub.conf
-if [ -f $backup_location/import/emonhub.conf ]; then
- echo "Import emonhub.conf > $emonhub_config_path/emohub.conf"
- sudo mv $backup_location/import/emonhub.conf $emonhub_config_path/emonhub.conf
- sudo chmod 666 $emonhub_config_path/emonhub.conf
+if [ -f "${import_location}/emonhub.conf" ]; then
+ if [ -d "${emonhub_config_path}" ]; then
+ echo "Import emonhub.conf > ${emonhub_config_path}/emohub.conf"
+ sudo mv "${import_location}/emonhub.conf" "${emonhub_config_path}/emonhub.conf"
+ sudo chmod 666 "${emonhub_config_path}/emonhub.conf"
+ else
+ echo "WARNING: emonhub.conf found in backup, but no emonHub directory (${emonhub_config_path}) found"
+ fi
fi
# Start with blank emonhub.conf
diff --git a/readme.md b/readme.md
index b2555b7..648b703 100644
--- a/readme.md
+++ b/readme.md
@@ -32,6 +32,7 @@ Install this module in /opt/emoncms/modules:
Run backup module installation script to modify php.ini and setup uploads folder:
+ cd backup
./install.sh
## Manual Export Instructions
diff --git a/usb-import.sh b/usb-import.sh
index 97d5a85..0649d7b 100755
--- a/usb-import.sh
+++ b/usb-import.sh
@@ -1,21 +1,22 @@
#!/bin/bash
script_location="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
+config_location=${script_location}/config.cfg
echo "=== USB Emoncms import start ==="
date +"%Y-%m-%d-%T"
echo "Backup module version:"
-cat $script_location/backup-module/module.json | grep version
+grep version ${script_location}/module.json
echo "EUID: $EUID"
-echo "Reading $script_location/config.cfg...."
-if [ -f "$script_location/config.cfg" ]
+echo "Reading ${config_location}...."
+if [ -f "${config_location}" ]
then
- source "$script_location/config.cfg"
+ source "${config_location}"
echo "Location of data databases: $database_path"
echo "Location of emonhub.conf: $emonhub_config_path"
echo "Location of Emoncms: $emoncms_location"
else
- echo "ERROR: Backup $script_location/backup/config.cfg file does not exist"
+ echo "ERROR: Backup config file ${config_location} does not exist"
exit 1
fi