various changes around data volumes
authorIan Kelling <ian@iankelling.org>
Sat, 26 Nov 2016 19:34:15 +0000 (11:34 -0800)
committerIan Kelling <ian@iankelling.org>
Sat, 26 Nov 2016 19:36:16 +0000 (11:36 -0800)
btrbk-run
check-subvol-stale
distro-begin
distro-end
input-setup
mount-latest-remote [new file with mode: 0755]
mount-latest-subvol

index c59faf99c9eecb0e976a532bd6e2ef00225c59f7..8cae3a79cb744f85edbd662fc192e7f6afdcaa85 100755 (executable)
--- a/btrbk-run
+++ b/btrbk-run
@@ -4,14 +4,13 @@ set -eE -o pipefail
 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
 }
 
-script_dir=$(dirname $(readlink "$BASH_SOURCE"))
+script_dir=$(dirname $(readlink -f "$BASH_SOURCE"))
 
 # todo: finish figuring out fai / distro-setup
 # initial fstab / subvol setup.
@@ -37,62 +36,36 @@ read primary <<<"$@"
 
 ##### end command line parsing ########
 
-target-section() {
-    local root=$1
-    local subvol=$2
-    mountpoint $root &>/dev/null || return
-    cat >>/etc/btrbk.conf <<EOF
-volume $root
-subvolume $subvol
-$remote_target
-
-EOF
-}
-
 rsync-dirs() {
     local host=$1
     local path=$2
     rsync $dry_run_arg -ahi --relative --delete "$path" "root@$host:/"
 }
 
+vol-conf() {
+    cat >>/etc/btrbk.conf <<EOF
+volume $vol
+EOF
+}
+sub-conf() {
+    cat >>/etc/btrbk.conf <<EOF
+subvolume $sub
+EOF
+}
+tg-conf() {
+    cat >>/etc/btrbk.conf <<EOF
+target send-receive ssh://$tg$vol/btrbk
+EOF
+}
 
-# note q is owned by root:1000
-# note p is owned 1000:1000 and chmod 700
-mountpoints=(/q)
-if awk '{print $2}' /etc/fstab | grep -xF /p &>/dev/null; then
-    mountpoints+=(/p)
-fi
 
-# if our mountpoints are from stale snapshots,
-# it doesn't make sense to do a backup.
-check-subvol-stale ${mountpoints[@]} || exit 1
 
-if [[ ! $targets ]]; then
-    case $HOSTNAME in
-        tp|x2)
-            if ! timeout -s 9 10 ssh frodo :; then
-                targets=($HOME_DOMAIN)
-            fi
-            ;;
-    esac
-    targets=(frodo)
+if ! which btrbk &>/dev/null; then
+    echo "$0: error: no btrbk binary found"
 fi
 
-
-# todo: make bash shell prompt show something when
-# a subvol on current host is not fresh.
-# umount first to ensure we don't have any errors
-# todo: do some kill fuser stuff to make umount more reliable
-# todo: run this on a systemd timer on $primary, once per hour,
-# and if primary is, change that timer over to primary, and make
-# sure we mount the latest
-# todo: setup lock so that if this is already running, we exit out, so
-# that manual runs don't interfere with cronjobs.
-
-for tg in ${targets[@]}; do
-    cat >/etc/btrbk.conf <<'EOF'
+cat >/etc/btrbk.conf <<'EOF'
 ssh_identity /root/.ssh/id_rsa
-transaction_syslog daemon
 
 # so we only run one at a time
 lockfile                   /var/lock/btrbk.lock
@@ -118,16 +91,71 @@ target_preserve_min 6h
 # btrbk -l debug -v dryrun
 EOF
 
