+++ /dev/null
-# to avoid booting problems with encrypted LVM, see <https://askubuntu.com/a/1105848>
-cryptsetup-initramfs
-lvm2
-# for secrets
-pmount
-# for my own scripts to run
-python3-venv
-# for syncing
-borgbackup
-# for accessing remote machines
-openssh-client
-# wayland usage essentials
-sway
-wl-clipboard
-# at a minimum sets env stuff without which sway won't start
-dbus-user-session
-# for sound
-pulseaudio
-# dmenu replacement
-wmenu
-# for status.sh to work
-calc
-# xterm replacement
-foot
-# for e.g. chromium to work (and to disappear certain error messages)
-xwayland
-# for firefox and tridactyl
-curl
-firefox-esr
-# for using Google services
-chromium
-# for passwords
-keepassxc
-# for installing Signal
-gpg
-wget
-#
--- /dev/null
+../../trixie/aptmark/desktop
\ No newline at end of file
+++ /dev/null
-# so we can work without the Ethernet adapter
-network-manager
-wpasupplicant
-firmware-iwlwifi
-# for battery management, we assume good defaults
-tlp
-
--- /dev/null
+../../trixie/aptmark/t490s
\ No newline at end of file
--- /dev/null
+../../trixie/copy/desktop
\ No newline at end of file
+++ /dev/null
-# This file describes the network interfaces available on your system
-# and how to activate them. For more information, see interfaces(5).
-
-source /etc/network/interfaces.d/*
-
-# The loopback network interface
-auto lo
-iface lo inet loopback
-
-# anything more would only confuse NetworkManager
+++ /dev/null
-# mere "kb" might be more flexible, but this way I won't accidentally try for
-# a non-existing "en" layout
-alias kb_de="swaymsg 'input * xkb_layout de'"
-alias kb_us="swaymsg 'input * xkb_layout us'"
-
-# miscellaneaous
-alias curlpost='curl -H "Content-Type: application/json" -X POST'
+++ /dev/null
-# because these are included by /etc/sway/config for probably good reason …
-include /etc/sway/config-vars.d/*
-include /etc/sway/config.d/*
-
-# font for wm text
-font pango:Terminus 16px
-
-# force "tabbed" as default layout for new windows
-workspace_layout tabbed
-
-# simple green background
-output * background #559911 solid_color
-
-# keyboard layout
-input * xkb_layout "us"
-
-# waybar
-bar {
- position top
- tray_output none
- status_command ~/.nonpath_bins/status.sh
-}
-
-# make Windows key modifier key for all wm actions
-set $mod Mod4
-floating_modifier $mod
-
-# program launcher
-bindsym $mod+d exec wmenu-run
-bindsym $mod+x exec wmenu-run
-
-# launch terminal emulator
-bindsym $mod+Return exec foot --font=monospace:size=12
-
-# kill window
-bindsym $mod+Shift+q kill
-
-# move focus between windows, but not by mouse
-bindsym $mod+Left focus left
-bindsym $mod+Down focus down
-bindsym $mod+Up focus up
-bindsym $mod+Right focus right
-focus_follows_mouse no
-
-# move windows
-bindsym $mod+Shift+Left move left
-bindsym $mod+Shift+Down move down
-bindsym $mod+Shift+Up move up
-bindsym $mod+Shift+Right move right
-
-# resize windows
-bindsym $mod+h resize shrink width 1 px or 1 ppt
-bindsym $mod+l resize grow width 1 px or 1 ppt
-bindsym $mod+j resize shrink height
-bindsym $mod+k resize grow height
-
-# toggle fullscreen for focused window
-bindsym $mod+f fullscreen
-
-# toggle floating of window, focus on floating or tabbed windows.
-bindsym $mod+Shift+space floating toggle
-bindsym $mod+space focus mode_toggle
-
-# reload config file
-bindsym $mod+Shift+c reload
-
-# stop wm
-bindsym $mod+Shift+p exit
-
-# switch workspaces
-bindsym $mod+1 workspace 1
-bindsym $mod+2 workspace 2
-bindsym $mod+3 workspace 3
-bindsym $mod+4 workspace 4
-bindsym $mod+5 workspace 5
-bindsym $mod+6 workspace 6
-bindsym $mod+7 workspace 7
-bindsym $mod+8 workspace 8
-bindsym $mod+9 workspace 9
-bindsym $mod+0 workspace 10
-
-# move window to workspace
-bindsym $mod+Shift+1 move workspace 1
-bindsym $mod+Shift+2 move workspace 2
-bindsym $mod+Shift+3 move workspace 3
-bindsym $mod+Shift+4 move workspace 4
-bindsym $mod+Shift+5 move workspace 5
-bindsym $mod+Shift+6 move workspace 6
-bindsym $mod+Shift+7 move workspace 7
-bindsym $mod+Shift+8 move workspace 8
-bindsym $mod+Shift+9 move workspace 9
-bindsym $mod+Shift+0 move workspace 10
+++ /dev/null
-[user]
- email = c.heller@plomlompom.de
- name = Christian Heller
+++ /dev/null
-#!/bin/sh
-set -e
-cd $(dirname "$0")
-. lib/abort
-. lib/print_usage
-
-ARG_HELP=--help
-USAGE_DESCRIPTION='Set backlight to maximum, or [INTEGER] percentage of it.'
-USAGE_LINES="COMMAND [${ARG_HELP}] [INTEGER]"
-
-if [ "$1" = "${ARG_HELP}" ]; then
- print_usage
- exit 0
-elif [ -z "$1" ]; then
- PERCENTAGE=100
-elif [ "$(echo -n $1 | sed -E 's/[0-9]*[%]?//g')" ]; then
- echo "Aborting due to unrecognized argument(s): $@" >&2
- exit 1
-elif [ "$1" -gt 100 ]; then
- echo "Aborting due to percentage > 100" >&2
- exit 1
-else
- PERCENTAGE=$1
-fi
-PATH_BACKLIGHTS=/sys/class/backlight
-FILENAME_MAX=max_brightness
-FILENAME_TARGET=brightness
-BACKLIGHTS=$(ls "${PATH_BACKLIGHTS}")
-for BACKLIGHT in ${BACKLIGHTS}; do
- PATH_DIR_BACKLIGHT=${PATH_BACKLIGHTS}/${BACKLIGHT}
- MAX_BRIGHTNESS=$(cat "${PATH_DIR_BACKLIGHT}/${FILENAME_MAX}")
- TARGET_VAL=$(calc "(${PERCENTAGE} * ${MAX_BRIGHTNESS} // 100)" | tr -d '\t')
- sudo sh -c "echo ${TARGET_VAL} > ${PATH_DIR_BACKLIGHT}/${FILENAME_TARGET}"
- printf 'set %s to %s%s (%s)\n' "${BACKLIGHT}" "${PERCENTAGE}" "%" "${TARGET_VAL}"
-done
+++ /dev/null
-#!/bin/sh
-set -e
-cd $(dirname "$0")
-. lib/abort
-. lib/constants_borg # PATH_BORG_CONF
-. lib/expect_n_args
-. lib/get_passphrase
-. lib/path_tmp_timestamped
-. lib/print_usage
-. lib/retry_until
-cd - > /dev/null
-
-USAGE_DESCRIPTION='Wrapper around certain borgbackup usages.\n\nAvailable commands:'
-USAGE_LINES='COMMAND [ARGUMENT]...'
-
-PATH_BORG_CONF_SECURITY="${PATH_BORG_CONF}/security"
-PATH_BORG_CONF_KEYS="${PATH_BORG_CONF}/keys"
-
-NAME_ARCHIVE_ORG=orgdir
-
-location_from_servername() { printf 'ssh://borg@%s/./borgrepo' "$1"; }
-servername_from_location() { echo "$1" | cut -d'/' -f3 | cut -d'@' -f2; }
-path_repo_location() { printf '%s' "${PATH_BORG_CONF_SECURITY}/${1}/location"; }
-
-explore_key_id() {
- local KEY_ID=$1
- local PATH_LOC="$(path_repo_location ${KEY_ID})"
- if [ ! -f "${PATH_LOC}" ]; then
- printf '?'
- return
- fi
- local LOCATION=$(cat "${PATH_LOC}")
- local NAME_SERVER=$(servername_from_location "${LOCATION}")
- if [ "${LOCATION}" = $(location_from_servername "${NAME_SERVER}") ]; then
- local PREFIX='+'
- else
- local PREFIX='-'
- fi
- printf '%s %s %s' "${PREFIX} ${NAME_SERVER} ${LOCATION}"
-}
-
-keydata_obsolete() {
- KEY_DATA=$1
- local PREFIX=$(echo "${KEY_DATA}" | cut -d' ' -f1)
- if [ "${PREFIX}" = '-' ]; then
- echo "Ignoring ${KEY_ID}, location doesn't match expected pattern."
- return 0
- fi
- return 1
-}
-
-# exits
-export BORG_EXIT_CODES=modern
-error_exit() { abort "Aborting due to $1"; }
-error_exit_with_usage() { error_exit "${1}\n\n$(print_usage)"; }
-exit_ok() { echo "$@"; exit 0; }
-
-# commands
-USAGE_INDICES='backup_keys claim help info init keys orgpull orgpush'
-
-_run_borg_with_passphrase() {
- _FIRST_RUN=1
- _ON_LOOP_START='
- if [ -z "${BORG_PASSPHRASE}" ]; then
- printf "Passphrase:"
- export BORG_PASSPHRASE="$(get_passphrase)"
- echo ""
- fi
- '
- _TO_TEST='borg '"$@"
- _ON_FAIL='echo "unexpected borg error, code ${_RESULT}."'
- _ON_LOOP_END='export BORG_PASSPHRASE='
- retry_until 52 "${_ON_LOOP_START}" "${_TO_TEST}" "${_ON_FAIL}" "${_ON_LOOP_END}"
-}
-
-_id_from_file() { head -1 "$1" | cut -d' ' -f2; }
-
-USAGE_ARGS_backup_keys='PATH'
-USAGE_DESC_backup_keys="copy known keys to PATH/, with their repos' server names as filenames"
-CMDFNC_backup_keys() {
- expect_n_args 1 1 "${USAGE_ARGS_backup_keys}" $@
- local PATH_TARGET_DIR=$(realpath "$1")
- if [ -e "${PATH_TARGET_DIR}" ] && [ ! -d "${PATH_TARGET_DIR}" ]; then
- error_exit "non-directory at ${PATH_TARGET_DIR}"
- fi
- mkdir -p "${PATH_TARGET_DIR}"
- cd "${PATH_BORG_CONF_KEYS}"
- ls -1 | while read _FILENAME; do
- local KEY_ID=$(_id_from_file "${PATH_BORG_CONF_KEYS}/${_FILENAME}")
- local KEY_DATA=$(explore_key_id "${KEY_ID}")
- if keydata_obsolete "${KEY_DATA}"; then
- continue;
- fi
- local NAME_SERVER=$(echo "${KEY_DATA}" | cut -d' ' -f2)
- local PATH_TARGET="${PATH_TARGET_DIR}/${NAME_SERVER}"
- echo "Copying ${_FILENAME} to ${PATH_TARGET} …"
- cp "${_FILENAME}" "${PATH_TARGET}"
- done
- cd - > /dev/null
-}
-
-USAGE_ARGS_claim='PATH'
-USAGE_DESC_claim="register file of PATH as key to repo at \"$(location_from_servername SERVER_NAME)\", with SERVER_NAME the filename portion of PATH"
-CMDFNC_claim() {
- expect_n_args 1 1 "${USAGE_ARGS_claim}" $@
- _PATH_SOURCE="$1"
- _ensure_no_overwrite_at() {
- if [ -f "$1" ]; then
- error_exit "refusing to overwrite pre-existing file at $1"
- fi
- }
-
- _FILENAME=$(basename ${_PATH_SOURCE})
- _PATH_TARGET_KEY="${PATH_BORG_CONF_KEYS}/${_FILENAME}"
- if [ ! -f "${_PATH_SOURCE}" ]; then
- error_exit "no file at ${_PATH_SOURCE}"
- fi
- _ensure_no_overwrite_at "${_PATH_TARGET_KEY}"
- _REPO_ID="$(_id_from_file ${_PATH_SOURCE})"
- if [ ! -z "$(echo ${_REPO_ID} | sed 's/[a-f0-9]//g')" ]; then
- error_exit "inability to parse valid repo ID from alleged key file at $1"
- fi
- _PATH_TARGET_LOCATION="$(path_repo_location ${_REPO_ID})"
- _ensure_no_overwrite_at "${_PATH_TARGET_LOCATION}"
- mkdir -p "${PATH_BORG_CONF_KEYS}" "$(dirname ${_PATH_TARGET_LOCATION})"
- echo "Copying ${_PATH_SOURCE} to ${_PATH_TARGET_KEY} …"
- cp "${_PATH_SOURCE}" "${_PATH_TARGET_KEY}"
- echo "Writing ${_PATH_TARGET_LOCATION} …"
- printf '%s' "$(location_from_servername ${_FILENAME})" > "${_PATH_TARGET_LOCATION}"
- chmod a-rwx,u+rw "${_PATH_TARGET_KEY}" "${_PATH_TARGET_LOCATION}"
-}
-
-USAGE_DESC_help='print this help and exit'
-CMDFNC_help() {
- expect_n_args 0 0 '' $@
- print_usage
-}
-
-USAGE_ARGS_info='SERVER_NAME [ARCHIVE]'
-USAGE_DESC_info="run 'borg info' against repo at \"$(location_from_servername SERVER_NAME)\", optionally only against ARCHIVE; if latter not provided, list most recent archives of repo"
-CMDFNC_info() {
- expect_n_args 1 2 "${USAGE_ARGS_info}" $@
- _TARGET_REPO="$(location_from_servername ${1})"
- if [ ! -z "$2" ]; then
- exit_ok $(borg info "${_TARGET_REPO}::$2")
- fi
- _run_borg_with_passphrase info "${_TARGET_REPO}"
- echo "${_OUTPUT}\n\nMost recent archives:"
- borg list "${_TARGET_REPO}" | tail -5
-}
-
-USAGE_ARGS_init='SERVER_NAME'
-USAGE_DESC_init="create repo at \"$(location_from_servername SERVER_NAME)\""
-CMDFNC_init() {
- expect_n_args 1 1 "${USAGE_ARGS_init}" $@
- _STASHED_BORG_PASSPHRASE="$(env | grep -E '^BORG_PASSPHRASE=' | cut -d'=' -f2-)"
- unset BORG_PASSPHRASE
- borg init --encryption=keyfile "$(location_from_servername $1)"
- if [ ! -z "${_STASHED_BORG_PASSPHRASE}" ]; then
- export BORG_PASSPHRASE="${_STASHED_BORG_PASSPHRASE}"
- _STASHED_BORG_PASSPHRASE=
- fi
-}
-
-USAGE_DESC_keys='list known repos in ID, key filename, and alleged location'
-CMDFNC_keys() {
- expect_n_args 0 0 '' $@
- echo "Known keys, as per ${PATH_BORG_CONF_KEYS}:"
- local EXIT_OK_PREFIX='(none, since directory'
- if [ ! -d "${PATH_BORG_CONF_KEYS}" ]; then
- exit_ok "${EXIT_OK_PREFIX} non-existant)"
- fi
- local KEYFILES="$(ls -1 ${PATH_BORG_CONF_KEYS})"
- if [ -z "${KEYFILES}" ]; then
- exit_ok "${EXIT_OK_PREFIX} empty)"
- fi
- echo "${KEYFILES}" | while read _FILENAME; do
- local KEY_ID=$(_id_from_file "${PATH_BORG_CONF_KEYS}/${_FILENAME}")
- local KEY_DATA=$(explore_key_id "${KEY_ID}")
- local PREFIX=$(echo "${KEY_DATA}" | cut -d' ' -f1)
- local LOCATION=$(echo "${KEY_DATA}" | cut -d' ' -f3)
- printf '%s %s %s %s\n' "${PREFIX}" "${KEY_ID}" "${_FILENAME}" "${LOCATION}"
- done
-}
-
-USAGE_DESC_orgpull='pull most recent org directory available in repos'
-CMDFNC_orgpull() {
- expect_n_args 0 0 '' $@
-
- # determine server and repo
- local PATH_PIPE="$(path_tmp_timestamped 'pipe')"
- mkfifo "${PATH_PIPE}"
- ls -1 "${PATH_BORG_CONF_SECURITY}/" > "${PATH_PIPE}" &
- while read _FILENAME; do
- local KEY_DATA=$(explore_key_id "${_FILENAME}")
- if keydata_obsolete "${KEY_DATA}"; then
- continue;
- fi
- local NAME_SERVER=$(echo "${KEY_DATA}" | cut -d' ' -f2)
- local LOCATION=$(echo "${KEY_DATA}" | cut -d' ' -f3)
- if ping -c1 -W2 "${NAME_SERVER}" > /dev/null 2>&1; then
- local REPO="${LOCATION}"
- break
- else
- echo "Cannot reach ${NAME_SERVER}, skipping."
- fi
- done < "${PATH_PIPE}"
- rm "${PATH_PIPE}"
- if [ -z "${REPO}" ]; then
- error_exit 'no repo being available.'
- fi
-
- # determine passphrase and archive
- echo "Checking out ${REPO} …"
- _run_borg_with_passphrase list "${REPO}"
- local ARCHIVE=$(echo "${_OUTPUT}" | grep "${NAME_ARCHIVE_ORG}" | tail -1 | cut -f1 -d' ')
-
- # pull archive
- echo "Pulling archive: ${ARCHIVE}"
- cd /
- borg extract --verbose "${REPO}::${ARCHIVE}"
-}
-
-USAGE_DESC_orgpush='push org directory to repos'
-CMDFNC_orgpush() {
- expect_n_args 0 0 '' $@
-
- for _FILENAME in $(ls "${PATH_BORG_CONF_SECURITY}/"); do
- local KEY_DATA=$(explore_key_id "${_FILENAME}")
- if keydata_obsolete "${KEY_DATA}"; then
- continue;
- fi
- local LOCATION=$(echo "${KEY_DATA}" | cut -d' ' -f3)
- local ARCHIVE="${LOCATION}::${NAME_ARCHIVE_ORG}-{utcnow:%Y-%m-%dT%H:%M}"
- _run_borg_with_passphrase create --verbose "${ARCHIVE}" "${HOME}/org"
- done
-}
-
-# parse args to execution
-if [ "$#" -lt 1 ]; then
- error_exit_with_usage 'missing command.'
-fi
-for CMD in ${USAGE_INDICES}; do
- if [ "$1" = "${CMD}" ]; then
- break
- fi
- CMD=
-done
-if [ -z "${CMD}" ]; then
- error_exit_with_usage "unknown command: ${1}"
-fi
-shift 1
-"CMDFNC_${CMD}" $@
+++ /dev/null
-#!/bin/sh
-set -e
-
-cd $(dirname "$0")
-. lib/abort_if_exists
-. lib/constants_borg # NAME_BORGAPP, PATH_BORG_CONF
-. lib/constants_secrets # PATH_REL_SECRETS, PATH_SECRETS, PATH_SECRETS_BORGKEYS, PATH_SECRETS_KDBX, PATH_USER_KDBX
-. lib/constants_ssh # PATH_USER_SSH
-. lib/constants_user # USERNAME
-. lib/copy_and_unmount_secrets
-. lib/mount_secrets
-. lib/prefixed_msg
-
-prefixed_msg_init
-
-abort_if_exists "${PATH_SECRETS}"
-prefixed_msg "Collecting new ${PATH_REL_SECRETS}."
-
-mkdir "${PATH_SECRETS}"
-cp -a "${PATH_USER_SSH}" "${PATH_SECRETS_SSH}"
-cp -a "${PATH_USER_KDBX}" "${PATH_SECRETS_KDBX}"
-"${NAME_BORGAPP}" backup_keys "${PATH_SECRETS_BORGKEYS}"
-
-prefixed_msg "secrets file, last update: $(whoami)/$(hostname) at $(date)" > "${PATH_SECRETS}/info"
-
-mount_secrets "$1" # sets PATH_MOUNTED_SECRETS
-SUFFIX_OLD=.old
-PATH_REL_SECRETS_OLD="${PATH_REL_SECRETS}${SUFFIX_OLD}"
-PATH_MOUNTED_SECRETS_OLD="${PATH_MOUNTED_SECRETS}${SUFFIX_OLD}"
-if [ -d "${PATH_MOUNTED_SECRETS}" ]; then
- prefixed_msg "Drive already has ${PATH_REL_SECRETS}, moving to ${PATH_REL_SECRETS_OLD}."
- rm -rf "${PATH_MOUNTED_SECRETS_OLD}"
- mv "${PATH_MOUNTED_SECRETS}" "${PATH_MOUNTED_SECRETS_OLD}"
-fi
-copy_and_unmount_secrets 'out'
-
-prefixed_msg_exit
+++ /dev/null
-#!/bin/sh
-set -e
-cd $(dirname "$0")
-. lib/abort
-. lib/audio_dev_is_mute
-. lib/print_usage
-
-MAX_LOUDNESS=150
-
-TARGET_IDX_SPEAKER=0
-TARGET_TYPE_SPEAKER=sink
-
-TARGET_IDX_MIC=1
-TARGET_TYPE_MIC=source
-
-
-
-USAGE_DESCRIPTION='Set audio device volume, or (if no LOUDNESS provided) toggle device muteness.\n\nAvailable arguments:'
-USAGE_LINES='[OPTION] [LOUDNESS]'
-USAGE_INDICES='_help _mic LOUDNESS'
-
-ARG_HELP_SHORT='-h'
-ARG_HELP_LONG='--help'
-USAGE_DESC__help='display this help and exit'
-USAGE_NAME__help="${ARG_HELP_SHORT}, ${ARG_HELP_LONG}"
-
-ARG_MIC_SHORT='-m'
-ARG_MIC_LONG='--mic'
-USAGE_DESC__mic='as device to manipulate, target microphone rather than speakers'
-USAGE_NAME__mic="${ARG_MIC_SHORT}, ${ARG_MIC_LONG}"
-
-USAGE_DESC_LOUDNESS="volume to set (as percentage, should be integer <= ${MAX_LOUDNESS}, final '%' optional)"
-
-
-
-abort_bad_args() {
- echo "Aborting due to unrecognized argument(s): $@" >&2
- echo ""
- print_usage
- exit 1
-}
-
-set_target_device() {
- TARGET_NAME="$1"
- TARGET_IDX="$2"
- TARGET_TYPE="$3"
-}
-
-toggle_mute() {
- if $(audio_dev_is_mute "${TARGET_TYPE}" "${TARGET_IDX}"); then
- MUTE_BOOL=0
- MUTE_WORD=off
- else
- MUTE_BOOL=1
- MUTE_WORD=on
- fi
- pacmd "set-${TARGET_TYPE}-mute" "${TARGET_IDX}" "${MUTE_BOOL}"
- echo "Toggled ${TARGET_NAME} muteness ${MUTE_WORD}."
-}
-
-set_volume_as_percentage() {
- _PERCENTAGE=$(echo "$1" | tr -d '%')
- if [ "${_PERCENTAGE}" -gt "${MAX_LOUDNESS}" ]; then
- abort "Aborting due to demand for unreasonably high loudness: ${_PERCENTAGE}%."
- fi
- AT_FULL=65536
- pacmd set-${TARGET_TYPE}-volume "${TARGET_IDX}" $(calc "(${_PERCENTAGE} * ${AT_FULL} // 100)")
- echo -n "Volume of ${TARGET_NAME} set to ${_PERCENTAGE}%."
- audio_dev_is_mute "${TARGET_TYPE}" "${TARGET_IDX}" && echo -n " (But device is muted.)"
- echo
-}
-
-
-
-set_target_device 'speaker' 0 'sink'
-if [ "$(echo $1 | cut -c1)" = '-' ]; then
- if [ "$1" = "${ARG_HELP_SHORT}" ] || [ "$1" = "${ARG_HELP_LONG}" ]; then
- print_usage
- exit 0
- elif [ "$1" = "${ARG_MIC_SHORT}" ] || [ "$1" = "${ARG_MIC_LONG}" ]; then
- set_target_device 'microphone' 1 'source'
- else
- error_exit "unrecognized argument: $1"
- abort_bad_args $@
- fi
- shift 1
-fi
-if [ -z "$1" ]; then
- toggle_mute
-elif [ -z "$(echo -n $1 | sed -E 's/[0-9]*[%]?//g')" ]; then
- set_volume_as_percentage "$1"
-else
- abort_bad_args $@
-fi
+++ /dev/null
-../../../../../scripts/lib/abort
\ No newline at end of file
+++ /dev/null
-../../../../../scripts/lib/abort_if_exists
\ No newline at end of file
+++ /dev/null
-audio_dev_is_mute() {
- _TYPE="$1"
- _IDX="$2"
- [ "$(pactl get-${_TYPE}-mute ${_IDX})" = "Mute: yes" ]
-}
+++ /dev/null
-../../../../../scripts/lib/constants_borg
\ No newline at end of file
+++ /dev/null
-../../../../../scripts/lib/constants_secrets
\ No newline at end of file
+++ /dev/null
-../../../../../scripts/lib/constants_ssh
\ No newline at end of file
+++ /dev/null
-../../../../../scripts/lib/constants_user
\ No newline at end of file
+++ /dev/null
-../../../../../scripts/lib/copy_and_unmount_secrets
\ No newline at end of file
+++ /dev/null
-../../../../../scripts/lib/expect_n_args
\ No newline at end of file
+++ /dev/null
-../../../../../scripts/lib/get_passphrase
\ No newline at end of file
+++ /dev/null
-../../../../../scripts/lib/mount_secrets
\ No newline at end of file
+++ /dev/null
-../../../../../scripts/lib/path_tmp_timestamped
\ No newline at end of file
+++ /dev/null
-../../../../../scripts/lib/prefixed_msg
\ No newline at end of file
+++ /dev/null
-print_usage() {
- echo 'Usage:'
- echo "${USAGE_LINES}" | while read _LINE; do
- echo " $(basename $0) ${_LINE}"
- done
- echo "\n${USAGE_DESCRIPTION}\n"
- _var_of() { eval printf '"%s"' '"${'"${1}${2}"'}"'; }
- _build_index() {
- _ARGS="$(_var_of 'USAGE_ARGS_' ${_IDX})"
- if [ ! -z "${_ARGS}" ]; then
- _ARGS=" ${_ARGS}"
- fi
- _NAME="${_IDX}"
- _ALT_NAME="$(_var_of 'USAGE_NAME_' ${_IDX})"
- if [ ! -z "${_ALT_NAME}" ]; then
- _NAME="${_ALT_NAME}"
- fi
- _KEY=" ${_NAME}${_ARGS}"
- }
- _MAX_LEN_KEY=0
- for _IDX in ${USAGE_INDICES}; do
- _build_index
- if [ ${#_KEY} -gt "${_MAX_LEN_KEY}" ]; then
- _MAX_LEN_KEY=${#_KEY}
- fi
- done
- for _IDX in ${USAGE_INDICES}; do
- _build_index
- printf '%s' "${_KEY}"
- _LEN_GAP=$(calc "${_MAX_LEN_KEY} - ${#_KEY} + 4")
- for _ in $(seq 1 ${_LEN_GAP}); do
- printf ' '
- done
- printf '%s\n' "$(_var_of 'USAGE_DESC_' ${_IDX})"
- done
-}
+++ /dev/null
-../../../../../scripts/lib/retry_until
\ No newline at end of file
+++ /dev/null
-# so we don't have to enter our SSH key password all the time
-eval $(ssh-agent) > /dev/null && ssh-add -q
-
-# zero audio volume (rather than "just" mute)
-vol 0
-
+++ /dev/null
-bind j scrollline 3
-bind k scrollline -3
-set hintuppercase false
-set hintchars 123456qwertasdfgyxcvb
-
-set searchengine duckduckgo
-set searchurls.wiktionary https://en.wiktionary.org/w/index.php?search=
-set searchurls.dictcc https://www.dict.cc/?s=
-
-autocmd DocStart www.reddit.com urlmodify -t www.reddit old.reddit
-
-set theme dark
-guiset gui none
-guiset tabs always
-guiset hoverlink left
-
-escapehatch
--- /dev/null
+../../trixie/copy/t490s
\ No newline at end of file
+++ /dev/null
-#!/bin/sh
-# see sway-bar(5) and swaybar-protocol(7)
-set -e
-
-. "${HOME}/.plomlib/audio_dev_is_mute"
-
-SYSCLASS_DIR=/sys/class
-
-COL_WHITE=dddddd
-COL_RED=dd0000
-COL_YELLOW=dddd00
-COL_GREEN=00dd00
-COL_GREY=aaaaaa
-
-print_bar_block() {
- printf '{"full_text": "%s", ' "$1"
- COLOR="${COL_GREY}"
- if [ ! -z "$2" ]; then
- COLOR="$2"
- fi
- printf '"color": "%s", ' "${COLOR}"
- if [ "$3" = "0" ]; then
- printf '"separator": false,\n'
- printf '"separator_block_width": 0,'
- fi
- printf '"markup": "pango",\n'
- printf '},\n'
-}
-
-print_calc() {
- printf "%d" $(calc "$1")
-}
-
-color_at() {
- IDX=0
- while true; do
- IDX=$(print_calc "${IDX} + 1")
- STEP=$(echo "$2" | cut -d'_' -f${IDX})
- if [ -z "${STEP}" ]; then
- break
- fi
- LIMIT=$(echo "${STEP}" | cut -d':' -f1)
- COLOR=$(echo "${STEP}" | cut -d':' -f2)
- if [ "${LIMIT}" -ge "${1}" ]; then
- printf "${COLOR}"
- break
- fi
- done
-}
-
-print_clipboard() {
- print_selection() {
- print_bar_block "$1 [" "${COL_WHITE}" 0
- CLEANED=$(wl-paste $2 | sed 's/"/\\"/g')
- ELLIPSIS=
- if [ $(echo "${CLEANED}" | wc -c) -gt 32 ]; then
- CLEANED=$(echo "${CLEANED}" | cut -zc'-29')
- ELLIPSIS='...'
- fi
- print_bar_block "${CLEANED}" "" 0
- print_bar_block "${ELLIPSIS}]" "${COL_WHITE}" $3
- }
- print_selection 'wl-paste' '' 0
- print_selection ' --primary' --primary
-}
-
-print_online() {
- print_conn() {
- print_bar_block "$(echo $1 | cut -c1):" "" 0
- IP=$(ip --brief addr show | grep "$1" | sed -E 's/ +/\t/g' | cut -f3 | cut -f1 -d'/')
- if [ -z "${IP}" ]; then
- print_bar_block '-'
- else
- print_bar_block "${IP}" "${COL_WHITE}" "$2"
- fi
- }
- print_conn enp
- print_conn wlp 0
- set +e
- STATUS_WIFI=$(nmcli -t -f IN-USE,SSID,SIGNAL dev wifi | grep '^\*:')
- set -e
- if [ ! -z "${STATUS_WIFI}" ]; then
- SIGNAL=$(echo -n "${STATUS_WIFI}" | cut -d':' -f3)
- COLOR=$(color_at $SIGNAL "45:${COL_RED}_85:${COL_YELLOW}_100:${COL_GREEN}")
- print_bar_block " ${SIGNAL}" "${COLOR}" 0
- print_bar_block "% $(echo "${STATUS_WIFI}" | cut -d':' -f2)"
- else
- print_bar_block " "
- fi
-}
-
-print_battery() {
- BAT_DIR="${SYSCLASS_DIR}/power_supply/BAT0"
-
- calc_percent () {
- cat_energy() {
- cat "${BAT_DIR}/energy_$1"
- }
- print_calc "100 * $(cat_energy $1) // $(cat_energy $2)"
- }
-
- CHARGE=$(calc_percent now full)
- COLOR=$(color_at $CHARGE "25:${COL_RED}_65:${COL_YELLOW}_100:${COL_GREEN}")
- print_bar_block "${CHARGE}%" "${COLOR}" 0
-
- COLOR="${COL_WHITE}"
- STATUS=$(cat "${BAT_DIR}/status")
- CHARGING=?
- if [ "${STATUS}" = "Not charging" ]; then
- CHARGING=-
- elif [ "${STATUS}" = "Charging" ]; then
- CHARGING=^
- COLOR="${COL_GREEN}"
- elif [ "${STATUS}" = "Discharging" ]; then
- CHARGING=v
- COLOR="${COL_YELLOW}"
- fi
- print_bar_block "${CHARGING}" "${COLOR}" 0
-
- print_bar_block "$(calc_percent full full_design)%"
-}
-
-print_temperature() {
- COLOR="${COL_WHITE}"
- TEMPERATURE=$(cat ${SYSCLASS_DIR}/thermal/thermal_zone0/temp)
- TEMPERATURE_IN_C=$(print_calc "${TEMPERATURE} // 1000")
- COLOR=$(color_at $TEMPERATURE_IN_C "65:${COL_GREEN}_85:${COL_YELLOW}_999:${COL_RED}")
- print_bar_block "${TEMPERATURE_IN_C}" "${COLOR}" 0
- print_bar_block '°'
-}
-
-print_datetime() {
- DATE=$(date +'%Y-%m-%d')
- TIME=$(date +'%H:%M:%S')
- TZ=$(date +'/%Z')
- print_bar_block "${DATE} " "" 0
- print_bar_block "${TIME}" "${COL_WHITE}" 0
- print_bar_block "${TZ}" ""
-}
-
-print_volume() {
- _print_vol() {
- _NAME="$1"
- _IDX="$2"
- _TYPE="$3"
- _BORDER="$4"
- print_bar_block "$1 " "${COL_WHITE}" 0
- VOLUME="$(pactl get-${_TYPE}-volume "${_IDX}" | head -1 | sed 's/ //g' | cut -d'/' -f2)"
- if $(audio_dev_is_mute "${_TYPE}" "${_IDX}"); then
- print_bar_block "<s>${VOLUME}</s>" '' "${_BORDER}"
- else
- print_bar_block "${VOLUME}" "${COL_YELLOW}" "${_BORDER}"
- fi
- }
- _print_vol 'vol' 0 'sink' 0
- _print_vol ' --mic' 1 'source'
-}
-
-print_keyboard() {
- LAYOUT=$(swaymsg -t get_inputs | grep 'xkb_active_layout_name' | sed -E 's/[ ,"]+//g' | cut -d':' -f2 | head -1)
- if [ "${LAYOUT}" = "English(US)" ]; then
- LAYOUT=us
- elif [ "${LAYOUT}" = "German" ]; then
- LAYOUT=de
- else
- LAYOUT=??
- fi
- print_bar_block "kb_${LAYOUT}"
-}
-
-printf '{"version": 1}\n['
-while true; do
- printf '['
- print_clipboard
- print_online
- print_battery
- print_temperature
- print_datetime
- print_volume
- print_keyboard
- printf '],'
- sleep 0.1
-done
+++ /dev/null
-#!/bin/sh
-set -e
-cd $(dirname "$0")
-. lib/abort
-. lib/abort_if_exists
-. lib/abort_if_not_user
-. lib/abort_if_offline
-. lib/constants_secrets # PATH_SECRETS, PATH_SECRETS_KDBX, PATH_SECRETS_SSH, PATH_SECRETS_BORGKEYS, PATH_USER_KDBX
-. lib/constants_ssh # PATH_USER_SSH
-. lib/constants_user # USERNAME
-. lib/constants_borg # NAME_BORGAPP
-. lib/copy_and_unmount_secrets
-. lib/expect_n_args
-. lib/mount_secrets
-. lib/prefixed_msg
-. lib/retry_until
-. lib/trapp
-
-prefixed_msg_init
-PATH_REPOS="${HOME}/repos"
-REPOS_SITE_DOMAIN=plomlompom.com
-REMOTE_PATH_REPOS=/var/repos
-
-expect_n_args 1 1 "(device name, e.g. 'sda')" $@
-abort_if_offline
-abort_if_not_user "${USERNAME}"
-abort_if_exists "${PATH_SECRETS}"
-abort_if_exists "${PATH_USER_SSH}"
-abort_if_exists "${PATH_REPOS}"
-
-mount_secrets "$1" # sets PASSPHRASE
-copy_and_unmount_secrets 'in'
-export BORG_PASSPHRASE="${PASSPHRASE}"
-
-prefixed_msg 'Copying passwords DB …'
-cp -a "${PATH_SECRETS_KDBX}" "${PATH_USER_KDBX}"
-
-prefixed_msg 'Setting up ~/.ssh …'
-cp -a "${PATH_SECRETS_SSH}" "${PATH_USER_SSH}"
-stty -echo
-trapp stty echo
-retry_until 1 'echo ""' 'ssh-add -q' 'prefixed_msg "Aborting due to ssh-add error"'
-stty echo
-trapp
-
-printf '\n'
-prefixed_msg 'Setting up ~/repos …'
-REPOS_SITE_LOGIN="${USERNAME}@${REPOS_SITE_DOMAIN}"
-mkdir "${PATH_REPOS}"
-cd "${PATH_REPOS}"
-ssh ${REPOS_SITE_LOGIN} "cd ${REMOTE_PATH_REPOS} && ls -1" | while read REPO_NAME; do
- prefixed_msg "Cloning ${REPO_NAME} …"
- git clone --quiet --recurse "${REPOS_SITE_LOGIN}:${REMOTE_PATH_REPOS}/${REPO_NAME}"
-done
-cd - > /dev/null
-
-prefixed_msg 'Setting up borg and pull in ~/org …'
-cd "${PATH_SECRETS_BORGKEYS}"
-ls -1 | while read _FILENAME; do
- "${NAME_BORGAPP}" claim "${_FILENAME}"
-done
-cd -
-retry_until 2 '' "${NAME_BORGAPP} orgpull" "prefixed_msg 'Aborting due to unexpected ${NAME_BORGAPP} error.'" '' 'direct'
-prefixed_msg "${_OUTPUT}"
-
-prefixed_msg_exit
--- /dev/null
+../../trixie/scripts/_setup_secrets_user.sh
\ No newline at end of file
+++ /dev/null
-. lib/abort
-
-abort_if_exists() {
- if [ -e "$1" ]; then
- abort "Aborting since $1 already exists."
- fi
-}
--- /dev/null
+../../../trixie/scripts/lib/abort_if_exists
\ No newline at end of file
+++ /dev/null
-. lib/abort
-
-abort_if_offline() {
- if ! ping -c1 -W2 1.1.1.1 > /dev/null 2>&1; then
- abort 'Must be run online.'
- fi
-}
--- /dev/null
+../../../trixie/scripts/lib/abort_if_offline
\ No newline at end of file
+++ /dev/null
-NAME_BORGAPP=borgplom
-PATH_BORG_CONF="${HOME}/.config/borg"
--- /dev/null
+../../../trixie/scripts/lib/constants_borg
\ No newline at end of file
+++ /dev/null
-FILENAME_PRESEED_CFG=preseed.cfg
-PATH_PRESEED_CFG=$(realpath "../${FILENAME_PRESEED_CFG}")
--- /dev/null
+../../../trixie/scripts/lib/constants_installer
\ No newline at end of file
+++ /dev/null
-PREV_RELEASE=trixie
-THIS_RELEASE=testing
+++ /dev/null
-. lib/constants_user
-PATH_MEDIA=/media
-PATH_REL_SECRETS=.secrets
-PATH_SECRETS="${PATH_USER_HOME}/${PATH_REL_SECRETS}"
-PATH_SECRETS_SSH="${PATH_SECRETS}/ssh"
-PATH_SECRETS_BORGKEYS="${PATH_SECRETS}/borgkeys"
-FILENAME_KDBX=Passwords.kdbx
-PATH_SECRETS_KDBX="${PATH_SECRETS}/${FILENAME_KDBX}"
-PATH_USER_KDBX="${PATH_USER_HOME}/${FILENAME_KDBX}"
--- /dev/null
+../../../trixie/scripts/lib/constants_secrets
\ No newline at end of file
+++ /dev/null
-. lib/constants_secrets # PATH_REL_SECRETS, PATH_SECRETS
-
-copy_and_unmount_secrets() {
-prefixed_msg_init copy_and_unmount_secrets
-
-prefixed_msg "Copying over ${PATH_REL_SECRETS}."
-if [ "$1" = "out" ]; then
- cp -a "${PATH_SECRETS}" "${PATH_MOUNTED_SECRETS}"
-elif [ "$1" = "in" ]; then
- cp -a "${PATH_MOUNTED_SECRETS}" "${PATH_SECRETS}"
-else
- abort "Illegal argument to unmount_secrets."
-fi
-pumount "${SECRETS_DEV}"
-prefixed_msg "You can remove device ${SECRETS_DEV} now."
-
-prefixed_msg_exit
-}
--- /dev/null
+../../../trixie/scripts/lib/copy_and_unmount_secrets
\ No newline at end of file
+++ /dev/null
-. lib/abort
-
-get_mountable_device_path() {
- _PATH_DEV="/dev/$1"
- if [ ! -b "${_PATH_DEV}" ]; then
- abort "No block device at ${_PATH_DEV}."
- elif [ $(mount | grep -E "^${_PATH_DEV}" | wc -l) -gt 0 ]; then
- abort "${_PATH_DEV} already mounted."
- fi
- printf "${_PATH_DEV}"
-}
--- /dev/null
+../../../trixie/scripts/lib/get_mountable_device_path
\ No newline at end of file
+++ /dev/null
-get_passphrase() {
- stty -echo
- read PASSPHRASE
- stty echo
- printf "${PASSPHRASE}"
-}
--- /dev/null
+../../../trixie/scripts/lib/get_passphrase
\ No newline at end of file
+++ /dev/null
-. lib/constants_secrets # PATH_MEDIA, PATH_REL_SECRETS
-. lib/expect_n_args
-. lib/get_passphrase
-. lib/path_tmp_timestamped
-. lib/prefixed_msg
-. lib/retry_until
-
-mount_secrets() {
-prefixed_msg_init mount_secrets
-
-SECRETS_DEV=$1
-if [ -z "${SECRETS_DEV}" ]; then
- abort "Aborting due to empty device argument."
-fi
-PATH_MOUNTED_SECRETS="${PATH_MEDIA}/${SECRETS_DEV}/${PATH_REL_SECRETS}"
-PATH_DEV="/dev/${SECRETS_DEV}"
-PATH_PMOUNT_ERR="$(path_tmp_timestamped 'err_mount')"
-prefixed_msg "Put secrets drive into slot for ${PATH_DEV}."
-while [ ! -e "${PATH_DEV}" ]; do
- sleep 0.1
-done
-_ON_LOOP_START='prefixed_msg_no_nl "Passphrase: "; PASSPHRASE=$(get_passphrase); echo ""'
-_TO_TEST='echo "${PASSPHRASE}" | pmount "${PATH_DEV}" 2>&1'
-_ON_FAIL='prefixed_msg "Aborting due to pmount error:"'
-retry_until 100 "${_ON_LOOP_START}" "${_TO_TEST}" "${_ON_FAIL}"
-prefixed_msg "${_OUTPUT}"
-
-prefixed_msg_exit
-}
--- /dev/null
+../../../trixie/scripts/lib/mount_secrets
\ No newline at end of file
+++ /dev/null
-path_tmp_timestamped () {
- printf "/tmp/${1}_$(date +'%s')"
-}
--- /dev/null
+../../../trixie/scripts/lib/path_tmp_timestamped
\ No newline at end of file
+++ /dev/null
-retry_until() {
- _CODE_FOR_CONTINUE="$1"
- _ON_LOOP_START="$2"
- _TO_TEST="$3"
- _ON_FAIL="$4"
- _ON_LOOP_END="$5"
- _OUTPUT_MODE="$6"
- while true; do
- eval "${_ON_LOOP_START}"
- set +e
- if [ "${_OUTPUT_MODE}" = 'direct' ]; then
- eval ${_TO_TEST}
- _RESULT=$?
- else
- _OUTPUT="$(eval ${_TO_TEST})"
- _RESULT=$?
- fi
- set -e
- if [ "${_RESULT}" = '0' ]; then
- break
- elif [ "${_RESULT}" != "${_CODE_FOR_CONTINUE}" ]; then
- eval "${_ON_FAIL}"
- abort
- fi
- eval "${_ON_LOOP_END}"
- done
-}
--- /dev/null
+../../../trixie/scripts/lib/retry_until
\ No newline at end of file
+++ /dev/null
-#!/bin/sh
-# based on <https://wiki.debian.org/DebianInstaller/WritableUSBStick>
-set -e
-cd $(dirname "$0")
-. lib/INSTALLER_VERSION
-. lib/abort
-. lib/abort_if_command_unknown
-. lib/abort_if_not_user
-. lib/abort_if_offline
-. lib/constants_installer # FILENAME_PRESEED_CFG, PATH_PRESEED_CFG
-. lib/expect_n_args
-. lib/get_mountable_device_path
-. lib/path_tmp_timestamped
-. lib/trapp
-
-expect_n_args 1 1 'DEVICE (e.g. "sdb")' $@
-abort_if_not_user root
-abort_if_offline
-abort_if_command_unknown mkfs.vfat
-abort_if_command_unknown parted
-abort_if_command_unknown rsync
-abort_if_command_unknown wget
-PATH_DEV="$(get_mountable_device_path $1)"
-PATH_MNT_ISO=/mnt/iso
-
-PATH_PROCESSING="$(path_tmp_timestamped make_writable_installer)"
-RM_PROCESSING="rm -rf ${PATH_PROCESSING}"
-echo "Setting up processing directory at ${PATH_PROCESSING} …"
-mkdir "${PATH_PROCESSING}"
-trapp "${RM_PROCESSING}"
-cd "${PATH_PROCESSING}"
-
-FILENAME_ISO="debian-${INSTALLER_VERSION}-amd64-netinst.iso"
-echo "Retrieving ${FILENAME_ISO} …"
-URL_ISO="https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/${FILENAME_ISO}"
-wget --quiet --output-document "${FILENAME_ISO}" "${URL_ISO}"
-
-echo "Preparing partition/filesystem on ${PATH_DEV} …"
-parted --script "${PATH_DEV}" mklabel msdos
-parted --script "${PATH_DEV}" mkpart primary fat32 0% 100%
-PATH_PARTITION="${PATH_DEV}1"
-mkfs.vfat "${PATH_PARTITION}" > /dev/null
-
-PATH_MNT_DEV='/mnt/'$(basename "${PATH_PARTITION}")
-echo -n "Mounting ${PATH_MNT_ISO} and ${PATH_MNT_DEV} …"
-mkdir -p "${PATH_MNT_ISO}" "${PATH_MNT_DEV}"
-do_umount() {
- echo "Unmounting $1 …"
- set +e
- umount "$1"
- set -e
-}
-mount "${PATH_PARTITION}" "${PATH_MNT_DEV}"
-trapp "${RM_PROCESSING}; do_umount ${PATH_MNT_DEV}"
-mount -o loop "${FILENAME_ISO}" "${PATH_MNT_ISO}" 2>&1 | sed 's|mount: /mnt/iso: WARNING: source write-protected, mounted read-only.||'
-trapp "${RM_PROCESSING}; do_umount ${PATH_MNT_DEV}; do_umount ${PATH_MNT_ISO}"
-
-echo "Copying contents of ${PATH_MNT_ISO} to ${PATH_MNT_DEV}/ …"
-FILENAME_RSYNC_ERRORS="rsync_errors"
-set +e
-rsync -a "${PATH_MNT_ISO}/" "${PATH_MNT_DEV}/" 2> "${FILENAME_RSYNC_ERRORS}"
-RESULT=$?
-set -e
-if [ "${RESULT}" != "0" ]; then
- echo 'RSYNC ERRORS:'
- cat "${FILENAME_RSYNC_ERRORS}"
- echo '\nrsync encountered errors, see above – continue? (Y/N)'
- read ANSWER
- FIRST_CHAR=$(echo "${ANSWER}" | cut -c1)
- if ! [ "${FIRST_CHAR}" = 'y' -o "${FIRST_CHAR}" = 'Y' ]; then
- abort 'as requested'
- fi
-fi
-
-echo "Installing preseed file …"
-cp "${PATH_PRESEED_CFG}" "${PATH_MNT_DEV}/"
-sed --in-place 's/ --- / --- preseed\/file=\/cdrom\/'"${FILENAME_PRESEED_CFG}"' /g' "${PATH_MNT_DEV}/boot/grub/grub.cfg"
-
-echo "Done!"
--- /dev/null
+../../trixie/scripts/make_writable_installer.sh
\ No newline at end of file
+++ /dev/null
-#!/bin/sh
-set -e
-cd $(dirname "$0")
-. lib/abort
-. lib/abort_if_offline
-. lib/apt_get_digested
-. lib/constants_etc # PATH_ETC
-. lib/constants_user # USERNAME
-. lib/copy_dirtrees_of_tags
-. lib/core_setup
-. lib/expect_n_args
-. lib/prefixed_msg
-. lib/put_finished_marker
-
-prefixed_msg_init
-prefixed_msg 'starting …'
-
-PATH_NETWORK_INTERFACES="${PATH_ETC}/network/interfaces"
-THINKPAD_NAMES="x220 w530 t490s"
-
-abort_if_offline
-
-get_system_class_for() {
- for THINKPAD_NAME in $THINKPAD_NAMES; do
- if [ "$1" = "${THINKPAD_NAME}" ]; then
- printf 'thinkpad'
- break
- fi
- done
- printf ''
-}
-abort_if_illegal_system_name() {
- LEGAL_SYSTEM_NAMES="${THINKPAD_NAMES} h610m"
- for SYSTEM_NAME_I in $LEGAL_SYSTEM_NAMES; do
- if [ "$1" = "$SYSTEM_NAME_I" ]; then
- return 0
- fi
- done
- abort 'Need legal system name.'
-}
-expect_n_args 2 2 "SYSTEM_NAME, USER_PW" $@
-SYSTEM_NAME="$1"
-USER_PW="$2"
-abort_if_illegal_system_name "${SYSTEM_NAME}"
-SYSTEM_CLASS_NAME="$(get_system_class_for ${SYSTEM_NAME})"
-INSTALL_TAGS="all ${SYSTEM_CLASS_NAME} ${SYSTEM_NAME} user desktop"
-
-adopt_wifi_connection() {
- get_network_interfaces_last_wpa_value() {
- REGEX="^\s+wpa-${1}\s+"
- cat "${PATH_NETWORK_INTERFACES}" | grep -E "${REGEX}" | sed -E "s/${REGEX}//g" | tail -1
- }
- WLAN_SSID=$(get_network_interfaces_last_wpa_value 'ssid')
- WLAN_PSK=$(get_network_interfaces_last_wpa_value 'psk')
- if [ ! -z "${WLAN_SSID}" ]; then
- prefixed_msg_no_nl "Found, adding to NetworkManager: "
- if [ -z "${WLAN_PSK}" ]; then
- nmcli connection add type wifi wifi.ssid "${WLAN_SSID}"
- else # NB: assumes last (collected with tail -1) wpa-psk that of last wlan-ssid
- nmcli connection add type wifi wifi.ssid "${WLAN_SSID}" wifi-sec.key-mgmt wpa-psk wifi-sec.psk "${WLAN_PSK}"
- fi
- fi
-}
-
-../../trixie/scripts/from_older_upgrade.sh desktop
-./from_older_upgrade.sh desktop
-
-# NB: This needs to come before steps potentially overwriting /etc/network/interfaces.
-apt_get_digested '-q -q install network-manager'
-if [ "$(nmcli -f TYPE conn | grep 'wifi' | wc -l)" = "0" ]; then
- prefixed_msg "Checking for existing wifi config in ${PATH_NETWORK_INTERFACES} …"
- adopt_wifi_connection
-else
- prefixed_msg 'Already know wifi connection, nothing to add …'
-fi
-
-core_setup "${SYSTEM_NAME}" "" "" "${INSTALL_TAGS}"
-
-prefixed_msg 'Ensuring our desired locale is available …'
-locale-gen
-
-prefixed_msg 'Final user setup …'
-adduser --quiet "${USERNAME}" plugdev # so user may use pmount
-echo "${USERNAME}:${USER_PW}" | chpasswd
-
-put_finished_marker 'setup_desktop'
-prefixed_msg_exit
--- /dev/null
+../../trixie/scripts/setup_desktop.sh
\ No newline at end of file
+++ /dev/null
-#!/bin/sh
-set -e
-cd $(dirname "$0")
-. lib/abort_if_not_user
-. lib/check_finished_marker
-. lib/constants_repopaths # PATH_CONF, PATH_SCRIPTS
-. lib/constants_user # USERNAME
-. lib/path_tmp_timestamped
-. lib/prefixed_msg
-
-prefixed_msg_init
-
-check_finished_marker 'setup_desktop'
-abort_if_not_user root
-PATH_REL_SETUP_SECRETS_USER="$(basename ${PATH_CONF})/$(basename ${PATH_SCRIPTS})/_setup_secrets_user.sh"
-PATH_REPO="$(dirname ${PATH_CONF})"
-PATH_TMP_REPO="$(path_tmp_timestamped configrepo)"
-
-prefixed_msg "Setting up config repo copy for user at ${PATH_TMP_REPO} …"
-cp -a "${PATH_REPO}" "${PATH_TMP_REPO}"
-chown -R "${USERNAME}:${USERNAME}" "${PATH_TMP_REPO}"
-su -l "${USERNAME}" -c "/bin/sh ${PATH_TMP_REPO}/${PATH_REL_SETUP_SECRETS_USER} $1"
-rm -rf "${PATH_TMP_REPO}"
-
-prefixed_msg_exit
--- /dev/null
+../../trixie/scripts/setup_secrets.sh
\ No newline at end of file
--- /dev/null
+# to avoid booting problems with encrypted LVM, see <https://askubuntu.com/a/1105848>
+cryptsetup-initramfs
+lvm2
+# for secrets
+pmount
+# for my own scripts to run
+python3-venv
+# for syncing
+borgbackup
+# for accessing remote machines
+openssh-client
+# wayland usage essentials
+sway
+wl-clipboard
+# at a minimum sets env stuff without which sway won't start
+dbus-user-session
+# for sound
+pulseaudio
+# dmenu replacement
+wmenu
+# for status.sh to work
+calc
+# xterm replacement
+foot
+# for e.g. chromium to work (and to disappear certain error messages)
+xwayland
+# for firefox and tridactyl
+curl
+firefox-esr
+# for using Google services
+chromium
+# for passwords
+keepassxc
+# for installing Signal
+gpg
+wget
+#
--- /dev/null
+# so we can work without the Ethernet adapter
+network-manager
+wpasupplicant
+firmware-iwlwifi
+# for battery management, we assume good defaults
+tlp
+
--- /dev/null
+# This file describes the network interfaces available on your system
+# and how to activate them. For more information, see interfaces(5).
+
+source /etc/network/interfaces.d/*
+
+# The loopback network interface
+auto lo
+iface lo inet loopback
+
+# anything more would only confuse NetworkManager
--- /dev/null
+# mere "kb" might be more flexible, but this way I won't accidentally try for
+# a non-existing "en" layout
+alias kb_de="swaymsg 'input * xkb_layout de'"
+alias kb_us="swaymsg 'input * xkb_layout us'"
+
+# miscellaneaous
+alias curlpost='curl -H "Content-Type: application/json" -X POST'
--- /dev/null
+# because these are included by /etc/sway/config for probably good reason …
+include /etc/sway/config-vars.d/*
+include /etc/sway/config.d/*
+
+# font for wm text
+font pango:Terminus 16px
+
+# force "tabbed" as default layout for new windows
+workspace_layout tabbed
+
+# simple green background
+output * background #559911 solid_color
+
+# keyboard layout
+input * xkb_layout "us"
+
+# waybar
+bar {
+ position top
+ tray_output none
+ status_command ~/.nonpath_bins/status.sh
+}
+
+# make Windows key modifier key for all wm actions
+set $mod Mod4
+floating_modifier $mod
+
+# program launcher
+bindsym $mod+d exec wmenu-run
+bindsym $mod+x exec wmenu-run
+
+# launch terminal emulator
+bindsym $mod+Return exec foot --font=monospace:size=12
+
+# kill window
+bindsym $mod+Shift+q kill
+
+# move focus between windows, but not by mouse
+bindsym $mod+Left focus left
+bindsym $mod+Down focus down
+bindsym $mod+Up focus up
+bindsym $mod+Right focus right
+focus_follows_mouse no
+
+# move windows
+bindsym $mod+Shift+Left move left
+bindsym $mod+Shift+Down move down
+bindsym $mod+Shift+Up move up
+bindsym $mod+Shift+Right move right
+
+# resize windows
+bindsym $mod+h resize shrink width 1 px or 1 ppt
+bindsym $mod+l resize grow width 1 px or 1 ppt
+bindsym $mod+j resize shrink height
+bindsym $mod+k resize grow height
+
+# toggle fullscreen for focused window
+bindsym $mod+f fullscreen
+
+# toggle floating of window, focus on floating or tabbed windows.
+bindsym $mod+Shift+space floating toggle
+bindsym $mod+space focus mode_toggle
+
+# reload config file
+bindsym $mod+Shift+c reload
+
+# stop wm
+bindsym $mod+Shift+p exit
+
+# switch workspaces
+bindsym $mod+1 workspace 1
+bindsym $mod+2 workspace 2
+bindsym $mod+3 workspace 3
+bindsym $mod+4 workspace 4
+bindsym $mod+5 workspace 5
+bindsym $mod+6 workspace 6
+bindsym $mod+7 workspace 7
+bindsym $mod+8 workspace 8
+bindsym $mod+9 workspace 9
+bindsym $mod+0 workspace 10
+
+# move window to workspace
+bindsym $mod+Shift+1 move workspace 1
+bindsym $mod+Shift+2 move workspace 2
+bindsym $mod+Shift+3 move workspace 3
+bindsym $mod+Shift+4 move workspace 4
+bindsym $mod+Shift+5 move workspace 5
+bindsym $mod+Shift+6 move workspace 6
+bindsym $mod+Shift+7 move workspace 7
+bindsym $mod+Shift+8 move workspace 8
+bindsym $mod+Shift+9 move workspace 9
+bindsym $mod+Shift+0 move workspace 10
--- /dev/null
+[user]
+ email = c.heller@plomlompom.de
+ name = Christian Heller
--- /dev/null
+#!/bin/sh
+set -e
+cd $(dirname "$0")
+. lib/abort
+. lib/print_usage
+
+ARG_HELP=--help
+USAGE_DESCRIPTION='Set backlight to maximum, or [INTEGER] percentage of it.'
+USAGE_LINES="COMMAND [${ARG_HELP}] [INTEGER]"
+
+if [ "$1" = "${ARG_HELP}" ]; then
+ print_usage
+ exit 0
+elif [ -z "$1" ]; then
+ PERCENTAGE=100
+elif [ "$(echo -n $1 | sed -E 's/[0-9]*[%]?//g')" ]; then
+ echo "Aborting due to unrecognized argument(s): $@" >&2
+ exit 1
+elif [ "$1" -gt 100 ]; then
+ echo "Aborting due to percentage > 100" >&2
+ exit 1
+else
+ PERCENTAGE=$1
+fi
+PATH_BACKLIGHTS=/sys/class/backlight
+FILENAME_MAX=max_brightness
+FILENAME_TARGET=brightness
+BACKLIGHTS=$(ls "${PATH_BACKLIGHTS}")
+for BACKLIGHT in ${BACKLIGHTS}; do
+ PATH_DIR_BACKLIGHT=${PATH_BACKLIGHTS}/${BACKLIGHT}
+ MAX_BRIGHTNESS=$(cat "${PATH_DIR_BACKLIGHT}/${FILENAME_MAX}")
+ TARGET_VAL=$(calc "(${PERCENTAGE} * ${MAX_BRIGHTNESS} // 100)" | tr -d '\t')
+ sudo sh -c "echo ${TARGET_VAL} > ${PATH_DIR_BACKLIGHT}/${FILENAME_TARGET}"
+ printf 'set %s to %s%s (%s)\n' "${BACKLIGHT}" "${PERCENTAGE}" "%" "${TARGET_VAL}"
+done
--- /dev/null
+#!/bin/sh
+set -e
+cd $(dirname "$0")
+. lib/abort
+. lib/constants_borg # PATH_BORG_CONF
+. lib/expect_n_args
+. lib/get_passphrase
+. lib/path_tmp_timestamped
+. lib/print_usage
+. lib/retry_until
+cd - > /dev/null
+
+USAGE_DESCRIPTION='Wrapper around certain borgbackup usages.\n\nAvailable commands:'
+USAGE_LINES='COMMAND [ARGUMENT]...'
+
+PATH_BORG_CONF_SECURITY="${PATH_BORG_CONF}/security"
+PATH_BORG_CONF_KEYS="${PATH_BORG_CONF}/keys"
+
+NAME_ARCHIVE_ORG=orgdir
+
+location_from_servername() { printf 'ssh://borg@%s/./borgrepo' "$1"; }
+servername_from_location() { echo "$1" | cut -d'/' -f3 | cut -d'@' -f2; }
+path_repo_location() { printf '%s' "${PATH_BORG_CONF_SECURITY}/${1}/location"; }
+
+explore_key_id() {
+ local KEY_ID=$1
+ local PATH_LOC="$(path_repo_location ${KEY_ID})"
+ if [ ! -f "${PATH_LOC}" ]; then
+ printf '?'
+ return
+ fi
+ local LOCATION=$(cat "${PATH_LOC}")
+ local NAME_SERVER=$(servername_from_location "${LOCATION}")
+ if [ "${LOCATION}" = $(location_from_servername "${NAME_SERVER}") ]; then
+ local PREFIX='+'
+ else
+ local PREFIX='-'
+ fi
+ printf '%s %s %s' "${PREFIX} ${NAME_SERVER} ${LOCATION}"
+}
+
+keydata_obsolete() {
+ KEY_DATA=$1
+ local PREFIX=$(echo "${KEY_DATA}" | cut -d' ' -f1)
+ if [ "${PREFIX}" = '-' ]; then
+ echo "Ignoring ${KEY_ID}, location doesn't match expected pattern."
+ return 0
+ fi
+ return 1
+}
+
+# exits
+export BORG_EXIT_CODES=modern
+error_exit() { abort "Aborting due to $1"; }
+error_exit_with_usage() { error_exit "${1}\n\n$(print_usage)"; }
+exit_ok() { echo "$@"; exit 0; }
+
+# commands
+USAGE_INDICES='backup_keys claim help info init keys orgpull orgpush'
+
+_run_borg_with_passphrase() {
+ _FIRST_RUN=1
+ _ON_LOOP_START='
+ if [ -z "${BORG_PASSPHRASE}" ]; then
+ printf "Passphrase:"
+ export BORG_PASSPHRASE="$(get_passphrase)"
+ echo ""
+ fi
+ '
+ _TO_TEST='borg '"$@"
+ _ON_FAIL='echo "unexpected borg error, code ${_RESULT}."'
+ _ON_LOOP_END='export BORG_PASSPHRASE='
+ retry_until 52 "${_ON_LOOP_START}" "${_TO_TEST}" "${_ON_FAIL}" "${_ON_LOOP_END}"
+}
+
+_id_from_file() { head -1 "$1" | cut -d' ' -f2; }
+
+USAGE_ARGS_backup_keys='PATH'
+USAGE_DESC_backup_keys="copy known keys to PATH/, with their repos' server names as filenames"
+CMDFNC_backup_keys() {
+ expect_n_args 1 1 "${USAGE_ARGS_backup_keys}" $@
+ local PATH_TARGET_DIR=$(realpath "$1")
+ if [ -e "${PATH_TARGET_DIR}" ] && [ ! -d "${PATH_TARGET_DIR}" ]; then
+ error_exit "non-directory at ${PATH_TARGET_DIR}"
+ fi
+ mkdir -p "${PATH_TARGET_DIR}"
+ cd "${PATH_BORG_CONF_KEYS}"
+ ls -1 | while read _FILENAME; do
+ local KEY_ID=$(_id_from_file "${PATH_BORG_CONF_KEYS}/${_FILENAME}")
+ local KEY_DATA=$(explore_key_id "${KEY_ID}")
+ if keydata_obsolete "${KEY_DATA}"; then
+ continue;
+ fi
+ local NAME_SERVER=$(echo "${KEY_DATA}" | cut -d' ' -f2)
+ local PATH_TARGET="${PATH_TARGET_DIR}/${NAME_SERVER}"
+ echo "Copying ${_FILENAME} to ${PATH_TARGET} …"
+ cp "${_FILENAME}" "${PATH_TARGET}"
+ done
+ cd - > /dev/null
+}
+
+USAGE_ARGS_claim='PATH'
+USAGE_DESC_claim="register file of PATH as key to repo at \"$(location_from_servername SERVER_NAME)\", with SERVER_NAME the filename portion of PATH"
+CMDFNC_claim() {
+ expect_n_args 1 1 "${USAGE_ARGS_claim}" $@
+ _PATH_SOURCE="$1"
+ _ensure_no_overwrite_at() {
+ if [ -f "$1" ]; then
+ error_exit "refusing to overwrite pre-existing file at $1"
+ fi
+ }
+
+ _FILENAME=$(basename ${_PATH_SOURCE})
+ _PATH_TARGET_KEY="${PATH_BORG_CONF_KEYS}/${_FILENAME}"
+ if [ ! -f "${_PATH_SOURCE}" ]; then
+ error_exit "no file at ${_PATH_SOURCE}"
+ fi
+ _ensure_no_overwrite_at "${_PATH_TARGET_KEY}"
+ _REPO_ID="$(_id_from_file ${_PATH_SOURCE})"
+ if [ ! -z "$(echo ${_REPO_ID} | sed 's/[a-f0-9]//g')" ]; then
+ error_exit "inability to parse valid repo ID from alleged key file at $1"
+ fi
+ _PATH_TARGET_LOCATION="$(path_repo_location ${_REPO_ID})"
+ _ensure_no_overwrite_at "${_PATH_TARGET_LOCATION}"
+ mkdir -p "${PATH_BORG_CONF_KEYS}" "$(dirname ${_PATH_TARGET_LOCATION})"
+ echo "Copying ${_PATH_SOURCE} to ${_PATH_TARGET_KEY} …"
+ cp "${_PATH_SOURCE}" "${_PATH_TARGET_KEY}"
+ echo "Writing ${_PATH_TARGET_LOCATION} …"
+ printf '%s' "$(location_from_servername ${_FILENAME})" > "${_PATH_TARGET_LOCATION}"
+ chmod a-rwx,u+rw "${_PATH_TARGET_KEY}" "${_PATH_TARGET_LOCATION}"
+}
+
+USAGE_DESC_help='print this help and exit'
+CMDFNC_help() {
+ expect_n_args 0 0 '' $@
+ print_usage
+}
+
+USAGE_ARGS_info='SERVER_NAME [ARCHIVE]'
+USAGE_DESC_info="run 'borg info' against repo at \"$(location_from_servername SERVER_NAME)\", optionally only against ARCHIVE; if latter not provided, list most recent archives of repo"
+CMDFNC_info() {
+ expect_n_args 1 2 "${USAGE_ARGS_info}" $@
+ _TARGET_REPO="$(location_from_servername ${1})"
+ if [ ! -z "$2" ]; then
+ exit_ok $(borg info "${_TARGET_REPO}::$2")
+ fi
+ _run_borg_with_passphrase info "${_TARGET_REPO}"
+ echo "${_OUTPUT}\n\nMost recent archives:"
+ borg list "${_TARGET_REPO}" | tail -5
+}
+
+USAGE_ARGS_init='SERVER_NAME'
+USAGE_DESC_init="create repo at \"$(location_from_servername SERVER_NAME)\""
+CMDFNC_init() {
+ expect_n_args 1 1 "${USAGE_ARGS_init}" $@
+ _STASHED_BORG_PASSPHRASE="$(env | grep -E '^BORG_PASSPHRASE=' | cut -d'=' -f2-)"
+ unset BORG_PASSPHRASE
+ borg init --encryption=keyfile "$(location_from_servername $1)"
+ if [ ! -z "${_STASHED_BORG_PASSPHRASE}" ]; then
+ export BORG_PASSPHRASE="${_STASHED_BORG_PASSPHRASE}"
+ _STASHED_BORG_PASSPHRASE=
+ fi
+}
+
+USAGE_DESC_keys='list known repos in ID, key filename, and alleged location'
+CMDFNC_keys() {
+ expect_n_args 0 0 '' $@
+ echo "Known keys, as per ${PATH_BORG_CONF_KEYS}:"
+ local EXIT_OK_PREFIX='(none, since directory'
+ if [ ! -d "${PATH_BORG_CONF_KEYS}" ]; then
+ exit_ok "${EXIT_OK_PREFIX} non-existant)"
+ fi
+ local KEYFILES="$(ls -1 ${PATH_BORG_CONF_KEYS})"
+ if [ -z "${KEYFILES}" ]; then
+ exit_ok "${EXIT_OK_PREFIX} empty)"
+ fi
+ echo "${KEYFILES}" | while read _FILENAME; do
+ local KEY_ID=$(_id_from_file "${PATH_BORG_CONF_KEYS}/${_FILENAME}")
+ local KEY_DATA=$(explore_key_id "${KEY_ID}")
+ local PREFIX=$(echo "${KEY_DATA}" | cut -d' ' -f1)
+ local LOCATION=$(echo "${KEY_DATA}" | cut -d' ' -f3)
+ printf '%s %s %s %s\n' "${PREFIX}" "${KEY_ID}" "${_FILENAME}" "${LOCATION}"
+ done
+}
+
+USAGE_DESC_orgpull='pull most recent org directory available in repos'
+CMDFNC_orgpull() {
+ expect_n_args 0 0 '' $@
+
+ # determine server and repo
+ local PATH_PIPE="$(path_tmp_timestamped 'pipe')"
+ mkfifo "${PATH_PIPE}"
+ ls -1 "${PATH_BORG_CONF_SECURITY}/" > "${PATH_PIPE}" &
+ while read _FILENAME; do
+ local KEY_DATA=$(explore_key_id "${_FILENAME}")
+ if keydata_obsolete "${KEY_DATA}"; then
+ continue;
+ fi
+ local NAME_SERVER=$(echo "${KEY_DATA}" | cut -d' ' -f2)
+ local LOCATION=$(echo "${KEY_DATA}" | cut -d' ' -f3)
+ if ping -c1 -W2 "${NAME_SERVER}" > /dev/null 2>&1; then
+ local REPO="${LOCATION}"
+ break
+ else
+ echo "Cannot reach ${NAME_SERVER}, skipping."
+ fi
+ done < "${PATH_PIPE}"
+ rm "${PATH_PIPE}"
+ if [ -z "${REPO}" ]; then
+ error_exit 'no repo being available.'
+ fi
+
+ # determine passphrase and archive
+ echo "Checking out ${REPO} …"
+ _run_borg_with_passphrase list "${REPO}"
+ local ARCHIVE=$(echo "${_OUTPUT}" | grep "${NAME_ARCHIVE_ORG}" | tail -1 | cut -f1 -d' ')
+
+ # pull archive
+ echo "Pulling archive: ${ARCHIVE}"
+ cd /
+ borg extract --verbose "${REPO}::${ARCHIVE}"
+}
+
+USAGE_DESC_orgpush='push org directory to repos'
+CMDFNC_orgpush() {
+ expect_n_args 0 0 '' $@
+
+ for _FILENAME in $(ls "${PATH_BORG_CONF_SECURITY}/"); do
+ local KEY_DATA=$(explore_key_id "${_FILENAME}")
+ if keydata_obsolete "${KEY_DATA}"; then
+ continue;
+ fi
+ local LOCATION=$(echo "${KEY_DATA}" | cut -d' ' -f3)
+ local ARCHIVE="${LOCATION}::${NAME_ARCHIVE_ORG}-{utcnow:%Y-%m-%dT%H:%M}"
+ _run_borg_with_passphrase create --verbose "${ARCHIVE}" "${HOME}/org"
+ done
+}
+
+# parse args to execution
+if [ "$#" -lt 1 ]; then
+ error_exit_with_usage 'missing command.'
+fi
+for CMD in ${USAGE_INDICES}; do
+ if [ "$1" = "${CMD}" ]; then
+ break
+ fi
+ CMD=
+done
+if [ -z "${CMD}" ]; then
+ error_exit_with_usage "unknown command: ${1}"
+fi
+shift 1
+"CMDFNC_${CMD}" $@
--- /dev/null
+#!/bin/sh
+set -e
+
+cd $(dirname "$0")
+. lib/abort_if_exists
+. lib/constants_borg # NAME_BORGAPP, PATH_BORG_CONF
+. lib/constants_secrets # PATH_REL_SECRETS, PATH_SECRETS, PATH_SECRETS_BORGKEYS, PATH_SECRETS_KDBX, PATH_USER_KDBX
+. lib/constants_ssh # PATH_USER_SSH
+. lib/constants_user # USERNAME
+. lib/copy_and_unmount_secrets
+. lib/mount_secrets
+. lib/prefixed_msg
+
+prefixed_msg_init
+
+abort_if_exists "${PATH_SECRETS}"
+prefixed_msg "Collecting new ${PATH_REL_SECRETS}."
+
+mkdir "${PATH_SECRETS}"
+cp -a "${PATH_USER_SSH}" "${PATH_SECRETS_SSH}"
+cp -a "${PATH_USER_KDBX}" "${PATH_SECRETS_KDBX}"
+"${NAME_BORGAPP}" backup_keys "${PATH_SECRETS_BORGKEYS}"
+
+prefixed_msg "secrets file, last update: $(whoami)/$(hostname) at $(date)" > "${PATH_SECRETS}/info"
+
+mount_secrets "$1" # sets PATH_MOUNTED_SECRETS
+SUFFIX_OLD=.old
+PATH_REL_SECRETS_OLD="${PATH_REL_SECRETS}${SUFFIX_OLD}"
+PATH_MOUNTED_SECRETS_OLD="${PATH_MOUNTED_SECRETS}${SUFFIX_OLD}"
+if [ -d "${PATH_MOUNTED_SECRETS}" ]; then
+ prefixed_msg "Drive already has ${PATH_REL_SECRETS}, moving to ${PATH_REL_SECRETS_OLD}."
+ rm -rf "${PATH_MOUNTED_SECRETS_OLD}"
+ mv "${PATH_MOUNTED_SECRETS}" "${PATH_MOUNTED_SECRETS_OLD}"
+fi
+copy_and_unmount_secrets 'out'
+
+prefixed_msg_exit
--- /dev/null
+#!/bin/sh
+set -e
+cd $(dirname "$0")
+. lib/abort
+. lib/audio_dev_is_mute
+. lib/print_usage
+
+MAX_LOUDNESS=150
+
+TARGET_IDX_SPEAKER=0
+TARGET_TYPE_SPEAKER=sink
+
+TARGET_IDX_MIC=1
+TARGET_TYPE_MIC=source
+
+
+
+USAGE_DESCRIPTION='Set audio device volume, or (if no LOUDNESS provided) toggle device muteness.\n\nAvailable arguments:'
+USAGE_LINES='[OPTION] [LOUDNESS]'
+USAGE_INDICES='_help _mic LOUDNESS'
+
+ARG_HELP_SHORT='-h'
+ARG_HELP_LONG='--help'
+USAGE_DESC__help='display this help and exit'
+USAGE_NAME__help="${ARG_HELP_SHORT}, ${ARG_HELP_LONG}"
+
+ARG_MIC_SHORT='-m'
+ARG_MIC_LONG='--mic'
+USAGE_DESC__mic='as device to manipulate, target microphone rather than speakers'
+USAGE_NAME__mic="${ARG_MIC_SHORT}, ${ARG_MIC_LONG}"
+
+USAGE_DESC_LOUDNESS="volume to set (as percentage, should be integer <= ${MAX_LOUDNESS}, final '%' optional)"
+
+
+
+abort_bad_args() {
+ echo "Aborting due to unrecognized argument(s): $@" >&2
+ echo ""
+ print_usage
+ exit 1
+}
+
+set_target_device() {
+ TARGET_NAME="$1"
+ TARGET_IDX="$2"
+ TARGET_TYPE="$3"
+}
+
+toggle_mute() {
+ if $(audio_dev_is_mute "${TARGET_TYPE}" "${TARGET_IDX}"); then
+ MUTE_BOOL=0
+ MUTE_WORD=off
+ else
+ MUTE_BOOL=1
+ MUTE_WORD=on
+ fi
+ pacmd "set-${TARGET_TYPE}-mute" "${TARGET_IDX}" "${MUTE_BOOL}"
+ echo "Toggled ${TARGET_NAME} muteness ${MUTE_WORD}."
+}
+
+set_volume_as_percentage() {
+ _PERCENTAGE=$(echo "$1" | tr -d '%')
+ if [ "${_PERCENTAGE}" -gt "${MAX_LOUDNESS}" ]; then
+ abort "Aborting due to demand for unreasonably high loudness: ${_PERCENTAGE}%."
+ fi
+ AT_FULL=65536
+ pacmd set-${TARGET_TYPE}-volume "${TARGET_IDX}" $(calc "(${_PERCENTAGE} * ${AT_FULL} // 100)")
+ echo -n "Volume of ${TARGET_NAME} set to ${_PERCENTAGE}%."
+ audio_dev_is_mute "${TARGET_TYPE}" "${TARGET_IDX}" && echo -n " (But device is muted.)"
+ echo
+}
+
+
+
+set_target_device 'speaker' 0 'sink'
+if [ "$(echo $1 | cut -c1)" = '-' ]; then
+ if [ "$1" = "${ARG_HELP_SHORT}" ] || [ "$1" = "${ARG_HELP_LONG}" ]; then
+ print_usage
+ exit 0
+ elif [ "$1" = "${ARG_MIC_SHORT}" ] || [ "$1" = "${ARG_MIC_LONG}" ]; then
+ set_target_device 'microphone' 1 'source'
+ else
+ error_exit "unrecognized argument: $1"
+ abort_bad_args $@
+ fi
+ shift 1
+fi
+if [ -z "$1" ]; then
+ toggle_mute
+elif [ -z "$(echo -n $1 | sed -E 's/[0-9]*[%]?//g')" ]; then
+ set_volume_as_percentage "$1"
+else
+ abort_bad_args $@
+fi
--- /dev/null
+../../../../../scripts/lib/abort
\ No newline at end of file
--- /dev/null
+../../../../../scripts/lib/abort_if_exists
\ No newline at end of file
--- /dev/null
+audio_dev_is_mute() {
+ _TYPE="$1"
+ _IDX="$2"
+ [ "$(pactl get-${_TYPE}-mute ${_IDX})" = "Mute: yes" ]
+}
--- /dev/null
+../../../../../scripts/lib/constants_borg
\ No newline at end of file
--- /dev/null
+../../../../../scripts/lib/constants_secrets
\ No newline at end of file
--- /dev/null
+../../../../../scripts/lib/constants_ssh
\ No newline at end of file
--- /dev/null
+../../../../../scripts/lib/constants_user
\ No newline at end of file
--- /dev/null
+../../../../../scripts/lib/copy_and_unmount_secrets
\ No newline at end of file
--- /dev/null
+../../../../../scripts/lib/expect_n_args
\ No newline at end of file
--- /dev/null
+../../../../../scripts/lib/get_passphrase
\ No newline at end of file
--- /dev/null
+../../../../../scripts/lib/mount_secrets
\ No newline at end of file
--- /dev/null
+../../../../../scripts/lib/path_tmp_timestamped
\ No newline at end of file
--- /dev/null
+../../../../../scripts/lib/prefixed_msg
\ No newline at end of file
--- /dev/null
+print_usage() {
+ echo 'Usage:'
+ echo "${USAGE_LINES}" | while read _LINE; do
+ echo " $(basename $0) ${_LINE}"
+ done
+ echo "\n${USAGE_DESCRIPTION}\n"
+ _var_of() { eval printf '"%s"' '"${'"${1}${2}"'}"'; }
+ _build_index() {
+ _ARGS="$(_var_of 'USAGE_ARGS_' ${_IDX})"
+ if [ ! -z "${_ARGS}" ]; then
+ _ARGS=" ${_ARGS}"
+ fi
+ _NAME="${_IDX}"
+ _ALT_NAME="$(_var_of 'USAGE_NAME_' ${_IDX})"
+ if [ ! -z "${_ALT_NAME}" ]; then
+ _NAME="${_ALT_NAME}"
+ fi
+ _KEY=" ${_NAME}${_ARGS}"
+ }
+ _MAX_LEN_KEY=0
+ for _IDX in ${USAGE_INDICES}; do
+ _build_index
+ if [ ${#_KEY} -gt "${_MAX_LEN_KEY}" ]; then
+ _MAX_LEN_KEY=${#_KEY}
+ fi
+ done
+ for _IDX in ${USAGE_INDICES}; do
+ _build_index
+ printf '%s' "${_KEY}"
+ _LEN_GAP=$(calc "${_MAX_LEN_KEY} - ${#_KEY} + 4")
+ for _ in $(seq 1 ${_LEN_GAP}); do
+ printf ' '
+ done
+ printf '%s\n' "$(_var_of 'USAGE_DESC_' ${_IDX})"
+ done
+}
--- /dev/null
+../../../../../scripts/lib/retry_until
\ No newline at end of file
--- /dev/null
+# so we don't have to enter our SSH key password all the time
+eval $(ssh-agent) > /dev/null && ssh-add -q
+
+# zero audio volume (rather than "just" mute)
+vol 0
+
--- /dev/null
+bind j scrollline 3
+bind k scrollline -3
+set hintuppercase false
+set hintchars 123456qwertasdfgyxcvb
+
+set searchengine duckduckgo
+set searchurls.wiktionary https://en.wiktionary.org/w/index.php?search=
+set searchurls.dictcc https://www.dict.cc/?s=
+
+autocmd DocStart www.reddit.com urlmodify -t www.reddit old.reddit
+
+set theme dark
+guiset gui none
+guiset tabs always
+guiset hoverlink left
+
+escapehatch
--- /dev/null
+#!/bin/sh
+# see sway-bar(5) and swaybar-protocol(7)
+set -e
+
+. "${HOME}/.plomlib/audio_dev_is_mute"
+
+SYSCLASS_DIR=/sys/class
+
+COL_WHITE=dddddd
+COL_RED=dd0000
+COL_YELLOW=dddd00
+COL_GREEN=00dd00
+COL_GREY=aaaaaa
+
+print_bar_block() {
+ printf '{"full_text": "%s", ' "$1"
+ COLOR="${COL_GREY}"
+ if [ ! -z "$2" ]; then
+ COLOR="$2"
+ fi
+ printf '"color": "%s", ' "${COLOR}"
+ if [ "$3" = "0" ]; then
+ printf '"separator": false,\n'
+ printf '"separator_block_width": 0,'
+ fi
+ printf '"markup": "pango",\n'
+ printf '},\n'
+}
+
+print_calc() {
+ printf "%d" $(calc "$1")
+}
+
+color_at() {
+ IDX=0
+ while true; do
+ IDX=$(print_calc "${IDX} + 1")
+ STEP=$(echo "$2" | cut -d'_' -f${IDX})
+ if [ -z "${STEP}" ]; then
+ break
+ fi
+ LIMIT=$(echo "${STEP}" | cut -d':' -f1)
+ COLOR=$(echo "${STEP}" | cut -d':' -f2)
+ if [ "${LIMIT}" -ge "${1}" ]; then
+ printf "${COLOR}"
+ break
+ fi
+ done
+}
+
+print_clipboard() {
+ print_selection() {
+ print_bar_block "$1 [" "${COL_WHITE}" 0
+ CLEANED=$(wl-paste $2 | sed 's/"/\\"/g')
+ ELLIPSIS=
+ if [ $(echo "${CLEANED}" | wc -c) -gt 32 ]; then
+ CLEANED=$(echo "${CLEANED}" | cut -zc'-29')
+ ELLIPSIS='...'
+ fi
+ print_bar_block "${CLEANED}" "" 0
+ print_bar_block "${ELLIPSIS}]" "${COL_WHITE}" $3
+ }
+ print_selection 'wl-paste' '' 0
+ print_selection ' --primary' --primary
+}
+
+print_online() {
+ print_conn() {
+ print_bar_block "$(echo $1 | cut -c1):" "" 0
+ IP=$(ip --brief addr show | grep "$1" | sed -E 's/ +/\t/g' | cut -f3 | cut -f1 -d'/')
+ if [ -z "${IP}" ]; then
+ print_bar_block '-'
+ else
+ print_bar_block "${IP}" "${COL_WHITE}" "$2"
+ fi
+ }
+ print_conn enp
+ print_conn wlp 0
+ set +e
+ STATUS_WIFI=$(nmcli -t -f IN-USE,SSID,SIGNAL dev wifi | grep '^\*:')
+ set -e
+ if [ ! -z "${STATUS_WIFI}" ]; then
+ SIGNAL=$(echo -n "${STATUS_WIFI}" | cut -d':' -f3)
+ COLOR=$(color_at $SIGNAL "45:${COL_RED}_85:${COL_YELLOW}_100:${COL_GREEN}")
+ print_bar_block " ${SIGNAL}" "${COLOR}" 0
+ print_bar_block "% $(echo "${STATUS_WIFI}" | cut -d':' -f2)"
+ else
+ print_bar_block " "
+ fi
+}
+
+print_battery() {
+ BAT_DIR="${SYSCLASS_DIR}/power_supply/BAT0"
+
+ calc_percent () {
+ cat_energy() {
+ cat "${BAT_DIR}/energy_$1"
+ }
+ print_calc "100 * $(cat_energy $1) // $(cat_energy $2)"
+ }
+
+ CHARGE=$(calc_percent now full)
+ COLOR=$(color_at $CHARGE "25:${COL_RED}_65:${COL_YELLOW}_100:${COL_GREEN}")
+ print_bar_block "${CHARGE}%" "${COLOR}" 0
+
+ COLOR="${COL_WHITE}"
+ STATUS=$(cat "${BAT_DIR}/status")
+ CHARGING=?
+ if [ "${STATUS}" = "Not charging" ]; then
+ CHARGING=-
+ elif [ "${STATUS}" = "Charging" ]; then
+ CHARGING=^
+ COLOR="${COL_GREEN}"
+ elif [ "${STATUS}" = "Discharging" ]; then
+ CHARGING=v
+ COLOR="${COL_YELLOW}"
+ fi
+ print_bar_block "${CHARGING}" "${COLOR}" 0
+
+ print_bar_block "$(calc_percent full full_design)%"
+}
+
+print_temperature() {
+ COLOR="${COL_WHITE}"
+ TEMPERATURE=$(cat ${SYSCLASS_DIR}/thermal/thermal_zone0/temp)
+ TEMPERATURE_IN_C=$(print_calc "${TEMPERATURE} // 1000")
+ COLOR=$(color_at $TEMPERATURE_IN_C "65:${COL_GREEN}_85:${COL_YELLOW}_999:${COL_RED}")
+ print_bar_block "${TEMPERATURE_IN_C}" "${COLOR}" 0
+ print_bar_block '°'
+}
+
+print_datetime() {
+ DATE=$(date +'%Y-%m-%d')
+ TIME=$(date +'%H:%M:%S')
+ TZ=$(date +'/%Z')
+ print_bar_block "${DATE} " "" 0
+ print_bar_block "${TIME}" "${COL_WHITE}" 0
+ print_bar_block "${TZ}" ""
+}
+
+print_volume() {
+ _print_vol() {
+ _NAME="$1"
+ _IDX="$2"
+ _TYPE="$3"
+ _BORDER="$4"
+ print_bar_block "$1 " "${COL_WHITE}" 0
+ VOLUME="$(pactl get-${_TYPE}-volume "${_IDX}" | head -1 | sed 's/ //g' | cut -d'/' -f2)"
+ if $(audio_dev_is_mute "${_TYPE}" "${_IDX}"); then
+ print_bar_block "<s>${VOLUME}</s>" '' "${_BORDER}"
+ else
+ print_bar_block "${VOLUME}" "${COL_YELLOW}" "${_BORDER}"
+ fi
+ }
+ _print_vol 'vol' 0 'sink' 0
+ _print_vol ' --mic' 1 'source'
+}
+
+print_keyboard() {
+ LAYOUT=$(swaymsg -t get_inputs | grep 'xkb_active_layout_name' | sed -E 's/[ ,"]+//g' | cut -d':' -f2 | head -1)
+ if [ "${LAYOUT}" = "English(US)" ]; then
+ LAYOUT=us
+ elif [ "${LAYOUT}" = "German" ]; then
+ LAYOUT=de
+ else
+ LAYOUT=??
+ fi
+ print_bar_block "kb_${LAYOUT}"
+}
+
+printf '{"version": 1}\n['
+while true; do
+ printf '['
+ print_clipboard
+ print_online
+ print_battery
+ print_temperature
+ print_datetime
+ print_volume
+ print_keyboard
+ printf '],'
+ sleep 0.1
+done
--- /dev/null
+#!/bin/sh
+set -e
+cd $(dirname "$0")
+. lib/abort
+# . lib/abort_if_exists
+. lib/abort_if_not_user
+. lib/abort_if_offline
+# . lib/constants_secrets # PATH_SECRETS, PATH_SECRETS_KDBX, PATH_SECRETS_SSH, PATH_SECRETS_BORGKEYS, PATH_USER_KDBX
+. lib/constants_ssh # PATH_USER_SSH
+. lib/constants_user # USERNAME
+# . lib/constants_borg # NAME_BORGAPP
+# . lib/copy_and_unmount_secrets
+. lib/expect_n_args
+# . lib/mount_secrets
+. lib/prefixed_msg
+# . lib/retry_until
+. lib/trapp
+
+prefixed_msg_init
+PATH_REPOS="${HOME}/repos"
+REPOS_SITE_DOMAIN=plomlompom.com
+REMOTE_PATH_REPOS=/var/repos
+
+expect_n_args 1 1 "(device name, e.g. 'sda')" $@
+abort_if_offline
+abort_if_not_user "${USERNAME}"
+abort_if_exists "${PATH_SECRETS}"
+abort_if_exists "${PATH_USER_SSH}"
+abort_if_exists "${PATH_REPOS}"
+
+mount_secrets "$1" # sets PASSPHRASE
+copy_and_unmount_secrets 'in'
+export BORG_PASSPHRASE="${PASSPHRASE}"
+
+prefixed_msg 'Copying passwords DB …'
+cp -a "${PATH_SECRETS_KDBX}" "${PATH_USER_KDBX}"
+
+prefixed_msg 'Setting up ~/.ssh …'
+cp -a "${PATH_SECRETS_SSH}" "${PATH_USER_SSH}"
+stty -echo
+trapp stty echo
+retry_until 1 'echo ""' 'ssh-add -q' 'prefixed_msg "Aborting due to ssh-add error"'
+stty echo
+trapp
+
+printf '\n'
+prefixed_msg 'Setting up ~/repos …'
+REPOS_SITE_LOGIN="${USERNAME}@${REPOS_SITE_DOMAIN}"
+mkdir "${PATH_REPOS}"
+cd "${PATH_REPOS}"
+ssh ${REPOS_SITE_LOGIN} "cd ${REMOTE_PATH_REPOS} && ls -1" | while read REPO_NAME; do
+ prefixed_msg "Cloning ${REPO_NAME} …"
+ git clone --quiet --recurse "${REPOS_SITE_LOGIN}:${REMOTE_PATH_REPOS}/${REPO_NAME}"
+done
+cd - > /dev/null
+
+prefixed_msg 'Setting up borg and pull in ~/org …'
+cd "${PATH_SECRETS_BORGKEYS}"
+ls -1 | while read _FILENAME; do
+ "${NAME_BORGAPP}" claim "${_FILENAME}"
+done
+cd -
+retry_until 2 '' "${NAME_BORGAPP} orgpull" "prefixed_msg 'Aborting due to unexpected ${NAME_BORGAPP} error.'" '' 'direct'
+prefixed_msg "${_OUTPUT}"
+
+prefixed_msg_exit
--- /dev/null
+INSTALLER_VERSION=13.0.0
--- /dev/null
+. lib/abort
+
+abort_if_exists() {
+ if [ -e "$1" ]; then
+ abort "Aborting since $1 already exists."
+ fi
+}
--- /dev/null
+. lib/abort
+
+abort_if_offline() {
+ if ! ping -c1 -W2 1.1.1.1 > /dev/null 2>&1; then
+ abort 'Must be run online.'
+ fi
+}
--- /dev/null
+NAME_BORGAPP=borgplom
+PATH_BORG_CONF="${HOME}/.config/borg"
--- /dev/null
+FILENAME_PRESEED_CFG=preseed.cfg
+PATH_PRESEED_CFG=$(realpath "../${FILENAME_PRESEED_CFG}")
--- /dev/null
+. lib/constants_user
+PATH_MEDIA=/media
+PATH_REL_SECRETS=.secrets
+PATH_SECRETS="${PATH_USER_HOME}/${PATH_REL_SECRETS}"
+PATH_SECRETS_SSH="${PATH_SECRETS}/ssh"
+PATH_SECRETS_BORGKEYS="${PATH_SECRETS}/borgkeys"
+FILENAME_KDBX=Passwords.kdbx
+PATH_SECRETS_KDBX="${PATH_SECRETS}/${FILENAME_KDBX}"
+PATH_USER_KDBX="${PATH_USER_HOME}/${FILENAME_KDBX}"
--- /dev/null
+. lib/constants_secrets # PATH_REL_SECRETS, PATH_SECRETS
+
+copy_and_unmount_secrets() {
+prefixed_msg_init copy_and_unmount_secrets
+
+prefixed_msg "Copying over ${PATH_REL_SECRETS}."
+if [ "$1" = "out" ]; then
+ cp -a "${PATH_SECRETS}" "${PATH_MOUNTED_SECRETS}"
+elif [ "$1" = "in" ]; then
+ cp -a "${PATH_MOUNTED_SECRETS}" "${PATH_SECRETS}"
+else
+ abort "Illegal argument to unmount_secrets."
+fi
+pumount "${SECRETS_DEV}"
+prefixed_msg "You can remove device ${SECRETS_DEV} now."
+
+prefixed_msg_exit
+}
--- /dev/null
+. lib/abort
+
+get_mountable_device_path() {
+ _PATH_DEV="/dev/$1"
+ if [ ! -b "${_PATH_DEV}" ]; then
+ abort "No block device at ${_PATH_DEV}."
+ elif [ $(mount | grep -E "^${_PATH_DEV}" | wc -l) -gt 0 ]; then
+ abort "${_PATH_DEV} already mounted."
+ fi
+ printf "${_PATH_DEV}"
+}
--- /dev/null
+get_passphrase() {
+ stty -echo
+ read PASSPHRASE
+ stty echo
+ printf "${PASSPHRASE}"
+}
--- /dev/null
+. lib/constants_secrets # PATH_MEDIA, PATH_REL_SECRETS
+. lib/expect_n_args
+. lib/get_passphrase
+. lib/path_tmp_timestamped
+. lib/prefixed_msg
+. lib/retry_until
+
+mount_secrets() {
+prefixed_msg_init mount_secrets
+
+SECRETS_DEV=$1
+if [ -z "${SECRETS_DEV}" ]; then
+ abort "Aborting due to empty device argument."
+fi
+PATH_MOUNTED_SECRETS="${PATH_MEDIA}/${SECRETS_DEV}/${PATH_REL_SECRETS}"
+PATH_DEV="/dev/${SECRETS_DEV}"
+PATH_PMOUNT_ERR="$(path_tmp_timestamped 'err_mount')"
+prefixed_msg "Put secrets drive into slot for ${PATH_DEV}."
+while [ ! -e "${PATH_DEV}" ]; do
+ sleep 0.1
+done
+_ON_LOOP_START='prefixed_msg_no_nl "Passphrase: "; PASSPHRASE=$(get_passphrase); echo ""'
+_TO_TEST='echo "${PASSPHRASE}" | pmount "${PATH_DEV}" 2>&1'
+_ON_FAIL='prefixed_msg "Aborting due to pmount error:"'
+retry_until 100 "${_ON_LOOP_START}" "${_TO_TEST}" "${_ON_FAIL}"
+prefixed_msg "${_OUTPUT}"
+
+prefixed_msg_exit
+}
--- /dev/null
+path_tmp_timestamped () {
+ printf "/tmp/${1}_$(date +'%s')"
+}
--- /dev/null
+retry_until() {
+ _CODE_FOR_CONTINUE="$1"
+ _ON_LOOP_START="$2"
+ _TO_TEST="$3"
+ _ON_FAIL="$4"
+ _ON_LOOP_END="$5"
+ _OUTPUT_MODE="$6"
+ while true; do
+ eval "${_ON_LOOP_START}"
+ set +e
+ if [ "${_OUTPUT_MODE}" = 'direct' ]; then
+ eval ${_TO_TEST}
+ _RESULT=$?
+ else
+ _OUTPUT="$(eval ${_TO_TEST})"
+ _RESULT=$?
+ fi
+ set -e
+ if [ "${_RESULT}" = '0' ]; then
+ break
+ elif [ "${_RESULT}" != "${_CODE_FOR_CONTINUE}" ]; then
+ eval "${_ON_FAIL}"
+ abort
+ fi
+ eval "${_ON_LOOP_END}"
+ done
+}
--- /dev/null
+#!/bin/sh
+# based on <https://wiki.debian.org/DebianInstaller/WritableUSBStick>
+set -e
+cd $(dirname "$0")
+. lib/INSTALLER_VERSION
+. lib/abort
+. lib/abort_if_command_unknown
+. lib/abort_if_not_user
+. lib/abort_if_offline
+. lib/constants_installer # FILENAME_PRESEED_CFG, PATH_PRESEED_CFG
+. lib/expect_n_args
+. lib/get_mountable_device_path
+. lib/path_tmp_timestamped
+. lib/trapp
+
+expect_n_args 1 2 'DEVICE (e.g. "sdb") [PATH_FILE_ISO]' $@
+abort_if_not_user root
+abort_if_command_unknown mkfs.vfat
+abort_if_command_unknown parted
+abort_if_command_unknown rsync
+abort_if_command_unknown wget
+FILENAME_ISO="debian-${INSTALLER_VERSION}-amd64-netinst.iso"
+if [ -z "$2" ]; then
+ abort_if_offline
+else
+ PATH_FILE_ISO=$(realpath "$2")
+ if [ ! "${FILENAME_ISO}" = $(basename "${PATH_FILE_ISO}") ]; then
+ abort "basename of PATH_FILE_ISO != expected ${FILENAME_ISO}"
+ elif [ ! -f "${PATH_FILE_ISO}" ]; then
+ abort 'no file found at PATH_FILE_ISO'
+ fi
+fi
+PATH_DEV="$(get_mountable_device_path $1)"
+PATH_MNT_ISO=/mnt/iso
+
+PATH_PROCESSING="$(path_tmp_timestamped make_writable_installer)"
+RM_PROCESSING="rm -rf ${PATH_PROCESSING}"
+echo "Setting up processing directory at ${PATH_PROCESSING} …"
+mkdir "${PATH_PROCESSING}"
+trapp "${RM_PROCESSING}"
+cd "${PATH_PROCESSING}"
+
+if [ -z "${PATH_FILE_ISO}" ]; then
+ echo "Retrieving ${FILENAME_ISO} …"
+ URL_ISO="https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/${FILENAME_ISO}"
+ wget --quiet --output-document "${FILENAME_ISO}" "${URL_ISO}"
+else
+ echo "Linking to ${PATH_FILE_ISO} …"
+ ln -s "${PATH_FILE_ISO}"
+fi
+
+echo "Preparing partition/filesystem on ${PATH_DEV} …"
+parted --script "${PATH_DEV}" mklabel msdos
+parted --script "${PATH_DEV}" mkpart primary fat32 0% 100%
+PATH_PARTITION="${PATH_DEV}1"
+mkfs.vfat "${PATH_PARTITION}" > /dev/null
+
+PATH_MNT_DEV='/mnt/'$(basename "${PATH_PARTITION}")
+echo -n "Mounting ${PATH_MNT_ISO} and ${PATH_MNT_DEV} …"
+mkdir -p "${PATH_MNT_ISO}" "${PATH_MNT_DEV}"
+do_umount() {
+ echo "Unmounting $1 …"
+ set +e
+ umount "$1"
+ set -e
+}
+mount "${PATH_PARTITION}" "${PATH_MNT_DEV}"
+trapp "${RM_PROCESSING}; do_umount ${PATH_MNT_DEV}"
+mount -o loop "${FILENAME_ISO}" "${PATH_MNT_ISO}" 2>&1 | sed 's|mount: /mnt/iso: WARNING: source write-protected, mounted read-only.||'
+trapp "${RM_PROCESSING}; do_umount ${PATH_MNT_DEV}; do_umount ${PATH_MNT_ISO}"
+
+echo "Copying contents of ${PATH_MNT_ISO} to ${PATH_MNT_DEV}/ …"
+FILENAME_RSYNC_ERRORS="rsync_errors"
+set +e
+rsync -a "${PATH_MNT_ISO}/" "${PATH_MNT_DEV}/" 2> "${FILENAME_RSYNC_ERRORS}"
+RESULT=$?
+set -e
+if [ "${RESULT}" != "0" ]; then
+ echo 'RSYNC ERRORS:'
+ cat "${FILENAME_RSYNC_ERRORS}"
+ echo '\nrsync encountered errors, see above – continue? (Y/N)'
+ read ANSWER
+ FIRST_CHAR=$(echo "${ANSWER}" | cut -c1)
+ if ! [ "${FIRST_CHAR}" = 'y' -o "${FIRST_CHAR}" = 'Y' ]; then
+ abort 'as requested'
+ fi
+fi
+
+echo "Installing preseed file …"
+cp "${PATH_PRESEED_CFG}" "${PATH_MNT_DEV}/"
+sed --in-place 's/ --- / --- preseed\/file=\/cdrom\/'"${FILENAME_PRESEED_CFG}"' /g' "${PATH_MNT_DEV}/boot/grub/grub.cfg"
+
+echo "Done!"
--- /dev/null
+#!/bin/sh
+set -e
+cd $(dirname "$0")
+. lib/abort
+. lib/abort_if_offline
+. lib/apt_get_digested
+. lib/constants_etc # PATH_ETC
+. lib/constants_user # USERNAME
+. lib/copy_dirtrees_of_tags
+. lib/core_setup
+. lib/expect_n_args
+. lib/prefixed_msg
+. lib/put_finished_marker
+
+prefixed_msg_init
+prefixed_msg 'starting …'
+
+PATH_NETWORK_INTERFACES="${PATH_ETC}/network/interfaces"
+THINKPAD_NAMES="x220 w530 t490s"
+
+abort_if_offline
+
+get_system_class_for() {
+ for THINKPAD_NAME in $THINKPAD_NAMES; do
+ if [ "$1" = "${THINKPAD_NAME}" ]; then
+ printf 'thinkpad'
+ break
+ fi
+ done
+ printf ''
+}
+abort_if_illegal_system_name() {
+ LEGAL_SYSTEM_NAMES="${THINKPAD_NAMES} h610m"
+ for SYSTEM_NAME_I in $LEGAL_SYSTEM_NAMES; do
+ if [ "$1" = "$SYSTEM_NAME_I" ]; then
+ return 0
+ fi
+ done
+ abort 'Need legal system name.'
+}
+expect_n_args 2 2 "SYSTEM_NAME, USER_PW" $@
+SYSTEM_NAME="$1"
+USER_PW="$2"
+abort_if_illegal_system_name "${SYSTEM_NAME}"
+SYSTEM_CLASS_NAME="$(get_system_class_for ${SYSTEM_NAME})"
+INSTALL_TAGS="all ${SYSTEM_CLASS_NAME} ${SYSTEM_NAME} user desktop"
+
+adopt_wifi_connection() {
+ get_network_interfaces_last_wpa_value() {
+ REGEX="^\s+wpa-${1}\s+"
+ cat "${PATH_NETWORK_INTERFACES}" | grep -E "${REGEX}" | sed -E "s/${REGEX}//g" | tail -1
+ }
+ WLAN_SSID=$(get_network_interfaces_last_wpa_value 'ssid')
+ WLAN_PSK=$(get_network_interfaces_last_wpa_value 'psk')
+ if [ ! -z "${WLAN_SSID}" ]; then
+ prefixed_msg_no_nl "Found, adding to NetworkManager: "
+ if [ -z "${WLAN_PSK}" ]; then
+ nmcli connection add type wifi wifi.ssid "${WLAN_SSID}"
+ else # NB: assumes last (collected with tail -1) wpa-psk that of last wlan-ssid
+ nmcli connection add type wifi wifi.ssid "${WLAN_SSID}" wifi-sec.key-mgmt wpa-psk wifi-sec.psk "${WLAN_PSK}"
+ fi
+ fi
+}
+
+../../trixie/scripts/from_older_upgrade.sh desktop
+./from_older_upgrade.sh desktop
+
+# NB: This needs to come before steps potentially overwriting /etc/network/interfaces.
+apt_get_digested '-q -q install network-manager'
+if [ "$(nmcli -f TYPE conn | grep 'wifi' | wc -l)" = "0" ]; then
+ prefixed_msg "Checking for existing wifi config in ${PATH_NETWORK_INTERFACES} …"
+ adopt_wifi_connection
+else
+ prefixed_msg 'Already know wifi connection, nothing to add …'
+fi
+
+core_setup "${SYSTEM_NAME}" "" "" "${INSTALL_TAGS}"
+
+prefixed_msg 'Ensuring our desired locale is available …'
+locale-gen
+
+prefixed_msg 'Final user setup …'
+adduser --quiet "${USERNAME}" plugdev # so user may use pmount
+echo "${USERNAME}:${USER_PW}" | chpasswd
+
+put_finished_marker 'setup_desktop'
+prefixed_msg_exit
--- /dev/null
+#!/bin/sh
+set -e
+cd $(dirname "$0")
+. lib/abort_if_not_user
+. lib/check_finished_marker
+. lib/constants_repopaths # PATH_CONF, PATH_SCRIPTS
+. lib/constants_user # USERNAME
+. lib/path_tmp_timestamped
+. lib/prefixed_msg
+
+prefixed_msg_init
+
+check_finished_marker 'setup_desktop'
+abort_if_not_user root
+PATH_REL_SETUP_SECRETS_USER="$(basename ${PATH_CONF})/$(basename ${PATH_SCRIPTS})/_setup_secrets_user.sh"
+PATH_REPO="$(dirname ${PATH_CONF})"
+PATH_TMP_REPO="$(path_tmp_timestamped configrepo)"
+
+prefixed_msg "Setting up config repo copy for user at ${PATH_TMP_REPO} …"
+cp -a "${PATH_REPO}" "${PATH_TMP_REPO}"
+chown -R "${USERNAME}:${USERNAME}" "${PATH_TMP_REPO}"
+su -l "${USERNAME}" -c "/bin/sh ${PATH_TMP_REPO}/${PATH_REL_SETUP_SECRETS_USER} $1"
+rm -rf "${PATH_TMP_REPO}"
+
+prefixed_msg_exit