summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVon Random <von@mechanus.net>2014-12-22 17:28:49 +0300
committerVon Random <von@mechanus.net>2014-12-22 17:28:49 +0300
commit54436c3cf27fa38eddb1d40ce3dd31bad096cfc0 (patch)
treec022846e285b64572c7f5dbe4e62f3b3237eec70
parent2e0cd8f7afed65b1f5334825de2ac6a8b044f5ec (diff)
some refactoring + support for multiple directories with and without incremental backups
-rw-r--r--backup.cfg4
-rwxr-xr-xbackup.zsh107
2 files changed, 62 insertions, 49 deletions
diff --git a/backup.cfg b/backup.cfg
index 1eab0a6..a676cf2 100644
--- a/backup.cfg
+++ b/backup.cfg
@@ -1,5 +1,4 @@
protocol=ssh # ftp, sftp, ftps, ssh or local
-source_dir=/home/user/source
remote_host=hostname.tld
backup_dir=relative_or_full_path
#snap_file=/var/backup/snapshot.list
@@ -7,3 +6,6 @@ backup_dir=relative_or_full_path
compress_format=xz # gz, bz2, xz or empty for non-compressed
remote_user=username
remote_pass=PassWd
+source_dirs=( '/home/user/source1:/var/backup/snapshot.list' )
+
+# vim: ft=zsh
diff --git a/backup.zsh b/backup.zsh
index 8c91f7c..5d7e64a 100755
--- a/backup.zsh
+++ b/backup.zsh
@@ -1,17 +1,16 @@
#!/usr/bin/env zsh
-set -e
self_name=$0
+default_cfg='/usr/local/etc/backup.cfg'
+default_postfix=$(date +%F-%H%M)
function err
{
- [[ -n $2 ]] && echo $2 >&2
- return $1
+ [[ -n $1 ]] && echo $1 >&2
}
function cfg_err
{
[[ -n $1 ]] && echo "$1 is not set in configuration, but is required by $0 to work." >&2
- return 5
}
function usage
@@ -19,50 +18,35 @@ function usage
echo "usage: $self_name [--help|--config]
--help -h - show this message
--config -c - use config from the specified path
-
+
Default config path /usr/local/etc/backup.cfg will be used if invoked without options"
}
-function read_config
+# function to read the configuration file and spit out some exceptions if stuff is missing
+function apply_config
{
source $cfg || err 15 'Config file does not exist'
- [[ -z $source_dir ]] && cfg_err 'Backup source'
- [[ -z $remote_host ]] && cfg_err 'Remote host'
- [[ -z $protocol ]] && cfg_err 'Backup protocol'
- [[ -z $backup_dir && $protocol != 'ssh' ]] && cfg_err 'Target directory'
+ [[ -z $source_dirs ]] && { cfg_err 'Backup source'; exit 5 }
+ [[ -z $remote_host ]] && { cfg_err 'Remote host'; exit 5 }
+ [[ -z $protocol ]] && { cfg_err 'Backup protocol'; exit 5 }
+ [[ -z $backup_dir && $protocol != 'ssh' ]] && { cfg_err 'Target directory'; exit 5 }
if [[ -z $local_host ]]; then
local_host=$HOST
fi
- src_basename=${source_dir:t}
- src_basedir=${source_dir:h}
-}
-
-function generate_fullpath
-{
- local backup_type
- local postfix
+ # date postfix
if [[ -z $outfile_postfix ]]; then
postfix=$default_postfix
else
postfix=$outfile_postfix
fi
- if [[ -s $snap_file ]]; then
- backup_type='incr'
- else
- backup_type='full'
- fi
- if [[ -z $backup_filename ]]; then
- outfile="$backup_dir/${local_host}-${src_basename}_${postfix}_${backup_type}.t${compress_format:-'ar'}"
- else
- outfile=$backup_filename
+ if [[ -z $remote_port ]]; then
+ case $protocol in
+ ('ftp'|'ftps') remote_port='21';;
+ ('sftp'|'ssh') remote_port='22';;
+ ('local') unset remote_port;;
+ (*) err 1 "$protocol is not a valid value for the protocol option.";;
+ esac
fi
-}
-
-function compress # compress to stdout
-{
- local compress_flag
- local exclude_option
- local snapshot_option
case $compress_format in
('xz') compress_flag='J' ;;
('bz2') compress_flag='j' ;;
@@ -84,19 +68,32 @@ function compress # compress to stdout
err 1 "Snapshot file $snap_file cannot be written."
fi
fi
+}
+
+# generate the full backup path
+function generate_fullpath
+{
+ local backup_type
+ # increment or full backup
+ if [[ -s $snap_file ]]; then
+ backup_type='incr'
+ else
+ backup_type='full'
+ fi
+ if [[ -z $backup_filename ]]; then
+ outfile="$backup_dir/${local_host}-${src_basename}_${postfix}_${backup_type}.t${compress_format:-'ar'}"
+ else
+ outfile=$backup_filename
+ fi
+}
+
+function compress # compress to stdout
+{
tar cf$compress_flag - -C $src_basedir $src_basename $snapshot_option $snapshot_file $exclude_option $exclude_list --ignore-failed-read
}
function store # store to local or remote
{
- if [[ -z $remote_port ]]; then
- case $protocol in
- ('ftp'|'ftps') remote_port='21';;
- ('sftp'|'ssh') remote_port='22';;
- ('local') unset remote_port;;
- (*) err 1 "$protocol is not a valid value for the protocol option.";;
- esac
- fi
case $protocol in
('local') dd of=$outfile ;;
('ssh') ssh -p$remote_port $remote_user@$remote_host "dd of=$outfile" ;;
@@ -105,7 +102,7 @@ function store # store to local or remote
esac
}
-function main
+function parse_opts
{
while [[ -n $1 ]]; do
case $1 in
@@ -113,11 +110,25 @@ function main
('--config'|'-c') shift; opt_cfg=$1; shift;;
esac
done
- cfg=${opt_cfg:-'/usr/local/etc/backup.cfg'}
- default_postfix=$(date +%F-%H%M)
- read_config
- generate_fullpath
- compress | store
+}
+
+function main
+{
+ parse_opts
+ if [[ -z $opt_cfg ]]; then
+ cfg=$default_cfg
+ else
+ cfg=$opt_cfg
+ fi
+ apply_config
+ for i in $source_dirs; do
+ unset src_basename src_basedir outfile
+ IFS=':' read source_dir snap_file <<< $i
+ src_basename=${source_dir:t}
+ src_basedir=${source_dir:h}
+ generate_fullpath
+ compress | store
+ done
return 0
}