-    remote_target="target send-receive ssh://${tg}/mnt/root/btrbk"
+# note q is owned by root:1000
+# note p is owned 1000:1000 and chmod 700
+mountpoints=(/q)
+if awk '{print $2}' /etc/fstab | grep -xF /p &>/dev/null; then
+    mountpoints+=(/p)
+fi
+
+# if our mountpoints are from stale snapshots,
+# it doesn't make sense to do a backup.
+check-subvol-stale ${mountpoints[@]} || exit 1
+
+if [[ ! $targets ]]; then
+    case $HOSTNAME in
+        tp|x2)
+            if ! timeout -s 9 10 ssh frodo :; then
+                targets=($HOME_DOMAIN)
+            fi
+            ;;
+    esac
+    targets=(frodo)
+fi
 
+
+# for i, we just do a 1 way sync from master to backup,
+# and manually manage any changes to that.
+do_i=false
+for tg in ${targets[@]}; do
+    # for an initial run, btrbk requires the dir to exist
+    ssh root@$tg mkdir -p /mnt/root/btrbk
     if [[ $tg == frodo && $HOSTNAME == treetowl ]]; then
-        target-section /mnt/iroot i
+        do_i=true
     fi
-    for d in ${mountpoints[@]}; do
-        target-section /mnt/root ${d##*/}
+done
+
+
+vol=/mnt/root
+vol-conf
+for m in ${mountpoints[@]}; do
+    sub=${m##*/}
+    sub-conf
+    for tg in ${targets[@]}; do
+        tg-conf
     done
 done
 
+if $do_i; then
+    vol=/mnt/iroot
+    vol-conf
+    sub=i
+    sub-conf
+    tg=frodo
+    vol=/mnt/root
+    tg-conf
+fi
+
+
+
+# todo: umount first to ensure we don't have any errors
+# todo: do some kill fuser stuff to make umount more reliable
+# todo: run this on a systemd timer on $primary, once per hour,
+# and if primary is, change that timer over to primary, and make
+# sure we mount the latest
+
+
+
 if $conf_only; then
     exit
 fi
@@ -135,7 +163,9 @@ fi
 if $dry_run; then
     btrbk -n $resume_arg run
 else
-    btrbk -q $resume_arg run
+    # -q and just using the syslog option seemed nice,
+    # but it doesn't show when a send has a parent and when it doesn't.
+    btrbk $resume_arg run
 fi
 
 # if we have /p, rsync to targets without /p
@@ -155,15 +185,7 @@ if mountpoint /p >/dev/null; then
 fi
 
 if ! $dry_run; then
-    for tg in ${targets[@]}; do
-        scp $script_dir/{mount-latest-subvol,check-subvol-stale} \
-            root@$tg:/usr/local/bin
-        ssh root@$tg bash <<'EOF'
-set -e
-chmod +x /usr/local/bin/{mount-latest-subvol,check-subvol-stale}
-mount-latest-subvol
-EOF
-    done
+    $script_dir/mount-latest-remote ${targets[@]}
 fi
 
 
index d9582286126696086ebf425997270a936210d3d7..7d36b461bcf269a67dbceeed6b2c420f06a403da 100644 (file)
@@ -7,6 +7,10 @@ trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?" >&2' ERR
 
 shopt -s nullglob
 
+if [[ ! $@ ]]; then
+    echo "$0: error: expected mountpoint argument"
+fi
+
 ret=0
 for d; do
     vol=${d##*/}
@@ -53,7 +57,3 @@ for d; do
 done
 exit $ret
 
-# todo: figure out what to do when there are no
-# snapshots yet. I guess that should be
-# yes to being stale? see the implications
-# in the other script.
index bf298d58e1fa741762ed8584c65aa782d4dd5a97..edb36f49c5ef870667a640e3e0fc7c6ab5e2eb8a 100755 (executable)
@@ -96,7 +96,7 @@ Description=Turn on automatic decryption of drives on boot
 # generally, I don't think targets order shutdown like they do startup.
 # So, I did systemd-analyze plot > something.svg, and picked a reliably started
 # service that happens late in the game.
-After=postfix.service
+After=ntp.service
 DefaultDependencies=no
 # not sure if needed, makes sure we shut down before reboot.target
 Conflicts=reboot.target
@@ -514,14 +514,14 @@ EOF
                 pi xkbset
             else
                 # xkbset was in testing for quite a while, dunno
-                # why it's not anymore. Sometime I should check and
-                # see if it's back in testing, but the unstable package
-                # doesn't upgrade anything form testing, and it's tiny
-                # so I'm not bothering to automate it.
+                # why it\'s not anymore. Sometime I should check and
+                # see if it\'s back in testing, but the unstable package
+                # doesn\'t upgrade anything form testing, and it\'s tiny
+                # so I\'m not bothering to automate it.
                 pi xkbset/unstable
-fi
-fi
-;;&
+            fi
+        fi
+        ;;&
 esac
 
 if has_x; then
@@ -545,12 +545,11 @@ s chown ian:ian  "${dirs[@]}"
 
 
 tu /etc/fstab <<'EOF'
-/i/w  /w  none  bind  0 0
-/i/k  /k  none  bind  0 0
+/i/w  /w  none  bind,noauto  0 0
+/i/k  /k  none  bind,noauto  0 0
 EOF
 
 
-
 if ! mountpoint /kr; then
     s mkdir -p /kr
     s chown ian:traci /kr
@@ -559,11 +558,11 @@ fi
 if home_network; then
     if [[ $HOSTNAME == treetowl ]]; then
         tu /etc/fstab <<'EOF'
-/k  /kr  none  bind  0 0
+/k  /kr  none  bind,noauto  0 0
 EOF
     else
         tu /etc/fstab <<'EOF'
-treetowl:/k  /kr  nfs  defaults  0 0
+treetowl:/k  /kr  nfs  noauto  0 0
 EOF
     fi
 fi
@@ -573,16 +572,54 @@ for dir in /{i,w,k}; do
     if mountpoint $dir; then continue; fi # already mounted
     s mkdir -p $dir
     s chown ian:ian $dir
-    s mount $dir
 done
 
+# not needed for all hosts, but rather just keep it uniform
+s mkdir -p /mnt/iroot
+
+# debian auto mounting of multi-disk encrypted btrfs is busted.  It is
+# in jessie, and in stretch as of 11/26/2016 I have 4 disks in cryptab,
+# based on 3 of those, it creates .device units for /dev/mapper/dev...
+# then waits endlessly for them on bootup, after the /dev/mapper disks
+# have already been created and exist. todo: create a simple repro
+# for this in a vm and report it upstream.
+s dd of=/root/imount <<'EOF'
+#!/bin/bash
+[[ $EUID == 0 ]] || exec sudo -E "$BASH_SOURCE" "$@"
+set -eE -o pipefail
+trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?" >&2' ERR
+for dir in /i /mnt/iroot /w /k /kr; do
+  if ! mountpoint $dir &>/dev/null && \
+        awk '{print $2}' /etc/fstab | grep -xFq $dir; then
+    mount $dir
+  fi
+done
+EOF
+s chmod +x /root/imount
+
+s dd of=/etc/systemd/system/imount.service <<'EOF'
+[Unit]
+Description=Mount /i and related mountpoints
+
+[Service]
+Type=oneshot
+ExecStart=/root/imount
+
+[Install]
+WantedBy=multi-user.target
+EOF
+sudo systemctl daemon-reload # needed if the file was already there
+sudo systemctl enable imount.service
+sudo systemctl start imount.service
+
+
 dir=/nocow
 if ! mountpoint $dir; then
     subvol=/mnt/root/nocow
-    if [[ ! -e nocow ]]; then
-        btrfs subvolume create $subvol
-        chown root:1000 $subvol
-        chattr +C $subvol
+    if [[ ! -e $subvol ]]; then
+        btrfs subvolume create $subvol
+        chown root:1000 $subvol
+        chattr +C $subvol
     fi
 
     first_root_crypt=$(awk '$2 == "/" {print $1}' /etc/mtab)
index f12d57515672f0de4020fb8a1b840b21fd26c983..dc97b0dd92834ef749801341d771c7c679ba206f 100755 (executable)
@@ -58,6 +58,7 @@ case $HOSTNAME in
     *)
         # universal packages
         # swh-plugins is for karaoke pulsaudio filter.
+        # mutagen for pithos
         simple_packages+=(
             apache2
             bwm-ng
@@ -71,6 +72,7 @@ case $HOSTNAME in
             gnome-screenshot
             jq
             locate
+            manpages
             meld
             nmap
             offlineimap
@@ -80,6 +82,7 @@ case $HOSTNAME in
             pdfgrep
             pianobar
             pidgin
+            python3-mutagen
             slock
             squashfs-tools
             swh-plugins
@@ -715,75 +718,75 @@ else
     pi synergy
 fi
 
-case $distro in
-    # ubuntu unknown. probably the same as debian, just check if the
-    # init scripts come with the package.
-    debian)
-        # copied from arch, but moved to etc
-        s dd of=/etc/systemd/user/synergys.service <<'EOF'
-[Unit]
-Description=Synergy Server Daemon
-After=network.target
-
-[Service]
-User=%i
-ExecStart=/usr/bin/synergys --no-daemon --config /etc/synergy.conf
-Restart=on-failure
-
-[Install]
-WantedBy=multi-user.target
-EOF
-        s dd of=/etc/systemd/user/synergys.socket <<'EOF'
-[Unit]
-Conflicts=synergys@.service
+case $distro in
+    # ubuntu unknown. probably the same as debian, just check if the
+    # init scripts come with the package.
+    debian)
+        # copied from arch, but moved to etc
+        s dd of=/etc/systemd/user/synergys.service <<'EOF'
+[Unit]
+Description=Synergy Server Daemon
+After=network.target
+
+[Service]
+User=%i
+ExecStart=/usr/bin/synergys --no-daemon --config /etc/synergy.conf
+Restart=on-failure
+
+[Install]
+WantedBy=multi-user.target
+EOF
+        s dd of=/etc/systemd/user/synergys.socket <<'EOF'
+[Unit]
+Conflicts=synergys@.service
 
-[Socket]
-ListenStream=24800
-Accept=false
+[Socket]
+ListenStream=24800
+Accept=false
 
-[Install]
-WantedBy=sockets.target
-EOF
-        # had this fail with 'Failed to connect to bus: No such file or directory'
-        # then when I tried it manually, it worked fine...
-        if ! systemctl --user daemon-reload; then
-            sleep 2
-            echo retrying systemd user daemon reload
-            systemctl --user daemon-reload
-        fi
-        ;;&
-    *)
-        # taken from arch wiki.
-        s dd of=/etc/systemd/system/synergyc@.service <<'EOF'
-[Unit]
-Description=Synergy Client
-After=network.target
-
-[Service]
-User=%i
-ExecStart=/usr/bin/synergyc --no-daemon frodo
-Restart=on-failure
-# per man systemd.unit, StartLimitInterval, by default we
-# restart more than 5 times in 10 seconds.
-# And this param defaults too 200 miliseconds.
-RestartSec=3s
-
-[Install]
-WantedBy=multi-user.target
-EOF
-        s systemctl daemon-reload
-        case $HOSTNAME in
-            x2|treetowl)
-                ser enable synergyc@ian
-                ser start synergyc@ian ||: # X might not be running yet
-                ;;
-            frodo)
-                systemctl --user start synergys ||:
-                systemctl --user enable synergys
-                ;;
-        esac
-        ;;
-esac
+[Install]
+WantedBy=sockets.target
+EOF
+        # had this fail with 'Failed to connect to bus: No such file or directory'
+        # then when I tried it manually, it worked fine...
+        if ! systemctl --user daemon-reload; then
+            sleep 2
+            echo retrying systemd user daemon reload
+            systemctl --user daemon-reload
+        fi
+        ;;&
+    *)
+        # taken from arch wiki.
+        s dd of=/etc/systemd/system/synergyc@.service <<'EOF'
+[Unit]
+Description=Synergy Client
+After=network.target
+
+[Service]
+User=%i
+ExecStart=/usr/bin/synergyc --no-daemon frodo
+Restart=on-failure
+# per man systemd.unit, StartLimitInterval, by default we
+# restart more than 5 times in 10 seconds.
+# And this param defaults too 200 miliseconds.
+RestartSec=3s
+
+[Install]
+WantedBy=multi-user.target
+EOF
+        s systemctl daemon-reload
+        case $HOSTNAME in
+            x2|treetowl)
+                ser enable synergyc@ian
+                ser start synergyc@ian ||: # X might not be running yet
+                ;;
+            frodo)
+                systemctl --user start synergys ||:
+                systemctl --user enable synergys
+                ;;
+        esac
+        ;;
+esac
 
 
 ######### end misc packages #########
