Knowledge Base

Preserving for the future: Shell scripts, AoC, and more

How I use quilt

To summarize my notes from a conversation about building dpkgs:

In a debuild (which calls dpkg-buildpackage) operation, it will run quilt push -a to apply all patches listed in debian/patches/series. This process is not tolerant of any fuzz. It's not clear from a debuild operation if it's fuzz or if it actually failed. I always have to manually quilt push iteratively (or quilt push -a to go through them until it stops). When you manually run quilt push it will tolerate fuzz but not errors. If a patch indicates that it has fuzz, before pushing the next patch, you run quilt refresh to refresh the current top-most patch. That's how I make the de-fuzzed patch files nowadays. If a patch has actual errors, you have to run quilt push -f (and notably there are not long-option equivalent parameters) to force the patch, and then you have to manually fix the errors and then run quilt refresh. It gets messy and it's not my favorite tool, but I've finally started understanding it just a little bit better.

One should read Using Quilt which is the official documentation for it.

edited 2023-07-24

My quiltrc is:

for where in ./ ../ ../../ ../../../ ../../../../ ../../../../../; do
    if [ -e ${where}debian/rules -a -d ${where}debian/patches ]; then
        export QUILT_PATCHES=debian/patches
        break
    fi
done
QUILT_PUSH_ARGS="--color=auto"
QUILT_DIFF_ARGS="--no-timestamps --no-index -p ab --color=auto"
QUILT_REFRESH_ARGS="--no-timestamps --no-index -p ab"
QUILT_DIFF_OPTS='-p'

Cheating in SuperTuxKart

I have recently installed SuperTuxKart, which is available in Devuan GNU+Linux of course. It's a great example of a FLOSS game. It's a fun little kart racing game. With only a few week's practice, I can now actually beat most tracks on expert difficulty (out of novice, intermediate, hard, and SuperTux options).

I first started by cracking the data files to make the expert difficulty as easy as the novice difficulty. I love open source games because it's easy to cheat at first, and then easy to restore when you're good enough. I put it back when I got good enough to compete, and if I slip up too much in a game, I will not come in first. I modified /usr/share/games/supertuxkart/stk_config.xml section <ai><hard>

<hard   time-full-steer="0.1"
        straight-length-for-zipper="35"
        use-slipstream="false"
        disable-slipstream-usage="true"
        shield-incoming-radius="0"
        false-start-probability="0.08"
        min-start-delay="0.3" max-start-delay="0.5"
        nitro-usage="0"
        item-skill="1"
        collect-avoid-items="false"
        handle-bomb="false"
        first-speed-cap="-100:1.0 -50:0.9 0:0.85 100:0.65"
        last-speed-cap="-150:0.92 -50:0.75 50:0.6"
        max-item-angle="0.7" max-item-angle-high-speed="0.3"
        bad-item-closeness="6"
        collect-item-probability="0:0"
        rb-skid-probability="0:0.0"
        skidding-threshold="4.0"
        />

I also modified ~/.config/supertuxkart/config-0.10/players.xml by editing node <story-mode> subnodes:

<gp1 solved="hard"/>

Just change any story-mode track name to solved="difficulty" of ["easy","medium","hard","best"]. By changing these, you are telling the game that you've completed various challenges of the story mode, so it unlocks later things for you.

My thoughts

My favorite tracks are Black Forest, Nessie's Pond, Ravenbridge Mansion, and Volcan Island. Some of these have fun music, and some are just pretty tracks.

I like to play just the time trials. I think the presents are superfluous.

Package for Devuan: python3-freeipa

I use FreeIPA extensively and have written about it before, of course. In Fedora Linux there is a package for a nifty python client for freeipa named, of course, python3-freeipa. I use it in my software freeipa-cert-alert. Well, this python3-freeipa library is not in Devuan, so I bothered to package this simple application, and now it is available for other Debian-based distros: https://build.opensuse.org/package/show/home:bgstack15/python-freeipa.

Due to how nice package management systems work, the directory debian/ is nice and simple. You can view its source on my cgit.

Bonus!

I also updated my freeipa-cert-alert project to search in the recent past as well:

$ PASTDAYS=60 DAYS=29 ./freeipa-cert-alert.py 
Certificates expiring within 89 days from 2022-10-19
Not valid before               Not valid after                Subject                                      
Thu Dec 03 15:40:47 2020 UTC   Sun Dec 04 15:40:47 2022 UTC   CN=dns2.ipa.internal.com,O=IPA.INTERNAL.COM  
Thu Dec 10 22:15:49 2020 UTC   Sun Dec 11 22:15:49 2022 UTC   CN=d2-03a.ipa.internal.com,O=IPA.INTERNAL.COM

Xscreensaver uses X11 xkbmap!

