aboutsummaryrefslogtreecommitdiff
path: root/variables
diff options
context:
space:
mode:
authorEinhard Leichtfuß <alguien@respiranto.de>2019-10-18 00:28:00 +0200
committerEinhard Leichtfuß <alguien@respiranto.de>2019-10-18 01:17:39 +0200
commit4e2ceb9875c81c33b09f6eaf0858b7f9591b22cc (patch)
treebe3860dc8c26b3c18a30c2a81b58e00025b98069 /variables
parent51f58d7c4c984ec8ccc5ab0a3d31d04cd39d499c (diff)
Restructure, and rewrite substantial partsHEADmasterdevel
A notable problem (to me) with the former version was, that upon simple movements in the source file tree, these would in general cause duplicated data in the backup forest. This problem has been resolved by essentially tracking file movements, using hard links. Also, the code has been divided into several different files, extranous code removed, the organization of remote code execution simplified. In the process of simplification, all parts requiring direct interaction of the user with the program have been replaced. In most cases, this means that the program now just terminates with an error instead of allowing the user to confirm deletion of an unexpected (remnant) file. This may be considered a drawback, but actually these interactive options were anyways suboptimal solutions in most cases - where they occured, which was due to remnant files of aborted or failed former backups. In general, there have been a lot of changes. Which are not thoroughly documented here. Since there is often no strong relation to the old code, this is not deemed necessary, as the in-code documentation is expected to be of sufficient help. Also, there has been added a little general documentation in the README and particularly the NOTES file. It is to be noted that this new version is far from sophisticated. It has been tested with and is in use for real data, however lacks a lot of convenience. In particular, if a backup fails unexpectedly, the next backup will in the very most cases loudly fail without manual intervention. Also, the program is not able to continue the growth of a backup tree built with former versions of this program, by itself. This can however be arranged by hand.
Diffstat (limited to 'variables')
-rw-r--r--variables211
1 files changed, 211 insertions, 0 deletions
diff --git a/variables b/variables
new file mode 100644
index 0000000..e3eb451
--- /dev/null
+++ b/variables
@@ -0,0 +1,211 @@
+#!/usr/bin/env bash
+#
+# variables.
+#
+# Copyright 2015 - 2019 Einhard Leichtfuß
+#
+# This file is part of rsync-backup.
+#
+# rsync-backup is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# rsync-backup is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with rsync-backup. If not, see <https://www.gnu.org/licenses/>.
+#
+
+
+## CONSTANTS
+typeset -r CONFIG=/etc/rsync-backup/config
+
+typeset -r RET_TYPES='
+ RET_SUCCESS RET_FAILURE RET_BADSYNTAX RET_FILE_ERR RET_ERROR'
+typeset -r RET_SUCCESS=0
+typeset -r RET_FAILURE=1
+typeset -r RET_BADSYNTAX=2
+typeset -r RET_FILE_ERR=4
+typeset -r RET_ERROR=8
+
+typeset -r DATEFMT='%Y-%m-%d_%H%M%S'
+
+# Shell options:
+# nullglob: In case of a non-matching glob, return nothing.
+# dotglob: Include dotfiles (except . and ..) in glob matching.
+typeset -r SHOPTS='dotglob'
+typeset -r SHOPTS_AFTER_GET_ARGS='nullglob'
+
+# Always give these variables and functions to remotely executed commands,
+# as they are very commonly used.
+# These will not be listed as required.
+# Note that $host is given as argument to run_function.
+typeset -r REMOTE_DEFAULT_VARS="$RET_TYPES verbose debug host"
+typeset -r REMOTE_DEFAULT_FUNS='prefixed_write message debug error
+ debug_error'
+
+
+## Global program variables.
+typeset src src_path src_host
+typeset dest dest_path dest_host
+typeset -a filter_args
+typeset -i n
+
+
+## Variables that may be configured.
+typeset RSYNC=rsync
+
+typeset verbose=true
+typeset debug=true
+
+# Location to put mirrored trees on the source.
+typeset src_mirror_reldir='.backup'
+
+typeset -a rsync_base_args
+typeset -a rsync_mirror_args
+typeset -a rsync_transfer_args
+typeset -A bakpath
+typeset -A filter_file
+typeset filter_file_all # Applied after specific filter.
+
+# Base arguments for rsync (-rptogAXlHS, --timeout=, --numeric-ids, --info=).
+# These are used both for creation of the source mirror and the transfer of
+# that mirror to the destination. In both cases, attributes may be added.
+rsync_args=(
+ --recursive
+ --perms --times --owner --group
+ --acls --xattrs
+ --links
+ --hard-links
+ --sparse
+ --numeric-ids
+ --timeout=60
+ #-vv
+ --info=progress2
+ )
+
+source "$CONFIG"
+
+
+# Set the globabl variables $src, $dest_path and $filter_args according to
+# command line parameters and the configuration.
+#
+# $@: command line parameters
+#
+# requires the shell option nullglob to be _unset_. (for test -v to work)
+#
+function get_args
+{
+ if [ $# -eq 0 ]
+ then
+ message "Usage: $exec_name <src> [<dest>]" 2>&1
+ return $RET_BADSYNTAX
+ fi
+
+ local l_src="$1"
+ local l_dest
+
+ # Set $src_path, $src_host and $src.
+ resolve_host_path src "$l_src" || return $?
+
+ if [ $# -gt 1 ]
+ then
+ l_dest="$2"
+ elif [[ -v bakpath[$src] ]] # $# -eq 1
+ then
+ l_dest="${bakpath[$src]}"
+ else
+ error "Backup path for \"$src\" neither configured" \
+ "nor specified on command line."
+
+ return $RET_BADSYNTAX
+ fi
+
+ # Set $dest_path, $dest_host and $dest.
+ resolve_host_path dest "$l_dest" || return $?
+
+ filter_args=()
+ if [[ -v filter_file[$src] && -f "${filter_file[$src]}" ]]
+ then
+ filter_args+=("--filter=merge ${filter_file[$src]}")
+ fi
+ if [[ -v filter_file_all && -f "$filter_file_all" ]]
+ then
+ filter_args+=("--filter=merge ${filter_file_all}")
+ fi
+
+ return $RET_SUCCESS
+}
+
+
+# Split host:target like rsync and convert local (!) relative paths to
+# absolute ones. This is needed at least for $src_path which is used as
+# key for associative arrays.
+#
+# The results are written to the global variables $<vtype>, $<vtype>_host
+# and $<vtype>_path, where <vtype> is either src or dest. $<vtype> gets
+# set to the original to be resolved string, unless we are local, i.e.
+# there is no host.
+#
+# Note: This is not a place for bash to shine. Perl for instance would do
+# this much more easily.
+#
+# Examples:
+# - a:b -> (a, b)
+# - a/b:c -> ('', a/b:c)
+#
+# $1: which global variables to set: (src|dest)
+# $2: path string potentially containing host prefix
+#
+# sets: ${$1}_host: host name (may be empty)
+# ${$1}_path: path (absolute, if local, i.e. ${$1}_host='')
+# ${$1}: ${$1}_path, if ${$1}_host='',
+# ${$1}_host:${$1}_path (= $2), elsewise.
+#
+function resolve_host_path
+{
+ local vtype="$1"
+ local combined="$2"
+ local host path
+
+ # Split host and path.
+ host=${combined%%:*}
+ if [[ "$host" == "$combined" || "$host" =~ '/' ]]
+ then
+ host=''
+ path="$combined"
+
+ # Resolve to absolute directory.
+ # pwd -P avoids symlinks.
+ # Do not resolve symlimks in ${path} or test for its existance.
+ # `- realpath could do that.
+ if ! [[ "$path" =~ / ]]
+ then
+ path="$(pwd -P)/${path}"
+ fi
+
+ combined="$path"
+ else
+ path="${combined#*:}"
+ fi
+
+ # Set global variables.
+ if [[ "$vtype" == 'src' ]]
+ then
+ src_host="$host"
+ src_path="$path"
+ src="$combined"
+ else # "$vtype" == 'dest'
+ dest_host="$host"
+ dest_path="$path"
+ dest="$combined"
+ fi
+
+ return $RET_SUCCESS
+}
+
+# vi: ft=bash ts=2 sw=2 noet