From 2ef2e2c1c255c3642e6b152595e2dc95488c2c10 Mon Sep 17 00:00:00 2001 From: Ian Kelling Date: Thu, 10 Nov 2016 00:58:38 -0800 Subject: [PATCH] wip using btrfs send for sync --- btrbk-run | 220 +++++++++++++++++++++++++++++++++++++------------ distro-begin | 48 +++++++---- distro-end | 3 +- postfix-setup | 223 +++++++++++++++++++++++++++++++++----------------- 4 files changed, 352 insertions(+), 142 deletions(-) diff --git a/btrbk-run b/btrbk-run index 9ca4eb3..4f4739d 100755 --- a/btrbk-run +++ b/btrbk-run @@ -5,32 +5,103 @@ trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?" >&2' ERR [[ $EUID == 0 ]] || exec sudo -E "$BASH_SOURCE" "$@" +usage() { + echo "top of script file:" + sed -n '1,/^[# ]*end command line/{p;b};q' "$0" + exit $1 +} + conf_only=false -dry_run=false -# mostly for testing -case $1 in - -c) conf_only=true ;; - -n) dry_run=true ;; - ?*) echo "$0: error: unsupported arg"; exit 1 ;; -esac - -# background on timezones. with short/long, timestamps use local time. -# for long, if your local time moves backwards, by moving timezones or -# for an hour when daylight savings changes it, you will temporarily get -# a more aggressive retention policy for the overlapping period, and -# vice versa for the opposite timezone move. The alternative is using -# long-iso, which puts timezone info into the timestamp, which means -# that instead of shifting time, you shift the start of day/week/month -# which is used for retention to your new local time, which means for -# example, if you moved forward by 8 hours, the daily/weekly/monthly -# retention will be 8 hours more aggressive since midnight is at a new -# time, unless you fake the timzeone using the TZ env variable. -# However, in the short term, there will be no inconsistencies. -# I don't see any problem with shifting when the day starts for -# retention, so I'm using long-iso. +dry_run=false # mostly for testing + +temp=$(getopt -l help,long-opt hcnt "$@") || usage 1 +eval set -- "$temp" +while true; do + case $1 in + -c) conf_only=true; shift ;; + -n) dry_run=true; dry_run_arg=-n; shift ;; + -t) IFS=, targets=($2); shift 2 ;; + -h|--help) usage ;; + --) shift; break ;; + *) echo "$0: Internal error!" ; exit 1 ;; + esac +done +read primary <<<"$@" + +##### end command line parsing ######## + +sed="sed -r --follow-symlinks" +last_snaps=() + +target-section() { + local root=$1 + local subvol=$2 + mountpoint $root &>/dev/null || return + cat >>/etc/btrbk.conf </etc/btrbk.conf <<'EOF' +last-snap() { + vol=${1##*/} + cd /mnt/root + last_snap=$( + for f in $vol.20*; do + printf "%s %s\n" $(date -d $(sed -r 's/(.{4})(..)(.{5})(..)(.*)/\1-\2-\3:\4:\5/' <<<${f#$vol.}) +%s) $f + done | sort -r | head -n 1 | awk '{print $2}' + ) + last_snaps+=($last_snap) +} + +# note q is owned by root:1000 +# note p is owned 1000:1000 and chmod 700 +mountpoints=(/q) +if mountpoint /p; then + mountpoints+=(/p) +fi + +if [[ ! $targets ]]; then + case $HOSTNAME in + tp|x2) + if ! timeout -s 9 10 ssh frodo :; then + targets=($HOME_DOMAIN) + fi + ;; + esac + targets=(frodo) +fi + + +# umount first to ensure we don't have any errors +# todo: do some kill fuser stuff to make umount more reliable +# todo: setup sync systemd timer on $primary, once per hour. +# todo: setup lock so that if this is already running, we exit out, so +# that manual runs don't interfere with cronjobs. +if [[ $primary ]] && ! $dry_run; then + for m in ${mountpoints[@]}; do + # note, this won't work for /i, due to path being /mnt/iroot + # todo: include /i for treetowl/frodo + btrfs property set -ts /mnt/root$m ro true + ssh root@$primary bash </etc/btrbk.conf <<'EOF' ssh_identity /root/.ssh/id_rsa transaction_syslog daemon @@ -54,36 +125,15 @@ target_preserve_min 6h # btrbk -l debug -v dryrun EOF + remote_target="target send-receive ssh://${tg}/mnt/root" -case $HOSTNAME in - tp|x2) - if ! timeout -s 9 10 ssh frodo :; then - target_host=$HOME_DOMAIN - cat >>/etc/btrbk.conf </dev/null || return - cat >>/etc/btrbk.conf <&2' ERR -# dunno why debian installed postfix with builddep emacs -# but I will just explicitly install it here since -# I use it for sending mail in emacs. -if private-host; then - relayhost="[mail.messagingengine.com]:587" -else - # ses initially suggests port 25, but I had problems connecting to that. - relayhost="[email-smtp.us-west-2.amazonaws.com]:587" -fi -if isdeb; then - s debconf-set-selections <&2' ERR + +type=$1 +postfix() { [[ $type == postfix ]]; } +exim() { [[ $type == exim ]]; } +if ! exim && ! postfix; then + echo "$1: error: expected exim or postfix as first arg" + exit 1 fi +if private-host; then + host=mail.messagingengine.com + forward=$HOSTNAME@$PERSONAL_DOMAIN +else + # ses initially suggests port 25, but I had problems connecting to that. + host=email-smtp.us-west-2.amazonaws.com + forward=$HOSTNAME@$IMPERSONAL_DOMAIN +fi -# This also works instead of ~/.forward +relayhost="[$host]:587" # postfix +smarthost="$host::587" # exim + +# background: This also works instead of ~/.forward # s sed -i --follow-symlinks '/^root/d' /etc/aliases ||: #echo "root: $HOSTNAME@$SOME_DOMAIN" | s tee -a /etc/aliases # this can't be a symlink and has permission restrictions # it might work in /etc/aliases, but this seems more proper. - -if s grep amazonaws /etc/postfix/sasl_passwd &>/dev/null; then - forward=$HOSTNAME@$IMPERSONAL_DOMAIN -else - forward=$HOSTNAME@$PERSONAL_DOMAIN -fi e $forward > ~/.forward e $forward | s tee /root/.forward # linode image has a root alias. completely useless, remove it. sudo sed -i '/^root:/d' /etc/aliases - s newaliases -# if I wanted the from address to be renamed and sent to a different address, -# echo "sdx@localhost development@localhost" | sudo dd of=/etc/postfix/recipient_canonical -# sudo postmap hash:/etc/postfix/recipient_canonical -# sudo service postfix reload +# offlineimap uses this too, it is much easier to use one location than to +# condition it's config and postfix's config +case $distro in + fedora) s lnf -T ca-certificates.crt /etc/ssl/ca-bundle.trust.crt ;; + *) : +esac + +read -r domain pass < <(s cat /etc/mailpass) +if postfix; then + # dunno why, but debian installed postfix with builddep emacs + # but I will just explicitly install it here since + # I use it for sending mail in emacs. + if isdeb; then + s debconf-set-selections </dev/null + s postmap hash:/etc/postfix/sasl_passwd + s service postfix reload +else + # wording of question from dpkg-reconfigure exim4-config + # 1. internet site; mail is sent and received directly using SMTP + # 2. mail sent by smarthost; received via SMTP or fetchmail + # 3. mail sent by smarthost; no local mail + # 4. local delivery only; not on a network + # 5. no configuration at this time + + # default mailname is $HOSTNAME.lan, + # mailname makes addresses like "root" be root@mailname + # and a qualified domain does not get forwarded per + # .forward. whatever, this fixes that. + s debconf-set-selections </dev/null + # https://blog.dhampir.no/content/make-exim4-on-debian-respect-forward-and-etcaliases-when-using-a-smarthost + # i only need .forwards, so just doing that one. + cd /etc/exim4/conf.d/router + a=userforward + b=${a}_higher_priority + tmp=$(mktemp) + of=175_$b + # sed to make the router name unique + sed -r s/^\\S+:/$b:/ 600_exim4-config_$a >$tmp + if diff -q >/dev/null $tmp $of; then + s dd if=$tmp of=$of >/dev/null + ser restart exim4 + fi +fi + +# based on http://www.postfix.org/qmgr.8.html and my notes in gnus +dir=/nocow/$type +sdir=/var/spool/$type +if [[ $(readlink -f $sdir) != $dir ]]; then + ser stop $type + if [[ ! -e $dir && -d $sdir ]]; then + s mv $sdir $dir + fi + s lnf -T $dir $sdir +fi + +sgo $type -s postmap hash:/etc/postfix/sasl_passwd -# offlineimap uses this too, it is much easier to use one location than to -# condition it's config and postfix's config -case $distro in - fedora) s lnf -T ca-certificates.crt /etc/ssl/ca-bundle.trust.crt ;; - *) : -esac -s service postfix reload -sgo postfix +# if I wanted the from address to be renamed and sent to a different address, +# echo "sdx@localhost development@localhost" | sudo dd of=/etc/postfix/recipient_canonical +# sudo postmap hash:/etc/postfix/recipient_canonical +# sudo service postfix reload -- 2.30.2