I use multiple input methods for X11, including QWERTY and Dvorak layouts for English (US). How I do that is with setxkbmap:

setxkbmap -option grp:switch,grp:shifts_toggle 'us,us(dvorak)'

The option grp allows me to use both shift keys at the same time to switch input. I've discussed this before, where I use my fork of fbxkb to display which variant is active.

I learned recently that xscreensaver happily displays which input method is active, so you don't have to get frustrated as to why your password is not working!

Also, as a bonus, as you can see in my screenshot I used Xephyr to run a nested X11 display. I ran these commands (among multiple terminal windows):

Xephyr -screen 800x600 :1
killall xscreensaver
DISPLAY=:1 xscreensaver
DISPLAY=:1 xscreensaver-command --lock

And then I could take a screenshot of my xscreensaver lock screen on GNU/Linux.

My kickstart for Fedora 37 VMs

I missed Fedora 35, so my last Fedora kickstart post was about Fedora 35. I'm still loading Xfce. Thankfully, there were extremely minimal changes required! It was just version numbers obviously, and I rearranged the package names and added xrandr which is no longer included by default (probably due to the Wayland infection spreading).

The kickstart file

# File: /mnt/public/Support/Platforms/Fedora/fc37x-ks.cfg
# Locations:
#    /mnt/public/Support/Platforms/Fedora/fc37x-ks.cfg
# Author: bgstack15
# Startdate: 2017-08-16
# Title: Kickstart for Fedora 37 xfce for ipa.internal.com
# Purpose: To provide an easy installation for VMs and other systems in the Internal network
# History:
#    2017-06 I learned how to use kickstart files for the RHCSA EX-200 exam
#    2017-08-08 Added notifyemail to --extra-args
#    2017-11-01 major revision to use local mirror
#    2017-11-04 converted for building directly into an iso file
#    2017-11-15 fedora 27
#    2018-05-05 fedora 28
#    2018-07-08 adjusted to use --network type=bridge,source=br0 instead of type=direct,source=eno1
#    2018-12-01 fedora 29
#    2019-05-05 fedora 30
#    2020-02-20 fedora 31
#    2020-05-05 fedora 32
#    2020-12-02 fedora 33
#    2021-05-04 fedora 34
#    2022-03-28 fedora 35
vm=fc37x-01a; sudo virsh destroy "${vm}"; sudo virsh undefine --remove-all-storage "${vm}";#    2022-12-08 Fedora 37
# Usage with virt-install:
#    vm=fc37x-01a ; time sudo virt-install -n "${vm}" --memory 2048 --vcpus=1 --os-variant=fedora32 --accelerate -v --disk path=/var/lib/libvirt/images/"${vm}".qcow2,size=30 -l /mnt/public/Support/SetupsBig/Linux/Fedora-Everything-netinst-x86_64-37-1.7.iso --initrd-inject=/mnt/public/Support/Platforms/Fedora/fc37x-ks.cfg --extra-args "inst.ks=file:/fc37x-ks.cfg SERVERNAME=${vm} NOTIFYEMAIL=bgstack15@gmail.com" --debug --network type=bridge,source=br0 --noautoconsole
#    vm=fc37x-01a; sudo virsh destroy "${vm}"; sudo virsh undefine --remove-all-storage "${vm}";
# Reference:
#    https://sysadmin.compxtreme.ro/automatically-set-the-hostname-during-kickstart-installation/
#    /mnt/public/Support/Platforms/CentOS7/install-vm.txt

#platform=x86, AMD64, or Intel EM64T
#version=DEVEL
# Install OS instead of upgrade
#install
# Keyboard layouts
keyboard --vckeymap=us --xlayouts=''
# Root password
rootpw --plaintext plaintextexamplepw
# my user
user --groups=wheel --name=bgstack15-local --password=$6$.gh9u7vg2HDJPPX/scrubbedpasswdentrygoeshere --iscrypted --gecos="bgstack15-local"

# System language
lang en_US.UTF-8
# Firewall configuration
firewall --enabled --ssh
# Reboot after installation
reboot
# Network information
#attempting to put it in the included ks file that accepts hostname from the virsh command.
#network  --bootproto=dhcp --device=eth0 --ipv6=auto --activate
%include /tmp/network.ks
# System timezone
timezone America/New_York --utc
# System authorization information
#auth  --useshadow  --passalgo=sha512
# Use network installation instead of CDROM installation media
url --url="https://www.example.com/mirror/fedora/linux/releases/37/Everything/x86_64/os/"

# Use text mode install
text
# SELinux configuration
selinux --enforcing
# Prepare X to run at boot
xconfig --startxonboot