@@ -884,11 +887,13 @@ EOF
         ;;
 esac
 
-# not using it atm, and for jessie, it depends on a higher version of btrfs-tools
+# note, for jessie, it depends on a higher version of btrfs-tools
 # case $distro in
 #     arch|debian|ubuntu) pi btrbk ;;
 #     # others unknown
 # esac
+cd /a/opt/btrbk
+s make install
 
 if [[ $HOSTNAME == treetowl ]] && [[ `debian-archive` != testing ]]; then
     # fail2 ban is broken, with a workaround, per
@@ -1116,19 +1121,6 @@ fi
 tu /etc/hosts <<< "127.0.1.1 $(hostname).lan $(hostname)"
 
 
-
-rootdev=$(mount | sed -rn 's#^(\S+) on / .*#\1#p')
-s mkdir /mnt/root
-tu /etc/fstab <<< "$rootdev  /mnt/root  btrfs  noatime,subvolid=0  0 0"
-mountpoint /mnt/root || s mount /mnt/root
-idev=$(mount | sed -rn 's#^(\S+) on /i .*#\1#p')
-if [[ $idev != $rootdev ]]; then
-    s mkdir /mnt/iroot
-    tu /etc/fstab <<< "$idev  /mnt/iroot  btrfs  noatime,subvolid=0  0 0"
-    mountpoint /mnt/iroot || s mount /mnt/iroot
-fi
-
-
 ######### begin stuff belonging at the end    ##########
 
 
