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.
##### 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
# 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
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
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
shopt -s nullglob
+if [[ ! $@ ]]; then
+ echo "$0: error: expected mountpoint argument"
+fi
+
ret=0
for d; do
vol=${d##*/}
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.
# 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
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
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
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
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
+ s btrfs subvolume create $subvol
+ s chown root:1000 $subvol
+ s chattr +C $subvol
fi
first_root_crypt=$(awk '$2 == "/" {print $1}' /etc/mtab)
*)
# universal packages
# swh-plugins is for karaoke pulsaudio filter.
+ # mutagen for pithos
simple_packages+=(
apache2
bwm-ng
gnome-screenshot
jq
locate
+ manpages
meld
nmap
offlineimap
pdfgrep
pianobar
pidgin
+ python3-mutagen
slock
squashfs-tools
swh-plugins
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 #########
;;
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
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 ##########
}
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
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
--- /dev/null
+#!/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
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
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