# Use all local repositories
# Online repos
repo --name=internalrpm --baseurl=https://www.example.com/internal/repo/rpm/
repo --name=fedora --baseurl=https://www.example.com/mirror/fedora/linux/releases/$releasever/Everything/$basearch/os/
repo --name=updates --baseurl=https://www.example.com/mirror/fedora/linux/updates/$releasever/Everything/$basearch/
repo --name=rpmfusion-free --baseurl=https://www.example.com/mirror/rpmfusion/free/fedora/releases/$releasever/Everything/$basearch/os/
repo --name=rpmfusion-free-updates --baseurl=https://www.example.com/mirror/rpmfusion/free/fedora/updates/$releasever/$basearch/
repo --name=copr-bgstack15-stackrpms --baseurl=https://www.example.com/mirror/copr-bgstack15-stackrpms/fedora-$releasever-$basearch/
repo --name=copr-bgstack15-aftermozilla --baseurl=https://download.copr.fedorainfracloud.org/results/bgstack15/AfterMozilla/fedora-$releasever-$basearch/

firstboot --disabled

# System bootloader configuration
bootloader --location=mbr
# Partition clearing information
clearpart --all --initlabel
# Disk partitioning information
autopart --type=lvm

%pre
echo "network  --bootproto=dhcp --device=eth0 --ipv6=auto --activate --hostname renameme.ipa.internal.com" > /tmp/network.ks
for x in $( cat /proc/cmdline );
do
   case $x in
      SERVERNAME*)
         eval $x
         echo "network  --bootproto=dhcp --device=eth0 --ipv6=auto --activate --hostname ${SERVERNAME}.ipa.internal.com" > /tmp/network.ks
         ;;
      NOTIFYEMAIL*)
         eval $x
         echo "${NOTIFYEMAIL}" > /mnt/sysroot/root/notifyemail.txt
     ;;
   esac
done
cp -p /run/install/repo/ca-ipa.internal.com.crt /etc/pki/ca-trust/source/anchors/ 2>/dev/null || :
wget http://www.example.com/internal/certs/ca-ipa.internal.com.crt -O /etc/pki/ca-trust/source/anchors/ca-ipa.internal-wget.com.crt || :
update-ca-trust || :
%end

%post
{
   set -x
   # Set temporary hostname
   #hostnamectl set-hostname renameme.ipa.internal.com;

   # Get local mirror root ca certificate
   wget http://www.example.com/internal/certs/ca-ipa.internal.com.crt -O /etc/pki/ca-trust/source/anchors/ca-ipa.internal.com.crt && update-ca-trust

   # Get local mirror repositories
   wget https://www.example.com/internal/repo/rpm/set-my-repos.sh --output-document /usr/local/sbin/set-my-repos.sh ; chmod +x /usr/local/sbin/set-my-scripts.sh ; sh -x /usr/local/sbin/set-my-repos.sh

   #dnf -y remove dnfdragora ;
   #dnf clean all ;
   #dnf update -y ;

   # Remove graphical boot and add serial console
   sed -i -r -e '/^GRUB_CMDLINE_LINUX=/{s/(\s*)(rhgb|quiet)\s*/\1/g;};' -e '/^GRUB_CMDLINE_LINUX=/{s/(\s*)\"$/ console=ttyS0 console=tty1\"/;}' /etc/default/grub
   grub2-mkconfig > /boot/grub2/grub.cfg

   systemctl enable sendmail.service && systemctl start sendmail.service
   # Send IP address to myself
   thisip="$( ifconfig 2>/dev/null | awk '/Bcast|broadcast/{print $2}' | tr -cd '[^0-9\.\n]' | head -n1 )"
   {
      echo "${SERVER} has IP ${thisip}."
      echo "system finished kickstart at $( date "+%Y-%m-%d %T" )";
   } | $( find /usr/share/bgscripts/send.sh /usr/bin/send 2>/dev/null | head -n1 ) -f "root@$( hostname --fqdn )" \
      -h -s "${SERVER} is ${thisip}" $( cat /root/notifyemail.txt 2>/dev/null )

   # Ensure boot to runlevel 5
   systemctl set-default graphical.target

   # fix the mkhomedir problem
   systemctl enable oddjobd.service && systemctl start oddjobd.service

   # Personal customizations
   mkdir -p /mnt/bgstack15 /mnt/public
   #su bgstack15-local -c "sudo /usr/share/bgconf/bgconf.py"
   tf=/etc/cron.d/01_init.cron
   touch "${tf}" ; chown root.root "${tf}" ; chmod 0600 "${tf}"
   cat <<-"EOFCRON" 1>"${tf}"
@reboot         root    su bgstack15-local -c "sudo /usr/bin/bgconf.py" 1>/root/clone.log 2>&1 ; rm -f /etc/cron.d/01_init.cron 1>/dev/null 2>&1 ; systemctl restart lightdm 1>/dev/null 2>&1 ;
EOFCRON

} 2>&1 | tee -a /root/install.log
%end