index 9f93cde1f3dc2750951203cd162e8d25a980e5dc..66a4b7ffd26d5ecf395bdd373c0b6fda8e2ea750 100755 (executable)
@@ -22,11 +22,11 @@ set_device_id() {
 }
 
 case $HOSTNAME in
-       tp|x2)
+       tp)
                # original saved with: xkbcomp $DISPLAY /a/c/stretch-9-2016.xkb
                xkbcomp /a/c/tp.xkb $DISPLAY
                ;;
-    treetowl*|iank-dev|frodo)
+    treetowl*|iank-dev|frodo|x2)
         # todo, differentiate for work pc
        #/a/bin/radl
         if [[ -z $DISPLAY ]]; then
@@ -39,6 +39,7 @@ case $HOSTNAME in
             xkbset exp =m  # stop mousekeys expiring after a timeout
 
             xset r rate 200 13 # decrease rate delay
+            cd / # so xbindkeys does not hold open mountpoints
             xbindkeys # configured to grab left and right scroll button presses
         fi
 
diff --git a/mount-latest-remote b/mount-latest-remote
new file mode 100755 (executable)
index 0000000..b67a460
--- /dev/null
@@ -0,0 +1,21 @@
+#!/bin/bash
+
+set -eE -o pipefail
+trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?" >&2' ERR
+
+script_dir=$(dirname $(readlink -f "$BASH_SOURCE"))
+
+if [[ ! $@ ]]; then
+    echo "mount-latest-remote: error: expected 1 or more host arguments"
+    exit 1
+fi
+
+for tg; do
+    scp $script_dir/{mount-latest-subvol,check-subvol-stale} \
+        root@$tg:/usr/local/bin
+    ssh root@$tg bash <<'EOF'
+set -e
+chmod +x /usr/local/bin/{mount-latest-subvol,check-subvol-stale}
+mount-latest-subvol
+EOF
+done
index f62f1f45612d274f1bf8196e9971973d10bba356..73709316d39b79dac8865aef265b0496574d0fc2 100644 (file)
@@ -73,34 +73,6 @@ $first_root_crypt  /p  btrfs  noatime,subvol=p  0 0
 EOF
         ;;
 esac
-if [[ $HOSTNAME == treetowl ]]; then
-    # partitioned it with fai partitioner outside of fai,
-    # because it\'s worth it to have 1% space reserved for boot and
-    # swap partitions in case I ever want to boot off those drives.
-    # as root:
-    # . /a/bin/fai/fai-wrapper
-    # eval-fai-classfile /a/bin/fai/fai/config/class/51-multi-boot
-    # fai-setclass ROTATIONAL
-    # export LUKS_DIR=/q/root/luks/
-    # # because the partition nums existed already
-    # fai-setclass REPARTITION
-    # /a/bin/fai/fai/config/hooks/partition.DEFAULT
-
-    # just the first in the btrfs raid
-    dev=ata-TOSHIBA_MD04ACA500_84REK6NTFS9A-part1
-    tu /etc/fstab <<EOF
-/dev/mapper/crypt_dev_$dev /i btrfs  noatime,subvol=i  0 0
-EOF
-    tu /etc/crypttab <<EOF
-crypt_dev_$dev  /dev/disk/by-id/$dev  /q/root/luks/host-treetowl  discard,luks
-EOF
-
-else
-    tu /etc/fstab <<'EOF'
-/q/i  /i  none  bind  0 0
-EOF
-
-fi
 
 for vol in q p; do
     d=/$vol
