summaryrefslogtreecommitdiff
path: root/guides/sysadmin
diff options
context:
space:
mode:
authorKévin Le Gouguec <kevin.legouguec@gmail.com>2025-01-18 19:00:03 +0100
committerKévin Le Gouguec <kevin.legouguec@gmail.com>2025-01-18 19:00:03 +0100
commit3eb4d872f7157b67691fb5a98e2cf53f716c5457 (patch)
treef8a994a39e359e2620ff01baa2e1096f7e0da633 /guides/sysadmin
parent9398b60e08f07022cf02bb290f36718b1c744eae (diff)
downloadmemory-leaks-3eb4d872f7157b67691fb5a98e2cf53f716c5457.tar.xz
Resume gratuitous shuffling
Diffstat (limited to 'guides/sysadmin')
-rw-r--r--guides/sysadmin/apps-demo/.gitignore2
-rw-r--r--guides/sysadmin/apps-demo/activate34
-rwxr-xr-xguides/sysadmin/apps-demo/napp/bin/napp3
-rwxr-xr-xguides/sysadmin/apps-demo/napp/share/doc.sh18
-rw-r--r--guides/sysadmin/apps-demo/napp/share/napp.md3
-rw-r--r--guides/sysadmin/apps.org186
-rw-r--r--guides/sysadmin/console.org19
-rw-r--r--guides/sysadmin/opensuse.org29
-rw-r--r--guides/sysadmin/plasma/baloo.org9
-rw-r--r--guides/sysadmin/plasma/kio.org10
-rw-r--r--guides/sysadmin/plasma/konsole.org51
11 files changed, 364 insertions, 0 deletions
diff --git a/guides/sysadmin/apps-demo/.gitignore b/guides/sysadmin/apps-demo/.gitignore
new file mode 100644
index 0000000..111d960
--- /dev/null
+++ b/guides/sysadmin/apps-demo/.gitignore
@@ -0,0 +1,2 @@
+man
+info
diff --git a/guides/sysadmin/apps-demo/activate b/guides/sysadmin/apps-demo/activate
new file mode 100644
index 0000000..b8c9138
--- /dev/null
+++ b/guides/sysadmin/apps-demo/activate
@@ -0,0 +1,34 @@
+# Hey Emacs; this is a -*- shell-script -*-.
+# Hopefully invoked by bash 🤞
+
+_apps_dir=$(realpath --no-symlinks $(dirname ${BASH_SOURCE}))
+
+_apps_PATH=$(
+ shopt -s nullglob
+ bins=( "${_apps_dir}"/*/bin )
+ IFS=: eval 'echo "${bins[*]}"'
+)
+export PATH=${_apps_PATH}:${PATH}
+
+_apps_XDG_DATA_DIRS=$(
+ shopt -s nullglob
+ # We could set globstar and let Bash loose, searching the depths
+ # of _apps_dir for
+ # **/{applications/*.desktop,systemd/user/*.service}
+ # but it seems like asking for trouble. Make some assumptions
+ # about where applications typically dump their XDG-related files.
+ datadirs=($(
+ {
+ for dkentry in "${_apps_dir}"/*/share/applications/*.desktop
+ do
+ echo ${dkentry%/applications/*.desktop}
+ done
+ for unit in "${_apps_dir}"/*/lib*/systemd/user/*.service
+ do
+ echo ${unit%/systemd/user/*.service}
+ done
+ } | sort -u
+ ))
+ IFS=: eval 'echo "${datadirs[*]}"'
+)
+export XDG_DATA_DIRS="${_apps_XDG_DATA_DIRS}:${XDG_DATA_DIRS:-/usr/local/share:/usr/share}"
diff --git a/guides/sysadmin/apps-demo/napp/bin/napp b/guides/sysadmin/apps-demo/napp/bin/napp
new file mode 100755
index 0000000..1bd6e9f
--- /dev/null
+++ b/guides/sysadmin/apps-demo/napp/bin/napp
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+echo 😴
diff --git a/guides/sysadmin/apps-demo/napp/share/doc.sh b/guides/sysadmin/apps-demo/napp/share/doc.sh
new file mode 100755
index 0000000..e7c8eb1
--- /dev/null
+++ b/guides/sysadmin/apps-demo/napp/share/doc.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+
+set -eux
+
+mkdir -p info man/man1
+
+pandoc napp.md -s -o man/man1/napp.1
+pandoc napp.md -s -o info/napp.texi \
+ -H <(cat <<EOF
+@dircategory Software development
+@direntry
+* Napp: (napp).
+* Napp node: (napp)napp
+@end direntry
+EOF
+)
+makeinfo info/napp.texi -o info
+install-info info/napp.info info/dir
diff --git a/guides/sysadmin/apps-demo/napp/share/napp.md b/guides/sysadmin/apps-demo/napp/share/napp.md
new file mode 100644
index 0000000..ce841df
--- /dev/null
+++ b/guides/sysadmin/apps-demo/napp/share/napp.md
@@ -0,0 +1,3 @@
+# napp
+
+You need it.
diff --git a/guides/sysadmin/apps.org b/guides/sysadmin/apps.org
new file mode 100644
index 0000000..0ff0184
--- /dev/null
+++ b/guides/sysadmin/apps.org
@@ -0,0 +1,186 @@
+#+TITLE: Installing applications under =$HOME=
+
+One day I woke up and decided to stop letting ~make install~ put
+programs under =/usr/local/=. Not every project provides an
+=uninstall= target, so over time, as more and more applications get
+lumped under that hierarchy, it becomes a clutter of stuff that I
+cannot remove without…
+
+1. guesstimating what files belong to any given program using
+ timestamps,
+2. weighing my odds of passing correctly crafted globs to the likes of
+ =sudo find -delete= and =sudo rm -r= without destroying my system.
+
+Instead I figured I would start ~./configure~'ing programs with
+=--prefix=${HOME}/apps/${program}=, and teach whichever dotfiles
+manage session environment variables to arrange for installed
+resources to be found.
+
+How hard could it be?
+
+* =PATH=
+The Correct Way™ to set environment variables seems to depend on
+
+1. the kind of session (TTY vs GUI),
+2. the init system (e.g. [[https://www.freedesktop.org/software/systemd/man/environment.d.html][systemd user environment variables]])
+3. the desktop environment (e.g. [[https://userbase.kde.org/Session_Environment_Variables][Plasma session environment variables]]),
+4. the display server,
+5. the distro?
+ - e.g. Debian's SSDM [[https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=794419][used not to]] source =~/.profile=,
+ - and [[https://github.com/sddm/sddm/issues/448][developers said]] it should not anyway,
+ - except [[https://github.com/sddm/sddm/issues/1551][it has provisions to do so]]?
+6. [[https://man7.org/linux/man-pages/man8/pam_env.8.html][PAM]]?
+
+Empirically with Plasma on both Tumbleweed (20230929) and Debian 12,
+=~/.profile= seems to be run for both TTY and GUI sessions. Unclear
+what arcane magic is causing that: probably the login manager - on
+Tumbleweed =/usr/share/sddm/scripts/Xsession= seems to start a ~bash
+--login~, but getting lost in the =/usr/etc/X11/xdm/= weeds trying to
+track down who might source that =Xesssion= script.
+
+=~/.profile= it is, then 🤞
+
+(For other DEs on X, my recollection was that =~/.xsessionrc= is the
+way to go for GUI sessions? No clue about Wayland)
+
+* ~man~ pages
+=manpath(5)= says:
+
+#+begin_quote
+By default, man-db examines the user's =$PATH=. For each
+=path_element= found there, it adds =manpath_element= to the search
+path.
+
+If there is no =MANPATH_MAP= line in the configuration file for a
+given =path_element=, then it adds all of =path_element/../man=,
+=path_element/man=, =path_element/../share=man=, and
+=path_element/shared/=man= that exist as directories to the search
+path.
+#+end_quote
+
+How convenient! Setting =PATH= automatically takes care of ~man~
+then… unless =MANPATH= is set, in which case that logic is bypassed.
+
+** openSUSE
+=/usr/etc/profile.d/manpath.sh= [fn:: sourced by =/etc/profile=,
+sourced by =/usr/etc/profile= and =~/.profile=.] plays a little danse
+to (a) query ~manpath~, which runs the heuristic described above (b)
+set the resulting value "in stone" by exporting =MANPATH=.
+
+This means that ~man~ will not consider any =PATH= element added by
+the user after that profile fragment was sourced.
+
+Solutions:
+
+1. Unset =MANPATH= in =~/.profile=, after =/etc/profile= is read.
+ =~/.profile= is "read each time a login shell is strated. All
+ other interactive shells will only read .bashrc", so unclear
+ whether that will affect graphical sessions.
+2. Extend =PATH= with apps /before/ those profile fragments are
+ loaded. Unclear how to accomplish that:
+ - [[https://wiki.archlinux.org/title/environment_variables#Per_user][systemd user environment variables]]? Seems to be limited to
+ =KEY=VALUE= directives; I would like to run a bit of logic that
+ will automatically add every =~/apps/*/bin= directory.
+ - [[https://userbase.kde.org/Session_Environment_Variables][Plasma session environment variables]]? Presumably will not affect
+ TTYs?
+3. Embrace the distro's method: if =MANPATH= is set, extend it.
+
+Went with solution 1 because empirically =~/.profile= seems to be
+sourced for GUI sessions (as noted in § =PATH=).
+
+* ~info~ pages
+Similar to ~man~, ~info~ knows to work with =PATH=. The priority
+[[https://git.savannah.gnu.org/cgit/texinfo.git/tree/info/infopath.c?h=texinfo-7.0.3#n41][seems to be]]:
+
+1. the =INFOPATH= environment variable,
+2. the =INFODIR= build macro, /if =infopath-no-defaults= is not set/,
+3. the =DEFAULT_INFOPATH= build macro, /if =INFOPATH= is unset or ends
+ with a trailing colon/.
+
+Any of these can contain the =PATH= literal, which means "iterate over
+=${PATH}= and add nearby =share/info= & =info= directories". By
+default, =DEFAULT_INFOPATH= contains =PATH= 🥳 but =INFODIR= has
+priority and is set to something boring like =/usr/share/info= 😒
+
+Solution:
+
+#+begin_src bash
+cat <<EOF > ~/.infokey
+#var
+# Disable INFODIR; fall back to DEFAULT_INFOPATH which prioritizes
+# program PATH over /usr/share/info.
+infopath-no-defaults=On
+EOF
+#+end_src
+
+* DONE systemd services
+=systemd.unit(5)= § "User Unit Search Path" mentions a couple of
+variables that we could append:
+
+- =$XDG_CONFIG_DIRS/systemd/user/*=
+- =$XDG_DATA_DIRS/systemd/user/*=
+
+And:
+
+#+begin_quote
+When the variable =$SYSTEMD_UNIT_PATH= is set, the contents of this
+variable overrides the unit load path. If =$SYSTEMD_UNIT_PATH= ends
+with an empty component (=:=), the usual unit load path will be
+appended to the contents of the variable.
+#+end_quote
+
+So we could either:
+
+1. find the directory 𝒟 where an app tucks =systemd/user= in its
+ installation tree, and append 𝒟 to one of the XDG variables,
+2. find the directory where an app tucks its =.service= files, and
+ append that directory to =SYSTEMD_UNIT_PATH=, keeping a final
+ colon.
+
+(1) could feed multiple birds with one scone: in particular,
+=XDG_DATA_DIRS= is used for other purposes (see § Desktop entry
+files). Serendipitously, [[https://github.com/systemd/systemd/blob/1d87a00a951dca801c8ccd79c1460fa91efa7dce/src/basic/path-lookup.c#L147][the systemd sources]] suggest =DATA= over
+=CONFIG= for our purposes:
+
+#+begin_src c
+ /* Implement the mechanisms defined in
+ *
+ * https://standards.freedesktop.org/basedir-spec/basedir-spec-0.6.html
+ *
+ * We look in both the config and the data dirs because we
+ * want to encourage that distributors ship their unit files
+ * as data, and allow overriding as configuration.
+ */
+#+end_src
+
+* DONE Desktop entry files
+The Freedesktop [[https://specifications.freedesktop.org/menu-spec/menu-spec-latest.html][Desktop Menu]] and [[https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html][Desktop Entry]] specs spell out how
+=XDG_DATA_DIRS= will be searched for =applications/*.desktop= files.
+
+* TODO ~bash~ completions
+
+* Putting it all together
+Presenting [[./apps-demo/activate][=~/apps/activate=]], to be sourced from =~/.profile=:
+
+#+INCLUDE: "apps-demo/activate" src sh
+
+* Resources
+** [[https://nullprogram.com/blog/2017/06/19/][nullprogram.com]] — Building and Installing Software in $HOME
+Explains how to set things up so that one can use =~/.local= as a
+first-class citizen for applications, libraries and development
+resources (headers, pkg-config, manpages).
+
+** [[https://specifications.freedesktop.org][specifications.freedesktop.org]] — Freedesktop.org Specifications
+Hosts the specifications for the behavior and environment variables
+most GNU/Linux distros (that I have experience with) adhere to, e.g.
+
+- the [[https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html][Base Directory spec]] :: defines the various
+ =XDG_*_@(HOME|DIR|DIRS)= variables referenced here;
+- the [[https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html][Desktop Entry spec]] :: explains the significance of a desktop
+ file's filename with respect to its position within =XDG_DATA_DIRS=;
+- the [[https://specifications.freedesktop.org/menu-spec/menu-spec-latest.html][Desktop Menu spec]] :: defines the expected file locations for
+ desktop files (and more) with respect to XDG base directories.
+
+** [[https://wiki.archlinux.org/title/Environment_variables#Per_user][wiki.archlinux.org]] — Environment variables § Per user - ArchWiki
+A thorough overview of the myriad of ways users can amend environment
+variables, as examined in § PATH.
diff --git a/guides/sysadmin/console.org b/guides/sysadmin/console.org
new file mode 100644
index 0000000..a6839c1
--- /dev/null
+++ b/guides/sysadmin/console.org
@@ -0,0 +1,19 @@
+* Keyboard settings
+Debian's =console-setup= package provides =setupcon=, a neat utility
+that reads XKB settings from =/etc/default/keyboard= and translates
+them to whatever format the Linux console understands.
+
+To get something similar to =ctrl:nocaps= on distros that do not
+feature this utility:
+#+begin_src sh
+$ localectl | grep "VC Keymap" # To spot the current KEYMAP.
+$ sudo mkdir -p /usr/local/share/kbd/keymaps
+# KEYMAPS_DIR: depending on the distro:
+# - /usr/share/kbd/keymaps/xkb
+# - /lib/kbd/keymaps/xkb
+$ gunzip --stdout ${KEYMAPS_DIR}/${KEYMAP}.map.gz |
+ sed 's/^keycode 58 = .*$/keycode 58 = Control/' |
+ sudo tee /usr/local/share/kbd/keymaps/${KEYMAP}-nocaps.map
+# In /etc/vconsole.conf, change KEYMAP to ^this^ absolute filename.
+# Reboot.
+#+end_src
diff --git a/guides/sysadmin/opensuse.org b/guides/sysadmin/opensuse.org
new file mode 100644
index 0000000..5ea173c
--- /dev/null
+++ b/guides/sysadmin/opensuse.org
@@ -0,0 +1,29 @@
+* Packages
+… that took me more than one minute to find.
+** spell-checking
+- hunspell
+- myspell-fr_FR
+* HOWTO
+** Open ports
+#+begin_src sh
+$ firewall-cmd --add-port=8000/tcp
+$ firewall-cmd --add-service=mdns
+#+end_src
+To make permanent, either:
+- run the command with =--permanent=, and restart ~firewalld~ for
+ immediate application,
+- run the command /a second time/ with =--permanent=,
+- run ~firewall-cmd --runtime-to-permanent~.
+** Auto-mount second disk under =$HOME/media=
+#+begin_example
+$ lsblk --fs
+[…]
+nvme0n1
+└─nvme0n1p1 xfs […UUID…]
+$ sudo $edit /etc/fstab
+[… add:
+UUID=[…UUID…] […$HOME…]/media xfs user,exec 0 0
+…]
+$ mkdir ~/media
+$ mount ~/media
+#+end_example
diff --git a/guides/sysadmin/plasma/baloo.org b/guides/sysadmin/plasma/baloo.org
new file mode 100644
index 0000000..b15c427
--- /dev/null
+++ b/guides/sysadmin/plasma/baloo.org
@@ -0,0 +1,9 @@
+Confused by
+
+- the memory footprint: htop reports "2.6%" of my 4GB RAM, while (a)
+ the indexer is suspended (b) no index file exists,
+
+- the "proper" way to disable it?
+ - ~balooctl disable~
+ - xdg-autostart =Hidden=true=
+ - ~systemctl disable --user plasma-baloorunner.service~
diff --git a/guides/sysadmin/plasma/kio.org b/guides/sysadmin/plasma/kio.org
new file mode 100644
index 0000000..677d3fd
--- /dev/null
+++ b/guides/sysadmin/plasma/kio.org
@@ -0,0 +1,10 @@
+* Phone file sharing
+Plasma-native apps can browse phone filesystems accessed over MTP
+thanks to the KIO API, but other apps need a mount point.
+Unfortunately [[https://invent.kde.org/system/kio-fuse/-/merge_requests/10][KIOFuse blacklists MTP]], so we need to resort to
+thirdparty tools to create such a mount point.
+
+[[https://whoozle.github.io/android-file-transfer-linux/][=android-file-transfer-linux=]] ([[https://packages.debian.org/stable/android-file-transfer][Debian]], [[https://software.opensuse.org/package/android-file-transfer-linux][openSUSE]]) can do the job with a
+simple ~aft-mtp-mount $MOUNTPOINT~, but one may need to ~pkill kiod~
+first, since [[https://bugs.kde.org/show_bug.cgi?id=412257][that daemon starts hogging]] the… USB… device… bus thing as
+soon as the phone is plugged.
diff --git a/guides/sysadmin/plasma/konsole.org b/guides/sysadmin/plasma/konsole.org
new file mode 100644
index 0000000..0693091
--- /dev/null
+++ b/guides/sysadmin/plasma/konsole.org
@@ -0,0 +1,51 @@
+* Keyboard shortcuts
+- ✏️ :: edited
+| =C-(= | split side |
+| =C-)= | split below |
+| =C-S-e= | hide/restore splits |
+| =C-]= | enlarge split ✏️ |
+| =C-[= | shrink split ✏️ |
+| =C-S-h= | tear split off |
+| =C-S-t= | new tab |
+| =C-TAB= | cycle splits & tabs |
+| =C-== | zoom in |
+| =C--= | zoom out |
+| =C-0= | reset zoom ✏️ |
+| =S-Pgup= | scroll up |
+| =S-Pgdown= | scroll down |
+| =C-S-f= | search |
+| =C-S-v= | paste from clipboard |
+| =C-S-m= | toggle menubar |
+| =C-S-,= | open preferences |
+| =C-M-,= | open shortcuts |
+
+Disabled:
+| =C-M-m= | previous profile |
+| =C-M-n= | next profile |
+** Plugins
+⚠️ Plugins define "activation shortcuts"; disabled by visiting each
+one. Shortcuts stored under =~/.config/kde.org/konsole.conf=:
+#+begin_src conf
+[plugins]
+quickcommands\shortcut="Ctrl+^"
+sshplugin\ssh_shortcut="Ctrl+@"
+#+end_src
+
+* UI
+** Toolbar Settings
+- [ ] Lock Toolbar Positions
+- Toolbars Shown: ∅
+ - (necessary to disable toolbar accelerators & free corresponding
+ readline bindings)
+* Profile
+** Appearance
+*** Miscellaneous
+- Inactive Terminals:
+ - [X] Darken
+** Mouse
+*** Text interaction
+- Copy options:
+ - [X] Copy on select
+*** Miscellaneous
+- Text Editor Command: ~emacs +LINE:COLUMN PATH~
+