%packages
@core
@^xfce-desktop-environment
@xfce-apps
@xfce-media
autossh
bc
bgconf
bgscripts
bgscripts-core
bind-utils
cifs-utils
cryptsetup
-dnfdragora
-dnfdragora-updater
dosfstools
expect
-firefox
firewalld
freeipa-client
git
-gstreamer1-plugins-ugly*
-hplip
iotop
librewolf
lightdm-gtk
locale-en_BS
mailx
man
net-tools
newmoon
nfs-utils
numix-icon-theme-circle
p7zip
parted
plocate
python3-policycoreutils
qemu-guest-agent
rpm-build
rsync
scite
screen
sendmail
spice-vdagent
strace
sysstat
tcpdump
telnet
-thunderbird
vim
vlc
wget
xdg-themes-stackrpms
xfce4-whiskermenu-plugin
xrandr
%end

The set-my-repos.sh script is the same as in the fedora 35 link at the top of this post.

Arandr-trayicon

I use fluxbox window manager, and a set of small/minimal applications to make my desktop experience. I wrote a small utility that facilitates changing which displays are enabled. It of course sits in the system tray, and uses arandr as a base program.

Arandr saves configurations to ~/.screenlayout, so this project arandr-trayicon (which is entirely unrelated to arandr itself) reads that directory, as well as /etc/screenlayouts, to list any existing configs on a menu for the tray icon.

Obviously this program is not necessary if you are using a full DE like XFCE.

I don't have any packaging recipe for it yet, but eventually I will add a debian/ build recipe.

Record outbound clicks on web page with small redirect project

I have built a new project which I call outbound. I designed it to redirect users to any outbound links on my blog or elsewhere on my site. This project requires modifying an outbound link to visit a configured location, e.g., /outbound/https://start.duckduckgo.com/.

As a minimal effort to reduce pointless traffic, a link will only redirect if the referer is in a whitelist configured by the admin.

The idea is to log to regular web server logs (apache, nginx, etc.) redirects. The admin can just view all http response 307 visits for path /outbound/.

To build a link, the page author needs to include the protocol after the prefix, so /outbound/https://start.duckduckgo.com/ is good, but /outbound/start.duckduckgo.com/ makes the link invalid.

I plan on using links like this in the future, so I can get some insights into what outbound links my audience uses, that is, if I have an audience.

For testing purposes, here are some outbound links in different formats, for testing my CMS (Nikola):

Custom search url in Firefox with bookmark

You can make a custom "search engine" with a bookmark in the web browser. Doing so makes it possible to type in the keyword followed by space and then the search query.

Make a custom bookmark with a keyword and with %s in the url that represents the placement of the search expression.

Then, when you visit your new "search engine" bookmark, it sends you to the url!

Supporting Linux desktop support clients with x11vnc, Wireguard, and Remmina

I have a Linux desktop support customer! (Read: I have a friend for whom I set up a Ubuntu desktop system. It's not ideal I realize, but it's better than Windows.)

On his Ubuntu desktop, I set up Wireguard as a peer to my main wg peer on my network. When his computer is on, it automatically connects. If he needs help where I need to see his screen, I connect over ssh and forward a port:

ssh -L 5900:localhost:5900

And then once there I su - customername and start x11vnc.

x11vnc -display :0 -once -localhost

And now on my client side I run Remmina and connect to localhost as type vnc. And then I can work on the same console session that my customer sees, while we're on the phone together.

Backstory

I already had a wireguard peer set up on my network for a multitude of reasons. Adding wireguard to autostart Ubuntu is well-established and outside the scope of this document. I remember reading in the past about some way to connect to an existing X11 console session, and x11vnc is the solution for that type of operation. Teamviewer is not FLOSS, and I gave it up years ago. Before that, I used LogMeIn.

I finally started using autofs for my network mounts!

In the past, I wrote about my ripped-off myautomount program which was a bash rewrite of a Go tool from TridentOS.

One main use of autofs is to automount network locations. I of course have my own nfs server and several mounts that are useful on all my clients. Here is what I set up for myself:

File /etc/autofs.internal-wireless.

* -fstype=nfs,noatime,rw,nosuid,rsize=262144,wsize=262144,soft server3:/var/server3/shares/&

And file /etc/auto.master.d/internal-wireless.autofs.

/net  /etc/autofs.internal-wireless --timeout=5

I also set the user's xfe bookmarks to include /net/$USERNAME manually. I don't currently use nfs-mounted home directories, but each user has a primary export on the file server. For future reference, an Xfe bookmark is simply in file ~/.config/xfe/xferc:

[bookmarks]
BOOKMARK1=/net/${USERNAME}

Where $USERNAME is of course fully evaluated already, so /mnt/bgstack15.