@@ -170,4 +142,46 @@ for vol in q p; do
         e mnt $dir
     done
 done
+
+if [[ $HOSTNAME == treetowl ]]; then
+    # partitioned it with fai partitioner outside of fai,
+    # because it\'s worth it to have 1% space reserved for boot and
+    # swap partitions in case I ever want to boot off those drives.
+    # as root:
+    # . /a/bin/fai/fai-wrapper
+    # eval-fai-classfile /a/bin/fai/fai/config/class/51-multi-boot
+    # fai-setclass ROTATIONAL
+    # export LUKS_DIR=/q/root/luks/
+    # # because the partition nums existed already
+    # fai-setclass REPARTITION
+    # /a/bin/fai/fai/config/hooks/partition.DEFAULT
+
+    devs=(
+        ata-TOSHIBA_MD04ACA500_84REK6NTFS9A-part1
+        ata-TOSHIBA_MD04ACA500_84R2K773FS9A-part1
+        ata-TOSHIBA_MD04ACA500_8471K430FS9A-part1
+        ata-TOSHIBA_MD04ACA500_8481K493FS9A-part1
+    )
+    first=true
+    for dev in ${devs[@]}; do
+        if $first; then
+            first=false
+            tu /etc/fstab <<EOF
+/dev/mapper/crypt_dev_$dev /i btrfs  noatime,subvol=i,noauto  0 0
+/dev/mapper/crypt_dev_$dev /mnt/iroot btrfs  noatime,subvolid=0,noauto  0 0
+EOF
+        fi
+        tu /etc/crypttab <<EOF
+crypt_dev_$dev  /dev/disk/by-id/$dev  /q/root/luks/host-treetowl  discard,luks
+EOF
+        if [[ ! -e /dev/mapper/crypt_dev_$dev ]]; then
+            cryptdisks_start crypt_dev_$dev
+        fi
+    done
+else
+    tu /etc/fstab <<'EOF'
+/q/i  /i  none  bind,noauto  0 0
+EOF
+fi
+
 exit $ret