Commit 035d54fa authored by HerrHase's avatar HerrHase

smaller refactoring add cleaning code

parent c316055a
......@@ -4,6 +4,10 @@ A simple bash-script to backup with tar, split and gpg.
## History
### Version 1.1.2
* smaller refactoring add cleaning code
### Version 1.1.1
**Bugfix**
......@@ -48,7 +52,7 @@ For more information show [https://rsync.samba.org/](https://rsync.samba.org/).
### ssh-key
Generate a ssh-key to authenficate on the Remote-Server.
Generate a ssh-key to authenficate on the Remote-Server.
```
ssh-keygen -t rsa -b 4096 -C "your-email@example.com"
......@@ -87,6 +91,27 @@ Your decision? 5
Do you really want to set this key to ultimate trust? (y/N) y
```
### gpg-agent
Cronjob maybe don't load the gpg-agent.
```bash
#!/usr/bin/env bash
envfile="${HOME}/.gnupg/gpg-agent.env"
if test -f "$envfile" && kill -0 $(grep GPG_AGENT_INFO "$envfile" | cut -d: -f 2) 2>/dev/null; then
eval "$(cat "$envfile")"
else
eval "$(gpg-agent --daemon --write-env-file "$envfile")"
fi
export GPG_AGENT_INFO # the env file does not contain the export statement
```
```bash
*/5 * * * * source /home/<username>/.gnupg/gpg-agent.env && export GPG_AGENT_INFO && cd <backup-tar> && ./backup.sh
```
[https://blog.tenak.net/2012/11/2012-11-gpg-agent.html](https://blog.tenak.net/2012/11/2012-11-gpg-agent.html)
## Commands
### ./backup.sh
......@@ -95,7 +120,7 @@ Start the backup.
### ./restore.sh
If no argument is set, it shows a list of the last backups. To restore a Backup add the filename without file-extension that you want to download.
## Config
## Config
This Scripts works with a config-file. Each command has the option "--config-file" to set the path to the
config-file. If you not set the option it will show in the directory of the Script.
......@@ -106,7 +131,7 @@ That is the directories and files you want to backup.
### work_directory
The **work_directory** is created during the backup and also if you restore files. If a backup runs and you dump data from
databases these files will write in this directory. After the backup the directory will be deleted. The backup and restore will only starts
if the directory don't exists.
if the directory don't exists.
### remote_username
### remote_host
......@@ -115,7 +140,7 @@ if the directory don't exists.
The number of days to preserve old backups, if files are older the will be deleted after the backup.
### optional: gpg_key_id
To encrypt data add the id of the gpg-key.
To encrypt data add the id of the gpg-key.
### optional: excludes
Exclude files and directories.
......@@ -124,7 +149,7 @@ Exclude files and directories.
### optional: remote_port
Port of ssh service on Remote Server, default is set to 22.
### optional: mysql_username
### optional: mysql_username
### optional: mysql_password
### optional: mysql_host
Host of mysql, default is set to "localhost"
\ No newline at end of file
Host of mysql, default is set to "localhost"
......@@ -10,23 +10,23 @@ set -o errexit
set -o pipefail
set -o nounset
_config_file=$(dirname "$0")/.config
targets=''
mysql_username=''
mysql_password=''
mysql_host='localhost'
work_directory=''
dumps_directory='dumps'
remote_username=''
remote_host=''
remote_port=22
remote_directory=''
max_age=0
chunk_size=10g
gpg_key_id=''
prefix=''
excludes=''
_config_file='.config'
# defaults for .config-file
export targets=''
export mysql_username=''
export mysql_password=''
export mysql_host='localhost'
export work_directory=''
export remote_username=''
export remote_host=''
export remote_port=22
export remote_directory=''
export max_age=0
export chunk_size=10g
export gpg_key_id=''
export prefix=''
export excludes=''
#
# options
......@@ -60,22 +60,17 @@ _config_validate()
local error=false
# check if config file is set and load it
if [ -f $_config_file ]; then
source $_config_file
else
echo "Whoops, $_config_file not found"
if [ -f "${_config_file}" ]; then
source "${_config_file}"
else
echo "Whoops, ${_config_file} not found"
exit 0
fi
# check if config file has chmod 600
if [ "$(stat --format '%a' $_config_file)" != '600' ]; then
echo "Whoops, $_config_file has wrong Permissions, set 600"
exit 0
fi
# check if work_directory is set, if not set default
if [ -z "${work_directory}" ]; then
work_directory="$HOME/backup"
if [ "$(stat --format '%a' "${_config_file}")" != '600' ]; then
echo "Whoops, ${_config_file} has wrong Permissions, set this to 600"
error=true
fi
# check if files are set
......@@ -85,23 +80,40 @@ _config_validate()
fi
# check if remote user is set
if [ -z "${remote_username}" ]; then
if [ -z "${remote_username}" ]; then
echo "Whoops, \"remote_user\" has to be set in .config"
error=true
fi
# check if remote host is set
if [ -z "${remote_host}" ]; then
if [ -z "${remote_host}" ]; then
echo "Whoops, \"remote_host\" has to be set in .config"
error=true
fi
# if any error shows up, exit
# if any error shows up, exit
if [ "${error}" = true ]; then
exit 0
fi
}
#
# defaults
#
#
_config_defaults()
{
# check if work_directory is set, if not set default
if [ -z "${work_directory}" ]; then
work_directory="$HOME/backup"
fi
# adding trailing slash to remote_directory if set
if [ -n "${remote_directory}" ] && [[ "${remote_directory}" =~ /?([?\#]+.+)?$ ]]; then
remote_directory+="/"
fi
}
#
# init
#
......@@ -109,17 +121,17 @@ _config_validate()
_config_init()
{
local error=false
# check if work directory is already in use
if [ -d "${work_directory}" ]; then
if [ -d "${work_directory}" ]; then
echo "Whoops, ${work_directory} already in use, please change work_directory or delete it"
error=true
fi
# if any error shows up, exit
# if any error shows up, exit
if [ "${error}" = true ]; then
exit 0
fi
mkdir -p ${work_directory}
}
\ No newline at end of file
mkdir -p "${work_directory}"
}
......@@ -8,7 +8,7 @@
# @author Björn Hase
#
source $(dirname "$0")/_config.sh
source "$(dirname "$0")/_config.sh"
set -o errexit
set -o pipefail
......@@ -34,14 +34,14 @@ _download_validate()
local error=false
if [ -z "${_download_filename}" ]; then
echo -e "Whoops! \$1 must be the filename you want to download"
echo -e "Whoops! <\$1> must be the filename you want to download"
error=true
fi
# if any error shows up, exit
# if any error shows up, exit
if [ ${error} = true ]; then
exit 0
fi
fi
}
#
......@@ -60,8 +60,8 @@ _download_main()
_download_remote_path="${remote_directory}/"
fi
rsync -avH --include="${_download_filename}*" --exclude="*" -e 'ssh -p'${remote_port}'' ${remote_username}@${remote_host}:${_download_remote_path} "${work_directory}"
rsync -avH --include="${_download_filename}*" --exclude="*" -e 'ssh -p '"${remote_port}"'' "${remote_username}"@"${remote_host}":"${remote_directory}" "${work_directory}"
}
# let it rain
_download_main "$@"
\ No newline at end of file
_download_main "$@"
......@@ -10,7 +10,7 @@
# @author Björn Hase
#
source $(dirname "$0")/_config.sh
source "$(dirname "$0")/_config.sh"
set -o errexit
set -o pipefail
......@@ -38,10 +38,10 @@ _gpg_decrypt_validate()
error=true
fi
# if any error shows up, exit
if [ ${error} = true ]; then
# if any error shows up, exit
if [ "${error}" = true ]; then
exit 0
fi
fi
}
#
......@@ -56,20 +56,21 @@ _gpg_decrypt_main()
_gpg_decrypt_options "$@"
_gpg_decrypt_validate
if [ ! -z "$gpg_key_id" ]; then
if [ -n "$gpg_key_id" ]; then
for encrypt_filename in $(find ${work_directory} -name "${_gpg_decrypt_filename}*.gpg" 2> /dev/null); do
# get decrypted filename
local decrypt_filename=${encrypt_filename//.gpg/}
local decrypt_filename
decrypt_filename="${encrypt_filename//.gpg/}"
# decrypt
gpg --output "${decrypt_filename}" --decrypt ${encrypt_filename}
gpg --output "${decrypt_filename}" --decrypt "${encrypt_filename}"
# delete encrypted file
rm ${encrypt_filename}
rm -f -v "${encrypt_filename}"
done
fi
}
# let it rain
_gpg_decrypt_main "$@"
\ No newline at end of file
_gpg_decrypt_main "$@"
......@@ -10,7 +10,7 @@
# @author Björn Hase
#
source $(dirname "$0")/_config.sh
source "$(dirname "$0")/_config.sh"
set -o errexit
set -o pipefail
......@@ -38,10 +38,10 @@ _gpg_encrypt_validate()
error=true
fi
# if any error shows up, exit
if [ ${error} = true ]; then
# if any error shows up, exit
if [ "${error}" = true ]; then
exit 0
fi
fi
}
#
......@@ -56,13 +56,13 @@ _gpg_encrypt_main()
_gpg_encrypt_options "$@"
_gpg_encrypt_validate
if [ ! -z "$gpg_key_id" ]; then
if [ -n "$gpg_key_id" ]; then
for filename in $(find ${work_directory} -name "${_gpg_encrypt_filename}*" 2> /dev/null); do
gpg --output ${filename}.gpg --encrypt --recipient ${gpg_key_id} ${filename}
rm ${filename}
gpg --output "${filename}".gpg --encrypt --recipient "${gpg_key_id}" "${filename}"
rm -f -v "${filename}"
done
fi
}
# let it rain
_gpg_encrypt_main "$@"
\ No newline at end of file
_gpg_encrypt_main "$@"
......@@ -10,7 +10,7 @@
# @author Björn Hase
#
source $(dirname "$0")/_config.sh
source "$(dirname "$0")/_config.sh"
set -o errexit
set -o pipefail
......@@ -38,10 +38,10 @@ _join_validate()
error=true
fi
# if any error shows up, exit
if [ ${error} = true ]; then
# if any error shows up, exit
if [ "${error}" = true ]; then
exit 0
fi
fi
}
#
......@@ -56,13 +56,13 @@ _join_main()
_join_options "$@"
_join_validate
local parts=$(find ${work_directory} -regex '.+\.[0-9]+' | sort -t'/' -n -k10)
local parts=$(find "${work_directory}" -regex '.+\.[0-9]+' | sort -t'/' -n -k10)
if [ ! -z "${parts}" ]; then
cat ${parts} > "${work_directory}/${_join_filename}"
rm ${parts}
rm -f -v "${parts}"
fi
}
# let it rain
_join_main "$@"
\ No newline at end of file
_join_main "$@"
......@@ -11,7 +11,7 @@
# @author Björn Hase
#
source $(dirname "$0")/_config.sh
source "$(dirname "$0")/_config.sh"
set -o errexit
set -o pipefail
......@@ -26,8 +26,8 @@ readonly _mysql_ignore="(^mysql|_schema$)"
#
_mysql_databases()
{
local sql="SHOW DATABASES WHERE \`Database\` NOT REGEXP '$_mysql_ignore'"
echo $(mysql --user=$mysql_username --password=$mysql_password --host=$mysql_host -e "$sql"|awk -F " " '{if (NR!=1) print $1}')
local sql="SHOW DATABASES WHERE \`Database\` NOT REGEXP '"${_mysql_ignore}"'"
echo $(mysql --user="${mysql_username}" --password="${mysql_password}" --host="${mysql_host}" -e "${sql}"|awk -F " " '{if (NR!=1) print $1}')
}
#
......@@ -42,9 +42,9 @@ _mysql_main()
# dump each database that you get from _mysql_databases
for database in $(_mysql_databases)
do
mysqldump --user=$mysql_username --password=$mysql_password --host=$mysql_host $database > "${work_directory}/${_mysql_prefix_file}-${database}.sql"
mysqldump --user="${mysql_username}" --password="${mysql_password}" --host="${mysql_host}" "${database}" > "${work_directory}/${_mysql_prefix_file}-${database}.sql"
done
}
# let it rain
_mysql_main "$@"
\ No newline at end of file
_mysql_main "$@"
#!/usr/bin/env bash
#
# packing files and spilt them if the are bigger
# than the chunk_size
#
# Usage:
# tar.sh
......@@ -10,7 +12,7 @@
# @author Björn Hase
#
source $(dirname "$0")/_config.sh
source "$(dirname "$0")/_config.sh"
set -o errexit
set -o pipefail
......@@ -38,30 +40,32 @@ _tar_validate()
error=true
fi
# if any error shows up, exit
if [ ${error} = true ]; then
# if any error shows up, exit
if [ "${error}" = true ]; then
exit 0
fi
fi
}
#
# get excludes, adding current $work_directory to ignore tar
# and add all files from exludes in config
#
#
#
#
_tar_get_excludes()
{
_tar_excludes=(--exclude="${work_directory}")
{
_tar_excludes=(--exclude="${work_directory}/${_tar_filename}")
if [ ! -z "${excludes}" ]; then
if [ -n "${excludes}" ]; then
# set delimiter
IFS=' '
read -ra excludes <<< "$excludes"
for value in "${excludes[@]}"; do
for value in ${excludes[@]}; do
_tar_excludes+=(--exclude="${value}")
done
fi
fi
}
#
......@@ -70,29 +74,32 @@ _tar_get_excludes()
#
_tar_main()
{
local _tar_fikesize
_config_options "$@"
_config_validate
_tar_options "$@"
_tar_validate
_tar_get_excludes
_tar_filename="${_tar_filename}.tar.bz2"
_tar_get_excludes
if [ ! -z "${mysql_username}" ] && [ ! -z "${mysql_password}" ]; then
if [ -n "${mysql_username}" ] && [ -n "${mysql_password}" ]; then
targets="${targets} ${work_directory}/*.sql"
fi
# tar the files
tar ${_tar_excludes[@]} -cvzf ${work_directory}/${_tar_filename} ${targets}
tar "${_tar_excludes[@]}" -cvzf "${work_directory}/${_tar_filename}" ${targets}
local _tar_filesize=$(find ${work_directory} -name "${_tar_filename}" -size +$(echo ${chunk_size} | tr a-z A-Z) | wc -l)
# check filesize of archive
_tar_filesize=$(find "${work_directory}" -name "${_tar_filename}" -size +$(echo "${chunk_size}" | tr a-z A-Z) | wc -l)
if [ $_tar_filesize -gt 0 ]; then
split -b ${chunk_size} -a 1 -d "${work_directory}/${_tar_filename}" "${work_directory}/${_tar_filename}."
rm "${work_directory}/${_tar_filename}"
if [ "$_tar_filesize" -gt 0 ]; then
split -b "${chunk_size}" -a 1 -d "${work_directory}"/"${_tar_filename}" "${work_directory}"/"${_tar_filename}."
rm -v -f "${work_directory}"/"${_tar_filename}"
fi
}
# let it rain
_tar_main "$@"
\ No newline at end of file
_tar_main "$@"
......@@ -8,7 +8,7 @@
# @author Björn Hase
#
source $(dirname "$0")/_config.sh
source "$(dirname "$0")/_config.sh"
set -o errexit
set -o pipefail
......@@ -38,10 +38,10 @@ _upload_validate()
error=true
fi
# if any error shows up, exit
if [ ${error} = true ]; then
# if any error shows up, exit
if [ "${error}" = true ]; then
exit 0
fi
fi
}
#
......@@ -56,8 +56,8 @@ _upload_main()
_upload_options "$@"
_upload_validate
rsync -avH --include="${_upload_filename}*" --exclude="*" "${work_directory}/" -e 'ssh -p '${remote_port}'' ${remote_username}@${remote_host}:${remote_directory}
rsync -avH --include="${_upload_filename}*" --exclude="*" "${work_directory}/" -e 'ssh -p '"${remote_port}"'' "${remote_username}"@"${remote_host}":"${remote_directory}"
}
# let it rain
_upload_main "$@"
\ No newline at end of file
_upload_main "$@"
#!/usr/bin/env bash
#
# Start backup
#
# Usage:
# backup.sh
# backup.sh
#
# options
# -c|--config-file
......@@ -10,8 +11,10 @@
# @author Björn Hase
#
_backup_path=$(dirname "$0")
source "${_backup_path}/_config.sh"
source "$(dirname "$0")/_config.sh"
# find files with date --utc +%FT%TZ
readonly _backup_regex_date='^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z.tar.bz2'
set -o errexit
set -o pipefail
......@@ -25,14 +28,9 @@ _backup_tar_clean()
{
if [ -n "${max_age}" ]; then
# adding slash
if [ -n "${remote_directory}" ]; then
remote_directory="${remote_directory}/"
fi
# getting list from remote server
files=$(rsync --list-only -e 'ssh -p '"${remote_port}"'' "${remote_username}"@"${remote_host}":"${remote_directory}" | awk {'print $5'} | grep -P '^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z.tar.bz2')
files=$(rsync --list-only -e 'ssh -p '"${remote_port}"'' "${remote_username}"@"${remote_host}":"${remote_directory}" | awk {'print $5'} | grep -P ${_backup_regex_date})
echo -e "Check files on Remote Server..."
echo -e "${files[@]}"
......@@ -44,11 +42,12 @@ _backup_tar_clean()
fi
fi
rm -R -f "${work_directory}"
# delete work_directory
rm -R -f -v "${work_directory}"
}
#
# check single file if it
# check single file if it
#
#
_backup_tar_check_file()
......@@ -62,7 +61,7 @@ _backup_tar_check_file()
file_date="${file_date//_/ }"
# calculate max time and file time
max_time=$(date -d "now - ${max_age} days" +'%s')
max_time=$(date -d "now - "${max_age}" days" +'%s')
file_time=$(date -d "${file_date}" +%s)
if [ "${max_time}" -gt "${file_time}" ]; then
......@@ -76,30 +75,36 @@ _backup_tar_check_file()
#
_backup_tar_filename()
{
local filename="$(date --utc +%FT%TZ)"
local filename
if [ ! -z "${prefix}" ]; then
filename="$(date --utc +%FT%TZ)"
# add prefix
if [ -n "${prefix}" ]; then
filename="${prefix}-${filename}"
fi
echo ${filename}
echo "${filename}"
}
#
# main
#
#
_backup_tar_main()
_backup_tar_main()
{
local filename
_config_options "$@"
_config_validate
_config_defaults
_config_init
# generate filename
local filename="$(_backup_tar_filename)"
# generate filename
filename="$(_backup_tar_filename)"
# check if mysql options are set, if run mysql.sh
if [ ! -z "${mysql_username}" ] && [ ! -z "${mysql_password}" ]; then
# check if mysql options are set and run mysql.sh
if [ -n "${mysql_username}" ] && [ -n "${mysql_password}" ]; then
./_mysql.sh
fi
......@@ -111,4 +116,4 @@ _backup_tar_main()
}
# let it rain
_backup_tar_main "$@"
\ No newline at end of file
_backup_tar_main "$@"
......@@ -11,7 +11,7 @@
# @author Björn Hase
#
source $(dirname "$0")/_config.sh
source "$(dirname "$0")/_config.sh"
set -o errexit
set -o pipefail
......@@ -34,22 +34,17 @@ _restore_main()
{
_config_options "$@"
_config_validate
_config_defaults
_restore_options "$@"
if [ -z "${_restore_filename}" ]; then
# adding slash
if [ ! -z $remote_directory ]; then
remote_directory="${remote_directory}/"
fi
if [ -z "${_restore_filename}" ]; then
echo -e "No <time>, instead showing files on server"
echo -e "$(rsync --list-only -e 'ssh -p '${remote_port}'' ${remote_username}@${remote_host}:${remote_directory} | grep '.tar.bz2*')"
else
echo -e "$(rsync --list-only -e 'ssh -p '"${remote_port}"'' "${remote_username}"@"${remote_host}":"${remote_directory}" | grep '.tar.bz2*')"
else
_config_init
./_download.sh "${_restore_filename}"
./_gpg-decrypt.sh "${_restore_filename}"
./_join.sh "${_restore_filename}"
......@@ -60,4 +55,4 @@ _restore_main()
}
# let it rain
_restore_main "$@"
\ No newline at end of file
_restore_main "$@"
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment