From c7aefbf115bd85a767467068917d8cbfabf4bd19 Mon Sep 17 00:00:00 2001 From: Ian Kelling Date: Fri, 20 Sep 2024 01:40:37 -0400 Subject: [PATCH] various minor fixes and improvements --- brc | 89 +++++++++++++++++-- brc2 | 54 ++++++----- brc3 | 73 ++++++--------- check-remote-mailqs | 3 - conflink | 3 + distro-begin | 2 +- distro-end | 14 +++ .../etc/udev/rules.d/99-kaleidoscope.rules | 2 +- filesystem/usr/local/bin/btrbk-run | 3 +- filesystem/usr/local/bin/i3-abrowser | 14 +-- filesystem/usr/local/bin/i3-abrowser-py | 47 ++++++++++ filesystem/usr/local/bin/i3-split-maybe | 8 +- filesystem/usr/local/bin/myupgrade | 12 --- mount-latest-remote | 2 +- trusted-network | 4 +- 15 files changed, 228 insertions(+), 102 deletions(-) create mode 100755 filesystem/usr/local/bin/i3-abrowser-py diff --git a/brc b/brc index c91d06b..3aad896 100644 --- a/brc +++ b/brc @@ -1338,6 +1338,7 @@ ccomp du dus # echo e() { printf "%s\n" "$*"; } +err() { echo "$(date +%Y-%m-%d) ${FUNCNAME[0]}: $*" >&2; } # echo args ea() { @@ -2794,17 +2795,23 @@ serstat() { 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 } @@ -2922,6 +2929,25 @@ skgit() { 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. @@ -3005,6 +3031,8 @@ sl() { 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] @@ -3018,6 +3046,7 @@ sl() { # [-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 @@ -3057,6 +3086,10 @@ sl() { 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]*) @@ -3100,6 +3133,8 @@ sl() { 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" @@ -3125,7 +3160,11 @@ sl() { 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 @@ -3137,13 +3176,17 @@ sl() { 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 @@ -3356,6 +3399,15 @@ tx() { 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() { @@ -3736,7 +3788,9 @@ if [[ $- == *i* ]]; then 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 @@ -4007,6 +4061,27 @@ btrfs() { 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 } diff --git a/brc2 b/brc2 index fa226c9..32f0065 100644 --- a/brc2 +++ b/brc2 @@ -1660,16 +1660,6 @@ order by timeSent;" } -# 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 / @@ -2480,6 +2470,10 @@ ilogs() { 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 @@ -3340,11 +3334,16 @@ s/^[^ ]*\.txt:\((.{2}).(.{2}).(.{4}) (.{8}) (.{2})\)?/\3-\1-\2_\4_\5/' \ # 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 @@ -3352,15 +3351,22 @@ myprof() { 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 @@ -3553,9 +3559,9 @@ j() { "$@" |& 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() { @@ -4736,12 +4742,12 @@ hssh-update() { 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 @@ -4992,6 +4998,8 @@ spdfx() { 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 @@ -5029,6 +5037,12 @@ ffdefault() { 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 diff --git a/brc3 b/brc3 index de4a8fe..ab6bcb9 100644 --- a/brc3 +++ b/brc3 @@ -3,64 +3,47 @@ ## 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 <= 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 diff --git a/filesystem/usr/local/bin/i3-abrowser-py b/filesystem/usr/local/bin/i3-abrowser-py new file mode 100755 index 0000000..2381b2a --- /dev/null +++ b/filesystem/usr/local/bin/i3-abrowser-py @@ -0,0 +1,47 @@ +#!/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() diff --git a/filesystem/usr/local/bin/i3-split-maybe b/filesystem/usr/local/bin/i3-split-maybe index 0e05259..0e39453 100755 --- a/filesystem/usr/local/bin/i3-split-maybe +++ b/filesystem/usr/local/bin/i3-split-maybe @@ -105,10 +105,10 @@ def set_layout(i3): 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, diff --git a/filesystem/usr/local/bin/myupgrade b/filesystem/usr/local/bin/myupgrade index 3438166..361bf3c 100755 --- a/filesystem/usr/local/bin/myupgrade +++ b/filesystem/usr/local/bin/myupgrade @@ -91,18 +91,6 @@ case $hn in 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 diff --git a/mount-latest-remote b/mount-latest-remote index f63a6f7..6a0ab1b 100755 --- a/mount-latest-remote +++ b/mount-latest-remote @@ -58,7 +58,7 @@ if [[ $tg == *:* ]]; then 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 "$@" diff --git a/trusted-network b/trusted-network index d065009..6cca15f 100755 --- a/trusted-network +++ b/trusted-network @@ -86,7 +86,7 @@ else #untrusted cat >/etc/systemd/resolved.conf.d/untrusted-network.conf <