export GOPATH=$HOME/go
path_add $GOPATH/bin
+path_add /usr/local/go/bin
export ARDUINO_PATH=/a/opt/Arduino/build/linux/work
source /b/bash_unpublished/source-semi-priv
fi
-script_dir=$(dirname $(readlink -f "$BASH_SOURCE"))
-
# note q is owned by root:1000
-# note p/m is owned 1000:1000 and chmod 700
-
mountpoints=()
rate_limit=no
verbose=true; verbose_arg=-v
progress_arg="--progress"
+pull_reexec=false
default_args_file=/etc/btrbk-run.conf
if [[ -s $default_args_file ]]; then
set -- $(< $default_args_file) "$@"
+ echo "$0: warning: default btrbk-run options set in $default_args_file (sleeping 5 seconds):"
+ cat $default_args_file
+ sleep 5
fi
-temp=$(getopt -l help cl:m:nps:t:vh "$@") || usage 1
+orig_args=("$@")
+temp=$(getopt -l pull-reexec,help cl:m:nps:t:vh "$@") || usage 1
eval set -- "$temp"
while true; do
case $1 in
-m) IFS=, mountpoints=($2); unset IFS; shift 2 ;;
-n) dry_run=true; dry_run_arg=-n; shift ;;
-p) progress_arg="--progress"; shift ;;
+ --pull-reexec) pull_reexec=true; shift ;;
-q) verbose=false; verbose_arg=; progress_arg=; shift ;;
# source host to receive a backup from
-s) source=$2; shift 2 ;;
# usefull commands are resume and archive
cmd_arg=${1:-run}
-if [[ -s $default_args_file ]]; then
- echo "$0: warning: default btrbk-run options set in $default_args_file (sleeping 5 seconds):"
- cat $default_args_file
- sleep 5
-fi
-
if [[ -v targets && $source ]]; then
echo "$0: error: -t and -s are mutually exclusive" >&2
exit 1
fi
+# pull_reexec stops us from getting into an infinite loop if there is some
+# kind of weird problem
+if ! $pull_reexec && [[ $source ]]; then
+ tmpf=$(mktemp)
+ scp $source:/a/bin/distro-setup/btrbk-run $tmpf
+ if diff -q $tmpf $BASH_SOURCE; then
+ echo "$0: found newer version on host $source. reexecing"
+ install -T $tmpf /usr/local/bin/btrbk-run
+ /usr/local/bin/btrbk-run --pull-reexec "${orig_args[@]}"
+ fi
+fi
+
+
echo -e "$0: options: conf_only=$conf_only\ndry_run=$dry_run\nrate_limit=$rate_limit\nverbose=$verbose\ncmd_arg=$cmd_arg"
+### end options parsing
+
# set default targets
if [[ ! -v targets && ! $source ]]; then
# limitations under the License.
### setup
-errcatch
+source /a/bin/errhandle/err
src="${BASH_SOURCE%/*}"
source $src/pkgs
# https://store.docker.com/editions/community/docker-ce-server-debian?tab=description
pi software-properties-common apt-transport-https
curl -fsSL https://download.docker.com/linux/$(distro-name-compat)/gpg | sudo apt-key add -
- sudo add-apt-repository \
- "deb [arch=amd64] https://download.docker.com/linux/$(distro-name-compat) \
- $(debian-codename-compat) \
- stable"
- p update
+ url=https://download.docker.com/linux/$(distro-name-compat)
+ l="deb [arch=amd64] $url $(debian-codename-compat) stable"
+
+ if ! grep -xFq "$l" /etc/apt/sources.list{,.d/*.list}; then
+ sudo add-apt-repository $l
+ p update
+ fi
# docker eats up a fair amount of cpu when doing nothing, so don't enable it unless
# we really need it.
pi-nostart docker-ce
trisquel|ubuntu)
# not packaged in xenial or flidas
pi software-properties-common
- s add-apt-repository -y ppa:certbot/certbot ||:
- p update
+ l="deb http://ppa.launchpad.net/certbot/certbot/ubuntu xenial main"
+ if ! grep -xFq "$l" /etc/apt/sources.list{,.d/*.list}; then
+ s add-apt-repository -y ppa:certbot/certbot ||:
+ p update
+ fi
pi python-certbot-apache
;;
# todo: other distros unknown
### end certbot install ###
-# dogcam setup
-case $HOSTNAME in
- lj|li)
- /a/bin/webcam/install-server
- ;;
- kw)
- /a/bin/webcam/install-client
- ;;
-esac
+# dogcam setup. not using atm
+# case $HOSTNAME in
+# lj|li)
+# /a/bin/webcam/install-server
+# ;;
+# kw)
+# /a/bin/webcam/install-client
+# ;;
+# esac
pi ${p1[@]}
# dependent packages.
pi ${pall[@]} $(apt-cache search ruby[.0-9]+-doc| awk '{print $1}') $(apt-cache depends gcc|grep -i suggests:| awk '{print $2}')
-sgo fsf-vpn-dns-cleanup
-
-case $distro in
- trisquel|ubuntu)
- l="deb http://ppa.launchpad.net/ansible/ansible/ubuntu xenial main"
- f=/etc/apt/sources.list.d/ansible-ubuntu-ansible-xenial.list
- if ! grep -qF "$l" $f; then
- s add-apt-repository -y ppa:ansible/ansible
- p update
- fi
- s pip install --upgrade pip
- # newer 2.7 versions have a bug that incorrectly detects trisquel version. fixed once 2.8 arrives
- # in 2019
- pip install --user ansible=2.7.4
- #pi ansible
- ;;
-esac
-
+if ! type pip; then
+ x=$(mktemp)
+ wget -O$x https://bootstrap.pypa.io/get-pip.py
+ python3 $x --user
+fi
+sgo fsf-vpn-dns-cleanup
case $distro in
pi chromium ;;
trisquel|ubuntu)
wget -qO - https://downloads.iridiumbrowser.de/ubuntu/iridium-release-sign-01.pub|sudo apt-key add -
- cat <<EOF | sudo tee /etc/apt/sources.list.d/iridium-browser.list
+ t=$(mktemp)
+ cat >$t <<EOF
deb [arch=amd64] https://downloads.iridiumbrowser.de/deb/ stable main
#deb-src https://downloads.iridiumbrowser.de/deb/ stable main
EOF
- p update
+ f=/etc/apt/sources.list.d/iridium-browser.list
+ if ! diff -q $t $f; then
+ cp $t $f
+ chmod 644 $f
+ p update
+ fi
pi iridium-browser
;;
esac
Pin: release a=bionic
Pin-Priority: 1005
-Package: *
+Package: btrfs-progs libzstd1
Pin: release a=bionic-updates
Pin-Priority: 1005
-Package: *
+Package: btrfs-progs libzstd1
Pin: release a=bionic-security
Pin-Priority: 1005
EOF
- # this will be needed if we want to pin something, generally useful for investigating
- s dd of=/etc/apt/sources.list.d/bionic.list 2>/dev/null <<EOF
+ t=$(mktemp)
+ cat >$t <<EOF
deb http://us.archive.ubuntu.com/ubuntu/ bionic main
deb http://us.archive.ubuntu.com/ubuntu/ bionic-updates main
deb http://us.archive.ubuntu.com/ubuntu/ bionic-security main
EOF
+ f=/etc/apt/sources.list.d/bionic.list
+ if ! diff -q $t $f; then
+ cp $t $f
+ chmod 644 $f
+ p update
+ fi
-
- p update
-
+ # no special reason, but its better for btrfs-progs to
+ # be closer to our kernel version
pi btrfs-progs
t=$(mktemp -d)
esac
n=$1
shift
+ if schroot -l | grep -xFq chroot:$n; then
+ echo "$0: $n schroot already installed, skipping"
+ return 0
+ fi
apps=($@)
d=/nocow/schroot/$n
s dd of=/etc/schroot/chroot.d/$n.conf <<EOF
# others unknown
esac
+
+# adapted from /var/lib/dpkg/info/transmission-daemon.postinst
+# 450 seems likely to be unused. we need to specify one or else
+# it won't be stable across installs.
+if ! getent passwd debian-transmission > /dev/null; then
+ case $distro in
+ arch)
+ s groupadd -g 450 debian-transmission
+ s useradd \
+ --system \
+ --create-home \
+ --gid 450 \
+ --uid 450 \
+ --home-dir /var/lib/transmission-daemon \
+ --shell /bin/false \
+ debian-transmission
+ ;;
+ *)
+ s adduser --quiet \
+ --gid 450 \
+ --uid 450 \
+ --system \
+ --group \
+ --no-create-home \
+ --disabled-password \
+ --home /var/lib/transmission-daemon \
+ debian-transmission
+ ;;
+ esac
+fi
+# We want group writable stuff from transmission.
+# However, after setting this, I learn that transmission sets it's
+# own umask based on it's settings file. Well, no harm leaving this
+# so it's set right from the beginning.
+s chfn debian-transmission -o umask=0002
+
case $distro in
debian|trisquel|ubuntu)
# note i had to do this, which is persistent:
# some reason it doesn\'t seem to start automatically anyways
pi-nostart transmission-daemon
+ # be extra sure its not started
+ ser disable transmission-daemon
+ ser stop transmission-daemon
# the folder was moved here after an install around 02/2017.
# it contains runtime data,
})) + "\n")
EOF
- # make sure its not enabled, not sure if this is needed
- ser disable transmission-daemon
;;
# todo: others unknown
esac
-# adapted from /var/lib/dpkg/info/transmission-daemon.postinst
-if ! getent passwd debian-transmission > /dev/null; then
- case $distro in
- arch)
- s useradd \
- --system \
- --create-home \
- --home-dir /var/lib/transmission-daemon \
- --shell /bin/false \
- debian-transmission
- ;;
- *)
- s adduser --quiet \
- --system \
- --group \
- --no-create-home \
- --disabled-password \
- --home /var/lib/transmission-daemon \
- debian-transmission
- ;;
- esac
-fi
-# We want group writable stuff from transmission.
-# However, after setting this, I learn that transmission sets it's
-# own umask based on it's settings file. Well, no harm leaving this
-# so it's set right from the beginning.
-s chfn debian-transmission -o umask=0002
# trisquel 8 = openvpn, debian stretch = openvpn-client
vpn_ser=openvpn-client
case $distro in
debian|trisquel|ubuntu)
+ if ! type -p go &>/dev/null; then
+ cd $(mktemp -d)
+ # just the latest stable at the time of writing
+ # TODO, maybe put this all into a build script,
+ # and do some automatic updates
+ wget https://dl.google.com/go/go1.12.4.linux-amd64.tar.gz
+ s tar -C /usr/local -xzf go1.12.4.linux-amd64.tar.gz
+ rm -f *
+ fi
+ go get -u mvdan.cc/fdroidcl
# a bit of googling, and added settings to bashrc
- go get -u github.com/mvdan/fdroidcl/cmd/fdroidcl
;;
esac
./configure --with-exuberant-ctags=/usr/bin/ctags
make
s make install
- s pip install pygments
+ pip install pygments
;;
*)
pi global
# others unknown
esac
-case $distro in
- debian|trisquel|ubuntu)
- # fdroidcl dependency
- e golang-go
- ;;
- # others unknown
-esac
-
### stuff brought in through deps in other distros
case $distro in
EOF
source /a/bin/bash_unpublished/source-semi-priv
- mkdir -p /etc/exim4/conf.d/main
+ mkdir -p /etc/exim4/conf.d/{main,transport,auth,router}
+ cat >/etc/exim4/rcpt_local_acl <<'EOF'
+# Only hosts we control send to mail.iankelling.org, so make sure
+# they are all authed.
+# Note, if we wanted authed senders for all domains,
+# we could make this condition in acl_check_mail
+deny
+ message = ian trusted domain recepient but no auth
+ !authenticated = *
+ domains = mail.iankelling.org
+EOF
+ cat >/etc/exim4/data_local_acl <<'EOF'
+# Except for the "condition =", this was
+# a comment in the check_data acl. The comment about this not
+# being suitable is mostly bs. The only thing related I found was to
+# add the condition =, cuz spamassassin has problems with big
+# messages and spammers don't bother with big messages,
+# but I've increased the size from 10k
+# suggested in official docs, and 100k in the wiki example because
+# those docs are rather old and I see a 110k spam message
+# pretty quickly looking through my spam folder.
+ warn
+ condition = ${if < {$message_size}{2000K}}
+ spam = Debian-exim:true
+ add_header = X-Spam_score: $spam_score\n\
+ X-Spam_score_int: $spam_score_int\n\
+ X-Spam_bar: $spam_bar\n\
+ X-Spam_report: $spam_report
+
+EOF
+ cat >/etc/exim4/conf.d/auth/29_exim4-config_auth <<'EOF'
+# from 30_exim4-config_examples
+
+plain_server:
+driver = plaintext
+public_name = PLAIN
+server_condition = "${if crypteq{$auth3}{${extract{1}{:}{${lookup{$auth2}lsearch{CONFDIR/passwd}{$value}{*:*}}}}}{1}{0}}"
+server_set_id = $auth2
+server_prompts = :
+.ifndef AUTH_SERVER_ALLOW_NOTLS_PASSWORDS
+server_advertise_condition = ${if eq{$tls_in_cipher}{}{}{*}}
+.endif
+EOF
+
+ cat >/etc/exim4/conf.d/router/900_exim4-config_local_user <<'EOF'
+### router/900_exim4-config_local_user
+#################################
+
+# This router matches local user mailboxes. If the router fails, the error
+# message is "Unknown user".
+
+local_user:
+ debug_print = "R: local_user for $local_part@$domain"
+ driver = accept
+ domains = +local_domains
+# ian: commented this, in conjunction with a dovecot lmtp
+# change so I get mail for all users.
+# check_local_user
+ local_parts = ! root
+ transport = LOCAL_DELIVERY
+ cannot_route_message = Unknown user
+EOF
+ cat >/etc/exim4/conf.d/transport/30_exim4-config_dovecot_lmtp <<'EOF'
+dovecot_lmtp:
+ driver = lmtp
+ socket = /var/run/dovecot/lmtp
+ #maximum number of deliveries per batch, default 1
+ batch_max = 200
+EOF
+
+ cat >/etc/exim4/conf.d/router/190_exim4-config_fsfsmarthost <<'EOF'
+# smarthost for fsf mail
+# ian: copied from /etc/exim4/conf.d/router/200_exim4-config_primary, and added senders = and
+# replaced DCsmarthost with mail.fsf.org
+fsfsmarthost:
+ debug_print = "R: smarthost for $local_part@$domain"
+ driver = manualroute
+ domains = ! +local_domains
+ senders = *@fsf.org
+ transport = remote_smtp_smarthost
+ route_list = * mail.fsf.org byname
+ host_find_failed = ignore
+ same_domain_copy_routing = yes
+ no_more
+EOF
#### begin mail cert setup ###
fi
if [[ $HOSTNAME == $MAIL_HOST ]]; then
local_mx=mail.iankelling.org
- rsync_common="rsync -ogtL --chown=root:Debian-exim --chmod=640 root@li:/etc/letsencrypt/live/$local_mx/"
+ rsync_common="rsync -ogtL --chown=root:Debian-exim --chmod=640 root@li.iankelling.org:/etc/letsencrypt/live/$local_mx/"
${rsync_common}fullchain.pem /etc/exim4/exim.crt
ret=$?
${rsync_common}privkey.pem /etc/exim4/exim.key
find / /nocow -xdev -gid $gid -exec chgrp -h 608 {} +
fi
+
# light version of exim does not have sasl auth support.
pi exim4-daemon-heavy spamassassin
-
##### begin spamassassin config
systemctl enable spamassassin
# per readme.debian
- cat >/etc/exim4/rcpt_local_acl <<'EOF'
-# Only hosts we control send to mail.iankelling.org, so make sure
-# they are all authed.
-# Note, if we wanted authed senders for all domains,
-# we could make this condition in acl_check_mail
-deny
- message = ian trusted domain recepient but no auth
- !authenticated = *
- domains = mail.iankelling.org
-EOF
- cat >/etc/exim4/data_local_acl <<'EOF'
-# Except for the "condition =", this was
-# a comment in the check_data acl. The comment about this not
-# being suitable is mostly bs. The only thing related I found was to
-# add the condition =, cuz spamassassin has problems with big
-# messages and spammers don't bother with big messages,
-# but I've increased the size from 10k
-# suggested in official docs, and 100k in the wiki example because
-# those docs are rather old and I see a 110k spam message
-# pretty quickly looking through my spam folder.
- warn
- condition = ${if < {$message_size}{2000K}}
- spam = Debian-exim:true
- add_header = X-Spam_score: $spam_score\n\
- X-Spam_score_int: $spam_score_int\n\
- X-Spam_bar: $spam_bar\n\
- X-Spam_report: $spam_report
-
-EOF
- cat >/etc/exim4/conf.d/auth/29_exim4-config_auth <<'EOF'
-# from 30_exim4-config_examples
-
-plain_server:
-driver = plaintext
-public_name = PLAIN
-server_condition = "${if crypteq{$auth3}{${extract{1}{:}{${lookup{$auth2}lsearch{CONFDIR/passwd}{$value}{*:*}}}}}{1}{0}}"
-server_set_id = $auth2
-server_prompts = :
-.ifndef AUTH_SERVER_ALLOW_NOTLS_PASSWORDS
-server_advertise_condition = ${if eq{$tls_in_cipher}{}{}{*}}
-.endif
-EOF
-
- cat >/etc/exim4/conf.d/router/900_exim4-config_local_user <<'EOF'
-### router/900_exim4-config_local_user
-#################################
-
-# This router matches local user mailboxes. If the router fails, the error
-# message is "Unknown user".
-
-local_user:
- debug_print = "R: local_user for $local_part@$domain"
- driver = accept
- domains = +local_domains
-# ian: commented this, in conjunction with a dovecot lmtp
-# change so I get mail for all users.
-# check_local_user
- local_parts = ! root
- transport = LOCAL_DELIVERY
- cannot_route_message = Unknown user
-EOF
- cat >/etc/exim4/conf.d/transport/30_exim4-config_dovecot_lmtp <<'EOF'
-dovecot_lmtp:
- driver = lmtp
- socket = /var/run/dovecot/lmtp
- #maximum number of deliveries per batch, default 1
- batch_max = 200
-EOF
-
- cat >/etc/exim4/conf.d/router/190_exim4-config_fsfsmarthost <<'EOF'
-# smarthost for fsf mail
-# ian: copied from /etc/exim4/conf.d/router/200_exim4-config_primary, and added senders = and
-# replaced DCsmarthost with mail.fsf.org
-fsfsmarthost:
- debug_print = "R: smarthost for $local_part@$domain"
- driver = manualroute
- domains = ! +local_domains
- senders = *@fsf.org
- transport = remote_smtp_smarthost
- route_list = * mail.fsf.org byname
- host_find_failed = ignore
- same_domain_copy_routing = yes
- no_more
-EOF
-
# 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
# mail-route can get messed up a bit randomly, I don't know why.
#/b/ds/mail-route up | /b/log-quiet/log-once -1 mail-route
+for f in $(awk '$1 == "localfolders" {print $NF}' ~/.offlineimaprc); do
+ mkdir -p $f
+ chmod 700 $f
+done
+
offlineimap -u quiet
shopt -s nullglob
+if grep -qP '^ *accounts.*fsf' ~/.offlineimaprc; then
+ if [[ ! -e /nocow/user/.mufsf ]]; then
+ mkdir -p /nocow/user/.mufsf
+ chmod 700 /nocow/user/.mufsf
+ mu index --maildir=/nocow/user/fsfmd
+ fi
+fi
+
omv() { # offlineimap mv. move mail files within $src_base/$1 to /m/md/$2
src="$1"
dst="$2"
local help="usage: path_add [options] PATH
--help: print this
--end: adds to end of path, which will give it lowest priority
---force: add to path even if directory does not exist"
+--ifexists: add to path only if directory exists"
local found x y z ifexists end loop newpath
- force=false
+ ifexists=false
end=false
loop=true
# portable substring matching is ugly http://mywiki.wooledge.org/BashFAQ/041
--*)
if [ "$1" = --end ]; then
end=true
- elif [ "$1" = --force ]; then
- force=true
+ elif [ "$1" = --ifexists ]; then
+ ifexists=true
elif [ "$1" = --help ]; then
echo "$help"
return
unset IFS
PATH="$newpath"
for x in "$@"; do
- if $force || [ -d "$x" ]; then
+ if ! $ifexists || [ -d "$x" ]; then
if [ ! "$PATH" ]; then
PATH="$x"
elif $end; then
# gnat-5 & ccache is for coreboot
p4=(
adb
+ ansible
apache2
apache2-doc
apt-doc
pry
pv
python-autopep8
- python-pip
python3-doc
qrencode
readline-doc