From 5a3268df3e188917ee6bd86b22c43ee20709c3f0 Mon Sep 17 00:00:00 2001 From: lemke_h Date: Fri, 21 Aug 2026 22:40:34 +0200 Subject: [PATCH] fix --- __pycache__/cheatsheet_overlaycpython-39.pyc | Bin 7963 -> 9641 bytes aramis-home | 2 +- cheatsheet_overlay | 48 +++++++++++-- check_kerberos_renewal | 70 +++++++++++++++++++ eco_from | 9 --- kerberos_ticket_renew.sh | 14 +++- snapshot_bernina | 7 -- startup_bernina_terminal | 21 +++++- 8 files changed, 143 insertions(+), 28 deletions(-) create mode 100755 check_kerberos_renewal delete mode 100755 eco_from delete mode 100755 snapshot_bernina diff --git a/__pycache__/cheatsheet_overlaycpython-39.pyc b/__pycache__/cheatsheet_overlaycpython-39.pyc index 1a11ef78c502e0d10ae1a1a28480f77ebdb9dd99..a6dd94628c1a9cbb26b959e9e3481ffeeff136c7 100644 GIT binary patch delta 3210 zcmZ`*Z)_Y#72nxCpVxQx`A=-ePHboFCUq`x>_9`BCc*hr+liCdPGeU|uh8}0&fMMF zd%M?}Ih!+%4#|-yl_08CLV~K&osf|FrJ@QdAIn!H_<)dTIrxeY;u8X-N=S(JcAby} zxYNFUGdu6ido#cJy?KB3!WnbmGjk?48y(DG ziKb4pNN!W!=x=IGou!(3 zZh)n8gRC=mkae-l11&eix>*mrhgmP{gZCkJfc3-s>R~p(20)D>&{wtWg#EVhsF(bn)ahEuR`mAb94)vWPq~tA zap4wR&Zu3qU0*6XQxSnf^SlrUPC0xA-Svx9iKm0*Q`8+1NJ$0H2LX&b?gW0p6=lxOQyG+bb6bxKr~_>-t(1-TYl})nIYHHfRKTs+b|t4pt{|$agdp=ZuyBHM#p8;5wN%v?+_N!rTo?}F+XV$K z;v}Y1sX14cT`AAgdFj{{J{1M)cmcT0SCtC6Lu}d1HscmU@HCJ?>-4RqZrb0W8|>5a(YLRSw(e!EP1kdc|eyu=dn; zR29~_28-u<9u-yJM--e;C0CxH(h+V&;r{!9N>TW206M7c*Pg7BLZp@KN`?Cp_lbYQ zm1>&abyX>-Dp(|##Hp9Kvx!>-n-jS~SW;OPTkaN4hp32g6}fv3PX8B8k*lXsgeX-M zUDjgAg{&cZ;ZrLC{+Jj9HLJG_*i115x)^>U4&kV7%avA871qc;rc2N(BjRh< zNk2JFI*B+Eeyd|N`BV6^Bf=kb%zkZ`>=D6KveCXvl)2G?BnYjPB29u&V~N#g+W;~E zUs`plu7XkfD2Cup=4l(h4@P8aKMs$jK7O$~&cTG`w-y#}&9@BKS7H<+Zj%ZSCysy~ zevw*l6Jw}-Jx#M)ph#?KhE6hMnwTI{BpE$@1p7LnC9;ni>7VQ5-O$dQBD0SkX8uUX z$*|fpNv6UNdWOlV@Mk@e{3JZt`!4x%_(?A%5*6+_PR?x%K+e@~SwGUuRL=3~vn0CYMk>8-8zSVPHJ6 ziJat;CGHkWO56(nJTy*jgz4c)av^+a_!{{%{O0hRWIg=NIU;G> z!+C0vE0_mrm=_dXs60@CVyZ>91>S(V>I1#nzQdnXe47dzn~Gvt1~&Ft%vs#_>%iSm zdm~!5y=}WDu~uRUw;3%!O)G&6%F!U7tL;E+MuTMyE(>Mg+Q<`LBWl!vP~(yT(Ln>4 zw^EBr1Ku)U|9pwPh4}8}V{n$?04pw5(gN?);Yvm>o zgvWU$tLNJH7dU4!h!KhNIpnmuw{2HhaKEu6aG=Bg30`C;2rbzOILeR&(jSMmqt&r{ z|A!dD`fR`>{{TX1c*Rm=PZK>1s;|%%-;Ym?VJ`<9hA) zK($_Yx>~aYYkQ!5M^k3QM1uXcR;a_plC?iDBd$&DAz;&u&Zc%>-_;vkDuc*W>5cA2 zkLtw>Ccs*Uc7GEt1Zn^o`@XSjGzOa(Xu5F_-w^{3DI;d>h=GS|zkPf`@O8KzKr&f# zxka|a^}~0^FGH@`WVG~R0CYi7V3CPQ>1z1-;iGyV3IBEYHF7z;Ju^_B#?9Cxv-i=yei6|b-;vj3KWeb_3+ct>}Bk2nU;m~TUM4t zl#!iiwObYo9Lo||W#e?CNxN{o0gx7H{BSKC87rQnsNO~4p*V~J%TpY8M1RPTVjTsN nRh(5h{CMoNc@f%)9+QNB8k_9RnEmFUdBi+xCQ}*nm`VN(Wfx6- delta 1482 zcmZ8hT})e596#sY_Hw!Xq_l;W-mR2k=@0^wvCT0C!Waw~n?PjOgwpn0%4Pk4a}O9u zkq1boOVrF0rrWlju5P?T9!KZV-v2)M4R2Y_uU%!70++btY-!zZvuQN|6k zWSHj5@vCM&yP>}r&lipS9iv=`SGI_0AU#gj^!P@$tQYByLxsxmhmKYWF4E7H0lM#r zNRQZmu&dEeJj3IbRE4BrUFLTuPOFi?8ie3AfE@F{0f<6e#Jwu+Jb>&V5bS#YTT>3O z3eV2F^n&+`gcmolRqOK2sqxIj)XdeoXp~9af%Pn^J57R(4eIl)IP2nufhh6CJMygD zY-IpM0eWFC8w!+Q0P@JqJe)dy?E6Z9guWT*fkVfi1)f5frtb$+ZD&~5uADb}h(U__ z!j{P5UmksshPa!48#LiVIvKi`=wsQ5w4_P7EkY_~&6m>)MmbZeZ0i|>vjwcuXQ3hI z7%Q{rxp4A@bIiko9Qrw&Wl&cp=U$!C=58#E&fo!_Jx}+;mr|3=)x=yD<4e5CX&*#u z%oi)Bp2?9ij_}%R^yhFhyhr~Gcf;A^_LcKOl^So`ALEVY7<$_*!&5kZ*#^z=gXK&2o3w(Bn!xSyV zhNWrl4$x0y6Cu^^u@}*#HQgwz5qzCWYCD{yU1|zmq&L-T@Q8k-z7Ch^Gj+Llgf~xc z_}}rDSnek_Oo;(tM35m~qF=|={qI;zzyZJt0`q`CA~1mpNPI_pFR=%zz!Hgr(Nn5{ zgMUcODC__SA_QfBKQKr7Y!X9oo2$x!oQL3TKpLzDE`YmWmB}479G*y_@c`^WqFAmP z*b}OP|!UWqYZeKVw?LL1u7>LySY1gUyQ(I+jQZzX56_ZVlSS0(P)jO*T+b&tws@-~R~W z72fka1ODKtar%2A=851G51Kf{=&24>YUgf(j&?j?ukn3H=h@pVp~)M#vdz987;|!; zte54UO{-PrJ!Qk>+5?dGC)0kOtIL^8Da&M)NuQ>h$)Mj}+{0%?bH~Ik`Y>7OwXe3w vl33@^#=$<7%_mMdyv%{WK3=64JNqQALx-DgcBVW{a#%hs56Y6|C diff --git a/aramis-home b/aramis-home index d4da7cf..fad612b 100755 --- a/aramis-home +++ b/aramis-home @@ -1,5 +1,5 @@ #!/bin/bash -source /opt/gfa/python +source bpy-env cd /afs/psi.ch/intranet/SF/Photonics/AramisOverview caqtdm -stylefile sfop.qss -macro chargelim=15,ES-DISPLAY=SAROP-CPCL-ARAMIS-UI:ARAMIS-ES.BB S_PH_Aramis_Overview.ui diff --git a/cheatsheet_overlay b/cheatsheet_overlay index 6dda391..40340b8 100755 --- a/cheatsheet_overlay +++ b/cheatsheet_overlay @@ -6,10 +6,14 @@ there's no "brand-new extension not recognized until Shell restarts" risk: this is just a normal process, like any other keybinding here. Toggle behavior: running this while an instance is already showing closes -it instead of opening a second one (tracked via a PID file). +it instead of opening a second one (tracked via a PID file). That PID file +is verified against /proc before ever being trusted or signaled -- on a +host where its directory isn't cleared across reboots (confirmed: some +hosts' /tmp isn't, which the PID file falls back to when XDG_RUNTIME_DIR +isn't set), a stale PID number could otherwise get reused by a completely +unrelated process after reboot. -Dismiss: Escape, clicking outside the panel, or pressing the trigger key -again. +Dismiss: Escape, the close button, or pressing the trigger key again. """ import json import os @@ -17,6 +21,7 @@ import signal import subprocess import sys import tempfile +import time import gi @@ -96,15 +101,32 @@ def load_categories(): pass +def _is_our_process(pid): + """True only if `pid` is actually still running *this* script -- not + just any process that happens to exist. Without this check, a PID + file surviving somewhere that isn't cleared across reboots (confirmed: + /tmp isn't, on at least one host here) could have its old PID number + reused by a completely unrelated process, which we'd otherwise + mistakenly SIGTERM and treat as "still showing".""" + try: + with open(f"/proc/{pid}/cmdline", "rb") as f: + return b"cheatsheet_overlay" in f.read() + except OSError: + return False + + def already_showing(): """If a live instance is already up, kill it and return True (caller should then just exit, giving Super+F1 toggle-to-close behavior).""" try: with open(PID_FILE, encoding="utf-8") as f: pid = int(f.read().strip()) - os.kill(pid, signal.SIGTERM) + if _is_our_process(pid): + os.kill(pid, signal.SIGTERM) + os.unlink(PID_FILE) + return True os.unlink(PID_FILE) - return True + return False except (FileNotFoundError, ValueError, ProcessLookupError): try: os.unlink(PID_FILE) @@ -226,7 +248,23 @@ def _on_key_press(widget, event): return False +def wait_for_source(timeout=10): + """Block until MD_PATH is actually readable, up to `timeout` seconds. + /sf/bernina is a real NFS mount (not autofs) so it's normally already + up by login, but this is cheap insurance against a race at boot, and + means the file always gets read fresh from the network filesystem on + every call -- no local copy to ever go stale.""" + deadline = time.monotonic() + timeout + while time.monotonic() < deadline: + if os.access(MD_PATH, os.R_OK): + return True + time.sleep(0.2) + return os.access(MD_PATH, os.R_OK) + + def main(): + wait_for_source() + if already_showing(): return diff --git a/check_kerberos_renewal b/check_kerberos_renewal new file mode 100755 index 0000000..4d5c660 --- /dev/null +++ b/check_kerberos_renewal @@ -0,0 +1,70 @@ +#!/bin/bash +# Read-only diagnostic for "kerberos_ticket_renew.sh renews/prompts too +# often" on the gac-bernina account. Checks the things that would make +# `kinit -R` fail more than it should (forcing the interactive password +# fallback instead of silent renewal), and looks for anything else that +# might already be renewing/touching this account's ticket independently. +# Makes no changes -- run it, read the output, nothing to clean up after. +# +# Usage: check_kerberos_renewal [principal] (default: gac-bernina) + +set -uo pipefail + +PRINCIPAL="${1:-gac-bernina}" + +section() { echo; echo "=== $* ==="; } + +section "Current ticket(s) + renewable flag (this krb5 build only supports klist -f, not -v)" +klist -f 2>&1 +echo +echo "Looking for an 'R' (renewable) flag on the krbtgt ticket in the output above" +echo "(e.g. 'Flags: FRIA' -- R present). If it's missing, kinit -R can NEVER" +echo "succeed for this ticket no matter how recently it was issued -- every" +echo "renewal attempt would fall straight through to the interactive password" +echo "prompt, which is exactly what over-frequent PROMPTING would look like." +echo +echo "Also compare 'Valid starting' -> 'Expires' (actual ticket lifetime) against" +echo "kerberos_ticket_renew.sh's RENEW_THRESHOLD (default 86400s = 24h): if the" +echo "real lifetime is shorter than the threshold -- e.g. PSI issuing ~10h" +echo "tickets renewable for 7 days is normal here -- every single hourly check" +echo "will always conclude renewal is needed and fire kinit -R, succeeding" +echo "silently but notifying every time. That's over-frequent NOTIFYING (not" +echo "prompting), and doesn't need anything external renewing to explain it." + +section "Any process already touching Kerberos for this account" +ps -eo pid,ppid,user,lstart,cmd 2>/dev/null | grep -iE "kinit|krb5|kerberos.?ticket.?renew|k5start|krenew" | grep -v grep + +section "Our own renewer: how many instances, and is the singleton lock actually working" +echo "-- process(es):" +pgrep -fa kerberos_ticket_renew.sh || echo "(none running right now)" +echo +echo "-- lock file (should be exactly one holder; if XDG_RUNTIME_DIR is unset or" +echo " inconsistent between invocations -- seen elsewhere this session -- the" +echo " lock could silently end up in different places, defeating the" +echo " single-instance guard and letting multiple copies run concurrently):" +echo "XDG_RUNTIME_DIR=${XDG_RUNTIME_DIR:-}" +for f in "${XDG_RUNTIME_DIR:-}/kerberos_ticket_renew.lock" "/tmp/kerberos_ticket_renew.lock"; do + [ -n "$f" ] && [ -e "$f" ] && echo "found: $f" && lsof "$f" 2>/dev/null +done + +section "Cron / systemd --user timers or services that might also renew this ticket" +echo "-- crontab:" +crontab -l 2>&1 +echo +echo "-- systemd --user timers:" +systemctl --user list-timers --all 2>&1 +echo +echo "-- systemd --user services with kerberos/krb in the name:" +systemctl --user list-units --type=service --all 2>&1 | grep -iE "krb|kerberos" + +section "KDC-side policy for this principal, if we're allowed to see it" +echo "(requires admin rights on the realm -- expected to fail for a normal" +echo " principal querying itself; worth trying anyway, costs nothing)" +kadmin -q "getprinc ${PRINCIPAL}" 2>&1 | grep -iE "maximum ticket life|maximum renewable life|attributes" || \ + echo "(no admin rights to query this, or kadmin unavailable -- expected)" + +section "Done" +echo "Send back everything above. The 'Renewable flag check' and 'lifetime vs" +echo "renewable window' sections are the most likely to show the actual cause;" +echo "the process/cron/timer sections rule in or out something else already" +echo "renewing independently, per your suspicion." diff --git a/eco_from b/eco_from deleted file mode 100755 index 36c0dc7..0000000 --- a/eco_from +++ /dev/null @@ -1,9 +0,0 @@ -#/bin/bash -#source /opt/gfa/python -source anaconda_env bernina37_dev - -ipython --pylab --profile=eco --no-banner -i -c "run $1 -l -s bernina" - - -#python /sf/bernina/config/src/python/eco/startup.py -s bernina "$@" -l - diff --git a/kerberos_ticket_renew.sh b/kerberos_ticket_renew.sh index 2cbe959..e80f980 100755 --- a/kerberos_ticket_renew.sh +++ b/kerberos_ticket_renew.sh @@ -13,12 +13,20 @@ # # Defaults to the generic gac-bernina account; override with # KRB_PRINCIPAL or -p to manage a different one. +# +# RENEW_THRESHOLD default: confirmed via check_kerberos_renewal that PSI's +# actual ticket lifetime here is only ~10h (renewable for 7 days) -- the +# old 24h default was longer than that entire lifetime, so every single +# hourly check always concluded "renewal needed" and silently renewed + +# notified every hour forever. 2h leaves several retry cycles of buffer +# before real expiry while only actually renewing (and notifying) roughly +# once per ticket lifetime instead of on every check. set -uo pipefail # no -e: one failed klist/kinit must not kill the loop PRINCIPAL="${KRB_PRINCIPAL:-gac-bernina}" -CHECK_INTERVAL="${KRB_CHECK_INTERVAL:-3600}" # seconds between checks (1h) -RENEW_THRESHOLD="${KRB_RENEW_THRESHOLD:-86400}" # renew once <24h remain +CHECK_INTERVAL="${KRB_CHECK_INTERVAL:-3600}" # seconds between checks (1h) +RENEW_THRESHOLD="${KRB_RENEW_THRESHOLD:-7200}" # renew once <2h remain ONCE=0 usage() { @@ -27,7 +35,7 @@ Usage: $(basename "$0") [-p principal] [-i check-interval-s] [-t renew-threshold -p Kerberos principal to manage (default: \$KRB_PRINCIPAL or gac-bernina) -i seconds between validity checks (default: \$KRB_CHECK_INTERVAL or 3600) - -t renew once fewer than this many seconds remain (default: \$KRB_RENEW_THRESHOLD or 86400) + -t renew once fewer than this many seconds remain (default: \$KRB_RENEW_THRESHOLD or 7200) -1 check once and exit instead of looping (for testing) EOF exit 1 diff --git a/snapshot_bernina b/snapshot_bernina deleted file mode 100755 index e5e046d..0000000 --- a/snapshot_bernina +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash - -source /opt/gfa/python 3.5 -snapshot -b /sf/bernina/config/snapshot/req \ - -d /sf/bernina/config/snapshot \ - --config /sf/bernina/config/snapshot/cfg/config_bernina_snapshot \ - $@ diff --git a/startup_bernina_terminal b/startup_bernina_terminal index f71d207..b6ac847 100755 --- a/startup_bernina_terminal +++ b/startup_bernina_terminal @@ -1,8 +1,5 @@ #!/bin/bash -# default controls python environment -source /opt/gfa/python - # make firefox with host-individual profile as default (important for gac-bernina account) xdg-settings set default-web-browser bernifox.desktop @@ -128,6 +125,24 @@ include "%L" : "Ζ" U0396 GREEK CAPITAL LETTER ZETA EOF +# Defensive cleanup: this script used to install and enable the "Shortcuts" +# gnome-shell extension (Shortcuts@kyle.aims.ac.za) for the cheat sheet +# overlay, bound to its own internal Super+F1 toggle, before switching to +# the current standalone cheatsheet_overlay script. Extension enabled-state +# is per-host/per-login and isn't touched by this script's own updates, so +# any host gac-bernina logged into during that period is still silently +# running it, intercepting Super+F1 before the custom-keybinding below ever +# gets a chance (confirmed on saresb-cons-05: the extension was still +# enabled and still bound, showing its own old-style overlay with no title +# bar, while ps showed no matching process at all -- because it renders +# inside gnome-shell itself, not as a separate process). Safe/idempotent if +# already disabled or never installed. +if gnome-extensions list --enabled 2>/dev/null | grep -qx "Shortcuts@kyle.aims.ac.za"; then + gnome-extensions disable "Shortcuts@kyle.aims.ac.za" + echo "Disabled leftover Shortcuts@kyle.aims.ac.za gnome-shell extension (superseded by cheatsheet_overlay)" +fi +rm -rf "$HOME/.local/share/gnome-shell/extensions/Shortcuts@kyle.aims.ac.za" + #custom bernina keyboard shortcuts gsettings reset org.gnome.settings-daemon.plugins.media-keys custom-keybindings if [ "$(hostname)" = "saresb-cons-03.psi.ch" ] || [ "$(hostname)" = "saresb-cons-04.psi.ch" ] || [ "$(hostname)" = "saresb-cons-05.psi.ch" ] || [ "$(hostname)" = "saresb-cons-08.psi.ch" ] || [ "$(hostname)" = "saresb-cons-09.psi.ch" ] || [ "$(hostname)" = "saresb-cons-10.psi.ch" ]; then