# echo
e() { printf "%s\n" "$*"; }
+err() { echo "$(date +%Y-%m-%d) ${FUNCNAME[0]}: $*" >&2; }
# echo args
ea() {
systemctl -n 40 status "$@"
}
-# quickly journalctl -f FINAL_ARG, then systemctl $@
+# journalctl -f FINAL_ARG, then systemctl $@ .
+# detects any existing background job so we can
+# run multiple times without making duplicate output.
serj() {
- local service jr_pid ret
+ local service jr_pid ret jobs_out regex
ret=0
service="${*: -1}"
+ jobs_out=$(jobs 2>/dev/null)
+ regex="^[^[:space]]+[[:space:]]+Running[[:space:]]+ journalctl -qn2 -f -u $service &"
+
journalctl -qn2 -f -u "$service" &
sleep 3
s systemctl "$@" || ret=$?
- sleep .5
- kill %%
- (( ret == 0 )) || return $ret
+ if (( ret != 0 )); then
+ echo "serj: note: systemctl returned nonzero, but journalctl worked and is running."
+ return $ret
+ fi
}
fi
}
+# where slow is hardcoded to 4 seconds. change if desired.
+slowdo() {
+ local lines ret start_sec=$EPOCHSECONDS loop=true
+ "$@" |& while true; do
+ ret=0
+ read -r -t1 line || ret=$?
+ if (( ret == 0 )); then
+ lines+="$line"$'\n'
+ elif (( ret != 142 )); then
+ break
+ fi
+ if (( EPOCHSECONDS > start_sec + 4 )); then
+ printf "%s" "$lines"
+ cat
+ break
+ fi
+ done
+}
+
#### sl: ssh wrapper, but maybe first rsync files that we configure and
# always source our .bashrc on the remote.
args=($SL_SSH_ARGS)
+ # when we last checked, these were the valid ssh args:
+
# ssh [-1246Antivivisectionist] [-b bind_address] [-c cipher_spec] [-D [bind_address:]port]
# [-E log_file] [-e escape_char] [-F configfile] [-I pkcs11] [-i identity_file] [-L address]
# [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port] [-Q query_option]
# [-O ctl_cmd] [-o option] [-p port] [-Q query_option] [-R address]
# [-S ctl_path] [-W host:port] [-w local_tun[:remote_tun]]
+ verbose_arg=false
force_rsync=false
if [[ $1 == --rsync ]]; then
force_rsync=true
case "$1" in
# note we dont support things like -4oOption
-[46AaCfGgKkMNnqsTtVvXxYy]*)
+ if [[ $1 == *v* ]]; then
+ # todo: try running slowdo if this is false
+ verbose_arg=true
+ fi
args+=("$1"); shift
;;
-[bcDEeFIiJLlmOopQRSWw]*)
tmp2=${tmp:11} # skip 11 chars
host_type=${tmp2%%-*}
extra_info=$(cat $sshinfo)
+ # debug
+ #echo d1 $host_type
else
# we test for string to know ssh succeeded
testbool="test -e $SL_FILES_DIR/.bashrc -a -L .bashrc -a -v LC_USEBASHRC"
info_sec=${tmp::10}
read -r files_sec _ < <(find -L $SL_FILES_DIR -printf "%T@ %p\n" | sort -nr || [[ $? == 141 || ${PIPESTATUS[0]} == 32 ]] )
files_sec=${files_sec%%.*}
+ # info_sec is the last time we synced to that host. files_sec is the
+ # greatest mod time out of files we want to sync.
+
if (( files_sec > info_sec )); then
+ #echo "d4 $files_sec > $info_sec"
do_rsync=true
rm -f $sshinfo
fi
echo 'error: missing SL_FILES_DIR env var' >&2
return 1
fi
-
if $do_rsync; then
+ # todo: it would be nice if we did this with -v, but
+ # only showed the output if the command lasted more than
+ # about 4 seconds.
RSYNC_RSH="ssh ${args[*]}" m rsync -rptL --delete $sl_rsync_args $SL_FILES_DIR "$remote":
fi
if $do_rsync || ! $haveinfo; then
sshinfo=$SL_INFO_DIR/$EPOCHSECONDS-$host_type-"$remote"
[[ -e $SL_INFO_DIR ]] || mkdir -p $SL_INFO_DIR
+ # debug
+ #echo d3: $sshinfo
printf "%s\n" "$extra_info" >$sshinfo
chmod 666 $sshinfo
fi
fi
}
+# toggle set -u
+tsu() {
+ if [[ $- == *u* ]]; then
+ set +u
+ else
+ set -u
+ fi
+}
+
# show all processes in the network namespace $1.
# blank entries appear to be subprocesses/threads
psnetns() {
unset IFS
if [[ $HISTFILE ]]; then
- history -a # save history
+ # save history. if our filesystem went read-only or something, continue on
+ history -a ||:
+
# if we aren't in ssh, maybe indicate history file
if [[ ! $SSH_CLIENT ]]; then
fi
}
+
+# $1 = snapshot
+btrfs-snapshot-rw() {
+ # -ts = type snapshot
+ # -f = force, required to overcome this error:
+ #
+ # ERROR: cannot flip ro->rw with received_uuid set, use force option
+ # -f if you really want unset the read-only status. The value of
+ # received_uuid is used for incremental send, consider making a
+ # snapshot instead. Read more at btrfs-subvolume(8) and Subvolume
+ # flags.
+ #
+ btrfs property set -f -ts "$1" ro false
+}
+
+# $1 = snapshot
+btrfs-snapshot-ro() {
+ btrfs property set -f -ts "$1" ro true
+}
+
+
brc3() {
source /a/c/brc3
}
}
-# service run, and watch the output
-srun() {
- local unit
- ret=0
- unit=$1
- journalctl -qn2 -f -u $unit &
- sleep 2
- systemctl start $unit
-}
-
sm() { # switch mail host
local tmp keyhash
c /
ilog-local() {
local d chan
chan="$1"
+ if [[ ! $chan ]]; then
+ err "requires 1 argument, got 0. check ssh interpolation"
+ return 1
+ fi
d=/var/lib/znc/moddata/log/iank/
for n in freenode libera; do
if [[ ! -d $d$n/"$chan" ]]; then
# my profanity
#
myprof() {
+
pushd /home/iank/.local/share/profanity/chatlogs/iank_at_fsf.org/rooms/office_at_conference.fsf.org
logs=(*)
+ cd /home/iank/.local/share/profanity/chatlogs/iank_at_fsf.org/rooms/sys-private_at_conference.fsf.org
+ logs=+(*)
+ logs=( $( printf "%s\n" ${logs[*]} | sort -u ) )
+ cd /home/iank/.local/share/profanity/chatlogs/iank_at_fsf.org/rooms
logcount=${#logs[@]}
- if (( logcount > 16 )); then
- i=$(( logcount - 16 ))
+ if (( logcount > 32 )); then
+ i=$(( logcount - 32 ))
else
i=0
fi
if [[ $(date +%A) == Monday ]]; then
min_date=$(date -d 'monday 2 weeks ago' +%s)
else
- min_date=$(date -d 'monday 3 weeks ago' +%s)
+ min_date=$(date -d 'monday 5 weeks ago' +%s)
fi
for (( ; i < logcount; i++ )); do
- log=${logs[$i]}
- d=$(date -d "$(head -n1 $log|awk '{print $1}')" +%s)
+ log_base=${logs[$i]}
+ day_logs=()
+ if [[ -e office_at_conference.fsf.org/$log_base ]]; then
+ day_logs+=(office_at_conference.fsf.org/$log_base)
+ fi
+ if [[ -e sys_at_conference.fsf.org/$log_base ]]; then
+ day_logs+=(office_at_conference.fsf.org/$log_base)
+ fi
+ d=$(date -d "$(head -n1 ${day_logs[0]} |awk '{print $1}')" +%s)
if (( d < min_date )); then
continue
fi
- if awk '$3 == "iank:"' $log | sed -r 's/^(.{10}).(.{8})[^ ]+(.*)/\1_\2\3/' | grep .; then
+ if awk '$3 == "iank:"' ${day_logs[@]} | sed -r 's/^(.{10}).(.{8})[^ ]+(.*)/\1_\2\3/' | grep . | sort; then
hr
fi
done
"$@" |& pee "xclip -r -selection clipboard" cat
}
-# xorg copy. copy text piped into command
+# xorg copy. copy text piped into command, or copy file(s) if given
xc() {
- xclip -r -selection clipboard
+ xclip -r -selection clipboard "$@"
}
# echo copy
ec() {
case $HOSTNAME in
sy|so|kd)
hosts=(
- kd.b8.nz x3.office.fsf.org syw x2.b8.nz
+ kd.b8.nz x3.office.fsf.org sy so x2.b8.nz
)
;;
x3)
hosts=(
- b8.nz sywg.b8.nz
+ b8.nz sywg.b8.nz sowg.b8.nz
)
;;
esac
spdx -f ~/.spd/spd/spd_data_financial.gpg "$@"
}
+# note: if no prompt and no error, that means we found a single pass and
+# put it i the clipboard.
spdx() {
local out i input pw file
if [[ $1 == -f ]]; then
xdg-settings set default-web-browser firefox.desktop
}
+snap-last() {
+ ls -lad /mnt/o/btrbk/o.* | tail -n2
+ for sub in a q; do
+ ls -lad /mnt/root/btrbk/$sub.* | tail -n2
+ done
+ }
export BASEFILE_DIR=/a/bin/fai-basefiles
## command where their main reason to exist is for documentation purposes,
# and I have no desire to always load them into my shell.
-# $1 = snapshot
-btrfs-snapshot-rw() {
- # -ts = type snapshot
- # -f = force, required to overcome this error:
- #
- # ERROR: cannot flip ro->rw with received_uuid set, use force option
- # -f if you really want unset the read-only status. The value of
- # received_uuid is used for incremental send, consider making a
- # snapshot instead. Read more at btrfs-subvolume(8) and Subvolume
- # flags.
- #
- btrfs property set -f -ts "$1" ro false
-}
-# $1 = snapshot
-btrfs-snapshot-ro() {
- btrfs property set -f -ts "$1" ro true
-}
+## todo: make this get all the package lists
+# if [[ ! -e main ]]; then
+# wget http://archive.ubuntu.com/ubuntu/dists/noble/{main,universe}/binary-amd64/Packages.gz
+# gunzip Packages.gz
+# mv Packages main
+# gunzip -S .gz.1 Packages.gz.1
+# fi
+# noble="main Packages"
-mmdebstrap-ecne-noble-missing() {
- local ecne ecne_prefix noble noble_prefix
- noble_prefix=/var/lib/apt/lists/archive.ubuntu.com_ubuntu_dists_noble
- noble=$(echo ${noble_prefix}{,-security,-updates}_{main,universe}_binary-amd64_Packages)
- for f in $noble; do
- if [[ ! -s $f ]]; then
- echo error: missing noble package lists. noble: $noble
- return 1
- ## todo: make this get all the package lists
- # if [[ ! -e main ]]; then
- # wget http://archive.ubuntu.com/ubuntu/dists/noble/{main,universe}/binary-amd64/Packages.gz
- # gunzip Packages.gz
- # mv Packages main
- # gunzip -S .gz.1 Packages.gz.1
- # fi
- # noble="main Packages"
- fi
- done
- ecne_prefix=/var/lib/apt/lists/archive.trisquel.org_trisquel_dists_ecne
- ecne=$(echo ${ecne_prefix}{,-updates,-security}_main_binary-amd64_Packages)
- for f in $ecne; do
+test-ecne-noble-package-lists-exist() {
+ for f in $noble $ecne; do
if [[ ! -s $f ]]; then
- echo error: missing ecne package lists. f: $f ecne: $ecne
+ echo error: missing package list: $f
return 1
fi
done
+}
+
+mmdebstrap-ecne-noble-missing() {
+ local prefix ecne noble
+ prefix=/var/lib/apt/lists/archive.
+ noble=$(echo ${prefix}ubuntu.com_ubuntu_dists_noble{,-security,-updates}_{main,universe}_binary-amd64_Packages)
+ ecne=$(echo ${prefix}trisquel.org_trisquel_dists_ecne{,-updates,-security}_main_binary-amd64_Packages)
+ test-ecne-noble-package-lists-exist
+ u24_kernel_pkgs=virtual|oem|image|generic|firmware|aws|azure|buildinfo|cloud|gcp|gke|headers|ibm|lowlatency|modules|nvidia|riscv|tools|intel|oracle|lib-rust
for dist in ecne noble; do
- # thunderbird is just a way to get rid of its langpacks, since its main package depends on snap
- { grep-dctrl -F package -v -r 'ubuntu\|zfs\|thunderbird\|snapd\|microcode\|^linux-' ${!dist} | grep-dctrl -s package -n -F depends,pre-depends -v snapd - ; if [[ $dist == noble ]]; then echo ubuntu-keyring; fi; } | sort -u >$dist
- # for just debootstrapped packages:
- #grep-dctrl -s package -n -F essential -r '^yes$' --or -F priority -r '^required\|important$' ${!dist} | sort >$dist
+ {
+ grep-dctrl -F package -v -e "ubuntu|zfs|thunderbird|snapd|microcode|^linux-($u24_kernel_pkgs)" ${!dist} | \
+ grep-dctrl -s package -n -F depends,pre-depends -v snapd -
+ if [[ $dist == noble ]]; then
+ echo ubuntu-keyring
+ fi
+ } | sort -u >$dist
done
- comm -13 ecne noble | tr '\n' ' ' | tee prefs-pkgs
cat >prefs <<EOF
Package: *
Pin: release n=noble,o=Ubuntu
Pin-Priority: -100
-Package: $(cat prefs-pkgs)
+Package: $(comm -13 ecne noble | tr '\n' ' ' | sed 's/ \+$//')
Pin: release n=noble,o=Ubuntu
Pin-Priority: 500
EOF
if [[ -s $statefile ]]; then
logsec=$(date +%s -d "$(head -n1 $statefile | awk '{print $1,$2}')")
case $h in
- frodo)
- hours=200
- ;;
*)
hours=20
;;
done
}
+#### end function definitions, begin main script ####
+
+
user=$(id -un)
all_dirs=({/a/bin/ds,/p/c}{,/machine_specific/$HOSTNAME})
# note, we assume a group of hosts does not have the
###### install X
- pi i3
+ pi i3 python3-i3ipc
##### install xinput
case $(distro-name) in
#
# if you get a notice about a firmware update, the notifier on i3
# is too dumb to do anything when you click it.
+ #
+ # To see current version: cat /sys/class/dmi/id/bios_version
+ # ref: https://support.system76.com/articles/transition-firmware/
+ #
# to manually get new firmware,
# system76-firmware-cli schedule --open
# to see a changelog, cd to
# ser list-timers
+### begin ansible
+
+## commented because fsf relies on using an old ansible for now.
+# if [[ ! -e /etc/apt/sources.list.d/ansible-ubuntu-ansible-$codename_compat.sources ]]; then
+# s add-apt-repository --yes --update ppa:ansible/ansible
+# pi ansible
+# fi
+
+### end ansible
+
### begin prometheus ###
case $HOSTNAME in
## iank: substituted := for =, based on
## Jun 09 12:27:48 so systemd-udevd[1385]: /etc/udev/rules.d/99-kaleidoscope.rules:18 ENV key ta
-kes '==', '!=', '=', or '+=' operator, assuming '='.
+## kes '==', '!=', '=', or '+=' operator, assuming '='.
SUBSYSTEMS=="usb", ATTRS{idVendor}=="1209", ATTRS{idProduct}=="2300", SYMLINK+="model01", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_CANDIDATE}="0", TAG+="uaccess", TAG+="seat"
SUBSYSTEMS=="usb", ATTRS{idVendor}=="1209", ATTRS{idProduct}=="2301", SYMLINK+="model01", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_CANDIDATE}="0", TAG+="uaccess", TAG+="seat"
mount-latest-subvol
check-subvol-stale
btrbk-run
+ umount-funcs
)
for f in ${install_bin_files[@]}; do
if ! diff -q /a/bin/ds/filesystem/usr/local/bin/$f /usr/local/bin/$f; then
e due to dry run, skipping check for newer files on source host
else
tmpf=$(mktemp)
- m rsync -ra $source:/usr/local/bin/{mount-latest-subvol,check-subvol-stale} /usr/local/bin
+ m rsync -ra $source:/usr/local/bin/{mount-latest-subvol,check-subvol-stale,umount-funcs} /usr/local/bin
m rsync -ra $source:/usr/local/lib/bash-bear /usr/local/lib
m rsync $source:/usr/local/bin/btrbk-run $tmpf
if ! diff -q $tmpf ${BASH_SOURCE[0]}; then
b=firefox
fi
-tag=abrowser
+mark=abrowser
if (( $# >= 1 )); then
- tag=$tag"${@:$#}"
+ mark=$mark"${*:$#}"
fi
+# debug
+echo "iankd1 mark: $mark" >/tmp/x
+
# spawn and mark if we dont have a mark already
-if ! i3-focus-maybe $tag; then
+if ! i3-focus-maybe $mark; then
+ # note workspace 2 is duplicated in i3-abrowser-py
i3-msg "workspace 2"
i3-split-maybe
# avoid our wrapper in /usr/local/bin
/usr/bin/$b "$@" &
- # on a fast computer, .5 is too fast, 1 is ok. on x200, 2 is ok if the computer isn't busy.
+ # on a fast computer, .5 is too fast, 1 is ok. on x200, 2 is ok if the computer isn't busy.
for (( i=0; i < 15; i++ )); do
sleep 1
- if i3-msg "[workspace=__focused__ class=\"$b\" instance=\"Navigator\" window_role=\"browser\"] mark $tag"; then
+ if i3-abrowser-py $b "mark $mark"; then
break
fi
done
--- /dev/null
+#!/usr/bin/python3
+# I, Ian Kelling, follow the GNU license recommendations at
+# https://www.gnu.org/licenses/license-recommendations.en.html. They
+# recommend that small programs, < 300 lines, be licensed under the
+# Apache License 2.0. This file contains or is part of one or more small
+# programs. If a small program grows beyond 300 lines, I plan to change
+# to a recommended GPL license.
+
+# Copyright 2024 Ian Kelling
+
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+
+# http://www.apache.org/licenses/LICENSE-2.0
+
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+from pprint import pprint
+import sys
+from i3ipc import Connection, Event
+
+def main():
+ i3 = Connection()
+ tree = i3.get_tree()
+ focused = tree.find_focused()
+ abrowsers = tree.find_classed(sys.argv[1])
+ find_failed = True
+ for abrowser in abrowsers:
+ #pprint(vars(abrowser))
+
+ # 2 is duplicated in i3-abrowser
+ if abrowser.workspace() == 2 and len(abrowser.marks) == 0:
+ find_failed = False
+ abrowser.command(sys.argv[2])
+ break
+
+ if find_failed:
+ exit(1)
+
+if __name__ == "__main__":
+ main()
return
# debug
- print('d2: len(parent.nodes):', len(parent.nodes),' > 1',
- 'and ( ph:',ph,' > h + 10:',h + 10,' or pw:',pw,' > w:',w,' )',
- 'and (screen_w:',screen_w,' < screen_h:',screen_h,' or w <= half_w:',half_w,')',
- 'and h <= half_h:',half_h,')')
+ # print('iankd2: len(parent.nodes):', len(parent.nodes),' > 1',
+ # 'and ( ph:',ph,' > h + 10:',h + 10,' or pw:',pw,' > w:',w,' )',
+ # 'and (screen_w:',screen_w,' < screen_h:',screen_h,' or w <= half_w:',half_w,')',
+ # 'and h <= half_h:',half_h,')')
# h + 10 because a tabbed window loses high compared to its parent.
# Note, it is redundant since we check above if the parent is tabbed,
esac
-# TODO: executed from cron, this doesnt sent an email when we reboot,
-# because rebooting from the script stops the ability to send email.
-# We should figure some workaround.
-
-# I originally had the idea that for MAIL_HOST, I'd just send an email
-# if something needs restarting. But atm, I have a bad habit of ignoring
-# those emails.
-
-if ! needrestart -p -k &>/dev/null; then
- myreboot
-fi
-
needrestart -b -l -r a |& logger -t myupgrade
sleep 1
rsynctg="[$tg]"
fi
# R = relative, t = times, O = omit-dir-times, p = perms
-er rsync -RtOp bin/{mount-latest-subvol,check-subvol-stale} lib/bash-bear "root@$rsynctg:/usr/local" ||:
+er rsync -RtOp bin/{mount-latest-subvol,check-subvol-stale,umount-funcs} lib/bash-bear "root@$rsynctg:/usr/local" ||:
# note: this can hang if we have an old nfs mount.
er ssh root@$tg timeout -s 9 600 /usr/local/bin/mount-latest-subvol "$@"
cat >/etc/systemd/resolved.conf.d/untrusted-network.conf <<EOF
[Resolve]
DNS=${servers[@]}
-Domains=~. b8.nz
+Domains=~. b8.nz fsf.org
DNSOverTLS=yes
EOF
# At least on systemd 237 ifupdown it sets a global and this is not
# needed. we are way past that, but I dont think it hurts.
- resolvectl revert $gateway_if
+ m resolvectl revert $gateway_if
else
e $0: no gateway_if found
fi