<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
    <channel>
      <title>Snamellit</title>
      <link>https://www.snamellit.com</link>
      <description></description>
      <generator>Zola</generator>
      <language>en</language>
      <atom:link href="https://www.snamellit.com/rss.xml" rel="self" type="application/rss+xml"/>
      <lastBuildDate>Fri, 20 Mar 2026 11:01:00 +0100</lastBuildDate>
      <item>
          <title>Install GUIX on Macbook 12</title>
          <pubDate>Fri, 20 Mar 2026 11:01:00 +0100</pubDate>
          <author>Peter Tillemans</author>
          <link>https://www.snamellit.com/posts/20260320t110150-install-guix-on-macbook-12-guix-linux-sysadmin/</link>
          <guid>https://www.snamellit.com/posts/20260320t110150-install-guix-on-macbook-12-guix-linux-sysadmin/</guid>
          <description xml:base="https://www.snamellit.com/posts/20260320t110150-install-guix-on-macbook-12-guix-linux-sysadmin/">&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;I have an old Intel macbook 12 of begin 2016, one of the so-called
&quot;Retina Macbooks&quot;. It is an ideal couch device but far too slow to run
modern OS-X, provided you wanted to run that to begin with.&lt;&#x2F;p&gt;
&lt;p&gt;I wanted to revive this machine to avoid lugging the BIG laptop,
especially for the friday SystemCrafters stream in my comfy chair in
the living.&lt;&#x2F;p&gt;
&lt;p&gt;I saw some experience reports with Ubuntu, which worked, but then I
never used it because Ubuntu is, well it is Ok, there is nothing wrong
with it... Gnome works fine, KDE worked fine, it is just all different
from my usual Arch&#x2F;Guix machines for little added benefit.&lt;&#x2F;p&gt;
&lt;p&gt;Because I was curious about immutable distros and leveraging
containers like toolbox&#x2F;flatpak I installed Fedora Silverblue. Again
it is fine, Gnome is really luxurious on this machine. It all works
well, but again different. Distributing the software between immutable
host (which you have to reboot to make packages appear  after
install), flatpaks and toolbox containers works fine again, but
inevitably causes friction when crossing the domains,
e.g. Emacs. Nothing insurmountable. Also I am not impresssed by
toolbox, it is simple, but it does nothing that distrobox does not
seem to do better, while being less tied to the OS. I am not a fan of
the dev container workflow, and Fedora Silverblue didn&#x27;t sell it to
me. Again in large deployments the balance might be different.&lt;&#x2F;p&gt;
&lt;p&gt;AFAICT Guix offers (almost) the same immutability features and
drawbacks but less pronounced. i.e. you do not have to reboot to make
host software available in most cases. The diffferent profiles allow
much more granular control with several half-way points to find the
right balance of reproducability and creature comfort. Of course this
is also means more opportunity to let it run out of control and create
a confusing mess. In any case I can leverage the GUIX configuration of
my servers and big laptop and ensure a consistent experience if I can
get it on the lil&#x27; macbook and liberate it to fight another day.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;installation-process&quot;&gt;Installation Process&lt;&#x2F;h2&gt;
&lt;p&gt;Installing Ubuntu and Silverblue learned me that there is nothing
specially difficult for the intel mac. It kinda just works with some
small caveats.&lt;&#x2F;p&gt;
&lt;p&gt;A quick hardware check shows a BCM4350 wireless network adapter which
is not on the open hardware list AFAIK, and since the laptop needs to
do laptop duty and has only a single USB-C port WiFi is the only way
to get something in and out of it. Intel graphics should not be a
problem. An intel soundchip. Some Apple NVMe controller (foreshadowing)&lt;&#x2F;p&gt;
&lt;p&gt;So we probably need the nonguix version to support the firmware blobs.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;creating-installation-media&quot;&gt;Creating Installation Media&lt;&#x2F;h3&gt;
&lt;p&gt;Check out on your local friendly Guix enabled device, a foreign
install is fine, checkout the &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;SystemCrafters&#x2F;guix-installer&#x2F;releases&#x2F;tag&#x2F;v202503220148&quot;&gt;SystemCrafters Guix Installer Repo&lt;&#x2F;a&gt;. In
the root of the project is a script &lt;code&gt;build.iso&lt;&#x2F;code&gt;. Run it and have a
walk outside or something. It takes a while. If you have no Guix
enabled machine yet, you can download the last released version, which
is over a year old, so the first &lt;code&gt;guix pull&lt;&#x2F;code&gt; on the macbook will be
epic... .&lt;&#x2F;p&gt;
&lt;p&gt;You&#x27;ll end up with a file &lt;code&gt;guix-installer-202603162333.iso&lt;&#x2F;code&gt; with of
course a probably newer timestamp is spacetime is behaving
consistently in your locati
This can be written to a thumb drive. Ensure you check with &lt;code&gt;dmesg -w&lt;&#x2F;code&gt;
which device the USB stick uses. On insertion you&#x27;ll see&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;shell&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-shell &quot;&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span&gt;$ sudo dmesg -w
&lt;&#x2F;span&gt;&lt;span&gt;... lots of lines skipped
&lt;&#x2F;span&gt;&lt;span&gt;[308042.889695] usb 1-4.3.2: new high-speed USB device number 12 using xhci_hcd
&lt;&#x2F;span&gt;&lt;span&gt;[308043.000238] usb 1-4.3.2: New USB device found, idVendor=0781, idProduct=5572, bcdDevice= 1.00
&lt;&#x2F;span&gt;&lt;span&gt;[308043.000242] usb 1-4.3.2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
&lt;&#x2F;span&gt;&lt;span&gt;[308043.000244] usb 1-4.3.2: Product: Cruzer Switch
&lt;&#x2F;span&gt;&lt;span&gt;[308043.000246] usb 1-4.3.2: Manufacturer: SanDisk
&lt;&#x2F;span&gt;&lt;span&gt;[308043.000247] usb 1-4.3.2: SerialNumber: 4C530001061011107340
&lt;&#x2F;span&gt;&lt;span&gt;[308043.038906] usb-storage 1-4.3.2:1.0: USB Mass Storage device detected
&lt;&#x2F;span&gt;&lt;span&gt;[308043.039031] scsi host2: usb-storage 1-4.3.2:1.0
&lt;&#x2F;span&gt;&lt;span&gt;[308043.039112] usbcore: registered new interface driver usb-storage
&lt;&#x2F;span&gt;&lt;span&gt;[308043.042575] usbcore: registered new interface driver uas
&lt;&#x2F;span&gt;&lt;span&gt;[308044.049756] scsi 2:0:0:0: Direct-Access     SanDisk  Cruzer Switch    1.00 PQ: 0 ANSI: 6
&lt;&#x2F;span&gt;&lt;span&gt;[308044.055625] sd 2:0:0:0: [sda] 62521344 512-byte logical blocks: (32.0 GB&#x2F;29.8 GiB)
&lt;&#x2F;span&gt;&lt;span&gt;[308044.056787] sd 2:0:0:0: [sda] Write Protect is off
&lt;&#x2F;span&gt;&lt;span&gt;[308044.056790] sd 2:0:0:0: [sda] Mode Sense: 43 00 00 00
&lt;&#x2F;span&gt;&lt;span&gt;[308044.057159] sd 2:0:0:0: [sda] Write cache: disabled, read cache: enabled, doesn&amp;#39;t support DPO or FUA
&lt;&#x2F;span&gt;&lt;span&gt;[308044.093399]  sda: sda1 sda2
&lt;&#x2F;span&gt;&lt;span&gt;[308044.093545] sd 2:0:0:0: [sda] Attached SCSI removable disk
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &#x27;[sda]&#x27; on the last lines shows that the USB is now available as
&lt;code&gt;&#x2F;dev&#x2F;sda&lt;&#x2F;code&gt;. Be careful as using your current harddisk by accident will
cause an unscheduled backup&#x2F;restore excercise. To be safe make sure
you use the data which appeared on screen when inserting the
drive. Pull it out and insert it again to be sure.&lt;&#x2F;p&gt;
&lt;p&gt;Also don&#x27;t mount&#x2F;open it if your smart desktop assistent comes asking
helpfully. It only makes things slower and more complicated.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;shell&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-shell &quot;&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span&gt;$ sudo dd if=guix-installer-202603162333.iso of=&#x2F;dev&#x2F;sda bs=1M
&lt;&#x2F;span&gt;&lt;span&gt;$ sync
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;code&gt;bs=1M&lt;&#x2F;code&gt; is to speed things up otherwise it takes forever. Value is
not critical but this is easy to type and _reasonable_™.&lt;&#x2F;p&gt;
&lt;p&gt;This will probably take a &lt;span class=&quot;underline&quot;&gt;refill coffee&lt;&#x2F;span&gt; amount of time to
complete. The `sync` should ensure the buffers are written before
unplugging the device.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;installation-process&quot;&gt;Installation Process&lt;&#x2F;h3&gt;
&lt;p&gt;One of the biggest challenges to start the installation process is to
build a Jenga tower of USB dongles to ensure you can power the macbook
and insert the USB stick. This device only has a single USB-C port, it
dislikes thunderbolt docks or even many USB-C docks. I used a
Steamdeck dock. In practice I assume most of the cheap USB extender
dongles will do it, however I had to experiment before it worked.&lt;&#x2F;p&gt;
&lt;p&gt;You can probably install the OS on whatever capacity is remaining
after all this time, but I would not rely on it and I would not want
to do the crypto setup of the disks with the battery draining like a
&lt;a href=&quot;https:&#x2F;&#x2F;youtu.be&#x2F;DoQwKe0lggw&quot;&gt;James Bond Villain Death Trap&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;I installed it a few times. First without disk encryption. Worked
fine. You follow the prompts.&lt;&#x2F;p&gt;
&lt;p&gt;Then with disk encryption. Worked fine.&lt;&#x2F;p&gt;
&lt;p&gt;I choose separate volumes for &lt;code&gt;root&lt;&#x2F;code&gt; and &lt;code&gt;home&lt;&#x2F;code&gt; formatted in ext4. When encrypting the
volumes using LUKS we now get an interesting issue. During boot up we
are asked 4 times to unlock the drives. Also once we selected the
image to boot in Grub the kernel will ask to unlock the disks, but the
internal laptop keyboard does not work. This can be solved by adding a
USB keyboard to your Jenga Tower and unlock the drives. This get tired
really quickly. For installation it is not a blocker so we plod on.&lt;&#x2F;p&gt;
&lt;p&gt;Also at some point the graphical installer decide that black is the
new orange and show nothing else than that. However the manual
installer is well documented.&lt;&#x2F;p&gt;
&lt;p&gt;Also the installation process for GUIXSD is far less important than
for other distros as you can completely control the OS using `guix
system reconfigure`. So if you can boot in a terminal and get on your
network you&#x27;re golden.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;crypto-setup&quot;&gt;Crypto Setup&lt;&#x2F;h3&gt;
&lt;p&gt;I am going to forget the keyboard issue for now and deal with the
passwords. Because if that is fixed the keyboard does not matter
anymore as once the kernel is fully started it works again.&lt;&#x2F;p&gt;
&lt;p&gt;If you followed along the installer will already have created the
partitioning and LUKS encryption of the volumes. We can use a keyfile
to unlock the partitions but we have to make sure the keyfile is not
exposed on an unencrypted volume. Some people suggest a keyfile on a
USB stick but this is not very practical on this device (think Jenga
tower).&lt;&#x2F;p&gt;
&lt;p&gt;There is no way to pass secrets from Grub to the booting
kernel. However we have access to files in the initial ramdisk. The
GUIX bootloader configuration has the &lt;code&gt;extra-initrd&lt;&#x2F;code&gt; option which was
originally added for this very purpose and adding the keyfile is
explained there.&lt;&#x2F;p&gt;
&lt;p&gt;So the plan is:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;add a key from a keyfile to a slot in the LUKS partitions&lt;&#x2F;li&gt;
&lt;li&gt;wrap the keyfile in a cpio image to merge to the initial ramdisk&lt;&#x2F;li&gt;
&lt;li&gt;configure the mapped devices to use this keyfile&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;add-keyfile-to-initrd&quot;&gt;add keyfile to initrd&lt;&#x2F;h4&gt;
&lt;p&gt;I created a random file&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;shell&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-shell &quot;&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span&gt;$ dd if=&#x2F;dev&#x2F;urandom of=&#x2F;keyfile.bin bs=1 count=512
&lt;&#x2F;span&gt;&lt;span&gt;$ chmod 0400 &#x2F;keyfile.bin
&lt;&#x2F;span&gt;&lt;span&gt;$ echo &#x2F;key-file.bin | cpio -oH newc &amp;gt;&#x2F;key-file.cpio
&lt;&#x2F;span&gt;&lt;span&gt;$ chmod 0000 &#x2F;keyfile.cpio
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;add the keyfile as a key to the LUKS partitions.&lt;&#x2F;p&gt;
&lt;p&gt;Update &lt;code&gt;&#x2F;etc&#x2F;config.scm&lt;&#x2F;code&gt; to add the &lt;code&gt;extra-initrd&lt;&#x2F;code&gt; option to make the file
accessible during early boot.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;scheme&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-scheme &quot;&gt;&lt;code class=&quot;language-scheme&quot; data-lang=&quot;scheme&quot;&gt;&lt;span&gt;(bootloader (bootloader-configuration
&lt;&#x2F;span&gt;&lt;span&gt;               (bootloader grub-efi-bootloader)
&lt;&#x2F;span&gt;&lt;span&gt;               (targets &amp;#39;(&amp;quot;&#x2F;boot&#x2F;efi&amp;quot;))
&lt;&#x2F;span&gt;&lt;span&gt;               (keyboard-layout keyboard-layout)
&lt;&#x2F;span&gt;&lt;span&gt;	              (extra-initrd &amp;quot;&#x2F;key-file.cpio&amp;quot;)))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h4 id=&quot;tell-kernel-to-use-the-keyfile&quot;&gt;Tell kernel to use the keyfile&lt;&#x2F;h4&gt;
&lt;p&gt;To configure the kernel to use the keyfile instead of asking for a
password, we have to add the &lt;code&gt;#:key-file &quot;&#x2F;key-file.bin&quot;&lt;&#x2F;code&gt; to the luks mapping&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;scheme&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-scheme &quot;&gt;&lt;code class=&quot;language-scheme&quot; data-lang=&quot;scheme&quot;&gt;&lt;span&gt;(mapped-devices
&lt;&#x2F;span&gt;&lt;span&gt; (list (mapped-device
&lt;&#x2F;span&gt;&lt;span&gt;        (source (uuid &amp;quot;47642581-ea45-4c53-84c8-d1baf81c70de&amp;quot;))
&lt;&#x2F;span&gt;&lt;span&gt;        (target &amp;quot;my-root&amp;quot;)
&lt;&#x2F;span&gt;&lt;span&gt;        (type luks-device-mapping)
&lt;&#x2F;span&gt;&lt;span&gt;	        (arguments &amp;#39;(#:key-file &amp;quot;&#x2F;key-file.bin&amp;quot;)))
&lt;&#x2F;span&gt;&lt;span&gt;       (mapped-device
&lt;&#x2F;span&gt;&lt;span&gt;        (source (uuid &amp;quot;f2d3ee87-7cc7-4a95-8f4c-1f6c0fa750ee&amp;quot;))
&lt;&#x2F;span&gt;&lt;span&gt;        (target &amp;quot;my-home&amp;quot;)
&lt;&#x2F;span&gt;&lt;span&gt;        (type luks-device-mapping)
&lt;&#x2F;span&gt;&lt;span&gt;	        (arguments &amp;#39;(#:key-file &amp;quot;&#x2F;key-file.bin&amp;quot;)))))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h4 id=&quot;apply-it&quot;&gt;Apply it&lt;&#x2F;h4&gt;
&lt;p&gt;run a &lt;code&gt;guix system reconfigure&lt;&#x2F;code&gt; and reboot and now you will only have to
enter 2x the password. A 50% improvement  ( or 500%, 600% according to
some world leader).&lt;&#x2F;p&gt;
&lt;p&gt;Now why does grub insist in decrypting the &lt;code&gt;&#x2F;home&lt;&#x2F;code&gt; partition?&lt;&#x2F;p&gt;
&lt;p&gt;A quick look in &lt;code&gt;&#x2F;boot&#x2F;grub&#x2F;grub.cfg&lt;&#x2F;code&gt; shows:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;shell&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-shell &quot;&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span&gt;➜ cat &#x2F;boot&#x2F;grub&#x2F;grub.cfg | head
&lt;&#x2F;span&gt;&lt;span&gt;# This file was generated from your Guix configuration.  Any changes
&lt;&#x2F;span&gt;&lt;span&gt;# will be lost upon reconfiguration.
&lt;&#x2F;span&gt;&lt;span&gt;insmod luks
&lt;&#x2F;span&gt;&lt;span&gt;insmod luks2
&lt;&#x2F;span&gt;&lt;span&gt;cryptomount -u 47642581ea454c5384c8d1baf81c70de
&lt;&#x2F;span&gt;&lt;span&gt;cryptomount -u f2d3ee877cc74a958f4c1f6c0fa750ee
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;# Set &amp;#39;root&amp;#39; to the partition that contains &#x2F;gnu&#x2F;store.
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Ok, that explains it. But why?&lt;&#x2F;p&gt;
&lt;p&gt;The manual does not give me any hints. Looking in the source code of
the guix bootloader generator shows that it makes a list of all mapped
devices which have a valid UUID and add it to grub. It throws a
warning when a mapped device uses the regular linux devicename instead
of the UUID as grub cannot find the devices with the linux name. This
makes sense and we can abuse it to get rid of the 2nd password prompt:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;scheme&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-scheme &quot;&gt;&lt;code class=&quot;language-scheme&quot; data-lang=&quot;scheme&quot;&gt;&lt;span&gt;(mapped-devices
&lt;&#x2F;span&gt;&lt;span&gt; (list (mapped-device
&lt;&#x2F;span&gt;&lt;span&gt;        (source (uuid &amp;quot;47642581-ea45-4c53-84c8-d1baf81c70de&amp;quot;))
&lt;&#x2F;span&gt;&lt;span&gt;        (target &amp;quot;my-root&amp;quot;)
&lt;&#x2F;span&gt;&lt;span&gt;        (type luks-device-mapping)
&lt;&#x2F;span&gt;&lt;span&gt;	  (arguments &amp;#39;(#:key-file &amp;quot;&#x2F;key-file.bin&amp;quot;)))
&lt;&#x2F;span&gt;&lt;span&gt;       (mapped-device
&lt;&#x2F;span&gt;&lt;span&gt;        ;;(source (uuid &amp;quot;f2d3ee87-7cc7-4a95-8f4c-1f6c0fa750ee&amp;quot;))
&lt;&#x2F;span&gt;&lt;span&gt;	  (source &amp;quot;&#x2F;dev&#x2F;nvme0n1p3&amp;quot;)
&lt;&#x2F;span&gt;&lt;span&gt;        (target &amp;quot;my-home&amp;quot;)
&lt;&#x2F;span&gt;&lt;span&gt;        (type luks-device-mapping)
&lt;&#x2F;span&gt;&lt;span&gt;	  (arguments &amp;#39;(#:key-file &amp;quot;&#x2F;key-file.bin&amp;quot;)))))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If we replace the UUID with the regular device name, it will no longer
be exported to &lt;code&gt;grub.cfg&lt;&#x2F;code&gt; and the kernel kan still find the device for
mapping it.&lt;&#x2F;p&gt;
&lt;p&gt;A quick reconfigure and reboot later confirms this. I can now remove
the keyboard from the Jenga tower, but that would be cheating.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;fixing-the-keyboard&quot;&gt;Fixing the keyboard&lt;&#x2F;h3&gt;
&lt;p&gt;Some searching in the Guix mailing list showed that &quot;hid_apple&quot; was
removed from the standard initrd somewhere in &#x27;24 because of issues
with RISCV.&lt;&#x2F;p&gt;
&lt;p&gt;That is where the &lt;code&gt;initrd-modules&lt;&#x2F;code&gt; option is for:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;scheme&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-scheme &quot;&gt;&lt;code class=&quot;language-scheme&quot; data-lang=&quot;scheme&quot;&gt;&lt;span&gt;(operating-system
&lt;&#x2F;span&gt;&lt;span&gt;  ...
&lt;&#x2F;span&gt;&lt;span&gt;  (initrd-modules (cons &amp;quot;hid_apple&amp;quot; %base-initrd-modules))
&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This fixes the issue. I forgot how I tested it, but it does.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;post-installation&quot;&gt;Post Installation&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;system-does-not-allow-to-login-after-sleep&quot;&gt;System does not allow to login after sleep&lt;&#x2F;h3&gt;
&lt;p&gt;Actually the problem is that the disk is still sleeping (remember the
foreshadowing when seeing the Apple NVMe device). This is not GUIX
specific as I already had to fix it in Ubuntu and Fedora. There you
add&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;shell&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-shell &quot;&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span&gt;echo 0 &amp;gt;&#x2F;sys&#x2F;bus&#x2F;pci&#x2F;devices&#x2F;0000\:01\:00.0&#x2F;d3cold_allowed
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;in the &lt;code&gt;crontab&lt;&#x2F;code&gt; on the &lt;code&gt;@reboot&lt;&#x2F;code&gt; event.&lt;&#x2F;p&gt;
&lt;p&gt;This syntax is not supported by the herd scheduled jobs and I did not
find an alternative and got no suggestions on the #guix IRC
channel. So I decided to make a small shepherd service for this.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;shell&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-shell &quot;&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span&gt;(define disk-sleep-shepherd-service
&lt;&#x2F;span&gt;&lt;span&gt;  (shepherd-service
&lt;&#x2F;span&gt;&lt;span&gt;   (provision &amp;#39;(disk-sleep))
&lt;&#x2F;span&gt;&lt;span&gt;   (documentation &amp;quot;Disallow disk to go to d3cold state to prevent crash on wake up.&amp;quot;)
&lt;&#x2F;span&gt;&lt;span&gt;   (one-shot? #t)
&lt;&#x2F;span&gt;&lt;span&gt;   (start #~(lambda _
&lt;&#x2F;span&gt;&lt;span&gt;	       (call-with-output-file &amp;quot;&#x2F;sys&#x2F;bus&#x2F;pci&#x2F;devices&#x2F;0000:01:00.0&#x2F;d3cold_allowed&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;		 (lambda (port) (display &amp;quot;0&amp;quot; port)))
&lt;&#x2F;span&gt;&lt;span&gt;	       #t))))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The only part I struggled with is that the &lt;code&gt;start&lt;&#x2F;code&gt; field takes a
function with a variable number of arguments. The &lt;code&gt;&#x2F;var&#x2F;log&#x2F;messages&lt;&#x2F;code&gt;
registered the error but was not very helpful. Herd did not show the
service at all until it was fixed. Comparing to other implementation
gave the needed clues.&lt;&#x2F;p&gt;
&lt;p&gt;To add this to the system:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;scheme&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-scheme &quot;&gt;&lt;code class=&quot;language-scheme&quot; data-lang=&quot;scheme&quot;&gt;&lt;span&gt;(operating-system
&lt;&#x2F;span&gt;&lt;span&gt; ...
&lt;&#x2F;span&gt;&lt;span&gt; (services
&lt;&#x2F;span&gt;&lt;span&gt;  ...
&lt;&#x2F;span&gt;&lt;span&gt;  (simple-service &amp;#39;disk-sleep-service shepherd-root-service-type
&lt;&#x2F;span&gt;&lt;span&gt;	  (list disk-sleep-shepherd-service))
&lt;&#x2F;span&gt;&lt;span&gt;  ...
&lt;&#x2F;span&gt;&lt;span&gt;  ))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;sound-no-sound-from-speakers-dot&quot;&gt;Sound : no sound from speakers.&lt;&#x2F;h3&gt;
&lt;p&gt;There is no sound coming from the speakers.&lt;&#x2F;p&gt;
&lt;p&gt;There is sound coming from the headphone jack. Good enough for use in
the living.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ll call this a feature, not a bug.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;things-i-would-do-differently&quot;&gt;Things I would do differently&lt;&#x2F;h2&gt;
&lt;p&gt;Basically use btrfs to have a single encrypted LUKS volume to deal with and
split the volumes in btrfs. That would also give the other goodness of
btrfs and should be well supported by grub.&lt;&#x2F;p&gt;
&lt;p&gt;But for now I&#x27;ll enjoy my new couch laptop.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Screenshot in Sway with GUIX</title>
          <pubDate>Sat, 25 Oct 2025 14:19:00 +0200</pubDate>
          <author>Peter Tillemans</author>
          <link>https://www.snamellit.com/posts/20251025t141904-screenshot-in-sway-with-guix-guix-linux/</link>
          <guid>https://www.snamellit.com/posts/20251025t141904-screenshot-in-sway-with-guix-guix-linux/</guid>
          <description xml:base="https://www.snamellit.com/posts/20251025t141904-screenshot-in-sway-with-guix-guix-linux/">&lt;h2 id=&quot;screenshots-in-sway-with-guix-home-manager&quot;&gt;Screenshots in Sway with Guix Home Manager&lt;&#x2F;h2&gt;
&lt;p&gt;A &lt;a href=&quot;https:&#x2F;&#x2F;kaibreucker.dev&#x2F;en&#x2F;content&#x2F;foss&#x2F;sway&#x2F;screenshots&#x2F;&quot;&gt;blog post&lt;&#x2F;a&gt; documented an elegant way to configure screenshots in
wayland using &lt;strong&gt;grim&lt;&#x2F;strong&gt; and &lt;strong&gt;grimshot&lt;&#x2F;strong&gt;. After moving my sway config to use
the &lt;strong&gt;GUIX&lt;&#x2F;strong&gt; &lt;code&gt;sway-service&lt;&#x2F;code&gt; to generate the config file Iost my configured
screenshot bindings.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;output-files&quot;&gt;Output Files&lt;&#x2F;h3&gt;
&lt;p&gt;The screenshots will be placed  in the &lt;code&gt;Pictures&#x2F;screenshots&lt;&#x2F;code&gt; folder
with the timestamp as filename.  To avoid duplication and ensure
consistency we&#x27;ll add  a variable to generate the filename&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;scheme&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-scheme &quot;&gt;&lt;code class=&quot;language-scheme&quot; data-lang=&quot;scheme&quot;&gt;&lt;span&gt;(sway-configuration
&lt;&#x2F;span&gt;&lt;span&gt;  (variables (append %sway-default-variables
&lt;&#x2F;span&gt;&lt;span&gt;		     `((menu .  ,#~(string-append
&lt;&#x2F;span&gt;&lt;span&gt;                                    #$fuzzel
&lt;&#x2F;span&gt;&lt;span&gt;                                    &amp;quot;&#x2F;bin&#x2F;fuzzel&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;                                    &amp;quot; -w 50 -x 8 -y 8 -r 3 -b 232635ff -t A6Accdff -s A6Accdff -S 232635ff -C c792eacc -m c792eacc -f \&amp;quot;JetBrains Mono:weight=light:size=10\&amp;quot; --icon-theme=\&amp;quot;Papirus-Dark\&amp;quot; --no-exit-on-keyboard-focus-loss&amp;quot;))
&lt;&#x2F;span&gt;&lt;span&gt;		       (term . ,(file-append alacritty &amp;quot;&#x2F;bin&#x2F;alacritty&amp;quot;))
&lt;&#x2F;span&gt;&lt;span&gt;		       (screenshot_out . &amp;quot;$(xdg-user-dir PICTURES)&#x2F;screenshots&#x2F;$(date +\&amp;quot;%Y%m%d-%H%M%S\&amp;quot;).png&amp;quot;))
&lt;&#x2F;span&gt;&lt;span&gt;		     ))
&lt;&#x2F;span&gt;&lt;span&gt;  ...)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;key-bindings&quot;&gt;Key Bindings&lt;&#x2F;h3&gt;
&lt;p&gt;I often use various screenshots pasted in chat windows or Jira tickets
so the clipboard is an important destination.
Alternatively saving them to move them to a target folder for
inclusion whereverr they needed is an important secondary use-case.&lt;&#x2F;p&gt;
&lt;p&gt;We can now use the variable made previously and add the following keybindings:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;scheme&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-scheme &quot;&gt;&lt;code class=&quot;language-scheme&quot; data-lang=&quot;scheme&quot;&gt;&lt;span&gt;(sway-configuration
&lt;&#x2F;span&gt;&lt;span&gt;	    ...
&lt;&#x2F;span&gt;&lt;span&gt;	    (keybindings (append
&lt;&#x2F;span&gt;&lt;span&gt;			  `(...
&lt;&#x2F;span&gt;&lt;span&gt;			    ;; Special key to take a screenshot with grim
&lt;&#x2F;span&gt;&lt;span&gt;			    ($mod+Shift+p . &amp;quot;exec grimshot copy anything&amp;quot;)
&lt;&#x2F;span&gt;&lt;span&gt;			    ($mod+Shift+s . &amp;quot;exec grimshot save screen $screenshot_out&amp;quot;)
&lt;&#x2F;span&gt;&lt;span&gt;			    ($mod+Shift+w . &amp;quot;exec grimshot save window $screenshot_out&amp;quot;)
&lt;&#x2F;span&gt;&lt;span&gt;			    ($mod+Shift+a . &amp;quot;exec grimshot save area $screenshot_out&amp;quot;)
&lt;&#x2F;span&gt;&lt;span&gt;			    ...
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;			    )
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;deploying-the-configuration&quot;&gt;Deploying the configuration&lt;&#x2F;h2&gt;
&lt;p&gt;To activate the configuration&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;shell&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-shell &quot;&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span&gt;$ make home
&lt;&#x2F;span&gt;&lt;span&gt;echo Loading modules from ~&#x2F;.config&#x2F;dotfiles&#x2F;guix&#x2F;src
&lt;&#x2F;span&gt;&lt;span&gt;Loading modules from &#x2F;home&#x2F;pti&#x2F;.config&#x2F;dotfiles&#x2F;guix&#x2F;src
&lt;&#x2F;span&gt;&lt;span&gt;guix home reconfigure -L ~&#x2F;.config&#x2F;dotfiles&#x2F;guix&#x2F;channel -c 32 ~&#x2F;.config&#x2F;dotfiles&#x2F;guix&#x2F;home-config-`hostname | cut -d. -f1`.scm
&lt;&#x2F;span&gt;&lt;span&gt;...
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;which quickly (for some value of quick) updates the home
configuration, writing a new &lt;strong&gt;~&#x2F;.config&#x2F;sway&#x2F;config&lt;&#x2F;strong&gt; file.&lt;&#x2F;p&gt;
&lt;p&gt;When the prompt returns a quick reload of the sway config with
&lt;code&gt;$mod+Shift+c&lt;&#x2F;code&gt; and testing if the modifications are active.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;testing-it-out&quot;&gt;Testing it Out&lt;&#x2F;h2&gt;
&lt;p&gt;I opened libre office writer to paste copied screenshots and made a
mess to show the &lt;code&gt;copy anything&lt;&#x2F;code&gt; works as expected. It does, it
highlights what it understands depending on your mouse location, a
window if hovering over a window, a rectangle if you start selecting
and all the screen if you move the mouse outside all windows (i.e. the
boundary on a tiling wm). It is a bit fiddly so sometimes I select the
wrong thing, but since it only clobbers the clipboard and I can
quickly try again, this seems reasonable.&lt;&#x2F;p&gt;
&lt;p&gt;Similarly using the 3 other bindings to save different type of
screenshots.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;shell&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-shell &quot;&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span&gt;  $ ls ~&#x2F;Pictures&#x2F;screenshots&#x2F;
&lt;&#x2F;span&gt;&lt;span&gt;20251025-141106.png  20251025-145006.png  20251025-145019.png
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Cool, that made a mess in the folder and &lt;strong&gt;displaying&lt;&#x2F;strong&gt; them show that it
are actually screenshots. Cool.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Consolidating Secrets in Pass</title>
          <pubDate>Sat, 28 Jun 2025 13:15:00 +0200</pubDate>
          <author>Peter Tillemans</author>
          <link>https://www.snamellit.com/posts/20250628t131556-consolidating-secrets-in-pass-emacs-linux-security/</link>
          <guid>https://www.snamellit.com/posts/20250628t131556-consolidating-secrets-in-pass-emacs-linux-security/</guid>
          <description xml:base="https://www.snamellit.com/posts/20250628t131556-consolidating-secrets-in-pass-emacs-linux-security/">&lt;h2 id=&quot;background&quot;&gt;Background&lt;&#x2F;h2&gt;
&lt;p&gt;Like a lot of people I&#x27;ve had  a long history managing passwords and
secrets over the years.  From a little black book, over an Excel sheet,
using a GPG encoded secrets file (works really well with Emacs gpg
support), 1password (till they racked up their prices), lastpass (till
they got bought by the Evil LogMeIn Corp), KeepassXC and lately &lt;a href=&quot;https:&#x2F;&#x2F;passwordstore.org&quot;&gt;pass&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;I was perfectly happy with KeepassXC for a very long time, except for
the command line integration.  So I kept ending up with passwords in
&lt;strong&gt;.envrc&lt;&#x2F;strong&gt; files in folders and excluded in the global &lt;strong&gt;.gitignore&lt;&#x2F;strong&gt; to avoid
too many red cheeks.  While this does keep secrets out of harms way
mostly, it kept nagging that I had them in plain text in those
files.  In theory there is &lt;strong&gt;keepassxc-cli&lt;&#x2F;strong&gt; to query the passwords from
the command line, but let&#x27;s say the experience does not spark joy.  It
has no easy way to cache the password between calls and it is
optimized for interactive use.  (AFAICT, just the giant size of the
command to type gives me dread).&lt;&#x2F;p&gt;
&lt;p&gt;Some day I stumbled over &lt;strong&gt;pass&lt;&#x2F;strong&gt; and found that after setup I could just
&lt;code&gt;pass snamellit&#x2F;website&lt;&#x2F;code&gt; to get the password on stdout.  I &lt;a href=&quot;https:&#x2F;&#x2F;www.snamellit.com&#x2F;blog&#x2F;20240624t104859-secrets-management-using-unix-password-store-pass-linux-osx-sysadmin&#x2F;&quot;&gt;wrote about
the setup and emacs integration in a previous post&lt;&#x2F;a&gt;. Since it
leverage gpg, password caching is handled by the gpg-agent and my
&lt;strong&gt;.envrc&lt;&#x2F;strong&gt; files quickly were purged of blasphemous secrets, replace by
pure bliss:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;export &lt;&#x2F;span&gt;&lt;span&gt;MY_SECRET&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;=$&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;pass&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt; my&#x2F;secret)
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;export &lt;&#x2F;span&gt;&lt;span&gt;OTHER_SECRET&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;=$&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;pass&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt; other&#x2F;secret)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;similarly in emacs I can consistently get my passwords and related
info with:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;lisp&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-lisp &quot;&gt;&lt;code class=&quot;language-lisp&quot; data-lang=&quot;lisp&quot;&gt;&lt;span&gt;(org&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;gcal&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;client&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;id (auth&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;source&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;pass&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;get&lt;&#x2F;span&gt;&lt;span&gt; &amp;#39;secret &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;snamellit&#x2F;org-gcal-client&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;))
&lt;&#x2F;span&gt;&lt;span&gt;(org&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;gcal&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;client&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;secret (auth&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;source&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;pass&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;get &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;id&amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;snamellit&#x2F;org-gcal-client&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;When needed the &lt;strong&gt;gpg-agent&lt;&#x2F;strong&gt; will launch the appropriate pin-entry
program whether in terminal or in the GUI and the caching will not
force me to login several times when entering the folder.&lt;&#x2F;p&gt;
&lt;p&gt;So I ended up with my interactive use covered by &lt;strong&gt;KeepassXC&lt;&#x2F;strong&gt; and
automated use by &lt;strong&gt;pass&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;However, after some time I ended up with hundreds of secrets in
&lt;strong&gt;KeepassXC&lt;&#x2F;strong&gt;, hundreds in &lt;strong&gt;pass&lt;&#x2F;strong&gt;, it is not always clear whether use is
interactive or automated so confusion and duplication starts and
things become harder to manage.  In addition &lt;strong&gt;KeepassXC&lt;&#x2F;strong&gt; was using
historically Dropbox to make it available on all my devices, recently
migrated to Nextcloud, which has issues with dealing with conflicts
which occasionally bite me in the behind.  On the other hand &lt;strong&gt;pass&lt;&#x2F;strong&gt;
secrets are stored encrypted in git where conflict punch you in the
face.  I prefer the latter.  And started contemplating whether to move
everything to pass.&lt;&#x2F;p&gt;
&lt;p&gt;Thanks to the encouragement of SummerEmacs, one of the more
enthusiastic SystemCrafters, ensuring the great experience in browsers
and iOS mobile devices I had no more excuses to keep postponing it.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;preparation&quot;&gt;Preparation&lt;&#x2F;h2&gt;
&lt;p&gt;I started out with keeping my pass passwords as part of my
dotfiles.   This was convenient when they were few.  However this is
&lt;span class=&quot;underline&quot;&gt;weird&lt;&#x2F;span&gt; so this will attract &lt;span class=&quot;underline&quot;&gt;weirdness&lt;&#x2F;span&gt; when configuring all integrations
I&#x27;ll need.&lt;&#x2F;p&gt;
&lt;p&gt;Also &lt;strong&gt;pass&lt;&#x2F;strong&gt; supports a &lt;strong&gt;git&lt;&#x2F;strong&gt; command to manage the password-store with git
which is not really useful when it is part of something else.   So the
first order of the day is to move all secrets to a separate repository
and update the &lt;strong&gt;dotfiles&lt;&#x2F;strong&gt; to check for presence and clone the repo if
missing (and do a gently pull when it is).
A quick visit to each of the machines in my machine park to apply this
change.
Everything still seems to be working.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;migration-of-the-keepassxc-data&quot;&gt;Migration of the KeepassXC data&lt;&#x2F;h2&gt;
&lt;p&gt;I used the &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;roddhjav&#x2F;pass-import&quot;&gt;pass-import&lt;&#x2F;a&gt; tool which adds in &lt;strong&gt;import&lt;&#x2F;strong&gt; command to pass which
supports a crazy amount of password managers, including keepassxc.  For
keepassxc it need the &lt;strong&gt;pykeepass&lt;&#x2F;strong&gt;.  If you&#x27;re running on Arch, everything
is a &lt;code&gt;yay -S&lt;&#x2F;code&gt; away.  However on Ubuntu and its derivatives it is the
usual slog we start to get accustomed to.  It&#x27;s all in the &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;roddhjav&#x2F;pass-import&quot;&gt;pass-import
README&lt;&#x2F;a&gt; , note that on Ubunty the &lt;strong&gt;pykeepass&lt;&#x2F;strong&gt; library is available with
&lt;code&gt;apt install python3-pykeepass&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Once it is installed I tried  a dry run (with the &lt;code&gt;-d&lt;&#x2F;code&gt; flag) to see if
basic functionality is working&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;pass&lt;&#x2F;span&gt;&lt;span&gt; import -a -d keepassxc &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;~&lt;&#x2F;span&gt;&lt;span&gt;&#x2F;Nextcloud&#x2F;Apps&#x2F;Keepassxc&#x2F;Passwords.kdbx
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;Password&lt;&#x2F;span&gt;&lt;span&gt; for &#x2F;home&#x2F;pti&#x2F;Nextcloud&#x2F;Apps&#x2F;Keepassxc&#x2F;Passwords.kdbx:
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;w&lt;&#x2F;span&gt;&lt;span&gt;  Data would be imported from keepassxc to pass
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;   Passwords imported from: &#x2F;home&#x2F;pti&#x2F;Nextcloud&#x2F;Apps&#x2F;Keepassxc&#x2F;Passwords.kdbx
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;   Passwords exported to: &#x2F;home&#x2F;pti&#x2F;.password-store
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;   Number of password imported: 2035
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;   All data imported
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;w&lt;&#x2F;span&gt;&lt;span&gt;  Weak password detected: eDGQqipE might be weak.  Score 2 (100000001 guesses)&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;  This estimate is based on the sequence eDGQqipE(bruteforce)
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;w&lt;&#x2F;span&gt;&lt;span&gt;  Weak password detected: eDGQqipE might be weak.  Score 2 (100000001 guesses)&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;  This estimate is based on the sequence eDGQqipE(bruteforce)
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;w&lt;&#x2F;span&gt;&lt;span&gt;  Weak password detected: eDGQqipE might be weak.  Score 2 (100000001 guesses)&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;  This estimate is based on the sequence eDGQqipE(bruteforce)
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;...&lt;&#x2F;span&gt;&lt;span&gt;  large list of names of secrets
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This asks for the password of the Keepass file and some remarks it
has.&lt;&#x2F;p&gt;
&lt;p&gt;This all looks reasonable.  So we can try the import.  Since the
password-store is a git repo no real damage can be done to it (as it
is safely pushed somewhere else where the import tool cannot touch it)
and any damage done can be reverted....&lt;&#x2F;p&gt;
&lt;p&gt;Now is a good time to check if the mooring lines of your laptop are
properly secured as encrypting all the secrets will spin up the
propellors if the number is large enough.&lt;&#x2F;p&gt;
&lt;p&gt;I run it again without the &lt;code&gt;-d&lt;&#x2F;code&gt; flag and after several minutes the
noise dies down and I am left with a lot of additional folders in my
&lt;code&gt;~&#x2F;.password-store&lt;&#x2F;code&gt; which match the grouping in KeepassXC.  The files
contain the secrets and the expected metadata.  This looks good so I
add&#x2F;commit the things to complete the level.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;integration-with-ios-for-my-iphone&quot;&gt;Integration with iOS for my iPhone&lt;&#x2F;h2&gt;
&lt;p&gt;Let&#x27;s start with the most scary one : the iPhone.&lt;&#x2F;p&gt;
&lt;p&gt;Upon recommendation I had installed &lt;strong&gt;passforios&lt;&#x2F;strong&gt; which needs to be
configured.&lt;&#x2F;p&gt;
&lt;p&gt;Configuring the host, repo and username to use for the git repository
is straightforward enough.&lt;&#x2F;p&gt;
&lt;p&gt;I always use ssh to access my repos so we need to add an ssh keypair
for this purpose.  There is no support to generate key-pairs in
passforios for reasons, so I have to do it externally and upload the
key. A quick &lt;code&gt;ssh-keygen&lt;&#x2F;code&gt; , uploading the public key to the forge,
allowing access to the repo and if I can get the private key on my
phone we can access the repo.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;passforios&lt;&#x2F;strong&gt; has a nice feature to load ascii armored keys via a QR
code. A bit digging surfaced the &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;yishilin14&#x2F;asc-key-to-qr-code-gif&quot;&gt;asc-key-to-qr-code-gif tool&lt;&#x2F;a&gt; which
was made for this specific purpose. The ssh key is already in the
appropriate format so this can be directly converted&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;.&#x2F;asc-to-gif.sh &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;~&lt;&#x2F;span&gt;&lt;span&gt;&#x2F;.ssh&#x2F;id-passforios ssh-pub.gif
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;display&lt;&#x2F;span&gt;&lt;span&gt; ssh-pub.gif
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Then go to the repository settings, press the circled i  on the &lt;strong&gt;SSH
Key&lt;&#x2F;strong&gt; button, select the ASCII-Armor Key and click to scan the QR
code. Point the camera to the QR code on the screen and it should
appear in the key field in the app.&lt;&#x2F;p&gt;
&lt;p&gt;We have to repeat this 2 more times to get the private and public key
for the password-store into the app. First exporting the keys&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;gpg&lt;&#x2F;span&gt;&lt;span&gt; --export -a 1234ABCD &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;gpg.pub
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;gpg&lt;&#x2F;span&gt;&lt;span&gt; --export-secret-key -a 1234ABCD &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;gpg.key
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;converting to a gif, displaying them and scanning them in *Settings -&amp;gt;
PGP Key -&amp;gt; ASCII-Armor Key in the respective fields.&lt;&#x2F;p&gt;
&lt;p&gt;If, after synching, you go now to the Passwords you should be greeted
with a listing of all folders and keys and the secrets should be
visible if made visible by tapping the eye icon.&lt;&#x2F;p&gt;
&lt;p&gt;I needed to enable &lt;strong&gt;passforios&lt;&#x2F;strong&gt; as a source for autofill : Settings -&amp;gt;
Passwords -&amp;gt; Autofill Passwords and slide the toggle for &lt;strong&gt;Pass&lt;&#x2F;strong&gt;. I also
disabled the toggle for &lt;strong&gt;Strongbox&lt;&#x2F;strong&gt; which I was using for integration
with the Keepass database.&lt;&#x2F;p&gt;
&lt;p&gt;Now I see the option to select the secrets from the &lt;strong&gt;passforios&lt;&#x2F;strong&gt; app. It
does not narrow down to the right key, but that is a problem for
future me.&lt;&#x2F;p&gt;
&lt;p&gt;Ok, the hard part is done. Or at least the most risky part, ... in my
eyes... whatever. Moving on...&lt;&#x2F;p&gt;
&lt;h2 id=&quot;integration-with-firefox&quot;&gt;Integration with FireFox&lt;&#x2F;h2&gt;
&lt;p&gt;Checking at the bottom of the &lt;a href=&quot;https:&#x2F;&#x2F;www.passwordstore.org&#x2F;&quot;&gt;pass website&lt;&#x2F;a&gt; we find that &lt;strong&gt;passff&lt;&#x2F;strong&gt; is the
good stuff for integration with FireFox.  From previous adventures with
KeepassXC and NativeMessaging I assumed there had to be a host part to
be installed too.&lt;&#x2F;p&gt;
&lt;p&gt;Indeed we are directed to the &lt;a href=&quot;https:&#x2F;&#x2F;codeberg.org&#x2F;PassFF&#x2F;passff-host&quot;&gt;passff-host github repo&lt;&#x2F;a&gt; to get an
install-script which generates the native messaging json for the
different browsers and a small executable python script which contains
remarkable clean and no-dependency code.  Similarly the install script
is straightforward. I do not understand why it support half a dozen
browser, mostly chrome based as for the life of me I cannot find an
extension which uses this host program.  So either I need bigger
glasses or there is some knowledge beyond my grasp.&lt;&#x2F;p&gt;
&lt;p&gt;Running the installer, installing the extension, restarting firefox
for good luck and the extension appears and offers passwords on the
sites I try.&lt;&#x2F;p&gt;
&lt;p&gt;Out of curiosity I check the configuration in
~.mozilla&#x2F;native-messaging :&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;pti@tuxedo &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;~&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; ls .mozilla&#x2F;native-messaging-hosts&#x2F;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;org.keepassxc.keepassxc_browser.json&lt;&#x2F;span&gt;&lt;span&gt;  passff.json  passff.py&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;*
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;pti@tuxedo &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;~&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; cat .mozilla&#x2F;native-messaging-hosts&#x2F;passff.json
&lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;name&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;passff&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;description&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;Host for communicating with zx2c4 pass&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;path&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;&#x2F;home&#x2F;pti&#x2F;.mozilla&#x2F;native-messaging-hosts&#x2F;passff.py&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;type&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;stdio&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;allowed_extensions&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;[ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;passff@invicem.pro&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;]
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;pti@tuxedo &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;~&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; cat .mozilla&#x2F;native-messaging-hosts&#x2F;passff.py
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#616e88;&quot;&gt;#!&#x2F;usr&#x2F;bin&#x2F;python3
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;&amp;quot;&amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;    Host application of the browser extension PassFF
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;    that wraps around the zx2c4 pass script.
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;&amp;quot;&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; json
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;...
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Nothing out of the ordinary, the passff.py python is the same as in
the repo.  My old keepassxc extension support is still there.&lt;&#x2F;p&gt;
&lt;p&gt;Firefox is installed natively on this machine, not with a flatpak
which I assume will come with its own challenges.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;chromium-support&quot;&gt;Chromium Support&lt;&#x2F;h2&gt;
&lt;p&gt;Time to tackle the Chrome family. Chrome is required to put food on
the table so we have to get that going eventually. But Chrome is
distributed as a flatpak (or a snap but I am &lt;strong&gt;NOT&lt;&#x2F;strong&gt; going to deal with
that), and I can install Chromium natively, and apparently native
installs are &lt;strong&gt;MUCH&lt;&#x2F;strong&gt; better supported than the versions in wrappers so
let&#x27;s start with that one first.&lt;&#x2F;p&gt;
&lt;p&gt;From the &lt;a href=&quot;https:&#x2F;&#x2F;www.passwordstore.org&#x2F;&quot;&gt;pass website&lt;&#x2F;a&gt; we find that &lt;strong&gt;&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;browserpass&#x2F;browserpass-extension&quot;&gt;browserpass&lt;&#x2F;a&gt;&lt;&#x2F;strong&gt; is the way to go for
the chrome family. The browser extension installs from the usual
places without drama and starts promptly complaining it cannot find
the native host to talk to.&lt;&#x2F;p&gt;
&lt;p&gt;The native host in question is from &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;browserpass&#x2F;browserpass-native&quot;&gt;the browsaerpass-native sister
repo&lt;&#x2F;a&gt; . As usual for all distro&#x27;s there are packages ready to install
but because Ubuntu-derivative I can compile from source. Downloading
the source for version 3.1.0 from the &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;browserpass&#x2F;browserpass-native&#x2F;releases&quot;&gt;releases page&lt;&#x2F;a&gt;. Again this repo
refers to all browsers including firefox although I cannot for the
life of me find a Firefox Extension supporting this host app.&lt;&#x2F;p&gt;
&lt;p&gt;Then building and installing timelapse :&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;tar&lt;&#x2F;span&gt;&lt;span&gt; -xzvf &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;~&lt;&#x2F;span&gt;&lt;span&gt;&#x2F;Downloads&#x2F;browserpass-native-3.1.0.tar.gz
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;cd&lt;&#x2F;span&gt;&lt;span&gt; browserpass-native-3.1.0
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;ls
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;less&lt;&#x2F;span&gt;&lt;span&gt; README.md
&lt;&#x2F;span&gt;&lt;span&gt;PREFIX&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&#x2F;usr&#x2F;local &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;make&lt;&#x2F;span&gt;&lt;span&gt; configure
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;span&gt; make PREFIX=&#x2F;usr&#x2F;local install
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;which&lt;&#x2F;span&gt;&lt;span&gt; browserpass
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;which shows the executable lives at &lt;code&gt;&#x2F;usr&#x2F;local&#x2F;bin&#x2F;browserpass&lt;&#x2F;code&gt; and
this totally went fine the first time (NOT!!!!).&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;Makefile&lt;&#x2F;code&gt; has support to install the magic json to enable native
messaging for the different browsers.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span&gt;PREFIX&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&#x2F;usr&#x2F;local &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;make&lt;&#x2F;span&gt;&lt;span&gt; hosts-chromium-user
&lt;&#x2F;span&gt;&lt;span&gt;PREFIX&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&#x2F;usr&#x2F;local &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;make&lt;&#x2F;span&gt;&lt;span&gt; hosts-chrome-user
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The second invocation is a hail-mary because I already know the Chrome
flatpak does not look in the same places and will require some
additional finnagling&lt;&#x2F;p&gt;
&lt;p&gt;For now focus on Chromium and check if the configuration looks
reasonable:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;pti@tuxedo &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;~&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; cd .config&#x2F;chromium&#x2F;NativeMessagingHosts&#x2F;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;pti@tuxedo &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;~&lt;&#x2F;span&gt;&lt;span&gt;&#x2F;.c&#x2F;c&#x2F;NativeMessagingHosts&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; ls
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;com.github.browserpass.native.json@
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;pti@tuxedo &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;~&lt;&#x2F;span&gt;&lt;span&gt;&#x2F;.c&#x2F;c&#x2F;NativeMessagingHosts&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; cat com.github.browserpass.native.json
&lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;name&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;com.github.browserpass.native&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;description&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;Browserpass native component for the Chromium extension&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;path&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;&#x2F;usr&#x2F;local&#x2F;bin&#x2F;browserpass&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;type&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;stdio&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;allowed_origins&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;chrome-extension:&#x2F;&#x2F;naepdomgkenhinolocfifgehidddafch&#x2F;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;chrome-extension:&#x2F;&#x2F;pjmbgaakjkbhpopmakjoedenlfdmcdgm&#x2F;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;chrome-extension:&#x2F;&#x2F;klfoddkbhleoaabpmiigbmpbjfljimgb&#x2F;&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;]
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Cool, the executable is looked at where it is installed (this is not
obvious, don&#x27;t ask how I know). The rest looks also like how these
things should look. Let&#x27;s try...&lt;&#x2F;p&gt;
&lt;p&gt;The extension settings page is no longer complaining the native host
is missing and there are password entries visible. Checking with some
website shows the password is injected. yay!.&lt;&#x2F;p&gt;
&lt;p&gt;Level complete, ready for the final boss.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;enabling-chrome-support-now-with-more-flatpak&quot;&gt;Enabling Chrome Support, now with more Flatpak!&lt;&#x2F;h2&gt;
&lt;p&gt;Ok, we have a working chromium support so repo access, host app,
native host configuration et al are proven working. We can only focus
on jumping over the Flatpak Firewall...&lt;&#x2F;p&gt;
&lt;p&gt;As a good cargo cultist I do a literature study and find that I should&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;find the config location of the flatpak app&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;use &lt;code&gt;flatpak-spawn&lt;&#x2F;code&gt; to spawn the native messaging host app&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;enable D-Bus Session socket access for chrome&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Package up the calling of the host app in a single script to
configure in the json.&lt;&#x2F;p&gt;
&lt;p&gt;Not necessarily in that order....&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;For the permission to access D-Bus Session start up &lt;strong&gt;flatseal&lt;&#x2F;strong&gt; from
flathub, navigate to &lt;strong&gt;com.google.Chrome&lt;&#x2F;strong&gt; and enable the D-Bus Session
socket. This should be possible with some additional cursing in the
manifest file of Chrome. I cannot find decent reference documentation
in a reasonable time, so &lt;strong&gt;flatseal&lt;&#x2F;strong&gt; it is.&lt;&#x2F;p&gt;
&lt;p&gt;The configuration of the flatpak app is easy too, painful experience
seared in my brain that flatpaks look in  &lt;strong&gt;~&#x2F;.var&#x2F;app&#x2F;&lt;&#x2F;strong&gt; folder so for
Chrome this will be &lt;strong&gt;~&#x2F;.var&#x2F;app&#x2F;com.google.Chrome&lt;&#x2F;strong&gt; . From the hail-mary
install for chrome done above I know that it just creates a symbolic
link to
&lt;strong&gt;&#x2F;usr&#x2F;local&#x2F;lib&#x2F;browserpass&#x2F;hosts&#x2F;chromium&#x2F;com.github.browserpass.native&lt;&#x2F;strong&gt;
so we can start from there. We will have to edit that so copy it. We
also need a wrapper to call the native host app&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;cd &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;~&lt;&#x2F;span&gt;&lt;span&gt;&#x2F;.var&#x2F;app&#x2F;com.google.Chrome&#x2F;config&#x2F;google-chrome&#x2F;NativeMessagingHosts
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;cp&lt;&#x2F;span&gt;&lt;span&gt; &#x2F;usr&#x2F;local&#x2F;lib&#x2F;browserpass&#x2F;hosts&#x2F;chromium&#x2F;com.github.browserpass.native
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;ec&lt;&#x2F;span&gt;&lt;span&gt; browserpass.sh
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Add the content of the wrapper&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#616e88;&quot;&gt;#!&#x2F;bin&#x2F;sh
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;cd &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;~
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;&#x2F;usr&#x2F;bin&#x2F;flatpak-spawn&lt;&#x2F;span&gt;&lt;span&gt; --host &#x2F;usr&#x2F;local&#x2F;bin&#x2F;browserpass &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;&#x2F;tmp&#x2F;browserpass-error.log
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I added the optional redirect of &lt;strong&gt;stderr&lt;&#x2F;strong&gt; to an error logfile because
from experience I know nothing ever goes wrong if you enable error
reporting beforehand.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;chmod&lt;&#x2F;span&gt;&lt;span&gt; +x browserpass.sh
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;pwd
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;pwd &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;| &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;wl-copy
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;ec&lt;&#x2F;span&gt;&lt;span&gt; com.github.browserpass.native.json
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Installing the browserpass extension in Chrome after restarting it (I
am not superstitious, just careful) and I can bask in the glory of
seeing proposals for passwords when trying to log in. Most of the
proposals are pretty garbage, but that is a problem for future me.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h2&gt;
&lt;p&gt;I have access to my password-store secrets on my phone, my browsers on laptop and
desktop, and most importantly &lt;strong&gt;Emacs&lt;&#x2F;strong&gt;. Narrowing of the proposed secrets
is, euhmmm, sub-optimal, but since it is sub-optimal in the same way
on all platforms I assume that some TLC in the password-store and
cleaning of the migrated secrets will fix that in time.&lt;&#x2F;p&gt;
&lt;p&gt;In the process I gained much more confidence in configuring flatpak
apps. I can decommission the keepassxc system including dealing with
the sync conflicts (which was admittedly super easy with the merge
database feature in KeepassXC). I no longer have to deal with giving
the KeepassXC window a place on the desktop and autostarting it.&lt;&#x2F;p&gt;
&lt;p&gt;I am a bit puzzled about the host-apps referring to supporting
browsers for which no extensions are available. This probably might
warrant some additional investigation.&lt;&#x2F;p&gt;
&lt;p&gt;Big step forward&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Samba Adventures with Guix</title>
          <pubDate>Sat, 17 Aug 2024 00:00:00 +0200</pubDate>
          <author>Peter Tillemans</author>
          <link>https://www.snamellit.com/posts/20240817-samba-adventures-in-guix/</link>
          <guid>https://www.snamellit.com/posts/20240817-samba-adventures-in-guix/</guid>
          <description xml:base="https://www.snamellit.com/posts/20240817-samba-adventures-in-guix/">&lt;p&gt;Samba or CIFS file sharing is a finicky area at best, but widely used,
especially since it was heavily pushed by Microsoft in the Windows
ecosystem, This makes it widely used in corporate and NAS environments
and even for Linux file sharing.&lt;&#x2F;p&gt;
&lt;p&gt;In this post I will look at some ways to use CIFS file sharing as a
client. Personally I find hardly any uses for Samba file serving
nowadays from my compute environments, with &lt;strong&gt;git&lt;&#x2F;strong&gt;, &lt;strong&gt;ssh&lt;&#x2F;strong&gt;, &lt;strong&gt;http(s)&lt;&#x2F;strong&gt;,
databases, MQTT, file synchronization services ... it hardly ever happens that
I face a situation where I think : &quot;Hey, I wish I could serve my files
from my PC&#x2F;VPS&#x2F;VM&#x2F;... with Samba&quot;. It is such a generic non-specific
service I usually find a more opinionated data sharing
service. Actually I find the same for NFS.&lt;&#x2F;p&gt;
&lt;p&gt;That being said, it is still ubiquitous to get enterprise data and to
connect to NAS or remote hard disks.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;cifs-server-simulator&quot;&gt;CIFS Server Simulator&lt;&#x2F;h2&gt;
&lt;p&gt;In practice setting up and connecting to a CIFS server is a
frustrating experience due to a bewildering array of different
protocols, security systems, credentials, ... .&lt;&#x2F;p&gt;
&lt;p&gt;To test out accessing a Samba server without having to deal with too
many moving pieces at the same time I like to use a known fixed local
basic samba server. This enables me to get working client - server
configurations which I find easier to tweak to real life servers than
starting from scratch.&lt;&#x2F;p&gt;
&lt;p&gt;Docker hub provides preconfigured images for Samba servers which are
easy to use :&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt; docker run --name test-smb -p 4139:139 --rm -p 4445:445 -v `&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;pwd&lt;&#x2F;span&gt;&lt;span&gt;`&#x2F;samples&#x2F;:&#x2F;mnt&#x2F;export --rm -d dperson&#x2F;samba -p -u &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;joe;schmoe&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; -s &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;export;&#x2F;mnt&#x2F;export&#x2F;;yes;no;no;joe;;;Test Share&amp;quot;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This will start a samba server and listen on ports 4139 and 4445 so it
does not clash if a server is running on the machine we&#x27;re using and
we do not need special privileges other than being in the &lt;code&gt;docker&lt;&#x2F;code&gt; group
to run &lt;strong&gt;docker&lt;&#x2F;strong&gt; as a regular user. The &lt;code&gt;-s ...&lt;&#x2F;code&gt; option configures a share
name &lt;strong&gt;export&lt;&#x2F;strong&gt; which is browsable, not readonly, not accessible by guest
users and  can only be accessed with the &lt;strong&gt;joe&lt;&#x2F;strong&gt; user account. This is to
make the experience a bit more in line with usual real world
configuration which are seldom as open as the default settings for
shares. For more details, see &lt;a href=&quot;https:&#x2F;&#x2F;hub.docker.com&#x2F;r&#x2F;dperson&#x2F;samba&quot;&gt;the github repo for the image&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Because this is not a fun command line to type I like to put them in a
&lt;strong&gt;Makefile&lt;&#x2F;strong&gt; in a folder with some support files&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt; cd ...
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt; mkdir test-smb
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt; cd test-smb
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt; mkdir samples
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt; echo &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;Hello, Samba&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;samples&#x2F;hello.txt
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;and then add the Makefile&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;makefile&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-makefile &quot;&gt;&lt;code class=&quot;language-makefile&quot; data-lang=&quot;makefile&quot;&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;servers-start&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;docker&lt;&#x2F;span&gt;&lt;span&gt; run --name test-smb -p 4139:139 --rm -p 4445:445 -v `&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;pwd&lt;&#x2F;span&gt;&lt;span&gt;`&#x2F;samples&#x2F;:&#x2F;mnt&#x2F;export --rm -d dperson&#x2F;samba -p -u &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;joe;schmoe&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; -s &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;export;&#x2F;mnt&#x2F;export&#x2F;;yes;no;no;joe;;;Test Share&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;servers-stop&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;docker&lt;&#x2F;span&gt;&lt;span&gt; stop test-smb
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;guix-notes-for-docker&quot;&gt;Guix Notes for Docker&lt;&#x2F;h3&gt;
&lt;p&gt;Docker  (and podman too) need some OS support to talk to the kernel to
create the namespaces to make the containers work. Even though podman
does not need a daemon to run, it still needs some &lt;strong&gt;setuid&lt;&#x2F;strong&gt; helpers. I
tend to mostly use &lt;strong&gt;docker&lt;&#x2F;strong&gt; because of habit and everyone else uses it
and tends to be better supported and documented for my use cases. In
any case I did not have any luck getting either to work in a local
&lt;code&gt;guix shell&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;To enable &lt;strong&gt;docker&lt;&#x2F;strong&gt; on Guix-SD I have the following in my system configuration.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;lisp&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-lisp &quot;&gt;&lt;code class=&quot;language-lisp&quot; data-lang=&quot;lisp&quot;&gt;&lt;span&gt;  ...
&lt;&#x2F;span&gt;&lt;span&gt;  (use&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;service&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;modules cups desktop docker networking ssh xorg)
&lt;&#x2F;span&gt;&lt;span&gt;  ...
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(operating&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;system
&lt;&#x2F;span&gt;&lt;span&gt;  ...
&lt;&#x2F;span&gt;&lt;span&gt;  (users
&lt;&#x2F;span&gt;&lt;span&gt;   (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;cons&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;*
&lt;&#x2F;span&gt;&lt;span&gt;    (user&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;account
&lt;&#x2F;span&gt;&lt;span&gt;     ...
&lt;&#x2F;span&gt;&lt;span&gt;     (supplementary&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;groups
&lt;&#x2F;span&gt;&lt;span&gt;      &amp;#39;( ... &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;docker&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)))  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#616e88;&quot;&gt;;; enable access to docker daemon
&lt;&#x2F;span&gt;&lt;span&gt;    %base&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;user&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;accounts))
&lt;&#x2F;span&gt;&lt;span&gt;...
&lt;&#x2F;span&gt;&lt;span&gt;(packages
&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;append
&lt;&#x2F;span&gt;&lt;span&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;list
&lt;&#x2F;span&gt;&lt;span&gt;   ...
&lt;&#x2F;span&gt;&lt;span&gt;   &lt;&#x2F;span&gt;&lt;span style=&quot;color:#616e88;&quot;&gt;;; add docker command line tools
&lt;&#x2F;span&gt;&lt;span&gt;   docker
&lt;&#x2F;span&gt;&lt;span&gt;   ...
&lt;&#x2F;span&gt;&lt;span&gt;   ))))
&lt;&#x2F;span&gt;&lt;span&gt;...
&lt;&#x2F;span&gt;&lt;span&gt;(services
&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;append
&lt;&#x2F;span&gt;&lt;span&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;list
&lt;&#x2F;span&gt;&lt;span&gt;   ...
&lt;&#x2F;span&gt;&lt;span&gt;   &lt;&#x2F;span&gt;&lt;span style=&quot;color:#616e88;&quot;&gt;;; enable docker
&lt;&#x2F;span&gt;&lt;span&gt;   (service docker&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;service&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;type)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;When using Guix on a host os, the native &lt;strong&gt;docker&lt;&#x2F;strong&gt; package should work
fine.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;connecting-using-smbclient&quot;&gt;Connecting using smbclient&lt;&#x2F;h2&gt;
&lt;p&gt;Before mounting drives we need to ascertain our credentials are
accepted by the Samba server. It makes no sense proceeding trying to
mount shares if we cannot get past authentication and the overhead of
configuring those shares and the Guix configuration rebuilding really
impacts iteration speed when trying things out.&lt;&#x2F;p&gt;
&lt;p&gt;The most straightforward way to connect to a CIFS server is with the
&lt;strong&gt;smbclient&lt;&#x2F;strong&gt; tool which is part of the &lt;strong&gt;samba&lt;&#x2F;strong&gt; package:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;➜&lt;&#x2F;span&gt;&lt;span&gt; guix shell samba
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;test-smb&lt;&#x2F;span&gt;&lt;span&gt; on  main via 🐃
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;➜&lt;&#x2F;span&gt;&lt;span&gt; smbclient -L &#x2F;&#x2F;localhost -p 4445 -U joe
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;Password&lt;&#x2F;span&gt;&lt;span&gt; for &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;WORKGROUP&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;\j&lt;&#x2F;span&gt;&lt;span&gt;oe&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;Sharename&lt;&#x2F;span&gt;&lt;span&gt;       Type      Comment
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;---------&lt;&#x2F;span&gt;&lt;span&gt;       ----      -------
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;export          &lt;&#x2F;span&gt;&lt;span&gt;Disk      Test Share
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;IPC$&lt;&#x2F;span&gt;&lt;span&gt;            IPC       IPC Service (Samba Server)
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;SMB1&lt;&#x2F;span&gt;&lt;span&gt; disabled&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt; --&lt;&#x2F;span&gt;&lt;span&gt; no workgroup available
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;test-smb&lt;&#x2F;span&gt;&lt;span&gt; on  main &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;[!]&lt;&#x2F;span&gt;&lt;span&gt; via 🐃  took 4s
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;➜&lt;&#x2F;span&gt;&lt;span&gt; smbclient &#x2F;&#x2F;localhost&#x2F;export -p 4445 -U joe
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;Password&lt;&#x2F;span&gt;&lt;span&gt; for &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;WORKGROUP&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;\j&lt;&#x2F;span&gt;&lt;span&gt;oe&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;Try &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;help&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; to get a list of possible commands.
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;smb: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;\&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; ls
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;                                   D        0  Sat Aug 17 03:49:32 2024
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;..&lt;&#x2F;span&gt;&lt;span&gt;                                  D        0  Sat Aug 17 05:22:38 2024
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;hello.txt&lt;&#x2F;span&gt;&lt;span&gt;                           N       13  Sat Aug 17 03:50:27 2024
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;1912951596&lt;&#x2F;span&gt;&lt;span&gt; blocks of size 1024. 998957000 blocks available
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;smb: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;\&amp;gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;code&gt;guix shell samba&lt;&#x2F;code&gt; creates a profile with the &lt;strong&gt;samba&lt;&#x2F;strong&gt; package
installed which places `smbclient` on the path.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;smbclient -L &#x2F;&#x2F;servername&lt;&#x2F;code&gt; lists the services offered by the server, in
our case &lt;strong&gt;localhost&lt;&#x2F;strong&gt; to connect to our docker instance. The &lt;code&gt;-p 4445&lt;&#x2F;code&gt;
option selects the custom port we specified on our docker
container. By default &lt;strong&gt;smbclient&lt;&#x2F;strong&gt; will use your login as uid, so we need
to override it to the user we created when starting the docker
container with &lt;code&gt;-U joe&lt;&#x2F;code&gt; .&lt;&#x2F;p&gt;
&lt;p&gt;The password is configured as &lt;code&gt;schmoe&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;We see the &lt;code&gt;export&lt;&#x2F;code&gt; folder is shared so we connect to it using
`smbclient &#x2F;&#x2F;localhost&#x2F;export -p 4445 -U joe` and can list the
contents. And of course we can upload, download and all the other
terminal goodness offered by &lt;strong&gt;smbclient&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;In practice it can be very fiddly to get the right username, password,
Workgroup or Domain, port number, SMB protocol, etc dialed in. The
obtuse messages often do not really help. The other methods make
interpreting errors even harder, with the exception of programmatic
access which is sometime surprisingly helpful in getting a connection
going.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;save-the-credentials&quot;&gt;Save the credentials&lt;&#x2F;h3&gt;
&lt;p&gt;The samba tools have a convention to save the credentials in a
&lt;strong&gt;authentication file&lt;&#x2F;strong&gt; which is supported by most tools AFAICT.&lt;&#x2F;p&gt;
&lt;p&gt;To use this create a file &lt;code&gt;.smbcredentials&lt;&#x2F;code&gt; in your home folder. Well,
it can be anything but I like that place as I typically only have my
NAS to connect to using samba and it is for my home folder, backup
folder, my Music and Movies folder and the like, i.e. stuff related to
my user account, so I find it in its place in my home folder.&lt;&#x2F;p&gt;
&lt;p&gt;In it place the &lt;code&gt;username&lt;&#x2F;code&gt;, &lt;code&gt;password&lt;&#x2F;code&gt; and &lt;code&gt;domain&lt;&#x2F;code&gt; which worked with
smbclient so they no longer need to be provided :&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;username=joe
&lt;&#x2F;span&gt;&lt;span&gt;password=schmoe
&lt;&#x2F;span&gt;&lt;span&gt;domain=WORKGROUP
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Then we can use it:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt; smbclient &#x2F;&#x2F;localhost&#x2F;export -p 4445 -A &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;~&lt;&#x2F;span&gt;&lt;span&gt;&#x2F;.smbcredentials
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;Try &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;help&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; to get a list of possible commands.
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;smb: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;\&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; ls
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;                                   D        0  Sat Aug 17 03:49:32 2024
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;..&lt;&#x2F;span&gt;&lt;span&gt;                                  D        0  Sat Aug 17 12:02:13 2024
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;hello.txt&lt;&#x2F;span&gt;&lt;span&gt;                           N       13  Sat Aug 17 03:50:27 2024
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;1912951596&lt;&#x2F;span&gt;&lt;span&gt; blocks of size 1024. 998918312 blocks available
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;smb: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;\&amp;gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This save a lot of typing and we can use this file in the next stages
and avoid spreading the credentials all over the disk. I am going to
gloss over encrypting this info any further because I do not keep
nuclear (or any other for that matter) secrets on my nas.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;mounting-shares-with-mount-dot-cifs&quot;&gt;Mounting Shares with &lt;code&gt;mount.cifs&lt;&#x2F;code&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Let&#x27;s create a mount point in our test folder&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt; mkdir mnt
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;and then mount the share with &lt;code&gt;mount.cifs&lt;&#x2F;code&gt;.  This is part of the &lt;code&gt;cifs-utils&lt;&#x2F;code&gt; package.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;ttest-smb&lt;&#x2F;span&gt;&lt;span&gt; on  main &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;[?]&lt;&#x2F;span&gt;&lt;span&gt; via 🐃
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;➜&lt;&#x2F;span&gt;&lt;span&gt; guix shell cifs-utils
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;The&lt;&#x2F;span&gt;&lt;span&gt; following derivation will be built:
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;&#x2F;gnu&#x2F;store&#x2F;2x7mmyrsnsf21aing02ass82899gm2yh-profile.drv
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;building&lt;&#x2F;span&gt;&lt;span&gt; CA certificate bundle...
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;listing&lt;&#x2F;span&gt;&lt;span&gt; Emacs sub-directories...
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;building&lt;&#x2F;span&gt;&lt;span&gt; fonts directory...
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;building&lt;&#x2F;span&gt;&lt;span&gt; directory of Info manuals...
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;building&lt;&#x2F;span&gt;&lt;span&gt; profile with 1 package...
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;est-smb&lt;&#x2F;span&gt;&lt;span&gt; on  main via 🐃
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;❮&lt;&#x2F;span&gt;&lt;span&gt; sudo mount.cifs &#x2F;&#x2F;localhost&#x2F;export mnt -o credentials=&#x2F;home&#x2F;pti&#x2F;.smbcredentials,port=4445
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;test-smb&lt;&#x2F;span&gt;&lt;span&gt; on  main &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;[?]&lt;&#x2F;span&gt;&lt;span&gt; via 🐃
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;➜&lt;&#x2F;span&gt;&lt;span&gt; ls mnt
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;hello.txt
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;test-smb&lt;&#x2F;span&gt;&lt;span&gt; on  main &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;[?]&lt;&#x2F;span&gt;&lt;span&gt; via 🐃
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;➜
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This mounts the share to the folder &lt;code&gt;mnt&lt;&#x2F;code&gt;. The &lt;code&gt;-o&lt;&#x2F;code&gt; option is used to
point to the credentials file and the port number of our docker NAS
simulator.&lt;&#x2F;p&gt;
&lt;p&gt;Checking with the regular &lt;code&gt;mount&lt;&#x2F;code&gt; command to see if it agrees we mounted
the share:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;❯&lt;&#x2F;span&gt;&lt;span&gt; sudo mount -t cifs
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;&#x2F;&#x2F;localhost&#x2F;export&lt;&#x2F;span&gt;&lt;span&gt; on &#x2F;home&#x2F;pti&#x2F;src&#x2F;test-smb&#x2F;mnt type cifs (rw,relatime,vers=3.1.1,cache=strict,username=joe,domain=WORKGROUP,uid=0,noforceuid,gid=0,noforcegid,addr=0000:0000:0000:0000:0000:0000:0000:0001,file_mode=0755,dir_mode=0755,soft,nounix,serverino,mapposix,rsize=4194304,wsize=4194304,bsize=1048576,echo_interval=60,actimeo=1,closetimeo=1)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;test-smb&lt;&#x2F;span&gt;&lt;span&gt; on  main &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;[?]&lt;&#x2F;span&gt;&lt;span&gt; via 🐃
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;➜&lt;&#x2F;span&gt;&lt;span&gt; sudo mount &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;| &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;grep&lt;&#x2F;span&gt;&lt;span&gt; cifs
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;&#x2F;etc&#x2F;auto.cifs&lt;&#x2F;span&gt;&lt;span&gt; on &#x2F;nas type autofs (rw,relatime,fd=6,pgrp=1732,timeout=600,minproto=5,maxproto=5,indirect,pipe_ino=27049)
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;&#x2F;&#x2F;localhost&#x2F;export&lt;&#x2F;span&gt;&lt;span&gt; on &#x2F;home&#x2F;pti&#x2F;src&#x2F;test-smb&#x2F;mnt type cifs (rw,relatime,vers=3.1.1,cache=strict,username=joe,domain=WORKGROUP,uid=0,noforceuid,gid=0,noforcegid,addr=0000:0000:0000:0000:0000:0000:0000:0001,file_mode=0755,dir_mode=0755,soft,nounix,serverino,mapposix,rsize=4194304,wsize=4194304,bsize=1048576,echo_interval=60,actimeo=1,closetimeo=1)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Calling &lt;code&gt;mount&lt;&#x2F;code&gt; without arguments lists all mounted filesystems, however
nowadays the output is so overwhelming that I prefer to use &lt;code&gt;grep&lt;&#x2F;code&gt; to
narrow down the output to the filesystem type I am interested in. The
same thing can be achieved by specifying the filesystem type with the
&lt;code&gt;-t&lt;&#x2F;code&gt; option.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;configuring-the-mounts-in-the-operating-system-dot&quot;&gt;Configuring the mounts in the operating system.&lt;&#x2F;h2&gt;
&lt;p&gt;The &lt;code&gt;mount.cifs&lt;&#x2F;code&gt; command is fine for testing and ad-hoc use but in
practice I mostly (read 99+% of the time) want the same shares of the
NAS mounted in the same place on my system. This is where the &lt;code&gt;fstab&lt;&#x2F;code&gt;
file comes in. This file is read by the mount command at boot time and
mounts the configured filesystems.&lt;&#x2F;p&gt;
&lt;p&gt;I do not recommend mounting CIFS shares at boot time, but configuring
the shares in &lt;code&gt;fstab&lt;&#x2F;code&gt; is a good way to be able to mount them when needed
with a quick &lt;code&gt;mount -a&lt;&#x2F;code&gt; command.&lt;&#x2F;p&gt;
&lt;p&gt;On my Tuxedo system I have in the &lt;code&gt;&#x2F;etc&#x2F;fstab&lt;&#x2F;code&gt; file&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;...
&lt;&#x2F;span&gt;&lt;span&gt;&#x2F;&#x2F;nas.snamellit.com&#x2F;home &#x2F;home&#x2F;pti&#x2F;nas   cifs   rw,uid=1000,gid=100,credentials=&#x2F;home&#x2F;pti&#x2F;.smbcredentials   0   0
&lt;&#x2F;span&gt;&lt;span&gt;&#x2F;&#x2F;nas.snamellit.com&#x2F;public &#x2F;mnt&#x2F;public   cifs   rw,uid=1000,gid=100,credentials=&#x2F;home&#x2F;pti&#x2F;.smbcredentials   0   0
&lt;&#x2F;span&gt;&lt;span&gt;&#x2F;&#x2F;nas.snamellit.com&#x2F;multimedia &#x2F;mnt&#x2F;multimedia   cifs   rw,uid=1000,gid=100,credentials=&#x2F;home&#x2F;pti&#x2F;.smbcredentials   0   0
&lt;&#x2F;span&gt;&lt;span&gt;...
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The first column is the reference to the share as we&#x27;ve seen
above. Then the mount point. The 3rd column indicates it is a &lt;code&gt;cifs&lt;&#x2F;code&gt;
share, Then the options we&#x27;ve seen with smbmount. Here I have to play
with the &lt;code&gt;uid&lt;&#x2F;code&gt; and &lt;code&gt;gid&lt;&#x2F;code&gt; to align my local user and group with the
configuration on the nas. The last 2 columns are whether to include
the mounts when dumping the filesystem and doing a filesystem check
which will probably always be 0 as the CIFS server is responsible for
that.&lt;&#x2F;p&gt;
&lt;p&gt;In theory this will mount the shares at boot time, and it probably
does, however in my experience it seems they are unmounted on suspend
and not remounted after resume. Or there is some timeout. I never
investigated I must admit. I just do a quick &lt;code&gt;mount -a&lt;&#x2F;code&gt; before I need
them and this works wonders.&lt;&#x2F;p&gt;
&lt;p&gt;On Guix-SD the &lt;code&gt;file-systems&lt;&#x2F;code&gt; are specified in the &lt;code&gt;operating-system&lt;&#x2F;code&gt;
section of the system configuration :&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;lisp&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-lisp &quot;&gt;&lt;code class=&quot;language-lisp&quot; data-lang=&quot;lisp&quot;&gt;&lt;span&gt;(operating&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;system
&lt;&#x2F;span&gt;&lt;span&gt; ...
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(file&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;systems
&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;cons&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;*
&lt;&#x2F;span&gt;&lt;span&gt;  ...
&lt;&#x2F;span&gt;&lt;span&gt;  (file&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;system
&lt;&#x2F;span&gt;&lt;span&gt;    (device &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;&#x2F;&#x2F;nas.snamellit.com&#x2F;public&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    (options &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;uid=1000,gid=1000,credentials=&#x2F;home&#x2F;pti&#x2F;.smbcredentials&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    (mount&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;point &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;&#x2F;mnt&#x2F;public&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    (type &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;cifs&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    (mount? #f)
&lt;&#x2F;span&gt;&lt;span&gt;    (create&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;mount&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;point? #t))
&lt;&#x2F;span&gt;&lt;span&gt;  (file&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;system
&lt;&#x2F;span&gt;&lt;span&gt;    (device &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;&#x2F;&#x2F;nas.snamellit.com&#x2F;multimedia&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    (options &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;uid=1000,gid=1000,credentials=&#x2F;home&#x2F;pti&#x2F;.smbcredentials&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    (mount&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;point &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;&#x2F;mnt&#x2F;multimedia&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    (type &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;cifs&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    (mount? #f)
&lt;&#x2F;span&gt;&lt;span&gt;    (create&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;mount&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;point? #t))
&lt;&#x2F;span&gt;&lt;span&gt;  (file&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;system
&lt;&#x2F;span&gt;&lt;span&gt;    (device &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;&#x2F;&#x2F;nas.snamellit.com&#x2F;home&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    (options &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;uid=1000,gid=1000,credentials=&#x2F;home&#x2F;pti&#x2F;.smbcredentials&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    (mount&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;point &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;&#x2F;home&#x2F;pti&#x2F;nas&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    (type &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;cifs&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    (mount? #f)
&lt;&#x2F;span&gt;&lt;span&gt;    (create&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;mount&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;point? #t))
&lt;&#x2F;span&gt;&lt;span&gt;  %base&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;file&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;systems)))
&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;background-color:#bf616a;color:#d8dee9;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Which is just a straightforward translation of the &lt;strong&gt;fstab&lt;&#x2F;strong&gt; columns in
&lt;a href=&quot;https:&#x2F;&#x2F;guix.gnu.org&#x2F;manual&#x2F;devel&#x2F;en&#x2F;html_node&#x2F;File-Systems.html&quot;&gt;Guix-ese.&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;automatic-mounting-with-autofs&quot;&gt;Automatic Mounting with AutoFs&lt;&#x2F;h2&gt;
&lt;p&gt;Of course the inefficiency of having to type &lt;code&gt;mount -a&lt;&#x2F;code&gt; almost on a
weekly basis is unbearable and this inefficiency has to be addressed
even if this means we cannot expect net positive effect in the coming
millenia.&lt;&#x2F;p&gt;
&lt;p&gt;Enter &lt;code&gt;autofs&lt;&#x2F;code&gt; which is an awesome system to dynamically mount and
unmount filesystems on an as needed basis. The kernel will notice when
a mounted folder is accessed and ask the &lt;strong&gt;autofs daemon&lt;&#x2F;strong&gt; to mount the
configured mount and unmount it after some timeout occurs without any
activity.&lt;&#x2F;p&gt;
&lt;p&gt;This is transparant for the user other than a slight delay when
accessing the folder the first time when it is unmounted.&lt;&#x2F;p&gt;
&lt;p&gt;This system is very flexible at it was clearly intended for far more
ambitious use-cases than accessing your personal music library from
your nas, but that does not mean we cannot strip it down and use it
for our purposes.&lt;&#x2F;p&gt;
&lt;p&gt;What is a bit confusing is the configuration. It uses 3 different
file types to configure the system.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;the &lt;code&gt;&#x2F;etc&#x2F;autofs.conf&lt;&#x2F;code&gt; file which configures the daemon operating
options, like the timeouts and the location of the main &lt;strong&gt;master file&lt;&#x2F;strong&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;the master file(s), there is always a main file, but this can
delegate to directory with additional parts of the file which can be
assumed to be imported in the main file. Its main purpose is to map
a parent folder of mount points to a &lt;strong&gt;map file&lt;&#x2F;strong&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;the map files which map a subfolder in the folder from the line in
the &lt;strong&gt;master file&lt;&#x2F;strong&gt; to a mount specification which will be used when
that folder is accessed.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;example-on-the-tuxedo&quot;&gt;Example on the Tuxedo:&lt;&#x2F;h3&gt;
&lt;p&gt;On my Tuxedo (running Tuxedo OS which is an Ubuntu 22.04 derivate) I have the following configuration:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;&#x2F;etc&#x2F;autofs.conf&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;...
&lt;&#x2F;span&gt;&lt;span&gt;[ autofs ]
&lt;&#x2F;span&gt;&lt;span&gt;#
&lt;&#x2F;span&gt;&lt;span&gt;# master_map_name - default map name for the master map.
&lt;&#x2F;span&gt;&lt;span&gt;#
&lt;&#x2F;span&gt;&lt;span&gt;master_map_name = &#x2F;etc&#x2F;auto.master
&lt;&#x2F;span&gt;&lt;span&gt;...
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;so the &lt;strong&gt;master map&lt;&#x2F;strong&gt; is in the file &lt;code&gt;&#x2F;etc&#x2F;auto.master&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;&#x2F;etc&#x2F;auto.master&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;...
&lt;&#x2F;span&gt;&lt;span&gt;&#x2F;-  &#x2F;etc&#x2F;autofs.direct  -ro
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The &quot;&#x2F;-&quot; is a special case which means &quot;any&quot; directory. In this case
the folder name in the &lt;strong&gt;map file&lt;&#x2F;strong&gt; is assumed to be a fully qualified
directory name instead of a subfolder in the folder mentioned in the
first column.  In this case the &lt;strong&gt;map file&lt;&#x2F;strong&gt; is &lt;code&gt;&#x2F;etc&#x2F;autofs.direct&lt;&#x2F;code&gt; and the
default options are &lt;code&gt;-ro&lt;&#x2F;code&gt; .&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;&#x2F;etc&#x2F;autofs.direct&lt;&#x2F;code&gt;:&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;&#x2F;home&#x2F;pti&#x2F;nas -fstype=cifs,rw,noperm,vers=3.0,credentials=&#x2F;home&#x2F;pti&#x2F;.smbcredentials    :&#x2F;&#x2F;nas.snamellit.com&#x2F;home
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
This shows that the mount point &lt;code&gt;&#x2F;home&#x2F;pti&#x2F;nas&lt;&#x2F;code&gt; will mount the share
&lt;code&gt;&#x2F;&#x2F;nas.snamellit.com&#x2F;home&lt;&#x2F;code&gt; of file system type cifs with the options
(the rest of the 2nd column) as mount options.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;example-on-the-guix-sd-desktop&quot;&gt;Example on the Guix-SD desktop&lt;&#x2F;h3&gt;
&lt;p&gt;Unfortunately there is not (yet) packaged support for an &lt;strong&gt;autofs&lt;&#x2F;strong&gt;
service-type, so we have to make it ourselves.&lt;&#x2F;p&gt;
&lt;p&gt;First we define a configuration record type for our new service:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;lisp&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-lisp &quot;&gt;&lt;code class=&quot;language-lisp&quot; data-lang=&quot;lisp&quot;&gt;&lt;span&gt;(define&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;record&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;type&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;* &amp;lt;&lt;&#x2F;span&gt;&lt;span&gt;autofs&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;configuration&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;  autofs&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;configuration make&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;autofs&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;configuration
&lt;&#x2F;span&gt;&lt;span&gt;  autofs&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;configuration?
&lt;&#x2F;span&gt;&lt;span&gt;  (pid&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;file autofs&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;configuration&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;pid&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;file
&lt;&#x2F;span&gt;&lt;span&gt;            (default &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;&#x2F;var&#x2F;run&#x2F;autofs.pid&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;))
&lt;&#x2F;span&gt;&lt;span&gt;  (autofs&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;direct autofs&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;configuration&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;autofs&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;direct
&lt;&#x2F;span&gt;&lt;span&gt;                 (default (plain&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;file &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;autofs.direct&amp;quot; &amp;quot;&#x2F;home&#x2F;pti&#x2F;autonas -fstype=cifs,rw,noperm,vers=3.0,credentials=&#x2F;home&#x2F;pti&#x2F;.smbcredentials  :&#x2F;&#x2F;nas.snamellit.com&#x2F;home&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;))))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I should probably not put my actual configuration in the default, but
it makes my life easier at the moment and I&#x27;ll refactor it
later. (Yeah, sure...)&lt;&#x2F;p&gt;
&lt;p&gt;Since the autofs service needs some boilerplate configuration files I
generate them with an activation function:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;lisp&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-lisp &quot;&gt;&lt;code class=&quot;language-lisp&quot; data-lang=&quot;lisp&quot;&gt;&lt;span&gt;(define (autofs&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;activation config)
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;Return the activation GEXP to create the config files for autofs&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;with-&lt;&#x2F;span&gt;&lt;span&gt;imported&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;modules &amp;#39;((guix build utils))
&lt;&#x2F;span&gt;&lt;span&gt;                         #~(begin
&lt;&#x2F;span&gt;&lt;span&gt;                             (use&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;modules (guix build utils)
&lt;&#x2F;span&gt;&lt;span&gt;                                          (ice&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;9&lt;&#x2F;span&gt;&lt;span&gt; textual&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;ports))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;                             (define (touch file&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;name)
&lt;&#x2F;span&gt;&lt;span&gt;                               (call&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-with-&lt;&#x2F;span&gt;&lt;span&gt;output&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;file file&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;name (const #t)))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;                             &lt;&#x2F;span&gt;&lt;span style=&quot;color:#616e88;&quot;&gt;;; &amp;#39;sshd&amp;#39; complains if the authorized-key directory and its parents
&lt;&#x2F;span&gt;&lt;span&gt;                             &lt;&#x2F;span&gt;&lt;span style=&quot;color:#616e88;&quot;&gt;;; are group-writable, which rules out &#x2F;gnu&#x2F;store.  Thus we copy the
&lt;&#x2F;span&gt;&lt;span&gt;                             &lt;&#x2F;span&gt;&lt;span style=&quot;color:#616e88;&quot;&gt;;; authorized-key directory to &#x2F;etc.
&lt;&#x2F;span&gt;&lt;span&gt;                             (call&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-with-&lt;&#x2F;span&gt;&lt;span&gt;output&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;file &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;&#x2F;etc&#x2F;autofs.conf&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;                               (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;lambda &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span&gt;) (put&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;string f &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;[ autofs ]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;master_map_name = &#x2F;etc&#x2F;auto.master
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;timeout = 300
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)))
&lt;&#x2F;span&gt;&lt;span&gt;                             (call&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-with-&lt;&#x2F;span&gt;&lt;span&gt;output&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;file &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;&#x2F;etc&#x2F;auto.master&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;                               (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;lambda &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span&gt;) (put&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;string f &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;format &lt;&#x2F;span&gt;&lt;span&gt;#f &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;&#x2F;-  ~a -ro&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; #$(autofs&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;configuration&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;autofs&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;direct config)))))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;                             )))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;You&#x27;ll recognize the absolutely stripped down versions of the files
mentioned above being generated. The &lt;code&gt;&#x2F;etc&#x2F;auto.master&lt;&#x2F;code&gt; file maps the
&lt;strong&gt;directfs&lt;&#x2F;strong&gt; map file to the file generated in the configuration record.&lt;&#x2F;p&gt;
&lt;p&gt;This should tie up nicely the links between the 3 files.&lt;&#x2F;p&gt;
&lt;p&gt;Then I need a &lt;strong&gt;shepherd service&lt;&#x2F;strong&gt; to start the &lt;strong&gt;autofs&lt;&#x2F;strong&gt; daemon:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;lisp&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-lisp &quot;&gt;&lt;code class=&quot;language-lisp&quot; data-lang=&quot;lisp&quot;&gt;&lt;span&gt;(define (autofs&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;shepherd&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;service config)
&lt;&#x2F;span&gt;&lt;span&gt;  (define pid&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;file (autofs&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;configuration&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;pid&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;file config))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;list
&lt;&#x2F;span&gt;&lt;span&gt;   (shepherd&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;service
&lt;&#x2F;span&gt;&lt;span&gt;    (provision &amp;#39;(autofs))
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;documentation &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;AutoFS Service.&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    (requirement &amp;#39;(networking))
&lt;&#x2F;span&gt;&lt;span&gt;    (start #~(make&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;forkexec&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;constructor
&lt;&#x2F;span&gt;&lt;span&gt;              (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;list
&lt;&#x2F;span&gt;&lt;span&gt;               #$(file&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;append&lt;&#x2F;span&gt;&lt;span&gt; autofs &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;&#x2F;sbin&#x2F;automount&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;               &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;-f&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#616e88;&quot;&gt;;; run in foreground to give shepherd more control
&lt;&#x2F;span&gt;&lt;span&gt;               &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;-p&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; #$(autofs&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;configuration&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;pid&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;file config)
&lt;&#x2F;span&gt;&lt;span&gt;               &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;&#x2F;etc&#x2F;auto.master&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;              #:pid-file #$(autofs&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;configuration&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;pid&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;file config)))
&lt;&#x2F;span&gt;&lt;span&gt;    (stop #~(make&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;kill&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;destructor))
&lt;&#x2F;span&gt;&lt;span&gt;    )))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We point it to the generated &lt;strong&gt;auto.master&lt;&#x2F;strong&gt; file from the activation
function. (I could probably refactor this to use guix instantiated
files but at this stage that extra level of indirection would only
confuse me and make debugging harder. I find jumping through 3 files
already hard enough to follow).&lt;&#x2F;p&gt;
&lt;p&gt;Then we need to put a bow around it and define an &lt;code&gt;autofs-service-type&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;lisp&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-lisp &quot;&gt;&lt;code class=&quot;language-lisp&quot; data-lang=&quot;lisp&quot;&gt;&lt;span&gt;(define autofs&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;service&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;type
&lt;&#x2F;span&gt;&lt;span&gt;  (service&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;type (name &amp;#39;autofs)
&lt;&#x2F;span&gt;&lt;span&gt;                (description &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;Run the autofs daemon to automount folders on access.&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;                (extensions
&lt;&#x2F;span&gt;&lt;span&gt;                 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;list
&lt;&#x2F;span&gt;&lt;span&gt;                  (service&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;extension activation&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;service&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;type autofs&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;activation)
&lt;&#x2F;span&gt;&lt;span&gt;                  (service&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;extension shepherd&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;root&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;service&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;type autofs&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;shepherd&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;service)))
&lt;&#x2F;span&gt;&lt;span&gt;                (compose &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;concatenate&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;                (default&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;value (autofs&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;configuration)))
&lt;&#x2F;span&gt;&lt;span&gt;  )
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This just extends the &lt;code&gt;activation-service-type&lt;&#x2F;code&gt; and the
&lt;code&gt;shepherd-root-service-type&lt;&#x2F;code&gt; to run our initialisation code and ensure
the &lt;strong&gt;autofs&lt;&#x2F;strong&gt; daemon gets started.&lt;&#x2F;p&gt;
&lt;p&gt;Then we can add this to our system configuration:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;lisp&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-lisp &quot;&gt;&lt;code class=&quot;language-lisp&quot; data-lang=&quot;lisp&quot;&gt;&lt;span&gt;(operating&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;system
&lt;&#x2F;span&gt;&lt;span&gt; ...
&lt;&#x2F;span&gt;&lt;span&gt; (packages
&lt;&#x2F;span&gt;&lt;span&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;append
&lt;&#x2F;span&gt;&lt;span&gt;   (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;list
&lt;&#x2F;span&gt;&lt;span&gt;    ...
&lt;&#x2F;span&gt;&lt;span&gt;    autofs)))
&lt;&#x2F;span&gt;&lt;span&gt; (services
&lt;&#x2F;span&gt;&lt;span&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;append
&lt;&#x2F;span&gt;&lt;span&gt;   (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;list
&lt;&#x2F;span&gt;&lt;span&gt;    ...
&lt;&#x2F;span&gt;&lt;span&gt;    (service autofs&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;service&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;type))
&lt;&#x2F;span&gt;&lt;span&gt;   ...)))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;i.e. add the &lt;code&gt;autofs&lt;&#x2F;code&gt; package to install the daemon and support stuff
and enable the service of type &lt;code&gt;autofs-service-type&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h2&gt;
&lt;p&gt;I can now use files on my nas transparantly. I was a bit flippant on
my reasons to enable &lt;strong&gt;autofs&lt;&#x2F;strong&gt;. The real reason was that I want to keep
automatic backup copies of my forge running on an VPS somewhere on my
NAS with a cron job, which means I would not be there to run a &lt;code&gt;mount -a&lt;&#x2F;code&gt; at the time. (I now realize I could do that as part of the cron
job : 20&#x2F;20 hindsight). In any case this is a major quality of life
improvement. As a side effect, my music library now gets properly
indexed and is made available on the default music player. Apparently
I still use CIFS more than I care to admit.&lt;&#x2F;p&gt;
&lt;p&gt;The big problem with SMB&#x2F;CIFS is getting the initial connection
going. Once that is achieved and the credentials are safely stored
away in &lt;strong&gt;credentials&lt;&#x2F;strong&gt; file, they can be easily reused with a lot less
surprising things along the way.&lt;&#x2F;p&gt;
&lt;p&gt;It also pays to test things out in the smallest possible meaningful
scope, in this case &lt;strong&gt;smbclient&lt;&#x2F;strong&gt; before adding more obfuscation layers on
top of it, as that just adds more complexity, pitfalls and rabbit
holes to get lost in. By going step by step, building on previous
result I often get results faster (or at all) even if I have to do
additional steps which turn out to no longer be needed in the final
solution.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Refactoring Emacs Config using Org</title>
          <pubDate>Sun, 28 Jul 2024 00:00:00 +0000</pubDate>
          <author>Peter Tillemans</author>
          <link>https://www.snamellit.com/posts/emacs-refactor/</link>
          <guid>https://www.snamellit.com/posts/emacs-refactor/</guid>
          <description xml:base="https://www.snamellit.com/posts/emacs-refactor/">&lt;h1 id=&quot;refactoring-my-emacs-config&quot;&gt;Refactoring my Emacs Config&lt;&#x2F;h1&gt;
&lt;p&gt;It is time to work on my Emacs config. Not because it is hopelessly broken, but to prevent that from happening. A long time ago I had a literate config I had to declare Emacs bankrupcy on because of the amount of cruft and lack of TLC. It had grown to a 4000 line 100kB+ inconsistent mess. It was nice to have evrything in a single file with documentation in place.&lt;&#x2F;p&gt;
&lt;p&gt;To reduce my config and leverage newer packages I then tried some of the big distros, Spacemacs and Doomemacs. This reduced the size I had to maintain to about 30k allowing me to keep on top of it. My personal modifications were then in a config.org file.&lt;&#x2F;p&gt;
&lt;p&gt;A few years ago I wanted to get better on using Windows and switched my main machine to a Windows desktop. I immediately noticed Doom Emacs being slow. Then a search started to find the right version of Emacs on Windows : msvc version, cygwin, msys2, wsl, ..., which all had different integration issues. I finally figured out that there is something in Doom which caused the sluggishness, and it is far less present in much more minimal config.
*
Hence I started relatively fresh using Rational Emacs, later Crafted Emacs as a base and organizing core. This is a regular elisp modular configuration. I split my personal configuration settings in different custom modules: pti-ui-XXX, pti-ide-XXX, pti-org-XXX, pti-evil-XXX.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;goals-to-achieve&quot;&gt;Goals to achieve&lt;&#x2F;h1&gt;
&lt;p&gt;I like to jot down some things I want to achieve to help me decide when is done and guide some decision along the way to avoid me getting stuck in the middle of a bramble forrest.&lt;&#x2F;p&gt;
&lt;p&gt;I came up with:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Manage &lt;em&gt;init.el&lt;&#x2F;em&gt; as an org-file&lt;&#x2F;li&gt;
&lt;li&gt;Use a simple robust tangling solution which works together with
Crafted Emacs&lt;&#x2F;li&gt;
&lt;li&gt;Leverage inclusion of &lt;del&gt;use-package&lt;&#x2F;del&gt; in Emacs29 for configuration and
loading&lt;&#x2F;li&gt;
&lt;li&gt;Reduce dependencies : read evaluate the value a package brings
before including it&lt;&#x2F;li&gt;
&lt;li&gt;Refactor existing configuration&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;In typical fashion the first goal is not a goal but what I will be doing, but judging from other &lt;em&gt;Business Analysis&lt;&#x2F;em&gt; efforts, this is part for the course. &lt;em&gt;What is the goal of the project? Do the project on time and in budget!&lt;&#x2F;em&gt; (real helpful...)&lt;&#x2F;p&gt;
&lt;p&gt;I actually added this when I notice the path getting all tangly and thorny and I remembered I forgot to list what I wanted to do. Well better late than never.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;approach&quot;&gt;Approach&lt;&#x2F;h1&gt;
&lt;p&gt;There are couple of constraints and probable consequences.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;likely editing the generated file instead of the source file&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;navigation-between-functions&quot;&gt;Navigation Between Functions&lt;&#x2F;h2&gt;
&lt;p&gt;Normally in Emacs Lisp buffers navigation between functions is magic. Who knows how this will pan out in org-babel.&lt;&#x2F;p&gt;
&lt;p&gt;That being said I found that in configuring emacs previously I use little homebrew functions which are usually close to where I use them and for the other functions &lt;code&gt;C-h f&lt;&#x2F;code&gt; is a good friend.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;editing-the-generated-file-iso-the-org-sources&quot;&gt;Editing the Generated File iso the Org Sources&lt;&#x2F;h2&gt;
&lt;p&gt;That is a &lt;em&gt;me&lt;&#x2F;em&gt; problem. I am &lt;em&gt;going&lt;&#x2F;em&gt; to be editing the generated file. So I need early feedback for this.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;tangling-and-git&quot;&gt;Tangling and Git&lt;&#x2F;h2&gt;
&lt;p&gt;Adding generated files in git is a no-no. I will have to add the generated file to the gitignore.&lt;&#x2F;p&gt;
&lt;p&gt;Then there is the issue that the config source file ideally is close to the generated file (see above). If I tangle the file from the git location into &lt;em&gt;~&#x2F;.config&#x2F;emacs&lt;&#x2F;em&gt; then I&#x27;ll have to navigate between the two locations. Probably there is an easy solution for this, but I don&#x27;t have it now.&lt;&#x2F;p&gt;
&lt;p&gt;If I symbolic link the file from the git location to &lt;em&gt;~&#x2F;.config&#x2F;emacs&lt;&#x2F;em&gt; then it is unclear if emacs will compare the creation date of the symbolic link or the file it points to. Probably this is well defined but I remember being bitten by this in the past.&lt;&#x2F;p&gt;
&lt;p&gt;But of course no-one is mandating that the emacs configuration has to be part of the &lt;em&gt;dotfiles&lt;&#x2F;em&gt; repo. I want to refactor that shortly and if I remove all the emacs stuff from the dotfiles repo then I can just clone the emacs config repo to &lt;em&gt;~&#x2F;.config&#x2F;emacs&lt;&#x2F;em&gt; and be done with it. And I have less to migrate in the dotfiles. So that is a win in my book.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;do-i-want-to-factor-out-crafted-emacs&quot;&gt;Do I want to factor out Crafted Emacs?&lt;&#x2F;h2&gt;
&lt;p&gt;I am not sure. I like the idea of having a base configuration which is well maintained and I can just add my personal configuration to. The upstream moves forward with the times, I can pull in the changes and the (mild) breakage over time will push me to keep my configuration up to date.&lt;&#x2F;p&gt;
&lt;p&gt;But I also like the idea of having a configuration which is mine and mine alone. I can do whatever I want with it. I can add a package, remove a package, change a package. I can do whatever I want.&lt;&#x2F;p&gt;
&lt;p&gt;However it is not on the goals list. I will keep it in mind and see how it goes.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;do-i-want-to-factor-out-the-custom-modules&quot;&gt;Do I want to factor out the custom modules?&lt;&#x2F;h2&gt;
&lt;p&gt;Yes. In the past I was pretty happy with a single org file. Before I declared emacs bankruptcy and moved to Spacemacs and Doom Emacs I had a single org file. I liked it. I could search for things easily. I could see the context of the configuration I could add documentation in context. I liked it.&lt;&#x2F;p&gt;
&lt;p&gt;What I did not like was technical debt and conflicting modules which were integrated at different times and not necessarily work well together. The experience was inconsistent and I felt I was running behind the current state of the art. Hence the need to explore the big distros.&lt;&#x2F;p&gt;
&lt;p&gt;After the big distros I moved to a modular configuration based on &lt;em&gt;Rational Emacs&lt;&#x2F;em&gt;, later renamed to &lt;em&gt;Crafted Emacs&lt;&#x2F;em&gt;. This was a good move. I could keep up with the changes in the emacs world and I could keep my configuration in check. It was all emacs lisp and this worked well for me.&lt;&#x2F;p&gt;
&lt;p&gt;I added a number of custom modules to the configuration. This works well bt I think the tools in org-mode can do better for this use-case. An Emacs config is not just code to do features. Emacs is also an integration platform where workflows are at least as important as the code. Having a place to document the workflows and the code in context is a big win. Also the code blocks can generate other files which integrate with the Emacs modules. And being able to run code blocks in the org file is a big win to show running examples or have ad-hoc tools available. Now this is also possible with comments in the source code, but I was brainwashed that comments are bad and code is good so I not comfortable with large comments in the source code. (Although that is changing slowly).&lt;&#x2F;p&gt;
&lt;h1 id=&quot;approach-1&quot;&gt;Approach&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;recover-the-infrastructure-from-the-old-configuration&quot;&gt;Recover the Infrastructure from the Old Configuration&lt;&#x2F;h2&gt;
&lt;p&gt;The tangling code proved to be very robust and will work fine with Crafted Emacs.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;use-elpaca-as-package-manager&quot;&gt;Use Elpaca as Package Manager&lt;&#x2F;h2&gt;
&lt;p&gt;I used &lt;em&gt;straight&lt;&#x2F;em&gt; as package manager with Crafted Emacs. I will switch to &lt;em&gt;elpaca&lt;&#x2F;em&gt; as one of the co-maintainers of &lt;em&gt;straight&lt;&#x2F;em&gt; started &lt;em&gt;elpaca&lt;&#x2F;em&gt; as a more user-friendly package manager.&lt;&#x2F;p&gt;
&lt;p&gt;The integration with &lt;em&gt;use-package&lt;&#x2F;em&gt; is more seamless and the configuration is more concise compared to &lt;em&gt;straight&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;I had to add &lt;em&gt;quelpa&lt;&#x2F;em&gt; in the mix for some reason. Part of the refactor is to remove both &lt;em&gt;straight&lt;&#x2F;em&gt; and &lt;em&gt;quelpa&lt;&#x2F;em&gt; and use &lt;em&gt;elpaca&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;It also seems to be more in line with the modern package managers in &lt;em&gt;neovim&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;use-org-babel-for-configuration&quot;&gt;Use Org-Babel for Configuration&lt;&#x2F;h2&gt;
&lt;p&gt;Yeah, Duh. This is the whole point of the exercise.&lt;&#x2F;p&gt;
&lt;p&gt;But it also for maintenance support, running examples and (if needed) generating support scripts.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;use-use-package-for-configuration&quot;&gt;Use &lt;em&gt;use-package&lt;&#x2F;em&gt; for Configuration&lt;&#x2F;h2&gt;
&lt;p&gt;Crafted Emacs leverages the customize infrastructure, including &lt;em&gt;package-install-selected-packages&lt;&#x2F;em&gt; to install packages. This means that adding the packages and configuring them is a two-step process and they end up in different modules.&lt;&#x2F;p&gt;
&lt;p&gt;Also there are subtle issues with state being persisted in the saved &lt;em&gt;custom.el&lt;&#x2F;em&gt; file. I maintain half a dozen systems which I want to be consistent. I have the feeling that &lt;em&gt;use-package&lt;&#x2F;em&gt; is better supported by the upstream package and I can steal more configs from the respective README&#x27;s. Time will tell.&lt;&#x2F;p&gt;
&lt;p&gt;However it is a new tool to learn and I never used it at this scale.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;no-new-features&quot;&gt;No new features&lt;&#x2F;h2&gt;
&lt;p&gt;My config suits me so I need no new features. I just want the same behavior after as before. I can quickly compare behavior on different machines. I will wait to update my VPS until I have a baseline on the desktop of the migration.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;do-incremental-changes&quot;&gt;Do incremental changes&lt;&#x2F;h2&gt;
&lt;p&gt;I kept my &lt;em&gt;init.el&lt;&#x2F;em&gt; relatively small and moved big chunks to separate modules. I can repeatedly copy a file in an org babel block and tangle it to the &lt;em&gt;init.el&lt;&#x2F;em&gt; file. Then the resulting config has to be the same&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;I will start with the &lt;em&gt;init.el&lt;&#x2F;em&gt; as an org file&lt;&#x2F;li&gt;
&lt;li&gt;Verify it works and behaves the same&lt;&#x2F;li&gt;
&lt;li&gt;Split the block in logical pieces give them an Org Header.&lt;&#x2F;li&gt;
&lt;li&gt;Evaluate if they are in the right place and move if needed.&lt;&#x2F;li&gt;
&lt;li&gt;Migrate the config to use &lt;em&gt;use-package&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Verify it works and behaves the same&lt;&#x2F;li&gt;
&lt;li&gt;Repeat until done&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;When a file is migrated, I baseline to the master branch and push it to the remote.&lt;&#x2F;p&gt;
&lt;p&gt;Then the next file.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;doing-it&quot;&gt;Doing it.&lt;&#x2F;h1&gt;
&lt;p&gt;I will spare the grind of the actual migration. Actually migrating was no problem. Dealing with the long tail of issues was.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;issues&quot;&gt;Issues&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;use-package-defer-and-loading-behavior&quot;&gt;Use-Package defer and loading behavior.&lt;&#x2F;h3&gt;
&lt;p&gt;I faced quite some issues with the loading behavior of the packages. I started with &lt;code&gt;:defer nil&lt;&#x2F;code&gt; to get things working. If Emacs took 15s to load then that was not a priority to fix. This bit me in the backend afterwards.&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;I misundertood the documentation and made the classic mistake of attributing *magic* properties to things as `:commands`, `:hook` and `:bind`. Although it is documented that these can only define to functions in the package, I made the mistake that other functions would trigger loading the package. Since this auto loading is a thin veneer over the standard Emacs loading mechanism, this is not the case. I formulated the rule that you can only refer to a thing in the package from a thing which is already loaded. That helped debugging and avoiding this issue.
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;I put a delay between 3 and 10s for modules I would classify as *creature comforts*. This is a good compromise between loading time and usability. I can always lower the delay if I feel the need for speed.
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;It took some time to get this directed acyclic graph sorted out. 
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;use-package-and-custom&quot;&gt;Use-Package and :custom&lt;&#x2F;h3&gt;
&lt;p&gt;Since Crafted Emacs uses the customize infrastructure, and I adopted that it would make sense to use the &lt;code&gt;:custom&lt;&#x2F;code&gt; keyword in &lt;code&gt;use-package&lt;&#x2F;code&gt;. Of course the penny dropped after I moved ton to &lt;code&gt;setq&lt;&#x2F;code&gt; forms in the &lt;code&gt;:init&lt;&#x2F;code&gt; blocks. This in turn caused issues with getting passwords with the &lt;em&gt;pass&lt;&#x2F;em&gt; command which is slow and requires sometimes a pin-entry.&lt;&#x2F;p&gt;
&lt;p&gt;Using &lt;code&gt;:custom&lt;&#x2F;code&gt; ensures the variables are still defined on loading the package so it can bootstrap and and the password will be unlocked at that time, which is probably when I do something that actually needs it.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;pinentry-in-emacs&quot;&gt;Pinentry in Emacs&lt;&#x2F;h3&gt;
&lt;p&gt;I did not have this issue before but Emacs seemed to hang when started from the i3 launcher. From comparing to starting on the terminal this is likely because it was waiting for the pinentry to be entered when the &lt;em&gt;emacs --daemon&lt;&#x2F;em&gt; was started which has no GUI frame. This resulted in multiple &lt;code&gt;emacs --daemon&lt;&#x2F;code&gt; processes in the process list, which surprised me as I never experienced this before.&lt;&#x2F;p&gt;
&lt;p&gt;I disabled the emacs pinentry support and then it pops up a GUI window so I could enter the password. This is not ideal but it works. In the mean time this is fixed as no more passwords are asked before Emacs is fully started. But it is likely this issue will return.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;elpaca-and-dev-releases-from-emacs&quot;&gt;Elpaca and Dev Releases from Emacs&lt;&#x2F;h3&gt;
&lt;p&gt;Elpaca needs the build date of emacs to compare to package versions or
something. However it does not support all dev versions. It has a
table to map released versions to date codes to compare to the build
date of emacs with the date of potential packages. (or something
similar).&lt;&#x2F;p&gt;
&lt;p&gt;This caused some headscratching how to get this and I finally settled on the
birthdate of the .drv package installed by &lt;em&gt;guix&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;For guix emacs-next packages you can find the date with: ( &lt;C-c C-c&gt;
in the source block below:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;#+BEGIN_SRC shell
&lt;&#x2F;span&gt;&lt;span&gt;stat &#x2F;gnu&#x2F;store&#x2F;*emacs-next-[23]*.drv | rg Birth | cut -d&amp;#39; &amp;#39; -f3 | tr -d &amp;#39;-&amp;#39;
&lt;&#x2F;span&gt;&lt;span&gt;#+END_SRC
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;#+RESULTS:
&lt;&#x2F;span&gt;&lt;span&gt;| 20240727 |
&lt;&#x2F;span&gt;&lt;span&gt;| 20240727 |
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;It is possible there are more so probably the most recent one is the
one to use.&lt;&#x2F;p&gt;
&lt;p&gt;I override the elpaca generated one with the one I found in &lt;em&gt;early-init.el&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;(setq elpaca-core-date &amp;quot;20240727&amp;quot;)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This is manual for now. Maybe I should trigger this on &lt;code&gt;guix home reconfigure&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;results&quot;&gt;Results&lt;&#x2F;h1&gt;
&lt;p&gt;I now like visiting my config more&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.snamellit.com&#x2F;posts&#x2F;emacs-refactor&#x2F;first-things.png&quot; alt=&quot;config screenshot&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I separated the config from my main dotfiles and published separately in a &lt;a href=&quot;https:&#x2F;&#x2F;forge.snamellit.com&#x2F;pti&#x2F;website&quot;&gt;public repo on my forge&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Here is an example with workflow notes and executable sample code :&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.snamellit.com&#x2F;posts&#x2F;emacs-refactor&#x2F;pass-sample.png&quot; alt=&quot;example of workflow notes and sample code&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Looking at the git log:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;commit 008f173ef49e2dfe175c4d84e6c87425442d1468
&lt;&#x2F;span&gt;&lt;span&gt;Date:   Tue Jul 30 16:51:18 2024 +0200
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;switch to new emacs config, burn old bridges
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;commit 2b44a918653890950b0985a4a5e8d65be22507c7
&lt;&#x2F;span&gt;&lt;span&gt;Author: Peter Tillemans &amp;lt;pti@snamellit.com&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;Date:   Tue Jul 30 16:47:28 2024 +0200
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;save crafted emacs before deleting;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;commit f79ab7ec6d8cd7af35253db997b291029174c38e
&lt;&#x2F;span&gt;&lt;span&gt;Author: Peter Tillemans &amp;lt;pti@snamellit.com&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;Date:   Tue Jul 30 00:49:19 2024 +0200
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;rework and testing of the new config
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;commit acf915e24b43d4eb3950931b13121a037b77a659
&lt;&#x2F;span&gt;&lt;span&gt;Author: Peter Tillemans &amp;lt;pti@snamellit.com&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;Date:   Mon Jul 29 17:51:19 2024 +0200
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;finished porting emacs init to org-mode
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;commit a1cd08f6e157e918f5979e57f0ee50b01688b98f
&lt;&#x2F;span&gt;&lt;span&gt;Author: Peter Tillemans &amp;lt;pti@snamellit.com&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;Date:   Mon Jul 29 11:25:56 2024 +0200
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;remove dependency on general to define evil keybindings
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;commit 739c067427c6944c96ba5cf1990788a99beb9386
&lt;&#x2F;span&gt;&lt;span&gt;Author: Peter Tillemans &amp;lt;pti@snamellit.com&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;Date:   Mon Jul 29 10:04:56 2024 +0200
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;remove migrated config
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;commit 4010de3d8eb8a7621d9e20bb7bc8af663059a527
&lt;&#x2F;span&gt;&lt;span&gt;Author: Peter Tillemans &amp;lt;pti@snamellit.com&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;Date:   Mon Jul 29 10:01:17 2024 +0200
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;fix issues with starting emacs.
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;- migrated pti-org-packages and pti-org-config
&lt;&#x2F;span&gt;&lt;span&gt;- migrated last requires
&lt;&#x2F;span&gt;&lt;span&gt;- resolved some existing conflicts
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;commit 99c83bb248a896c99700cca6025777a938d36701
&lt;&#x2F;span&gt;&lt;span&gt;Author: Peter Tillemans &amp;lt;pti@snamellit.com&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;Date:   Mon Jul 29 01:26:08 2024 +0200
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;Start refactor emacs config to org-mode again.
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I started on July 27th at 01:30 and the initial migration was done on July 19th 18:00 about. At that point the emacs config moved to a new repo.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.snamellit.com&#x2F;posts&#x2F;emacs-refactor&#x2F;grus-plan.jpg&quot; alt=&quot;Gru evaluates before and after&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;comparing the results we see that the files reduced from 12 to 3, total lines is the same (1851 vs 1871). However total size increased  from 67kB to about 85kB.&lt;&#x2F;p&gt;
&lt;p&gt;I am pretty happy with the change. I removed some duplication, removed some packages I hardly used, found some configs in the wrong place and I have held everything in my hands for a late spring cleaning.&lt;&#x2F;p&gt;
&lt;p&gt;Is it better than my before emacs lisp configuration? I don&#x27;t know. It is just a tradeoff, exchanging some consequences for other consequences. I learned a ton which will help maintain it in the future. Maybe I change my mind in a few years and migrate back, which will be another great opportunity for a spring cleaning.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Workflows for Unix Password Store with Emacs and Shell</title>
          <pubDate>Tue, 25 Jun 2024 00:00:00 +0000</pubDate>
          <author>Peter Tillemans</author>
          <link>https://www.snamellit.com/posts/20240624t104859-secrets-management-using-unix-password-store-pass-linux-osx-sysadmin/</link>
          <guid>https://www.snamellit.com/posts/20240624t104859-secrets-management-using-unix-password-store-pass-linux-osx-sysadmin/</guid>
          <description xml:base="https://www.snamellit.com/posts/20240624t104859-secrets-management-using-unix-password-store-pass-linux-osx-sysadmin/">&lt;h1 id=&quot;table-of-contents&quot;&gt;Table of Contents&lt;&#x2F;h1&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;www.snamellit.com&#x2F;posts&#x2F;20240624t104859-secrets-management-using-unix-password-store-pass-linux-osx-sysadmin&#x2F;#orgeea54c9&quot;&gt;Managing Secrets using Pass&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;www.snamellit.com&#x2F;posts&#x2F;20240624t104859-secrets-management-using-unix-password-store-pass-linux-osx-sysadmin&#x2F;#org44c3160&quot;&gt;Installation&lt;&#x2F;a&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;www.snamellit.com&#x2F;posts&#x2F;20240624t104859-secrets-management-using-unix-password-store-pass-linux-osx-sysadmin&#x2F;#org7920015&quot;&gt;GUIX&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;www.snamellit.com&#x2F;posts&#x2F;20240624t104859-secrets-management-using-unix-password-store-pass-linux-osx-sysadmin&#x2F;#orgbee77ce&quot;&gt;Debian, Ubuntu et al&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;www.snamellit.com&#x2F;posts&#x2F;20240624t104859-secrets-management-using-unix-password-store-pass-linux-osx-sysadmin&#x2F;#orgad61fe8&quot;&gt;Emacs Integration&lt;&#x2F;a&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;www.snamellit.com&#x2F;posts&#x2F;20240624t104859-secrets-management-using-unix-password-store-pass-linux-osx-sysadmin&#x2F;#orgf739a63&quot;&gt;Enable the Unix Password Store.&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;www.snamellit.com&#x2F;posts&#x2F;20240624t104859-secrets-management-using-unix-password-store-pass-linux-osx-sysadmin&#x2F;#org1c798ff&quot;&gt;Helper Function&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;www.snamellit.com&#x2F;posts&#x2F;20240624t104859-secrets-management-using-unix-password-store-pass-linux-osx-sysadmin&#x2F;#org25108ee&quot;&gt;Using in Emacs Configuration&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;www.snamellit.com&#x2F;posts&#x2F;20240624t104859-secrets-management-using-unix-password-store-pass-linux-osx-sysadmin&#x2F;#org849f72f&quot;&gt;Shell integration&lt;&#x2F;a&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;www.snamellit.com&#x2F;posts&#x2F;20240624t104859-secrets-management-using-unix-password-store-pass-linux-osx-sysadmin&#x2F;#org299dd7c&quot;&gt;DirEnv integration&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;www.snamellit.com&#x2F;posts&#x2F;20240624t104859-secrets-management-using-unix-password-store-pass-linux-osx-sysadmin&#x2F;#org158dbf2&quot;&gt;Tips&lt;&#x2F;a&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;www.snamellit.com&#x2F;posts&#x2F;20240624t104859-secrets-management-using-unix-password-store-pass-linux-osx-sysadmin&#x2F;#org00fffd0&quot;&gt;Entering passwords on the terminal&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;www.snamellit.com&#x2F;posts&#x2F;20240624t104859-secrets-management-using-unix-password-store-pass-linux-osx-sysadmin&#x2F;#org6ab1e11&quot;&gt;Getting fields from multi field secrets&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;&lt;a id=&quot;orgeea54c9&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;managing-secrets-using-pass&quot;&gt;Managing Secrets using Pass&lt;&#x2F;h1&gt;
&lt;p&gt;On UNIX there is a well known tool to manage secrets called
&lt;strong&gt;password-store&lt;&#x2F;strong&gt; or &lt;strong&gt;pass&lt;&#x2F;strong&gt; for short.&lt;&#x2F;p&gt;
&lt;p&gt;It is a very minimal tool, more to facilitate workflows that to do
real work, very much in the UNIX philosophy. It stores all secrets in
plain files in a folder structure. It does not care about what is in
the files and encrypts them using a GPG public key so only the owner
of the private key can decrypt them. It does offer special access to
the first line so a password can be quickly fetched and copied to the
clipboard or stdout or wherever some &lt;strong&gt;pass&lt;&#x2F;strong&gt; aware integration needs it.&lt;&#x2F;p&gt;
&lt;p&gt;Certain folders can be configured to use a different public keys to
allow pragmatic secret delegation to different systems without
exposing all secrets.&lt;&#x2F;p&gt;
&lt;p&gt;It leverages the &lt;strong&gt;gpg&lt;&#x2F;strong&gt; infrastructure for key management, distribution,
unlocking with &lt;strong&gt;pinentry&lt;&#x2F;strong&gt;, caching with &lt;strong&gt;gpg-agent&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a id=&quot;org44c3160&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;installation&quot;&gt;Installation&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;a id=&quot;org7920015&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;guix&quot;&gt;GUIX&lt;&#x2F;h2&gt;
&lt;p&gt;Add &lt;strong&gt;password-store&lt;&#x2F;strong&gt;, &lt;strong&gt;gpg&lt;&#x2F;strong&gt; and &lt;strong&gt;pinentry&lt;&#x2F;strong&gt; to your package list.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;strong&gt;pinentry&lt;&#x2F;strong&gt; program provides a client to securely unlock your keys in
a GUI and terminal environment. There are other options to make it
better fit your environment, but this is fine for me.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a id=&quot;orgbee77ce&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;debian-ubuntu-et-al&quot;&gt;Debian, Ubuntu et al&lt;&#x2F;h2&gt;
&lt;p&gt;Add &lt;strong&gt;pass&lt;&#x2F;strong&gt;, &lt;strong&gt;gpg&lt;&#x2F;strong&gt;, &lt;strong&gt;gpg-agent&lt;&#x2F;strong&gt; and &lt;strong&gt;pinentry-gnome&lt;&#x2F;strong&gt; of &lt;strong&gt;pinentry-qt&lt;&#x2F;strong&gt; using&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;$ apt-get install pass gpg gpg-agent pinentry-qt
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Both the gnome and qt versions at least fall back gracefully if no
graphical environment are available.&lt;&#x2F;p&gt;
&lt;p&gt;The current selected pinentry program is provided as
&lt;strong&gt;&#x2F;usr&#x2F;bin&#x2F;pinentry&lt;&#x2F;strong&gt; and this link is managed by the usual alternatives
machinery in debian based distros.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a id=&quot;orgad61fe8&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;emacs-integration&quot;&gt;Emacs Integration&lt;&#x2F;h1&gt;
&lt;p&gt;Emacs &lt;strong&gt;auth-source&lt;&#x2F;strong&gt; infrastructure supports &lt;strong&gt;pass&lt;&#x2F;strong&gt; out of the box.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a id=&quot;orgf739a63&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;enable-the-unix-password-store&quot;&gt;Enable the Unix Password Store.&lt;&#x2F;h2&gt;
&lt;p&gt;We have to make sure the password-store is added to the
auth-sources. There is a handy function for that:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;;; enable unix password-store
&lt;&#x2F;span&gt;&lt;span&gt;(auth-source-pass-enable)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We add that somewhere in the init.el before any secrets are needed.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a id=&quot;org1c798ff&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;helper-function&quot;&gt;Helper Function&lt;&#x2F;h2&gt;
&lt;p&gt;Auth-sources is a flexible system and works like a database, i.e. you
can query, browse through results and have multiple fields per secret.&lt;&#x2F;p&gt;
&lt;p&gt;Example:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;(defun snam-password (host user)
&lt;&#x2F;span&gt;&lt;span&gt;  &amp;quot;Get password from the unix password store.
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;Searches the password file for a secret in the folder corresponding to
&lt;&#x2F;span&gt;&lt;span&gt;the HOST name given, which is the folder with the &amp;#39;&#x2F;&amp;#39; replaced by a &amp;#39;.&amp;#39;.
&lt;&#x2F;span&gt;&lt;span&gt;The filename in the folder corresponds to the USER argument with a
&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;.pgp&amp;#39; extension.&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;  (auth-info-password
&lt;&#x2F;span&gt;&lt;span&gt;   (car (auth-source-search
&lt;&#x2F;span&gt;&lt;span&gt;         :max 1
&lt;&#x2F;span&gt;&lt;span&gt;         :host host
&lt;&#x2F;span&gt;&lt;span&gt;         :user user))))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;`auth-source-search` returns a list of results, so we have to get the
first entry with `car`. The secret is lightly obfuscated, hence the
need to decode it with the `auth-info-password` function.&lt;&#x2F;p&gt;
&lt;p&gt;Luckily there is a function &lt;a href=&quot;help:auth-source-pass-get&quot;&gt;auth-source-pass-get&lt;&#x2F;a&gt; to get a password
from the password store which also follows the recommended conventions
for multiple fields in a pass file.&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;(auth-source-pass-get &amp;#39;secret &amp;quot;snamellit&#x2F;znc&amp;quot;)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The pseudo key `&#x27;secret` returns the first line of the password store
entry which contains the password, per &lt;strong&gt;pass&lt;&#x2F;strong&gt; conventions.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a id=&quot;org25108ee&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;using-in-emacs-configuration&quot;&gt;Using in Emacs Configuration&lt;&#x2F;h2&gt;
&lt;p&gt;For single secrets, like connecting to my &lt;strong&gt;znc&lt;&#x2F;strong&gt; IRC bouncer:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;(erc-tls :id &amp;#39;znc :server &amp;quot;********&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;         :port &amp;quot;****&amp;quot; :user &amp;quot;xyz&amp;quot; :nick
&lt;&#x2F;span&gt;&lt;span&gt;         &amp;quot;foobar&amp;quot; :password (auth-source-pass-get &amp;#39;secret &amp;quot;foobar&#x2F;znc&amp;quot;)))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;For multifield secrets, like for google authentication, we can
leverage the multiple fields in the password store. Here is my
&lt;strong&gt;org-gcal&lt;&#x2F;strong&gt; configuration:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;(setq org-gcal-client-id (auth-source-pass-get &amp;#39;secret &amp;quot;snamellit&#x2F;org-gcal-client&amp;quot;)
&lt;&#x2F;span&gt;&lt;span&gt;      org-gcal-client-secret (auth-source-pass-get &amp;quot;id&amp;quot; &amp;quot;snamellit&#x2F;org-gcal-client&amp;quot;)
&lt;&#x2F;span&gt;&lt;span&gt;      org-gcal-fetch-file-alist &amp;#39;((&amp;quot;xyz@foobar.com&amp;quot; .  &amp;quot;~&#x2F;org&#x2F;schedule.org&amp;quot;)))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;a id=&quot;org849f72f&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;shell-integration&quot;&gt;Shell integration&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;a id=&quot;org299dd7c&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;direnv-integration&quot;&gt;DirEnv integration&lt;&#x2F;h2&gt;
&lt;p&gt;When developping 12-factor or similar inspired apps, the configuration
is passed using environment variables. Using &lt;strong&gt;.envrc&lt;&#x2F;strong&gt; files with
&lt;strong&gt;direnv&lt;&#x2F;strong&gt; integration in the shell is a very smooth way to work in
multiple projects.&lt;&#x2F;p&gt;
&lt;p&gt;It is of course less than ideal to have the secrets exposed in the
&lt;strong&gt;.envrc&lt;&#x2F;strong&gt; files in your project tree even if it is in the &lt;strong&gt;.gitignore&lt;&#x2F;strong&gt;
file, although that is infinitely better than having secrets end up in
the git repository.&lt;&#x2F;p&gt;
&lt;p&gt;Secrets in the &lt;strong&gt;.envrc&lt;&#x2F;strong&gt; files can be easily moved to the password store
by entering the folder. The following snippet prints the current value
to the screen and then inserts it in the password store, and verifies
it actually is entered correctly.&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;$ echo $FOO_BAR_PASSWORD
&lt;&#x2F;span&gt;&lt;span&gt;$ echo $FOO_BAR_PASSWORD | pass add -e foo&#x2F;bar
&lt;&#x2F;span&gt;&lt;span&gt;$ pass foo&#x2F;bar
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;and then editing the &lt;strong&gt;.envrc&lt;&#x2F;strong&gt; file from&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;...
&lt;&#x2F;span&gt;&lt;span&gt;FOO_BAR_PASSWORD=&amp;lt;some secret&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;...
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;to&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;...
&lt;&#x2F;span&gt;&lt;span&gt;FOO_BAR_PASSWORD=$(pass foo&#x2F;bar)
&lt;&#x2F;span&gt;&lt;span&gt;...
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;After modification you&#x27;ll be asked to allow to read the new &lt;strong&gt;.envrc&lt;&#x2F;strong&gt;
file content and you can check if it still works by comparing the
password with the one printed previously.&lt;&#x2F;p&gt;
&lt;p&gt;Printing the passwords allows to fix any typos. If this are the only
copies you have of them you might rug-pull yourself. Ideally it should
be possible to quickly recreate secrets if you lose any, but reality
is often far from ideal. Echoing all these passwords is also not
ideal, but preferable over keeping a little black book of secrets. If
these passwords are coming from another password manager it is not
needed of course.&lt;&#x2F;p&gt;
&lt;p&gt;Do not forget to clear your terminal scroll back history with&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;$ clear
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;To help migration of &lt;strong&gt;.envrc&lt;&#x2F;strong&gt; files I created a bash script I stored in
&lt;strong&gt;~&#x2F;.local&#x2F;bin&#x2F;envrc-to-pass&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;#!&#x2F;bin&#x2F;bash
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;if [ &amp;quot;$#&amp;quot; -ne 2 ]; then
&lt;&#x2F;span&gt;&lt;span&gt;    echo &amp;quot;Usage: $0 &amp;lt;variable_name&amp;gt; &amp;lt;namespace&amp;gt;&amp;quot; &amp;gt;&amp;amp;2
&lt;&#x2F;span&gt;&lt;span&gt;    exit 1
&lt;&#x2F;span&gt;&lt;span&gt;fi
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;VAR_NAME=$1
&lt;&#x2F;span&gt;&lt;span&gt;SLUG=$(echo $VAR_NAME | sed &amp;#39;s&#x2F;_&#x2F;-&#x2F;g&amp;#39; | tr &amp;#39;[:upper:]&amp;#39; &amp;#39;[:lower:]&amp;#39;)
&lt;&#x2F;span&gt;&lt;span&gt;NAMESPACE=$2
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;echo &amp;quot;Moving variable $VAR_NAME to $NAMESPACE&#x2F;$SLUG in password store&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;SECRET=$(grep &amp;quot;$VAR_NAME=&amp;quot; .envrc | cut -d&amp;#39;=&amp;#39; -f2)
&lt;&#x2F;span&gt;&lt;span&gt;if (echo $SECRET | grep &amp;#39;^\$(pass.*)&amp;#39;); then
&lt;&#x2F;span&gt;&lt;span&gt;    echo &amp;quot;secret already migrated&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;else
&lt;&#x2F;span&gt;&lt;span&gt;    echo $SECRET | pass insert -e $NAMESPACE&#x2F;$SLUG
&lt;&#x2F;span&gt;&lt;span&gt;fi
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;sed -i &amp;quot;s#$VAR_NAME=.*#$VAR_NAME=\\\$(pass $NAMESPACE\&#x2F;$SLUG)#&amp;quot; .envrc
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This makes short work of migrating projects to use the password-store.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a id=&quot;org158dbf2&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;tips&quot;&gt;Tips&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;a id=&quot;org00fffd0&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;entering-passwords-on-the-terminal&quot;&gt;Entering passwords on the terminal&lt;&#x2F;h2&gt;
&lt;p&gt;Usually invoking `pass add foobar&#x2F;baz` will ask to enter the password
and confirm it in the shell.&lt;&#x2F;p&gt;
&lt;p&gt;However when piping a secret into the password-store
with&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;echo FOO_BAR_PASSWORD | pass add foo&#x2F;bar
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;will silently fail although the man pages tell that `pass add` will
read from &lt;strong&gt;stdin&lt;&#x2F;strong&gt;. It is not clear IMO that you have to specify the &lt;strong&gt;-e&lt;&#x2F;strong&gt;
flag like :&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;echo FOO_BAR_PASSWORD | pass -e add foo&#x2F;bar
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;to suppress the confirmation and make it work as expected.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a id=&quot;org6ab1e11&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;getting-fields-from-multi-field-secrets&quot;&gt;Getting fields from multi field secrets&lt;&#x2F;h2&gt;
&lt;p&gt;Often secrets come in multiple parts which are nice to be stored in a
single entry in order not to complicate the tree. The &lt;strong&gt;pass&lt;&#x2F;strong&gt;
documentation suggests:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;&amp;lt;password or main secret&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;field1: &amp;lt;some data&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;field2: &amp;lt;more data&amp;gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;the main secret is just the first line, and can have the same
structure as the other lines, if that makes more sense.&lt;&#x2F;p&gt;
&lt;p&gt;e.g. for a google integration:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;service-account: 1234567-abcdefghijklm@developer.gserviceadmin.com(some-project)
&lt;&#x2F;span&gt;&lt;span&gt;email: xyz@foobar.com
&lt;&#x2F;span&gt;&lt;span&gt;private-key: ...
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In this case it is useful to &lt;span class=&quot;underline&quot;&gt;document&lt;&#x2F;span&gt; which kind of secret it is as it
could also be an api-key, or a refresh-token, or whatever part of the
authentication menagerie that Google offers.&lt;&#x2F;p&gt;
&lt;p&gt;To get these fields individually I use:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;GOOGLE_EMAIL=$(pass foo&#x2F;bar | awk &amp;#39;&#x2F;^email:&#x2F; {print $2}) 
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;in emacs this syntax is supported directly and the same info can be
fetched with&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;(let
&lt;&#x2F;span&gt;&lt;span&gt;    ((google-email (auth-source-pass-get &amp;quot;email&amp;quot; &amp;quot;foo&#x2F;bar&amp;quot;)))
&lt;&#x2F;span&gt;&lt;span&gt;  ... )
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</description>
      </item>
      <item>
          <title>Deploying Cuirass on GuixSD</title>
          <pubDate>Tue, 11 Jun 2024 00:00:00 +0000</pubDate>
          <author>Peter Tillemans</author>
          <link>https://www.snamellit.com/posts/deploying-cuirass-on-guixsd/</link>
          <guid>https://www.snamellit.com/posts/deploying-cuirass-on-guixsd/</guid>
          <description xml:base="https://www.snamellit.com/posts/deploying-cuirass-on-guixsd/">&lt;h1 id=&quot;table-of-contents&quot;&gt;Table of Contents&lt;&#x2F;h1&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;www.snamellit.com&#x2F;posts&#x2F;deploying-cuirass-on-guixsd&#x2F;#orge201d70&quot;&gt;Install Cuirass in Guix&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;www.snamellit.com&#x2F;posts&#x2F;deploying-cuirass-on-guixsd&#x2F;#org0f19dc3&quot;&gt;Create a postgresql server&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;www.snamellit.com&#x2F;posts&#x2F;deploying-cuirass-on-guixsd&#x2F;#org5f8483e&quot;&gt;Enable the cuirass service&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;www.snamellit.com&#x2F;posts&#x2F;deploying-cuirass-on-guixsd&#x2F;#org8d12621&quot;&gt;Enabling the Web Frontend&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;www.snamellit.com&#x2F;posts&#x2F;deploying-cuirass-on-guixsd&#x2F;#orged5a51b&quot;&gt;Submitting jobs&lt;&#x2F;a&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;www.snamellit.com&#x2F;posts&#x2F;deploying-cuirass-on-guixsd&#x2F;#org2ef3b08&quot;&gt;Figure out a more elegant way to submit jobs&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;&lt;a id=&quot;orge201d70&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;install-cuirass-in-guix&quot;&gt;Install Cuirass in Guix&lt;&#x2F;h1&gt;
&lt;p&gt;I had a hard time installing &lt;strong&gt;cuirass&lt;&#x2F;strong&gt; on my system. I tried to collect
some notes to move step by step to a working solution.&lt;&#x2F;p&gt;
&lt;p&gt;GUIX is great that it is really easy to revert your step to get out or
a dead end and start over from a previous point. Something I made
liberally use off to get something working. However it also means my
deployment process was not really linear but much more error driven.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a id=&quot;org0f19dc3&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;create-a-postgresql-server&quot;&gt;Create a postgresql server&lt;&#x2F;h1&gt;
&lt;p&gt;Starting the cuirass service will pull in a postgres server, however
it will use by default a version 10. Let&#x27;s update that to 15 for some
future proofing:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;(service postgresql-role-service-type
&lt;&#x2F;span&gt;&lt;span&gt;         (postgresql-role-configuration
&lt;&#x2F;span&gt;&lt;span&gt;          (roles
&lt;&#x2F;span&gt;&lt;span&gt;           (list (postgresql-role
&lt;&#x2F;span&gt;&lt;span&gt;                  (name &amp;quot;cuirass&amp;quot;)
&lt;&#x2F;span&gt;&lt;span&gt;                  (create-database? #t))
&lt;&#x2F;span&gt;&lt;span&gt;                 (postgresql-role
&lt;&#x2F;span&gt;&lt;span&gt;                  (name &amp;quot;xyz&amp;quot;)
&lt;&#x2F;span&gt;&lt;span&gt;                  (create-database? #t))))))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I also added a database user for me (&lt;strong&gt;xyz&lt;&#x2F;strong&gt; here stands for my user
account).&lt;&#x2F;p&gt;
&lt;p&gt;This will also create a database with the same name to allow the
cuirass user (and me) to login to the postgres database and do
database things.&lt;&#x2F;p&gt;
&lt;p&gt;Run a `guix system reconfigure` and check if the postgres is running
with `sudo herd status postgres`.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a id=&quot;org5f8483e&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;enable-the-cuirass-service&quot;&gt;Enable the cuirass service&lt;&#x2F;h1&gt;
&lt;p&gt;With the database in place there is a fighting chance to get the
service running :&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;(service cuirass-service-type
&lt;&#x2F;span&gt;&lt;span&gt;         (cuirass-configuration
&lt;&#x2F;span&gt;&lt;span&gt;          (specifications #~(list))))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The example in the reference documentation offers something more
interesting than an empty list but whatever I tried ended up with
&#x27;invalid field specifier&#x27; errors. But I get that too for nginx
configuration parts so that is probably a skill issue on my part.&lt;&#x2F;p&gt;
&lt;p&gt;Edit: definitely skill issue. I did not see that I defined them in the &lt;code&gt;operating-system&lt;&#x2F;code&gt; expression instead of on toplevel because it starts several screens up and down. Duh. Moving the define of the specifications to toplevel and using them here works just fine.&lt;&#x2F;p&gt;
&lt;p&gt;With a bit of luck we&#x27;ll see:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;xyz@foo ~&#x2F;.config&#x2F;dotfiles&#x2F;guix [env]$ sudo herd status cuirass
&lt;&#x2F;span&gt;&lt;span&gt;Status of cuirass:
&lt;&#x2F;span&gt;&lt;span&gt;  It is running since 05:19:42 PM (4 hours ago).
&lt;&#x2F;span&gt;&lt;span&gt;  Running value is 6513.
&lt;&#x2F;span&gt;&lt;span&gt;  It is enabled.
&lt;&#x2F;span&gt;&lt;span&gt;  Provides (cuirass).
&lt;&#x2F;span&gt;&lt;span&gt;  Requires (user-processes guix-daemon postgres postgres-roles networking).
&lt;&#x2F;span&gt;&lt;span&gt;  Will be respawned.
&lt;&#x2F;span&gt;&lt;span&gt;xyz@foo ~&#x2F;.config&#x2F;dotfiles&#x2F;guix [env]$ sudo herd status cuirass-web
&lt;&#x2F;span&gt;&lt;span&gt;Status of cuirass-web:
&lt;&#x2F;span&gt;&lt;span&gt;  It is running since 05:22:41 PM (4 hours ago).
&lt;&#x2F;span&gt;&lt;span&gt;  Running value is 6679.
&lt;&#x2F;span&gt;&lt;span&gt;  It is enabled.
&lt;&#x2F;span&gt;&lt;span&gt;  Provides (cuirass-web).
&lt;&#x2F;span&gt;&lt;span&gt;  Requires (user-processes cuirass).
&lt;&#x2F;span&gt;&lt;span&gt;  Will be respawned.
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If not there may be some info in `&#x2F;var&#x2F;log&#x2F;cuirass.log` or `&#x2F;var&#x2F;log&#x2F;cuirass-web.log`&lt;&#x2F;p&gt;
&lt;p&gt;Alternatively for debugging we can run the application from the git
repository.&lt;&#x2F;p&gt;
&lt;p&gt;First of all we have to give our user access to the database:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;xyz@foo ~&#x2F;.config&#x2F;dotfiles&#x2F;guix [env]$ sudo -u cuirass psql
&lt;&#x2F;span&gt;&lt;span&gt;Password:
&lt;&#x2F;span&gt;&lt;span&gt;psql (15.4)
&lt;&#x2F;span&gt;&lt;span&gt;Type &amp;quot;help&amp;quot; for help.
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;cuirass=&amp;gt; grant all on database cuirass to xyz;
&lt;&#x2F;span&gt;&lt;span&gt;GRANT
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;if the cuirass service has initialised the database already you can
add:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;cuirass=&amp;gt; grant all on all tables in schema public to xyz;
&lt;&#x2F;span&gt;&lt;span&gt;GRANT
&lt;&#x2F;span&gt;&lt;span&gt;cuirass=&amp;gt; grant all on all sequences  in schema public to xyz;
&lt;&#x2F;span&gt;&lt;span&gt;GRANT
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This allows access without jumping through the sudo hoop.&lt;&#x2F;p&gt;
&lt;p&gt;The code in the &lt;strong&gt;guix-cuirass&lt;&#x2F;strong&gt; project folder will now just work. Except
the postgresql socket should be exposed too in the proposed command of
the reference manual:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;guix shell -CPNW --expose=&#x2F;var&#x2F;log&#x2F;guix&#x2F;drvs \
&lt;&#x2F;span&gt;&lt;span&gt;--expose=&#x2F;var&#x2F;run&#x2F;dbus --expose=&#x2F;run&#x2F;avahi-daemon \
&lt;&#x2F;span&gt;&lt;span&gt;--expose=&#x2F;etc&#x2F;ssl&#x2F;certs --expose=&#x2F;var&#x2F;run&#x2F;postgresql
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Note that if the tables and sequences are created when running in your
account it is quite possible that the &lt;strong&gt;cuirass&lt;&#x2F;strong&gt; user will not be able to
access them and complain with access denied errors. In that case we
have to do the grants for the &lt;strong&gt;cuirass&lt;&#x2F;strong&gt; user:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;xyz@foo ~&#x2F;.config&#x2F;dotfiles&#x2F;guix [env]$ psql cuirass
&lt;&#x2F;span&gt;&lt;span&gt;Password:
&lt;&#x2F;span&gt;&lt;span&gt;psql (15.4)
&lt;&#x2F;span&gt;&lt;span&gt;Type &amp;quot;help&amp;quot; for help.
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;xyz=&amp;gt; grant all on all tables in schema public to cuirass;
&lt;&#x2F;span&gt;&lt;span&gt;GRANT
&lt;&#x2F;span&gt;&lt;span&gt;xyz=&amp;gt; grant all on all sequences  in schema public to cuirass;
&lt;&#x2F;span&gt;&lt;span&gt;GRANT
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Then restarting the service with `sudo herd restart cuirass` should
make it start, or at least give a different error.&lt;&#x2F;p&gt;
&lt;p&gt;Once &lt;strong&gt;cuirass&lt;&#x2F;strong&gt; service is running, it will be possible to run the
&lt;strong&gt;cuirass-web&lt;&#x2F;strong&gt; service. It relies on the existence of the
&lt;strong&gt;&#x2F;var&#x2F;run&#x2F;cuirass&#x2F;bridge&lt;&#x2F;strong&gt; file which is created by the cuirass service.&lt;&#x2F;p&gt;
&lt;p&gt;Just to be sure that the web server is running :&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;xyz@foo ~&#x2F;src&#x2F;guix-cuirass [env]$ wget http:&#x2F;&#x2F;localhost:8081
&lt;&#x2F;span&gt;&lt;span&gt;--2024-06-11 21:59:09--  http:&#x2F;&#x2F;localhost:8081&#x2F;
&lt;&#x2F;span&gt;&lt;span&gt;Resolving localhost (localhost)... 127.0.0.1
&lt;&#x2F;span&gt;&lt;span&gt;Connecting to localhost (localhost)|127.0.0.1|:8081... connected.
&lt;&#x2F;span&gt;&lt;span&gt;HTTP request sent, awaiting response... 200 OK
&lt;&#x2F;span&gt;&lt;span&gt;Length: 6142 (6.0K) [text&#x2F;html]
&lt;&#x2F;span&gt;&lt;span&gt;Saving to: ‘index.html’
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;index.html                    100%[================================================&amp;gt;]   6.00K  --.-KB&#x2F;s    in 0s
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;2024-06-11 21:59:09 (378 MB&#x2F;s) - ‘index.html’ saved [6142&#x2F;6142]
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Cool, we have a 200 Ok status code and some index.html file so the web
UI is running. Now exposing it to the &#x27;net.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a id=&quot;org8d12621&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;enabling-the-web-frontend&quot;&gt;Enabling the Web Frontend&lt;&#x2F;h1&gt;
&lt;p&gt;In the reference manual there is a nice configuration to start from to
configure nginx as a frontend for &lt;strong&gt;cuirass-web&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;However you cannot start nginx https without having the certificates
and you cannot get the certificates without the server running. (Well
you can but that is outside the scope of this post)&lt;&#x2F;p&gt;
&lt;p&gt;So we have to cut back the configuration to only start the http nginx
server to do the first handschake with letsencrypt to get the initial
certificates&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s start with the &lt;strong&gt;certbot-service&lt;&#x2F;strong&gt; :&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;(service certbot-service-type
&lt;&#x2F;span&gt;&lt;span&gt;         (certbot-configuration
&lt;&#x2F;span&gt;&lt;span&gt;          (email &amp;quot;xyz@bar.com&amp;quot;)
&lt;&#x2F;span&gt;&lt;span&gt;          (certificates
&lt;&#x2F;span&gt;&lt;span&gt;           (list
&lt;&#x2F;span&gt;&lt;span&gt;            (certificate-configuration
&lt;&#x2F;span&gt;&lt;span&gt;             (domains &amp;#39;(&amp;quot;foo.bar.com&amp;quot;)))
&lt;&#x2F;span&gt;&lt;span&gt;            ))))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Then add the minimal part for a nginx http server to do the
letsencrypt dance.&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;(service nginx-service-type
&lt;&#x2F;span&gt;&lt;span&gt;         (nginx-configuration
&lt;&#x2F;span&gt;&lt;span&gt;          (server-blocks
&lt;&#x2F;span&gt;&lt;span&gt;           (list
&lt;&#x2F;span&gt;&lt;span&gt;            ;; TLS is required for authentication; serve the site via
&lt;&#x2F;span&gt;&lt;span&gt;            ;; HTTPS only.
&lt;&#x2F;span&gt;&lt;span&gt;            (nginx-server-configuration
&lt;&#x2F;span&gt;&lt;span&gt;             (listen &amp;#39;(&amp;quot;80&amp;quot;))
&lt;&#x2F;span&gt;&lt;span&gt;             (raw-content
&lt;&#x2F;span&gt;&lt;span&gt;              (list &amp;quot;return 308 https:&#x2F;&#x2F;$host$request_uri;&amp;quot;)))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;            ))))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Doing a `guix system reconfigure` now will start the nginx server and
download fresh certificates.&lt;&#x2F;p&gt;
&lt;p&gt;We can now add the https server proxy-ing the &lt;strong&gt;cuirass-web&lt;&#x2F;strong&gt; server:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;(service nginx-service-type
&lt;&#x2F;span&gt;&lt;span&gt;         (nginx-configuration
&lt;&#x2F;span&gt;&lt;span&gt;          (server-blocks
&lt;&#x2F;span&gt;&lt;span&gt;           (list
&lt;&#x2F;span&gt;&lt;span&gt;            ;; TLS is required for authentication; serve the site via
&lt;&#x2F;span&gt;&lt;span&gt;            ;; HTTPS only.
&lt;&#x2F;span&gt;&lt;span&gt;            (nginx-server-configuration
&lt;&#x2F;span&gt;&lt;span&gt;             (listen &amp;#39;(&amp;quot;80&amp;quot;))
&lt;&#x2F;span&gt;&lt;span&gt;             (raw-content
&lt;&#x2F;span&gt;&lt;span&gt;              (list &amp;quot;return 308 https:&#x2F;&#x2F;$host$request_uri;&amp;quot;)))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;            (nginx-server-configuration
&lt;&#x2F;span&gt;&lt;span&gt;             (listen &amp;#39;(&amp;quot;443 ssl&amp;quot;))
&lt;&#x2F;span&gt;&lt;span&gt;             (server-name &amp;#39;(&amp;quot;foo.bar.com&amp;quot;))
&lt;&#x2F;span&gt;&lt;span&gt;             (ssl-certificate &amp;quot;&#x2F;etc&#x2F;letsencrypt&#x2F;live&#x2F;foo.bar.com&#x2F;fullchain.pem&amp;quot;)
&lt;&#x2F;span&gt;&lt;span&gt;             (ssl-certificate-key &amp;quot;&#x2F;etc&#x2F;letsencrypt&#x2F;live&#x2F;foo.bar.com&#x2F;privkey.pem&amp;quot;)
&lt;&#x2F;span&gt;&lt;span&gt;             (locations
&lt;&#x2F;span&gt;&lt;span&gt;              (list
&lt;&#x2F;span&gt;&lt;span&gt;               ;; Proxy the whole Cuirass web site...
&lt;&#x2F;span&gt;&lt;span&gt;               (nginx-location-configuration
&lt;&#x2F;span&gt;&lt;span&gt;                (uri &amp;quot;&#x2F;&amp;quot;)
&lt;&#x2F;span&gt;&lt;span&gt;                (body (list &amp;quot;proxy_pass http:&#x2F;&#x2F;localhost:8081;&amp;quot;)))
&lt;&#x2F;span&gt;&lt;span&gt;               ;; ... but require authentication for the admin pages.
&lt;&#x2F;span&gt;&lt;span&gt;               (nginx-location-configuration
&lt;&#x2F;span&gt;&lt;span&gt;                (uri &amp;quot;~ ^&#x2F;admin&amp;quot;)
&lt;&#x2F;span&gt;&lt;span&gt;                (body
&lt;&#x2F;span&gt;&lt;span&gt;                 (list &amp;quot;if ($ssl_client_verify != SUCCESS) \
&lt;&#x2F;span&gt;&lt;span&gt;            { return 403; } proxy_pass http:&#x2F;&#x2F;localhost:8081;&amp;quot;)))))
&lt;&#x2F;span&gt;&lt;span&gt;             ;; (raw-content
&lt;&#x2F;span&gt;&lt;span&gt;             ;;  ;; Register your self-generated certificate authority.
&lt;&#x2F;span&gt;&lt;span&gt;             ;;  (list &amp;quot;ssl_client_certificate &#x2F;etc&#x2F;ssl&#x2F;certs&#x2F;Snamellit_CA.pem;&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;             ;;        &amp;quot;ssl_verify_client optional;&amp;quot;))
&lt;&#x2F;span&gt;&lt;span&gt;             )
&lt;&#x2F;span&gt;&lt;span&gt;            ))))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Creating and installing the root CA is a bit out of scope. For this
post we&#x27;ll just wave our hands and assume the certificate magically
appeared in the `&#x2F;etc&#x2F;ssl&#x2F;certs&#x2F;Snamellit&lt;sub&gt;CA.pem&lt;&#x2F;sub&gt;` location. Creating a
client certificate for firefox and importing it allows to access the
admin section and retrigger jobs etc.&lt;&#x2F;p&gt;
&lt;p&gt;Once that is setup the commented out section can be activated.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a id=&quot;orged5a51b&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;interactivele-submitting-jobs&quot;&gt;Interactivele Submitting jobs&lt;&#x2F;h1&gt;
&lt;p&gt;For some reason I do not understand yet, the specification file must
be in the loadpath of the cuirass program.&lt;&#x2F;p&gt;
&lt;p&gt;For testing I add them to the &lt;strong&gt;examples&lt;&#x2F;strong&gt; folder in the &lt;strong&gt;guix-cuirass&lt;&#x2F;strong&gt;
folder in the home folder of the &lt;strong&gt;cuirass&lt;&#x2F;strong&gt; user&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;$ sudo -u cuirass -- bash              # start a shell in the cuirass user
&lt;&#x2F;span&gt;&lt;span&gt;$ cd guix-cuirass                      # enter the project folder
&lt;&#x2F;span&gt;&lt;span&gt;$ cp &#x2F;foo&#x2F;bar&#x2F;snamguix.scm examples    # put spec somewhere on loadpath
&lt;&#x2F;span&gt;&lt;span&gt;$ # start dev environment in container
&lt;&#x2F;span&gt;&lt;span&gt;$ guix shell -CPNW --expose=&#x2F;var&#x2F;log&#x2F;guix&#x2F;drvs \
&lt;&#x2F;span&gt;&lt;span&gt;    --expose=&#x2F;var&#x2F;run&#x2F;dbus --expose=&#x2F;run&#x2F;avahi-daemon \
&lt;&#x2F;span&gt;&lt;span&gt;    --expose=&#x2F;etc&#x2F;ssl&#x2F;certs --expose=&#x2F;var&#x2F;run&#x2F;postgresql
&lt;&#x2F;span&gt;&lt;span&gt;guix shell: loading environment from &amp;#39;&#x2F;home&#x2F;pti&#x2F;src&#x2F;guix-cuirass&#x2F;guix.scm&amp;#39;...
&lt;&#x2F;span&gt;&lt;span&gt;$ ~&#x2F;src&#x2F;guix-cuirass [env]$ # register new recipe
&lt;&#x2F;span&gt;&lt;span&gt;$ ~&#x2F;src&#x2F;guix-cuirass [env]$ .&#x2F;pre-inst-env cuirass register -S examples&#x2F;snamguix.scm
&lt;&#x2F;span&gt;&lt;span&gt;2024-06-11T20:18:08 running Fibers on 8 kernel threads
&lt;&#x2F;span&gt;&lt;span&gt;2024-06-11T20:18:08 marking stale builds as &amp;quot;scheduled&amp;quot;...
&lt;&#x2F;span&gt;&lt;span&gt;2024-06-11T20:18:08 builds will be made via the local build daemon
&lt;&#x2F;span&gt;&lt;span&gt;2024-06-11T20:18:08 will perform up to 8 evaluations concurrently
&lt;&#x2F;span&gt;&lt;span&gt;2024-06-11T20:18:08 opening bridge socket at &amp;#39;&#x2F;tmp&#x2F;cuirass-tests&#x2F;var&#x2F;run&#x2F;cuirass&#x2F;bridge&amp;#39;
&lt;&#x2F;span&gt;&lt;span&gt;2024-06-11T20:18:08 retrieving list of pending builds...
&lt;&#x2F;span&gt;&lt;span&gt;2024-06-11T20:18:08 unused GC roots older than 2592000s will be deleted every 86400s
&lt;&#x2F;span&gt;&lt;span&gt;2024-06-11T20:18:08 deleting old GC roots from &amp;#39;&#x2F;var&#x2F;guix&#x2F;gcroots&#x2F;profiles&#x2F;per-user&#x2F;pti&#x2F;cuirass&amp;#39;...
&lt;&#x2F;span&gt;&lt;span&gt;2024-06-11T20:18:08 selected 0 GC roots to remove
&lt;&#x2F;span&gt;&lt;span&gt;WARNING: (cuirass base): imported module (fibers) overrides core binding `sleep&amp;#39;
&lt;&#x2F;span&gt;&lt;span&gt;2024-06-11T20:18:08 heap: 12.18 MiB; threads: 17; file descriptors: 76
&lt;&#x2F;span&gt;&lt;span&gt;WARNING: (cuirass scripts register): imported module (fibers) overrides core binding `sleep&amp;#39;
&lt;&#x2F;span&gt;&lt;span&gt;2024-06-11T20:18:08 canceling 0 stale builds
&lt;&#x2F;span&gt;&lt;span&gt;2024-06-11T20:18:08 restarting 0 pending builds
&lt;&#x2F;span&gt;&lt;span&gt;2024-06-11T20:18:08 building 0 derivations in batches of 200
&lt;&#x2F;span&gt;&lt;span&gt;2024-06-11T20:18:08 done with 0 derivations
&lt;&#x2F;span&gt;&lt;span&gt;2024-06-11T20:18:08 outputs:
&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;C-C&amp;gt; 
&lt;&#x2F;span&gt;&lt;span&gt;$
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This actually starts the scheduler and it just keeps running (unless
we also give the –one-shot flag) but the side effect is to add the
specification to the database. It also allows to see immediately if there are syntax
errors or similar. When satisfied Ctrl-C out of it.&lt;&#x2F;p&gt;
&lt;p&gt;From now on the channel will be checked and build any updated
packages.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a id=&quot;org2ef3b08&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;permanently-add-the-job&quot;&gt;Permanently add the job&lt;&#x2F;h2&gt;
&lt;p&gt;Once vetted the specification can be added to the system configuration.&lt;&#x2F;p&gt;
&lt;p&gt;Define the specifications on the toplevel of the system config file. (Be careful, I lost a lot of time because I did not see it was actually in the &lt;em&gt;operating-system&lt;&#x2F;em&gt; expression)&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;;; cuirass specifications
&lt;&#x2F;span&gt;&lt;span&gt;(define %cuirass-specifications
&lt;&#x2F;span&gt;&lt;span&gt;#~(list
&lt;&#x2F;span&gt;&lt;span&gt;    (specification
&lt;&#x2F;span&gt;&lt;span&gt;    (name &amp;quot;hello&amp;quot;)
&lt;&#x2F;span&gt;&lt;span&gt;    (build &amp;#39;hello))
&lt;&#x2F;span&gt;&lt;span&gt;    (specification
&lt;&#x2F;span&gt;&lt;span&gt;    (name &amp;#39;snamguix)
&lt;&#x2F;span&gt;&lt;span&gt;    (build &amp;#39;(channels . (snamguix)))
&lt;&#x2F;span&gt;&lt;span&gt;    (channels
&lt;&#x2F;span&gt;&lt;span&gt;    (cons (channel
&lt;&#x2F;span&gt;&lt;span&gt;            (name &amp;#39;snamguix)
&lt;&#x2F;span&gt;&lt;span&gt;            (url &amp;quot;https:&#x2F;&#x2F;forge.snamellit.com&#x2F;pti&#x2F;snamguix.git&amp;quot;)
&lt;&#x2F;span&gt;&lt;span&gt;            (branch &amp;quot;main&amp;quot;))
&lt;&#x2F;span&gt;&lt;span&gt;            %default-channels)))))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;then replace the empty list in the &lt;em&gt;cuirass-service&lt;&#x2F;em&gt; :&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;       (service cuirass-service-type
&lt;&#x2F;span&gt;&lt;span&gt;                (cuirass-configuration
&lt;&#x2F;span&gt;&lt;span&gt;                 (specifications %cuirass-specifications)))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;reconfigure your system and restart &lt;em&gt;cuirass&lt;&#x2F;em&gt; with &lt;code&gt;sudo herd restart cuirass&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;It is not &lt;em&gt;really&lt;&#x2F;em&gt; needed as it was already added to the database, but this will be useful when the CI server need to be repaved.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Terraform workflow using Guix and Emacs</title>
          <pubDate>Wed, 05 Jun 2024 00:00:00 +0000</pubDate>
          <author>Peter Tillemans</author>
          <link>https://www.snamellit.com/posts/terraform-workflow-using-guix-and-emacs/</link>
          <guid>https://www.snamellit.com/posts/terraform-workflow-using-guix-and-emacs/</guid>
          <description xml:base="https://www.snamellit.com/posts/terraform-workflow-using-guix-and-emacs/">&lt;h1 id=&quot;terraform-deployments&quot;&gt;Terraform Deployments&lt;&#x2F;h1&gt;
&lt;p&gt;Terraform allows infrastructure to be defined to deploy applications
and other solutions as code and supports a plethora of on-premise and
cloud deployment targets.&lt;&#x2F;p&gt;
&lt;p&gt;It is essentially based on building a graph of dependencies between
resources, data and modules using the terraform language.&lt;&#x2F;p&gt;
&lt;p&gt;Due to the nature of the beast these things tend to run in the CI
pipelines which makes editing these files frustrating as the edits
have to be committed, pushed, runners have to be scheduled and usually
the deploy pipeline is not the first job.&lt;&#x2F;p&gt;
&lt;p&gt;So good local tooling is needed to get fast feedback.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;terraform-tooling-on-guix&quot;&gt;Terraform tooling on GUIX&lt;&#x2F;h1&gt;
&lt;p&gt;In order to run terraform I need to first package it as it is not
available in the GUIX repositories.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;lisp&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-lisp &quot;&gt;&lt;code class=&quot;language-lisp&quot; data-lang=&quot;lisp&quot;&gt;&lt;span&gt;(define&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;public terraform
&lt;&#x2F;span&gt;&lt;span&gt;  (package
&lt;&#x2F;span&gt;&lt;span&gt;   (name &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;snam-terraform&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;   (version &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;1.8.4&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;   (source (origin
&lt;&#x2F;span&gt;&lt;span&gt;            (method url&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;fetch)
&lt;&#x2F;span&gt;&lt;span&gt;            (uri (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;string&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;append &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;https:&#x2F;&#x2F;releases.hashicorp.com&#x2F;terraform&#x2F;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; version &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;&#x2F;terraform_&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; version &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;_linux_amd64.zip&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;))
&lt;&#x2F;span&gt;&lt;span&gt;            (sha256
&lt;&#x2F;span&gt;&lt;span&gt;             (base32
&lt;&#x2F;span&gt;&lt;span&gt;	       &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;1i181cmzwlrx8d40z1spilcwgnhkzwalrg8822d23sqdmrs7a5hj&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;))))
&lt;&#x2F;span&gt;&lt;span&gt;   (build&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;system binary&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;build&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;system)
&lt;&#x2F;span&gt;&lt;span&gt;   (supported&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;systems &amp;#39;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;x86_64-linux&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;))
&lt;&#x2F;span&gt;&lt;span&gt;   (arguments &amp;#39;(
&lt;&#x2F;span&gt;&lt;span&gt;      #:install-plan
&lt;&#x2F;span&gt;&lt;span&gt;      `((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;.&amp;quot; &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;terraform&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;bin&#x2F;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;))
&lt;&#x2F;span&gt;&lt;span&gt;      #:phases
&lt;&#x2F;span&gt;&lt;span&gt;      (modify&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;phases %standard&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;phases
&lt;&#x2F;span&gt;&lt;span&gt;		     &lt;&#x2F;span&gt;&lt;span style=&quot;color:#616e88;&quot;&gt;;; this is required because standard unpack expects
&lt;&#x2F;span&gt;&lt;span&gt;		     &lt;&#x2F;span&gt;&lt;span style=&quot;color:#616e88;&quot;&gt;;; the archive to contain a directory with everything inside it,
&lt;&#x2F;span&gt;&lt;span&gt;		     &lt;&#x2F;span&gt;&lt;span style=&quot;color:#616e88;&quot;&gt;;; while babashka&amp;#39;s release .tar.gz only contains the `bb` binary.
&lt;&#x2F;span&gt;&lt;span&gt;		     (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;replace&lt;&#x2F;span&gt;&lt;span&gt; &amp;#39;unpack
&lt;&#x2F;span&gt;&lt;span&gt;			      (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;lambda&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span&gt;(#:key inputs #:allow-other-keys)
&lt;&#x2F;span&gt;&lt;span&gt;				(system&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span&gt;(which &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;unzip&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;					 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;assoc&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;ref inputs &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;source&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;))
&lt;&#x2F;span&gt;&lt;span&gt;				#t)))))
&lt;&#x2F;span&gt;&lt;span&gt;   (inputs
&lt;&#x2F;span&gt;&lt;span&gt;    `((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;libstdc++&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; ,(make&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;libstdc&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;++&lt;&#x2F;span&gt;&lt;span&gt; gcc))
&lt;&#x2F;span&gt;&lt;span&gt;      (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;zlib&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; ,zlib)))
&lt;&#x2F;span&gt;&lt;span&gt;   (native&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;inputs
&lt;&#x2F;span&gt;&lt;span&gt;    `((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;unzip&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; ,unzip)))
&lt;&#x2F;span&gt;&lt;span&gt;   (synopsis &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;A tool to describe and deploy infrastructure as code&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;   (description
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;Terraform allows you to describe your complete infrastructure in the form of code. Even if your servers come from different providers such as AWS or Azure, Terraform helps you build and manage these resources in parallel across providers.&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;   (home&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;page &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;https:&#x2F;&#x2F;hashicorp.com&#x2F;terraform&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;   (license #f)))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(define&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;public snam&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;terraform&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;1.6
&lt;&#x2F;span&gt;&lt;span&gt;  (package
&lt;&#x2F;span&gt;&lt;span&gt;    (inherit terraform)
&lt;&#x2F;span&gt;&lt;span&gt;    (version &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;1.6.6&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    (source (origin
&lt;&#x2F;span&gt;&lt;span&gt;             (method url&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;fetch)
&lt;&#x2F;span&gt;&lt;span&gt;             (uri (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;string&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;append &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;https:&#x2F;&#x2F;releases.hashicorp.com&#x2F;terraform&#x2F;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; version &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;&#x2F;terraform_&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; version &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;_linux_amd64.zip&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;))
&lt;&#x2F;span&gt;&lt;span&gt;             (sha256
&lt;&#x2F;span&gt;&lt;span&gt;              (base32
&lt;&#x2F;span&gt;&lt;span&gt;	       &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;002g0ypkkfqy5nf989jyk3m1l7l0455hsaq11xfhr5lbv4zqh5yi&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;))))))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I immediately added support to build older versions because that&#x27;s
what the customer is on and terraform is quite version dependent
AFAICT.&lt;&#x2F;p&gt;
&lt;p&gt;Now I can create a manifest for this project. I usually bootstrap them
with &lt;code&gt;guile shell --export-manifes go gopls&lt;&#x2F;code&gt; or similar and then add
stuff when it comes up.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;lisp&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-lisp &quot;&gt;&lt;code class=&quot;language-lisp&quot; data-lang=&quot;lisp&quot;&gt;&lt;span style=&quot;color:#616e88;&quot;&gt;;; What follows is a &amp;quot;manifest&amp;quot; equivalent to the command line you gave.
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#616e88;&quot;&gt;;; You can store it in a file that you may then pass to any &amp;#39;guix&amp;#39; command
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#616e88;&quot;&gt;;; that accepts a &amp;#39;--manifest&amp;#39; (or &amp;#39;-m&amp;#39;) option.
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(specifications&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;manifest
&lt;&#x2F;span&gt;&lt;span&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;list &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;go&amp;quot; &amp;quot;gopls&amp;quot; 
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;google-cloud-sdk&amp;quot; 
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;postgresql&amp;quot; 
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;snam-terraform-1.6&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#616e88;&quot;&gt;; from snamellit channel
&lt;&#x2F;span&gt;&lt;span&gt;        ))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;direnv-support&quot;&gt;Direnv support&lt;&#x2F;h1&gt;
&lt;p&gt;In order to manage my project environment and align it with the CI
environment I added the expected variables and use the guix support in
the stdlib of direnv. This will create a guix environment configured
from the manifest.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;lisp&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-lisp &quot;&gt;&lt;code class=&quot;language-lisp&quot; data-lang=&quot;lisp&quot;&gt;&lt;span&gt;use guix
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;export DB_URL=&amp;quot;postgresql:&#x2F;&#x2F;&amp;lt;db_ip&amp;gt;&#x2F;myproj&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;export DB_USER=&amp;quot;xyz&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;export DB_PASSWORD=&amp;quot;secret&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;export PGPASSWORD=$DB_PASSWORD
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;export VAULT_TOKEN=&amp;quot;&amp;lt;blablabla&amp;gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;export APPTIO_URL=https:&#x2F;&#x2F;acme.tpondemand.com
&lt;&#x2F;span&gt;&lt;span&gt;export APPTIO_TOKEN=&amp;lt;blablabla&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;export OPENAI_API_KEY=&amp;lt;blablabla&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;export VAULT_ADDR=https:&#x2F;&#x2F;vault.acme.com
&lt;&#x2F;span&gt;&lt;span&gt;export STATE_BUCKET=com-acme-test-myproj-tf-state
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;export TF_VAR_project_short=myproj
&lt;&#x2F;span&gt;&lt;span&gt;export TF_VAR_project=com-acme-test-${TF_VAR_project_short}
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;PATH_add .&#x2F;node_modules&#x2F;.bin
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;emacs-support&quot;&gt;Emacs support&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;direnv-support-1&quot;&gt;Direnv Support&lt;&#x2F;h2&gt;
&lt;p&gt;Emacs &lt;em&gt;direnv mode&lt;&#x2F;em&gt; will load the configuration from the &lt;em&gt;.envrc&lt;&#x2F;em&gt; file
when opening a file in that project. The variables and apps are then
available for complition, LSP, shell, etc.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;lisp&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-lisp &quot;&gt;&lt;code class=&quot;language-lisp&quot; data-lang=&quot;lisp&quot;&gt;&lt;span style=&quot;color:#616e88;&quot;&gt;;; enable direnv mode
&lt;&#x2F;span&gt;&lt;span&gt;(direnv&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;mode)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I just enable it globally because I want that always, not just for
terraform.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;terraform-support&quot;&gt;Terraform Support&lt;&#x2F;h2&gt;
&lt;p&gt;Enable some syntax highlighting and more importantly documentation
help. Also set &lt;code&gt;format-on-save&lt;&#x2F;code&gt; and the indent to 2 spaces&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;lisp&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-lisp &quot;&gt;&lt;code class=&quot;language-lisp&quot; data-lang=&quot;lisp&quot;&gt;&lt;span style=&quot;color:#616e88;&quot;&gt;;; configure terraform support
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;require&lt;&#x2F;span&gt;&lt;span&gt; &amp;#39;terraform&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;mode)
&lt;&#x2F;span&gt;&lt;span&gt;(add&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;hook &amp;#39;terraform&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;mode&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;hook 
&lt;&#x2F;span&gt;&lt;span&gt;          (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;lambda &lt;&#x2F;span&gt;&lt;span&gt;()
&lt;&#x2F;span&gt;&lt;span&gt;            (outline&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;minor&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;mode &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;)))
&lt;&#x2F;span&gt;&lt;span&gt;(custom&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;set&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;variables
&lt;&#x2F;span&gt;&lt;span&gt; &amp;#39;(terraform&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;indent&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;level &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt; &amp;#39;(terraform&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;format&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;on&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;save &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;t&lt;&#x2F;span&gt;&lt;span&gt;))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;and expose the functionality in similar keybindings as I use for LSP
support :&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;(evil-define-key &amp;#39;normal terraform-mode-map
&lt;&#x2F;span&gt;&lt;span&gt;  (kbd &amp;quot;&amp;lt;leader&amp;gt;c k&amp;quot;) #&amp;#39;terraform-open-doc
&lt;&#x2F;span&gt;&lt;span&gt;  (kbd &amp;quot;&amp;lt;leader&amp;gt;c f&amp;quot;) #&amp;#39;terraform-format
&lt;&#x2F;span&gt;&lt;span&gt;  (kbd &amp;quot;&amp;lt;leader&amp;gt;c F&amp;quot;) #&amp;#39;terraform-format-buffer
&lt;&#x2F;span&gt;&lt;span&gt;  (kbd &amp;quot;&amp;lt;leader&amp;gt;c n&amp;quot;) &amp;#39;flymake-goto-next-error
&lt;&#x2F;span&gt;&lt;span&gt;  (kbd &amp;quot;&amp;lt;leader&amp;gt;c p&amp;quot;) &amp;#39;flymake-goto-prev-error)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;em&gt;&lt;SPACE c k&gt;&lt;&#x2F;em&gt; will now open a browser window with the documentation of
the terraform element under the cursor. This does need terraform to be
installed though.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;add-support-to-makefile&quot;&gt;Add support to Makefile&lt;&#x2F;h2&gt;
&lt;p&gt;In order to save me from remembering the commandlines and because I
keep the terraform files in a &lt;em&gt;terraform&lt;&#x2F;em&gt; directory I make some &lt;em&gt;make&lt;&#x2F;em&gt;
targets to quickly access them.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;makefile&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-makefile &quot;&gt;&lt;code class=&quot;language-makefile&quot; data-lang=&quot;makefile&quot;&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;tfinit&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;: 
&lt;&#x2F;span&gt;&lt;span&gt;	&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;terraform&lt;&#x2F;span&gt;&lt;span&gt; -chdir&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;terraform init -backend-config&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;bucket=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;${&lt;&#x2F;span&gt;&lt;span&gt;STATE_BUCKET&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;tfcheck&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;	&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;terraform&lt;&#x2F;span&gt;&lt;span&gt; -chdir&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;terraform validate
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;tfapply&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;	&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;terraform&lt;&#x2F;span&gt;&lt;span&gt; -chdir&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;terraform apply
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;tfplan&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;	&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;terraform&lt;&#x2F;span&gt;&lt;span&gt; -chdir&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;terraform plan
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;tflint&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;	&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;docker&lt;&#x2F;span&gt;&lt;span&gt; run --rm -v `&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;pwd&lt;&#x2F;span&gt;&lt;span&gt;`&#x2F;terraform:&#x2F;data -t ghcr.io&#x2F;terraform-linters&#x2F;tflint
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;workflow-tips&quot;&gt;Workflow tips&lt;&#x2F;h1&gt;
&lt;p&gt;Most of it is essentially hidden in the normal workflow. i.e. opening
a terraform file will load it, saving formats it. The &lt;em&gt;compile&lt;&#x2F;em&gt; feature
can be used to do file checking and linting.&lt;&#x2F;p&gt;
&lt;p&gt;Magit commit - push triggers the CI pipeline to run the deploy.&lt;&#x2F;p&gt;
&lt;p&gt;It is easy to test things out locally with the Makefile and it reduces
the number of steps in the CI script , so less things which can do
weird things.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>KeePassXC from flatpak</title>
          <pubDate>Sun, 12 May 2024 00:00:00 +0000</pubDate>
          <author>Peter Tillemans</author>
          <link>https://www.snamellit.com/posts/keepassxc-and-flatpak/</link>
          <guid>https://www.snamellit.com/posts/keepassxc-and-flatpak/</guid>
          <description xml:base="https://www.snamellit.com/posts/keepassxc-and-flatpak/">&lt;h1 id=&quot;table-of-contents&quot;&gt;Table of Contents&lt;&#x2F;h1&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;www.snamellit.com&#x2F;posts&#x2F;keepassxc-and-flatpak&#x2F;#orgd08a78a&quot;&gt;KeePassXC from flatpak&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;www.snamellit.com&#x2F;posts&#x2F;keepassxc-and-flatpak&#x2F;#orgfed6df2&quot;&gt;Allow access to the socket file&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;www.snamellit.com&#x2F;posts&#x2F;keepassxc-and-flatpak&#x2F;#org95da879&quot;&gt;keepassxc-proxy&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;www.snamellit.com&#x2F;posts&#x2F;keepassxc-and-flatpak&#x2F;#orgacf3b27&quot;&gt;Configure Chrome&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;www.snamellit.com&#x2F;posts&#x2F;keepassxc-and-flatpak&#x2F;#org93487a3&quot;&gt;Configure Brave&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;www.snamellit.com&#x2F;posts&#x2F;keepassxc-and-flatpak&#x2F;#org3956323&quot;&gt;Configure Firefox&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;www.snamellit.com&#x2F;posts&#x2F;keepassxc-and-flatpak&#x2F;#org2844960&quot;&gt;references&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;&lt;a id=&quot;orgd08a78a&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;keepassxc-from-flatpak&quot;&gt;KeePassXC from flatpak&lt;&#x2F;h1&gt;
&lt;p&gt;More and more browsers are coming packaged in containers like flatpak or snaps. Especially the ones of the chromium variety.&lt;&#x2F;p&gt;
&lt;p&gt;Since browsers are at the best of times scary things with arbitrary code being executed in every webpage runnning them in a sandbox makes a lot of sense.&lt;&#x2F;p&gt;
&lt;p&gt;However the sandbox also impacts communication with helpers like the password manager KeepassXC.&lt;&#x2F;p&gt;
&lt;p&gt;In order to keep things reproducible on many machines, if we&#x27;re going to fight with flatpak we might as well run keepassxc as a flatpak.&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;$ flatpak install org.keepassxc.KeePassXC
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;a id=&quot;orgfed6df2&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;allow-access-to-the-socket-file&quot;&gt;Allow access to the socket file&lt;&#x2F;h1&gt;
&lt;p&gt;Allow read-only access to the keepassxc socket at
$XDG&lt;sub&gt;RUNTIME&lt;&#x2F;sub&gt;&lt;sub&gt;DIR&lt;&#x2F;sub&gt;&#x2F;org.keepassxc.KeePassXC.BrowserServer:ro :&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;$ flatpak override --user \
&lt;&#x2F;span&gt;&lt;span&gt;  --filesystem=xdg-run&#x2F;app&#x2F;org.keepassxc.KeePassXC:ro \
&lt;&#x2F;span&gt;&lt;span&gt;  com.google.Chrome
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;this needs to be done for each flatpak application needing access to keepassxc.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a id=&quot;org95da879&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;keepassxc-proxy&quot;&gt;keepassxc-proxy&lt;&#x2F;h1&gt;
&lt;p&gt;There is  a statically compiled rust based socket proxy.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;varjolintu&#x2F;keepassxc-proxy-rust&quot;&gt;rust based keepassxc proxy&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;It can be compiled with MUSL for a fully static executable.&lt;&#x2F;p&gt;
&lt;p&gt;Place it together with the configuration file&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;a id=&quot;orgacf3b27&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;configure-chrome&quot;&gt;Configure Chrome&lt;&#x2F;h1&gt;
&lt;p&gt;The Chrome flatpak can be configured in the folder
*~&#x2F;.var&#x2F;app&#x2F;com.google.Chrome :&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;❯ ls .var&#x2F;app&#x2F;com.google.Chrome&#x2F;config&#x2F;google-chrome&#x2F;NativeMessagingHosts 
&lt;&#x2F;span&gt;&lt;span&gt;keepassxc-proxy  org.keepassxc.keepassxc_browser.json
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;the native messaging config file needs to be configured for the local
user:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    &amp;quot;allowed_origins&amp;quot;: [
&lt;&#x2F;span&gt;&lt;span&gt;        &amp;quot;chrome-extension:&#x2F;&#x2F;pdffhmdngciaglkoonimfcmckehcpafo&#x2F;&amp;quot;,
&lt;&#x2F;span&gt;&lt;span&gt;        &amp;quot;chrome-extension:&#x2F;&#x2F;oboonakemofpalcgghocfoadofidjkkk&#x2F;&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;    ],
&lt;&#x2F;span&gt;&lt;span&gt;    &amp;quot;description&amp;quot;: &amp;quot;KeePassXC integration with native messaging support&amp;quot;,
&lt;&#x2F;span&gt;&lt;span&gt;    &amp;quot;name&amp;quot;: &amp;quot;org.keepassxc.keepassxc_browser&amp;quot;,
&lt;&#x2F;span&gt;&lt;span&gt;    &amp;quot;path&amp;quot;: &amp;quot;&#x2F;home&#x2F;pti&#x2F;.var&#x2F;app&#x2F;com.google.Chrome&#x2F;config&#x2F;google-chrome&#x2F;NativeMessagingHosts&#x2F;keepassxc-proxy&amp;quot;,
&lt;&#x2F;span&gt;&lt;span&gt;    &amp;quot;type&amp;quot;: &amp;quot;stdio&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;and do not forget to give access to the socket&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;$ flatpak override --user --filesystem=xdg-run&#x2F;app&#x2F;org.keepassxc.KeePassXC:ro com.google.Chrome
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Notes;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;the &lt;strong&gt;path&lt;&#x2F;strong&gt; field needs to contain the full path including the username
AFAICT.&lt;&#x2F;li&gt;
&lt;li&gt;The extension id can be stolen from the URL box when going into the
settings pane of the extension. It has changed in the past.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;a id=&quot;org93487a3&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;configure-brave&quot;&gt;Configure Brave&lt;&#x2F;h1&gt;
&lt;p&gt;we need again an &lt;strong&gt;org.keepassxc.keepassxc&lt;sub&gt;browser.json&lt;&#x2F;sub&gt;&lt;&#x2F;strong&gt; file in
&lt;strong&gt;~&#x2F;.var&#x2F;app&#x2F;com.brave.Browser&#x2F;config&#x2F;BraveSoftware&#x2F;Brave-Browser&#x2F;NativeMessagingHosts&#x2F;&lt;&#x2F;strong&gt;
folder together with an executable version of the proxy compiled above.&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    &amp;quot;allowed_origins&amp;quot;: [
&lt;&#x2F;span&gt;&lt;span&gt;        &amp;quot;chrome-extension:&#x2F;&#x2F;pdffhmdngciaglkoonimfcmckehcpafo&#x2F;&amp;quot;,
&lt;&#x2F;span&gt;&lt;span&gt;        &amp;quot;chrome-extension:&#x2F;&#x2F;oboonakemofpalcgghocfoadofidjkkk&#x2F;&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;    ],
&lt;&#x2F;span&gt;&lt;span&gt;    &amp;quot;description&amp;quot;: &amp;quot;KeePassXC integration with native messaging support&amp;quot;,
&lt;&#x2F;span&gt;&lt;span&gt;    &amp;quot;name&amp;quot;: &amp;quot;org.keepassxc.keepassxc_browser&amp;quot;,
&lt;&#x2F;span&gt;&lt;span&gt;    &amp;quot;path&amp;quot;: &amp;quot;&#x2F;home&#x2F;pti&#x2F;.var&#x2F;app&#x2F;com.brave.Browser&#x2F;config&#x2F;BraveSoftware&#x2F;Brave-Browser&#x2F;NativeMessagingHosts&#x2F;keepassxc-proxy&amp;quot;,
&lt;&#x2F;span&gt;&lt;span&gt;    &amp;quot;type&amp;quot;: &amp;quot;stdio&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;You can copy it from the Google Chrome config but do not forget to
update the path to the proxy.&lt;&#x2F;p&gt;
&lt;p&gt;Now we still need to give access to brave to the keepassxc socket:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;$ flatpak override --user --filesystem=xdg-run&#x2F;app&#x2F;org.keepassxc.KeePassXC:ro com.brave.Browser
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;a id=&quot;org3956323&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;configure-firefox&quot;&gt;Configure Firefox&lt;&#x2F;h1&gt;
&lt;p&gt;I have firefox running native on my laptop so these shenanigans are
not needed. However the example I based most of was for firefox so I
assume it works similar. Note that the native messaging file is
different for firefox.&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    &amp;quot;allowed_extensions&amp;quot;: [
&lt;&#x2F;span&gt;&lt;span&gt;        &amp;quot;keepassxc-browser@keepassxc.org&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;    ],
&lt;&#x2F;span&gt;&lt;span&gt;    &amp;quot;description&amp;quot;: &amp;quot;KeePassXC integration with native messaging support, workaround for flatpaked Firefox, see https:&#x2F;&#x2F;is.gd&#x2F;flatpakFirefoxKPXC&amp;quot;,
&lt;&#x2F;span&gt;&lt;span&gt;    &amp;quot;name&amp;quot;: &amp;quot;org.keepassxc.keepassxc_browser&amp;quot;,
&lt;&#x2F;span&gt;&lt;span&gt;    &amp;quot;path&amp;quot;: &amp;quot;&#x2F;home&#x2F;pti&#x2F;.var&#x2F;app&#x2F;org.mozilla.firefox&#x2F;.mozilla&#x2F;native-messaging-hosts&#x2F;keepassxc-proxy&amp;quot;,
&lt;&#x2F;span&gt;&lt;span&gt;    &amp;quot;type&amp;quot;: &amp;quot;stdio&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;it uses &lt;strong&gt;allowed&lt;sub&gt;extensions&lt;&#x2F;sub&gt;&lt;&#x2F;strong&gt; iso &lt;strong&gt;allowed&lt;sub&gt;origin&lt;&#x2F;sub&gt;&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;And give access to the socker file to firefox&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;$ flatpak override --user --filesystem=xdg-run&#x2F;app&#x2F;org.keepassxc.KeePassXC:ro org.mozilla.firefox
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;a id=&quot;org2844960&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;references&quot;&gt;references&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;discourse.flathub.org&#x2F;t&#x2F;how-to-run-firefox-and-keepassxc-in-a-flatpak-and-get-the-keepassxc-browser-add-on-to-work&#x2F;437&quot;&gt;post on discourse flathub&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;varjolintu&#x2F;keepassxc-proxy-rust&quot;&gt;rust based keepassxc proxy&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;developer.chrome.com&#x2F;docs&#x2F;extensions&#x2F;develop&#x2F;concepts&#x2F;native-messaging&quot;&gt;Google Chrome documentation for Native Messaging&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;keepassxreboot&#x2F;keepassxc-browser&#x2F;issues&#x2F;1631&quot;&gt;Github Issue on keepassxc&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;keepassxreboot&#x2F;keepassxc-browser&#x2F;issues&#x2F;1267&quot;&gt;issue 1267 on keepassxc&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</description>
      </item>
      <item>
          <title>Issue with SBCL console output in Sly</title>
          <pubDate>Sat, 13 Apr 2024 00:00:00 +0000</pubDate>
          <author>Peter Tillemans</author>
          <link>https://www.snamellit.com/posts/sly-repl-io-issues/</link>
          <guid>https://www.snamellit.com/posts/sly-repl-io-issues/</guid>
          <description xml:base="https://www.snamellit.com/posts/sly-repl-io-issues/">&lt;h1 id=&quot;inconsistent-output-in-repl&quot;&gt;Inconsistent output in REPL&lt;&#x2F;h1&gt;
&lt;p&gt;When doing the examples in the &lt;em&gt;Practical Common Lisp&lt;&#x2F;em&gt; book I had confusing output in the repl when prompting the user for CDs using SBCL.&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;; Dedicated output stream setup (port 46185)
&lt;&#x2F;span&gt;&lt;span&gt;; Redirecting all output to this MREPL
&lt;&#x2F;span&gt;&lt;span&gt;; SLY 1.0.43 (#&amp;lt;MREPL mrepl-1-1&amp;gt;)
&lt;&#x2F;span&gt;&lt;span&gt;CL-USER&amp;gt; (prompt-for-cd)
&lt;&#x2F;span&gt;&lt;span&gt;Title: Unplugged
&lt;&#x2F;span&gt;&lt;span&gt;Eric Clapton 
&lt;&#x2F;span&gt;&lt;span&gt;8
&lt;&#x2F;span&gt;&lt;span&gt;y
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Apparently a similar issue was first found on MacOSX and later confirmed on Arch.&lt;&#x2F;p&gt;
&lt;p&gt;The suggestion was given to disable passing the output via a socket to have higher performance that via the protocol by adding&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;(setf slynk:*use-dedicated-output-stream* nil)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Since I rather have something working than it being highly performant and not-working I followed the suggestion which fixed the issue:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;CL-USER&amp;gt; (prompt-for-cd)
&lt;&#x2F;span&gt;&lt;span&gt;Title: Bar 
&lt;&#x2F;span&gt;&lt;span&gt;Artist: Foo Fighters
&lt;&#x2F;span&gt;&lt;span&gt;Rating: 8
&lt;&#x2F;span&gt;&lt;span&gt;Ripped: y
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;y (y or n) y
&lt;&#x2F;span&gt;&lt;span&gt;(:TITLE &amp;quot;Bar &amp;quot; :ARTIST &amp;quot;Foo Fighters&amp;quot; :RATING 8 :RIPPED T)
&lt;&#x2F;span&gt;&lt;span&gt;CL-USER&amp;gt;  
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;so I can continue with the chapter.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Intercepting Bluetooth Keyboard Events</title>
          <pubDate>Thu, 14 Dec 2023 00:00:00 +0000</pubDate>
          <author>Peter Tillemans</author>
          <link>https://www.snamellit.com/posts/20231214-intercepting-bluetooth-keyboard-events/</link>
          <guid>https://www.snamellit.com/posts/20231214-intercepting-bluetooth-keyboard-events/</guid>
          <description xml:base="https://www.snamellit.com/posts/20231214-intercepting-bluetooth-keyboard-events/">&lt;h1 id=&quot;intercepting-bluetooth-keyboard-events&quot;&gt;Intercepting Bluetooth Keyboard Events&lt;&#x2F;h1&gt;
&lt;p&gt;I like keyboards and I like custom keyboards. However many do not allow sufficient configuration to let
a key be Ctrl on hold and Esc on top. Notably the HHKB.&lt;&#x2F;p&gt;
&lt;p&gt;USB devices are nicely listed in &lt;em&gt;&#x2F;dev&#x2F;input&#x2F;by-id&#x2F;&lt;&#x2F;em&gt; folder but on my system the event device is anonymously placed in &lt;em&gt;&#x2F;dev&#x2F;input&#x2F;&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;figuring-out-the-name&quot;&gt;Figuring out the name&lt;&#x2F;h2&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;❯ for dev in &#x2F;dev&#x2F;input&#x2F;*; do udevadm info --attribute-walk $dev; done | grep -A10 -B10 Keyboard
&lt;&#x2F;span&gt;&lt;span&gt;Unknown device &amp;quot;&#x2F;dev&#x2F;input&#x2F;by-id&amp;quot;: No such device
&lt;&#x2F;span&gt;&lt;span&gt;Unknown device &amp;quot;&#x2F;dev&#x2F;input&#x2F;by-path&amp;quot;: No such device
&lt;&#x2F;span&gt;&lt;span&gt;    ATTRS{capabilities&#x2F;led}==&amp;quot;1f&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;    ATTRS{capabilities&#x2F;msc}==&amp;quot;10&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;    ATTRS{capabilities&#x2F;rel}==&amp;quot;0&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;    ATTRS{capabilities&#x2F;snd}==&amp;quot;0&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;    ATTRS{capabilities&#x2F;sw}==&amp;quot;0&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;    ATTRS{id&#x2F;bustype}==&amp;quot;0005&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;    ATTRS{id&#x2F;product}==&amp;quot;0021&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;    ATTRS{id&#x2F;vendor}==&amp;quot;04fe&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;    ATTRS{id&#x2F;version}==&amp;quot;0001&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;    ATTRS{inhibited}==&amp;quot;0&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;    ATTRS{name}==&amp;quot;HHKB-Hybrid_1 Keyboard&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;    ATTRS{phys}==&amp;quot;04:33:c2:f4:e9:70&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;    ATTRS{power&#x2F;control}==&amp;quot;auto&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;    ATTRS{power&#x2F;runtime_active_time}==&amp;quot;0&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;    ATTRS{power&#x2F;runtime_status}==&amp;quot;unsupported&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;    ATTRS{power&#x2F;runtime_suspended_time}==&amp;quot;0&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;    ATTRS{properties}==&amp;quot;0&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;    ATTRS{uniq}==&amp;quot;cb:7a:7c:03:2d:f2&amp;quot;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;for other keyboards a bit of finagling for searching with grep might be needed or pipe into &lt;em&gt;less&lt;&#x2F;em&gt; and scroll till you find it.&lt;&#x2F;p&gt;
&lt;p&gt;Now I can add it to my *&#x2F;etc&#x2F;interception&#x2F;udevmon.d&#x2F;ctrl_tap_esc.yaml :&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;- JOB: &amp;quot;intercept -g $DEVNODE | dual-function-keys -c &#x2F;etc&#x2F;interception&#x2F;dual-function-keys.yaml | uinput -d $DEVNODE&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;  DEVICE:
&lt;&#x2F;span&gt;&lt;span&gt;    NAME: &amp;quot;PFU Limited HHKB-Hybrid&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;    EVENTS: 
&lt;&#x2F;span&gt;&lt;span&gt;      EV_KEY: [KEY_LEFTCTRL]
&lt;&#x2F;span&gt;&lt;span&gt;- JOB: &amp;quot;intercept -g $DEVNODE | dual-function-keys -c &#x2F;etc&#x2F;interception&#x2F;dual-function-keys.yaml | uinput -d $DEVNODE&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;  DEVICE:
&lt;&#x2F;span&gt;&lt;span&gt;    NAME: &amp;quot;PFU Limited HHKB-Hybrid Keyboard&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;    EVENTS: 
&lt;&#x2F;span&gt;&lt;span&gt;      EV_KEY: [KEY_LEFTCTRL]
&lt;&#x2F;span&gt;&lt;span&gt;- JOB: &amp;quot;intercept -g $DEVNODE | dual-function-keys -c &#x2F;etc&#x2F;interception&#x2F;dual-function-keys.yaml | uinput -d $DEVNODE&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;  DEVICE:
&lt;&#x2F;span&gt;&lt;span&gt;    NAME: &amp;quot;HHKB-Hybrid_1 Keyboard&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;    EVENTS: 
&lt;&#x2F;span&gt;&lt;span&gt;      EV_KEY: [KEY_LEFTCTRL]
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The first 2 are for USB but that is still a work in progress&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Emacs Debugging with Dape</title>
          <pubDate>Fri, 20 Oct 2023 00:00:00 +0000</pubDate>
          <author>Peter Tillemans</author>
          <link>https://www.snamellit.com/posts/dape/</link>
          <guid>https://www.snamellit.com/posts/dape/</guid>
          <description xml:base="https://www.snamellit.com/posts/dape/">&lt;p&gt;For reasons I keep a set of machines where I regularly work on in sync so they offer a familiar environment. This includes a dual boot desktop (Ubuntu&#x2F;Windows+WSL), laptop (Arch&#x2F;Windows+WSL), a VPS(Arch) doing stuff, a  virtual Ubuntu thing which is always running to monitor stuff on my NAS, and a Steam deck (Arch kinda). I expect these to be familiar environments so I can do some light development and scripting on them at least.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;test-plan&quot;&gt;Test plan&lt;&#x2F;h1&gt;
&lt;p&gt;In order to test the debugging support we need some minimum set of requirements to avoid descending in the abyss of incremental details.&lt;&#x2F;p&gt;
&lt;p&gt;To evaluate the configuration for a  language we need&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;a simple project in order not to be debugging the build system or the code itself taking more time than setting up the debugging. DAP is plenty complicated on its own.&lt;&#x2F;li&gt;
&lt;li&gt;The DAP adapter installed with minimal manual work because otherwise it wont get done and there will be too much variance&#x2F;rework between systems&lt;&#x2F;li&gt;
&lt;li&gt;A set of familiar keybindings&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;My requirements are:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;I can run the program in the debugger&lt;&#x2F;li&gt;
&lt;li&gt;I can pass command line arguments to the script&lt;&#x2F;li&gt;
&lt;li&gt;I can break the program on a line in the editor&lt;&#x2F;li&gt;
&lt;li&gt;I can examine variables in scope when the breakpoint is hit&lt;&#x2F;li&gt;
&lt;li&gt;I can see the output of the program&lt;&#x2F;li&gt;
&lt;li&gt;I can quit&#x2F;restart and there should not be leaking of processes&#x2F;network ports&#x2F;buffers. I.e. I can get back to editing and debugging without rebooting my PC.&lt;&#x2F;li&gt;
&lt;li&gt;(I would like to pass environment variables too, but since apparently direnv works fine for my purposes I hardly ever use it anymore, so keep that on the backburner for now.)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;I do not really use debugging for something else. I actually seldom use the debugger. Mostly for learning new programming languages or playing with libraries concepts. If things get hairy I return back to logging&#x2F;println debugging anyway (or adding more tests to herd the bugs in a small area).&lt;&#x2F;p&gt;
&lt;p&gt;My test procedure is as follows.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;open the source code&lt;&#x2F;li&gt;
&lt;li&gt;place a breakpoint early in the program after some variables are set&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;leader&amp;gt;dd&lt;&#x2F;code&gt; to start the debugger&lt;&#x2F;li&gt;
&lt;li&gt;curse on the dape prompt to select the program and pass arguments, set the &lt;em&gt;cwd&lt;&#x2F;em&gt; and more of that fun.&lt;&#x2F;li&gt;
&lt;li&gt;check if the breakpoint is hit&lt;&#x2F;li&gt;
&lt;li&gt;examine the variables&lt;&#x2F;li&gt;
&lt;li&gt;continue to see the program continue with &lt;code&gt;&amp;lt;leader&amp;gt;dc&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;quit the program with &lt;code&gt;&amp;lt;leader&amp;gt;dq&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;verify we are back in our familiar editing session&lt;&#x2F;li&gt;
&lt;li&gt;do a quick &lt;code&gt;ps ax&lt;&#x2F;code&gt; to see if we do not have unwanted critters still crawling around the process space.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;It is far from a comprehensive test, but we are testing here if the DAP adapter is properly installed and behaving as expected in my environment, not a validation test of the adapter itself.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;javascript-typescript-example&quot;&gt;Javascript&#x2F;Typescript example&lt;&#x2F;h2&gt;
&lt;p&gt;I assume that if I can debug typescript, I can debug javascript. So I created a little typescript program to calculate the answer to the meaning of life, the universe and everything.&lt;&#x2F;p&gt;
&lt;p&gt;But first installing the DAP adapter. It is a bit fiddly and I do not want to repeat that on all my systems so I let emacs to the heavy lifting. It are just the instructions from the &lt;em&gt;dape&lt;&#x2F;em&gt; repo:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;(setq snam-vscode-js-debug-dir (file-name-concat user-emacs-directory &amp;quot;dape&#x2F;vscode-js-debug&amp;quot;))
&lt;&#x2F;span&gt;&lt;span&gt;(defun snam-install-vscode-js-debug ()
&lt;&#x2F;span&gt;&lt;span&gt;  &amp;quot;Run installation procedure to install JS debugging support&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;  (interactive)
&lt;&#x2F;span&gt;&lt;span&gt;  (mkdir snam-vscode-js-debug-dir t)
&lt;&#x2F;span&gt;&lt;span&gt;  (let ((default-directory (expand-file-name snam-vscode-js-debug-dir)))
&lt;&#x2F;span&gt;&lt;span&gt;    
&lt;&#x2F;span&gt;&lt;span&gt;    (vc-git-clone &amp;quot;https:&#x2F;&#x2F;github.com&#x2F;microsoft&#x2F;vscode-js-debug.git&amp;quot; &amp;quot;.&amp;quot; nil)
&lt;&#x2F;span&gt;&lt;span&gt;    (message &amp;quot;git repository created&amp;quot;)
&lt;&#x2F;span&gt;&lt;span&gt;    (call-process &amp;quot;npm&amp;quot; nil &amp;quot;*snam-install*&amp;quot; t &amp;quot;install&amp;quot;)
&lt;&#x2F;span&gt;&lt;span&gt;    (message &amp;quot;npm dependencies installed&amp;quot;)
&lt;&#x2F;span&gt;&lt;span&gt;    (call-process &amp;quot;npx&amp;quot; nil &amp;quot;*snam-install*&amp;quot; t &amp;quot;gulp&amp;quot; &amp;quot;dapDebugServer&amp;quot;)
&lt;&#x2F;span&gt;&lt;span&gt;    (message &amp;quot;vscode-js-debug installed&amp;quot;)))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Then add the  dap config for the javascript and typescript modes:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;lisp&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-lisp &quot;&gt;&lt;code class=&quot;language-lisp&quot; data-lang=&quot;lisp&quot;&gt;&lt;span&gt;            (add&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-to-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;list&lt;&#x2F;span&gt;&lt;span&gt; &amp;#39;dape&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;configs
&lt;&#x2F;span&gt;&lt;span&gt;                         `(vscode&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;js&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;node
&lt;&#x2F;span&gt;&lt;span&gt;                           modes (js&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;mode js&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;ts&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;mode typescript&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;mode typescript&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;ts&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;mode)
&lt;&#x2F;span&gt;&lt;span&gt;                           host &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;localhost&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;                           port &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;8123
&lt;&#x2F;span&gt;&lt;span&gt;                           command &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;node&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;                           command&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;cwd ,(file&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;name&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;concat snam&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;vscode&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;js&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;debug&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;dir &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;dist&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;                           command&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;args (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;src&#x2F;dapDebugServer.js&amp;quot; &amp;quot;8123&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;                           :type &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;pwa-node&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;                           :request &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;launch&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;                           :cwd dape&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;cwd&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;fn
&lt;&#x2F;span&gt;&lt;span&gt;                           :program dape&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;find&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;file&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;buffer&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;default
&lt;&#x2F;span&gt;&lt;span&gt;                           :outputCapture &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;console&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;                           :sourceMapRenames &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;t
&lt;&#x2F;span&gt;&lt;span&gt;                           :pauseForSourceMap &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;nil
&lt;&#x2F;span&gt;&lt;span&gt;                           :enableContentValidation &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;t
&lt;&#x2F;span&gt;&lt;span&gt;                           :autoAttachChildProcesses &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;t
&lt;&#x2F;span&gt;&lt;span&gt;                           :console &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;internalConsole&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;                           :killBehavior &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;forceful&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The debugging our little app. Answer at the prompt:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;vscode-js-node :program &amp;quot;src&#x2F;main.ts&amp;quot; 
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;and the debug view opens:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.snamellit.com&#x2F;posts&#x2F;dape&#x2F;typescript_example.png&quot; alt=&quot;Typescript Debug Example&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;python-example&quot;&gt;Python example&lt;&#x2F;h2&gt;
&lt;p&gt;As indicated on the dape repo install the python DAP adapter&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;sh&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-sh &quot;&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt; pip install debugpy
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Add the default settings to &lt;code&gt;dape-configs&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;lisp&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-lisp &quot;&gt;&lt;code class=&quot;language-lisp&quot; data-lang=&quot;lisp&quot;&gt;&lt;span&gt;            (add&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-to-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;list&lt;&#x2F;span&gt;&lt;span&gt; &amp;#39;dape&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;configs
&lt;&#x2F;span&gt;&lt;span&gt;                         `(debugpy
&lt;&#x2F;span&gt;&lt;span&gt;                           modes (python&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;ts&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;mode python&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;mode)
&lt;&#x2F;span&gt;&lt;span&gt;                           command &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;c:&#x2F;Python312&#x2F;python.exe&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;                           command&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;args (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;-m&amp;quot; &amp;quot;debugpy.adapter&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;                           :type &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;executable&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;                           :request &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;launch&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;                           :cwd dape&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;cwd&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;fn
&lt;&#x2F;span&gt;&lt;span&gt;                           :program dape&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;find&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;file&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;buffer&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;default))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;and update the command to wherever python is installed. This is from my windows machine which succeeded again to lose its default python config so I have to coerce it a bit to find it.&lt;&#x2F;p&gt;
&lt;p&gt;Open a python file, and start the debugger. On the &lt;code&gt;Dape config:&lt;&#x2F;code&gt; prompt enter:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;debugpy :args [&amp;quot;6&amp;quot; &amp;quot;7&amp;quot;]
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;There are many more parameters, but &lt;em&gt;dape&lt;&#x2F;em&gt; will ask the missing ones with the functions in the configuration, here &lt;code&gt;dapy-cwd-fn&lt;&#x2F;code&gt; to fill in the current working directory (usually the project root) in the &lt;code&gt;:cwd&lt;&#x2F;code&gt; field and &lt;code&gt;dape-find-file-buffer-default&lt;&#x2F;code&gt; will propose the open file to run as the program to debug.&lt;&#x2F;p&gt;
&lt;p&gt;It cannot meaningfully guess which parameters I want to pass so I add manually the &lt;code&gt;:attr&lt;&#x2F;code&gt; field with the values &lt;code&gt;&quot;6&quot;&lt;&#x2F;code&gt; and &lt;code&gt;&quot;7&quot;&lt;&#x2F;code&gt; in a vector. Do not use a list for that as that is not properly encoded by the json converter.&lt;&#x2F;p&gt;
&lt;p&gt;It asks to confirm the program and opens the debugging views:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.snamellit.com&#x2F;posts&#x2F;dape&#x2F;python_example.png&quot; alt=&quot;Python debugging views&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;go-example&quot;&gt;Go Example&lt;&#x2F;h2&gt;
&lt;p&gt;Installing the go adapter is just installing &lt;em&gt;delve&lt;&#x2F;em&gt; with your favorite package manager. If your package manager does not help (looking at you, chocolatey):&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;sh&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-sh &quot;&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;go&lt;&#x2F;span&gt;&lt;span&gt; install github.com&#x2F;go-delve&#x2F;delve&#x2F;cmd&#x2F;dlv@latest
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I did not bother to emacsify this as it is completely different for all my systems and I probably revisit that some time if I have a good idea to somehow abstract the differences away.&lt;&#x2F;p&gt;
&lt;p&gt;Adding the config to &lt;code&gt;dape-configs&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;            (add-to-list &amp;#39;dape-configs
&lt;&#x2F;span&gt;&lt;span&gt;                         `(delve
&lt;&#x2F;span&gt;&lt;span&gt;                           modes (go-mode go-ts-mode)
&lt;&#x2F;span&gt;&lt;span&gt;                           command &amp;quot;dlv&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;                           command-args (&amp;quot;dap&amp;quot; &amp;quot;--listen&amp;quot; &amp;quot;127.0.0.1:55878&amp;quot;)
&lt;&#x2F;span&gt;&lt;span&gt;                           command-cwd dape-cwd-fn
&lt;&#x2F;span&gt;&lt;span&gt;                           host &amp;quot;127.0.0.1&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;                           port 55878
&lt;&#x2F;span&gt;&lt;span&gt;                           :type &amp;quot;debug&amp;quot;       ;; needed to set the adapterID correctly as a string type
&lt;&#x2F;span&gt;&lt;span&gt;                           :request &amp;quot;launch&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;                           :cwd dape-cwd-fn
&lt;&#x2F;span&gt;&lt;span&gt;                           :program dape-cwd-fn))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;see debugging tips for an experience report (I made some typo while copy pasting... ). I used it to illustrate how I got around installation hickups.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rust-example&quot;&gt;Rust Example&lt;&#x2F;h2&gt;
&lt;p&gt;Similar to Typescript I assume that if I can debug Rust, I should be able to debug C&#x2F;C++ (which I try to avoid as much as possible).&lt;&#x2F;p&gt;
&lt;p&gt;I automated the installation of the DAP adapter for LLD&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;lisp&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-lisp &quot;&gt;&lt;code class=&quot;language-lisp&quot; data-lang=&quot;lisp&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;setq&lt;&#x2F;span&gt;&lt;span&gt; snam&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;codelldb&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;dir (file&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;name&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;concat user&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;emacs&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;directory &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;dape&#x2F;codelldb&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;))
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;defun &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;snam-install-codelldb &lt;&#x2F;span&gt;&lt;span&gt;()
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;Install Vadimcn.Vscode-Lldb DAP server for C&#x2F;C++&#x2F;RUST&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;  (interactive)
&lt;&#x2F;span&gt;&lt;span&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;let* &lt;&#x2F;span&gt;&lt;span&gt;((default&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;directory&lt;&#x2F;span&gt;&lt;span&gt; snam&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;codelldb&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;dir)
&lt;&#x2F;span&gt;&lt;span&gt;         (arch (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;car &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;split&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt; system&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;configuration &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;-&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;nil nil&lt;&#x2F;span&gt;&lt;span&gt;)))
&lt;&#x2F;span&gt;&lt;span&gt;         (os (pcase system&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;type
&lt;&#x2F;span&gt;&lt;span&gt;               (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;windows&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;nt &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;windows&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;               (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;gnu&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;linux &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;linux&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;               (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;darwin &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;darwin&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;               (&amp;#39;_ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;unknown&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)))
&lt;&#x2F;span&gt;&lt;span&gt;         (version &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;1.10.0&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;         (release&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;url (concat &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;https:&#x2F;&#x2F;github.com&#x2F;vadimcn&#x2F;codelldb&#x2F;releases&#x2F;download&#x2F;v&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; version &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;&#x2F;codelldb-&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; arch &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;-&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; os &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;.vsix&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)))
&lt;&#x2F;span&gt;&lt;span&gt;    (mkdir default&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;directory &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;t&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    (url&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;copy&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;file release&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;url &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;codelldb.zip&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;t&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    (message &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;codelldb archive downloaded&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    (call&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;process &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;unzip&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;nil &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;*snam-install*&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;t &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;codelldb.zip&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    (message &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;codelldb installed&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    ))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Again this is just the installation instructions from the &lt;em&gt;dape&lt;&#x2F;em&gt; repo in emacs lisp.&lt;&#x2F;p&gt;
&lt;p&gt;adding the default config:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;lisp&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-lisp &quot;&gt;&lt;code class=&quot;language-lisp&quot; data-lang=&quot;lisp&quot;&gt;&lt;span&gt;            (add&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-to-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;list&lt;&#x2F;span&gt;&lt;span&gt; &amp;#39;dape&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;configs
&lt;&#x2F;span&gt;&lt;span&gt;                         `(codelldb
&lt;&#x2F;span&gt;&lt;span&gt;                           modes (c&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;mode c&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;ts&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;mode
&lt;&#x2F;span&gt;&lt;span&gt;                                         c&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;++-&lt;&#x2F;span&gt;&lt;span&gt;mode c&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;++-&lt;&#x2F;span&gt;&lt;span&gt;ts&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;mode
&lt;&#x2F;span&gt;&lt;span&gt;                                         rust&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;ts&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;mode rust&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;mode)
&lt;&#x2F;span&gt;&lt;span&gt;                           &lt;&#x2F;span&gt;&lt;span style=&quot;color:#616e88;&quot;&gt;;; Replace vadimcn.vscode-lldb with the vsix directory you just extracted
&lt;&#x2F;span&gt;&lt;span&gt;                           command ,(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;expand&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;file&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;name
&lt;&#x2F;span&gt;&lt;span&gt;                                     (file&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;name&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;concat
&lt;&#x2F;span&gt;&lt;span&gt;                                      snam&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;codelldb&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;dir
&lt;&#x2F;span&gt;&lt;span&gt;                                      (concat &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;extension&#x2F;adapter&#x2F;codelldb&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;                                              (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;eq&lt;&#x2F;span&gt;&lt;span&gt; system&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;type &amp;#39;windows&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;nt)
&lt;&#x2F;span&gt;&lt;span&gt;                                                  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;.exe&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;                                                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;))))
&lt;&#x2F;span&gt;&lt;span&gt;                           host &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;localhost&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;                           port &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;5818
&lt;&#x2F;span&gt;&lt;span&gt;                           command&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;args (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;--port&amp;quot; &amp;quot;5818&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;                           :type &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;lldb&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;                           :request &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;launch&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;                           :cwd dape&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;cwd&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;fn
&lt;&#x2F;span&gt;&lt;span&gt;                           :program dape&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;find&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;file))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Since here the DAP is a binary I have to finagle the Windows file extension to make it work.&lt;&#x2F;p&gt;
&lt;p&gt;Then opening a rust binary, here &lt;code&gt;src&#x2F;main.rs&lt;&#x2F;code&gt;, setting a breakpoint and launching the debugger.&lt;&#x2F;p&gt;
&lt;p&gt;I answered on the prompt&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;codelldb :args [&amp;quot;on&amp;quot;]
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;to specify the arguments for the program to be debugged.&lt;&#x2F;p&gt;
&lt;p&gt;Dape sees that the program is not specified so it asks for it and with tab completion &lt;code&gt;tar&amp;lt;TAB&amp;gt;deb&amp;lt;TAB&amp;gt;bil&amp;lt;TAB&amp;gt;&lt;&#x2F;code&gt; this is quickly selected and I am greeted with:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.snamellit.com&#x2F;posts&#x2F;dape&#x2F;rust_example.png&quot; alt=&quot;Rust debugging example&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;debugging-tips&quot;&gt;Debugging Tips&lt;&#x2F;h2&gt;
&lt;p&gt;When trying the Go example I hit a snag : the debugger started but no active thread was present.&lt;&#x2F;p&gt;
&lt;p&gt;First stop is to open &lt;code&gt;*dape_debug*&lt;&#x2F;code&gt; buffer :&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;[info] Starting new multi session
&lt;&#x2F;span&gt;&lt;span&gt;[info] Server process started (&amp;quot;dlv&amp;quot; &amp;quot;dap&amp;quot; &amp;quot;--listen&amp;quot; &amp;quot;127.0.0.1:55878&amp;quot;)
&lt;&#x2F;span&gt;&lt;span&gt;[info] 
&lt;&#x2F;span&gt;&lt;span&gt;Process (&amp;quot;dlv&amp;quot; &amp;quot;dap&amp;quot; &amp;quot;--listen&amp;quot; &amp;quot;127.0.0.1:55878&amp;quot;) exited with 1
&lt;&#x2F;span&gt;&lt;span&gt;[info] Connection to server established 127.0.0.1:55878
&lt;&#x2F;span&gt;&lt;span&gt;[io] Sending:
&lt;&#x2F;span&gt;&lt;span&gt;(:arguments
&lt;&#x2F;span&gt;&lt;span&gt; (:clientID &amp;quot;dape&amp;quot; :adapterID nil :pathFormat &amp;quot;path&amp;quot; :linesStartAt1 t :columnsStartAt1 t :supportsRunInTerminalRequest t :supportsProgressReporting t :supportsStartDebuggingRequest t)
&lt;&#x2F;span&gt;&lt;span&gt; :type &amp;quot;request&amp;quot; :command &amp;quot;initialize&amp;quot; :seq 1)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;[info] 
&lt;&#x2F;span&gt;&lt;span&gt;Process nil exited with 256
&lt;&#x2F;span&gt;&lt;span&gt;[error] Timeout for reached for seq 1
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;So the process immediately exits, but we see no output. It would be nice to get that in the buffer, but it isn&#x27;t...&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s steal the command and run it in a terminal :&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;Zeus :: ~ % dlv dap --listen 127.0.0.1:55878                                                                      &amp;gt;&amp;gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;DAP server listening at: 127.0.0.1:55878
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now restart the debugger by quitting the debug session and starting a fresh one (we cannot use the restart command as the adapter is not running, we need to restart the adapter not the debugged program).&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;Zeus :: ~ % dlv dap --listen 127.0.0.1:55878                                                                      &amp;gt;&amp;gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;DAP server listening at: 127.0.0.1:55878
&lt;&#x2F;span&gt;&lt;span&gt;2023-10-20T18:13:02+02:00 error layer=dap DAP error: json: cannot unmarshal bool into Go struct field InitializeRequestArguments.arguments.adapterID of type string
&lt;&#x2F;span&gt;&lt;span&gt;Zeus :: ~ %      
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Ok, the typechecker got a bool where it expected a string.  Opening &lt;em&gt;dape.el&lt;&#x2F;em&gt; and searching for &lt;code&gt;json-serialize&lt;&#x2F;code&gt; we find the location.&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;(defun dape-send-object (process seq object)
&lt;&#x2F;span&gt;&lt;span&gt;  &amp;quot;Helper for `dape-request&amp;#39; to send SEQ request with OBJECT to PROCESS.&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;  (let* ((object (plist-put object :seq seq))
&lt;&#x2F;span&gt;&lt;span&gt;         (json (json-serialize object :false-object nil))
&lt;&#x2F;span&gt;&lt;span&gt;         (string (format &amp;quot;Content-Length: %d\r\n\r\n%s&amp;quot; (length json) json)))
&lt;&#x2F;span&gt;&lt;span&gt;    (dape--debug &amp;#39;io &amp;quot;Sending:\n%s&amp;quot; (pp-to-string object))
&lt;&#x2F;span&gt;&lt;span&gt;    (process-send-string process string)))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Let&#x27;s print out the JSON we&#x27;re sending :&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;(defun dape-send-object (process seq object)
&lt;&#x2F;span&gt;&lt;span&gt;  &amp;quot;Helper for `dape-request&amp;#39; to send SEQ request with OBJECT to PROCESS.&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;  (let* ((object (plist-put object :seq seq))
&lt;&#x2F;span&gt;&lt;span&gt;         (json (json-serialize object :false-object nil))
&lt;&#x2F;span&gt;&lt;span&gt;         (string (format &amp;quot;Content-Length: %d\r\n\r\n%s&amp;quot; (length json) json)))
&lt;&#x2F;span&gt;&lt;span&gt;    (dape--debug &amp;#39;io &amp;quot;Sending:\n%s&amp;quot; (pp-to-string object))
&lt;&#x2F;span&gt;&lt;span&gt;    (dape--debug &amp;#39;io &amp;quot;Sending JSON:\n%s&amp;quot; json)
&lt;&#x2F;span&gt;&lt;span&gt;    (process-send-string process string)))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;this gives&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;(:arguments
&lt;&#x2F;span&gt;&lt;span&gt; (:clientID &amp;quot;dape&amp;quot; :adapterID nil :pathFormat &amp;quot;path&amp;quot; :linesStartAt1 t :columnsStartAt1 t :supportsRunInTerminalRequest t :supportsProgressReporting t :supportsStartDebuggingRequest t)
&lt;&#x2F;span&gt;&lt;span&gt; :type &amp;quot;request&amp;quot; :command &amp;quot;initialize&amp;quot; :seq 1)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;[io] Sending JSON:
&lt;&#x2F;span&gt;&lt;span&gt;{&amp;quot;arguments&amp;quot;:{&amp;quot;clientID&amp;quot;:&amp;quot;dape&amp;quot;,&amp;quot;adapterID&amp;quot;:false,&amp;quot;pathFormat&amp;quot;:&amp;quot;path&amp;quot;,&amp;quot;linesStartAt1&amp;quot;:true,&amp;quot;columnsStartAt1&amp;quot;:true,&amp;quot;supportsRunInTerminalRequest&amp;quot;:true,&amp;quot;supportsProgressReporting&amp;quot;:true,&amp;quot;supportsStartDebuggingRequest&amp;quot;:true},&amp;quot;type&amp;quot;:&amp;quot;request&amp;quot;,&amp;quot;command&amp;quot;:&amp;quot;initialize&amp;quot;,&amp;quot;seq&amp;quot;:1}
&lt;&#x2F;span&gt;&lt;span&gt;[info] 
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The supportsXXX things look to be bools, but the &lt;em&gt;adapterID&lt;&#x2F;em&gt; feels funny to be a bool... Where does this come from?&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;(defun dape--initialize (process)
&lt;&#x2F;span&gt;&lt;span&gt;  &amp;quot;Send initialize request to PROCESS.&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;  (dape-request process
&lt;&#x2F;span&gt;&lt;span&gt;                &amp;quot;initialize&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;                (list :clientID &amp;quot;dape&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;                      :adapterID (plist-get dape--config
&lt;&#x2F;span&gt;&lt;span&gt;                                            :type)
&lt;&#x2F;span&gt;&lt;span&gt;                      :pathFormat &amp;quot;path&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;                      :linesStartAt1 t
&lt;&#x2F;span&gt;&lt;span&gt;                      :columnsStartAt1 t
&lt;&#x2F;span&gt;&lt;span&gt;                      ;;:locale &amp;quot;en-US&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;                      ;;:supportsVariableType t
&lt;&#x2F;span&gt;&lt;span&gt;                      ;;:supportsVariablePaging t
&lt;&#x2F;span&gt;&lt;span&gt;                      :supportsRunInTerminalRequest t
&lt;&#x2F;span&gt;&lt;span&gt;                      ;;:supportsMemoryReferences t
&lt;&#x2F;span&gt;&lt;span&gt;                      ;;:supportsInvalidatedEvent t
&lt;&#x2F;span&gt;&lt;span&gt;                      ;;:supportsMemoryEvent t
&lt;&#x2F;span&gt;&lt;span&gt;                      ;;:supportsArgsCanBeInterpretedByShell t
&lt;&#x2F;span&gt;&lt;span&gt;                      :supportsProgressReporting t
&lt;&#x2F;span&gt;&lt;span&gt;                      :supportsStartDebuggingRequest t
&lt;&#x2F;span&gt;&lt;span&gt;                      ;;:supportsVariableType t
&lt;&#x2F;span&gt;&lt;span&gt;                      )
&lt;&#x2F;span&gt;&lt;span&gt;...
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Ok, it comes from the config &lt;code&gt;:type&lt;&#x2F;code&gt; attribute... What do I have in my config???&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;            (add-to-list &amp;#39;dape-configs
&lt;&#x2F;span&gt;&lt;span&gt;                         `(delve
&lt;&#x2F;span&gt;&lt;span&gt;                           modes (go-mode go-ts-mode)
&lt;&#x2F;span&gt;&lt;span&gt;                           command &amp;quot;dlv&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;                           command-args (&amp;quot;dap&amp;quot; &amp;quot;--listen&amp;quot; &amp;quot;127.0.0.1:55878&amp;quot;)
&lt;&#x2F;span&gt;&lt;span&gt;                           command-cwd dape-cwd-fn
&lt;&#x2F;span&gt;&lt;span&gt;                           host &amp;quot;127.0.0.1&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;                           port 55878
&lt;&#x2F;span&gt;&lt;span&gt;                           dape &amp;quot;debug&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;                           :request &amp;quot;launch&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;                           :cwd dape-cwd-fn
&lt;&#x2F;span&gt;&lt;span&gt;                           :program dape-cwd-fn))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Hmm... what is that &lt;code&gt;dape&lt;&#x2F;code&gt; attribute. In all other configs there is a &lt;code&gt;:type&lt;&#x2F;code&gt; in that place. That seems a slip of the finger triggering an unlucky evil command. (I checked on the repo and it was correct there so it was my fault). Let&#x27;s change it to &lt;code&gt;:type&lt;&#x2F;code&gt; and &lt;code&gt;C-x C-e&lt;&#x2F;code&gt; the &lt;code&gt;add-to-list&lt;&#x2F;code&gt; expression to update the default config.&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s try again :&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.snamellit.com&#x2F;posts&#x2F;dape&#x2F;go_example.png&quot; alt=&quot;go debug example&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Ok, now we&#x27;re cookin&#x27; with fire!!!&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Snamellit</title>
          <pubDate>Tue, 05 Sep 2023 00:00:00 +0000</pubDate>
          <author>Peter Tillemans</author>
          <link>https://www.snamellit.com/about/</link>
          <guid>https://www.snamellit.com/about/</guid>
          <description xml:base="https://www.snamellit.com/about/">&lt;h1 id=&quot;welcome-to-snamellit&quot;&gt;Welcome to Snamellit&lt;&#x2F;h1&gt;
</description>
      </item>
      <item>
          <title>Contact Information</title>
          <pubDate>Tue, 05 Sep 2023 00:00:00 +0000</pubDate>
          <author>Peter Tillemans</author>
          <link>https://www.snamellit.com/contact/</link>
          <guid>https://www.snamellit.com/contact/</guid>
          <description xml:base="https://www.snamellit.com/contact/">&lt;p&gt;Peter Tillemans&lt;&#x2F;p&gt;
&lt;p&gt;Snamellit BV&lt;&#x2F;p&gt;
&lt;p&gt;Verbonstraat 57&lt;&#x2F;p&gt;
&lt;p&gt;2000 Antwerpen&lt;&#x2F;p&gt;
&lt;p&gt;VAT BE0892.789.787&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Home</title>
          <pubDate>Sun, 28 Nov 2021 12:57:12 +0000</pubDate>
          <author>Peter Tillemans</author>
          <link>https://www.snamellit.com/home/</link>
          <guid>https://www.snamellit.com/home/</guid>
          <description xml:base="https://www.snamellit.com/home/">&lt;h1 id=&quot;brilliant-design-simplicity-at-scale&quot;&gt;Brilliant design.&lt;br &#x2F;&gt;
Simplicity at scale.&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;img src=&quot;http:&#x2F;&#x2F;www.snamellit.com&#x2F;wp-content&#x2F;uploads&#x2F;2021&#x2F;11&#x2F;image-1.jpg&quot; alt=&quot;Image description&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;http:&#x2F;&#x2F;www.snamellit.com&#x2F;wp-content&#x2F;uploads&#x2F;2021&#x2F;11&#x2F;image-2.jpg&quot; alt=&quot;Image description&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;i-m-aabha-i-like-simple-and-clean-design&quot;&gt;I&#x27;m Aabha, I like simple and clean design.&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;www.snamellit.com&#x2F;gallery&#x2F;&quot;&gt;PORTFOLIO&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;http:&#x2F;&#x2F;www.snamellit.com&#x2F;wp-content&#x2F;uploads&#x2F;2021&#x2F;11&#x2F;image-3.jpg&quot; alt=&quot;Image description&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;experience-delicate-and-beautiful-design&quot;&gt;Experience delicate and beautiful design&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;www.snamellit.com&#x2F;contact&#x2F;&quot;&gt;CONSULTATIONS&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;“We are so grateful we found Aabha. Having her navigate the project made all the difference.”&lt;&#x2F;p&gt;
&lt;p&gt;Paul F - San Fransisco&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h3 id=&quot;let-me-design-your-home&quot;&gt;Let me design your home&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;www.snamellit.com&#x2F;contact&#x2F;&quot;&gt;Book a Consultation&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Running Emacs with wsl2-xrdp</title>
          <pubDate>Sun, 17 Jan 2021 00:00:00 +0000</pubDate>
          <author>Peter Tillemans</author>
          <link>https://www.snamellit.com/posts/running-emacs-with-wsl2-xrdp/</link>
          <guid>https://www.snamellit.com/posts/running-emacs-with-wsl2-xrdp/</guid>
          <description xml:base="https://www.snamellit.com/posts/running-emacs-with-wsl2-xrdp/">&lt;h1 id=&quot;why&quot;&gt;Why&lt;&#x2F;h1&gt;
&lt;p&gt;I have been using Emacs in WSL2 using an X server running in Windows and
that works fine as long as long as the computer does not go to sleep.
When the computer goes to sleep, the X connection is cut and the emacs
process crashes. I like to just have my emacs session available so I can
continue where I was last time and I like my computer to go to sleep
when I not use it because Global Warming.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;start emacs in WSL2 in GUI mode&lt;&#x2F;li&gt;
&lt;li&gt;can be reconnected after sleep&lt;&#x2F;li&gt;
&lt;li&gt;copy-paste works transparent&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;plan&quot;&gt;Plan&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;use &lt;strong&gt;xrdp&lt;&#x2F;strong&gt; as remote desktop is built into windows&lt;&#x2F;li&gt;
&lt;li&gt;configure xrdp to startup in WSL2&lt;&#x2F;li&gt;
&lt;li&gt;run emacs in a remote desktop session&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;installation&quot;&gt;Installation&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;install-xrdp&quot;&gt;Install xrdp&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wiki.archlinux.org&#x2F;index.php&#x2F;xrdp&quot;&gt;Arch wiki page for xrdp&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;sh&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-sh &quot;&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt; yay -S xrdp xorgxrdp-git
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We do not have systemd in WSL2 so I started the daemons manually with a
small script *&#x2F;usr&#x2F;local&#x2F;bin&#x2F;start-xrdp:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;sh&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-sh &quot;&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span style=&quot;color:#616e88;&quot;&gt;#!&#x2F;bin&#x2F;bash
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;span&gt; &#x2F;usr&#x2F;sbin&#x2F;xrdp
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;span&gt; &#x2F;usr&#x2F;sbin&#x2F;xrdp-sesman
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We can now start it with &lt;strong&gt;start-xrdp&lt;&#x2F;strong&gt; from the bash command line or
using &lt;strong&gt;wsl -u root &#x2F;usr&#x2F;local&#x2F;bin&#x2F;start-xrdp&lt;&#x2F;strong&gt;. If not running as root
(or recently authenticated sudo access) it will ask for your Linux
password to allow running as &lt;strong&gt;sudo&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Trying to connect lets me login but after a timeout is shows a dialog
box telling me Xorg did not want to start. This is confirmed in the
&lt;strong&gt;&#x2F;var&#x2F;log&#x2F;xrdp-sesman.log&lt;&#x2F;strong&gt; file.&lt;&#x2F;p&gt;
&lt;p&gt;The root cause is that I cannot read properly because if I could, I
would have read to add &lt;em&gt;allowed\&lt;del&gt;users&lt;&#x2F;del&gt;=anybody&lt;&#x2F;em&gt; to the
&lt;strong&gt;&#x2F;etc&#x2F;X11&#x2F;Xwrapper.config&lt;&#x2F;strong&gt; file to allow &lt;strong&gt;Xorg&lt;&#x2F;strong&gt; to be started by
regular users like me instead of only &lt;strong&gt;root&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Once that is there I get a nice black screen after login.&lt;&#x2F;p&gt;
&lt;p&gt;Note: Each time WSL2 restarts it gets a random ip address. So I created
a small script to dig out the actual ip address out of the output of
&lt;strong&gt;ip address&lt;&#x2F;strong&gt; :&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;sh&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-sh &quot;&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span style=&quot;color:#616e88;&quot;&gt;#!&#x2F;bin&#x2F;bash
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;ip&lt;&#x2F;span&gt;&lt;span&gt; address show dev eth0 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;| &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;grep &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;inet &amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;| &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;sed&lt;&#x2F;span&gt;&lt;span&gt; -e &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;#39;s&#x2F;.*inet \([^&#x2F;]*\).*&#x2F;\1&#x2F;&amp;#39;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Which I gave the original name of &lt;strong&gt;&#x2F;usr&#x2F;local&#x2F;bin&#x2F;ip-address&lt;&#x2F;strong&gt; (do not
forget to &lt;code&gt;chmod +x &#x2F;usr&#x2F;local&#x2F;bin&#x2F;ip-address&lt;&#x2F;code&gt; to make it executable) so
I can easily call it from powershell with &lt;code&gt;wsl ip-address&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;installing-dbus-replacement&quot;&gt;Installing DBUS replacement&lt;&#x2F;h2&gt;
&lt;p&gt;DBUS is the de-facto GNU&#x2F;Linux desktop communication bus which glues all
kind of GUI apps together. I do not know if it is directly used by Emacs
or any of the extensions I use, however it reduces the amount of errors
and warnings.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;sh&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-sh &quot;&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt; yay -S dbus-x11
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;allows xfce and other programs to feel happy and display the desktop
with an emacs window. Now just maximizing the window and the goal is
reached.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;automatic-start-of-emacs-only&quot;&gt;Automatic start of Emacs only&lt;&#x2F;h2&gt;
&lt;p&gt;In order to just start emacs maximized in a single remote desktop window
we only need to start it as the only program in the XSession. This of
course also means there is no chrome on the X-Window or the ability to
lauch other programs outside of Emacs. This is exactly how I like it.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;sh&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-sh &quot;&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span style=&quot;color:#616e88;&quot;&gt;#file:~&#x2F;.xinitrc
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;emacs&lt;&#x2F;span&gt;&lt;span&gt; -mm
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If you rather have a full desktop environment, see further.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;installing-xfce4-optional&quot;&gt;Installing Xfce4 (Optional)&lt;&#x2F;h2&gt;
&lt;p&gt;I&#x27;d rather have something more lightweight as window manager, but I
have experience with Xfce4 in Arch and I also like something which just
works.&lt;&#x2F;p&gt;
&lt;p&gt;I only intend to run emacs in the window however having something a bit
more capable which works can help me debug the environment. (I have some
font things to sort out too...)&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;sh&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-sh &quot;&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt; sudo pacman -S xfce4
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;and then start it form &lt;strong&gt;~&#x2F;.xinitrc&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;sh&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-sh &quot;&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;emacs &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;amp;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;startxfce4
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If you have skipped the &lt;strong&gt;DBUS&lt;&#x2F;strong&gt; setup above, this hangs while the
&lt;strong&gt;~&#x2F;.xorgxrdp.log&lt;&#x2F;strong&gt; file is filling up with errors complaining about
missing connection to dbus.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;using-this-from-windows&quot;&gt;Using this from Windows&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;starting-from-the-command-line&quot;&gt;Starting from the command-line&lt;&#x2F;h2&gt;
&lt;p&gt;We can start remote desktop session using&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;&amp;gt;_ mstsc &#x2F;v:$(wsl ip-address) &#x2F;h:2560 &#x2F;w:1600
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This works, however we get now a prompt to accept the certificate and we
still need to login. We can make this smoother&lt;&#x2F;p&gt;
&lt;h2 id=&quot;accepting-the-certificate&quot;&gt;Accepting the certificate&lt;&#x2F;h2&gt;
&lt;p&gt;You can accept the certificate and let remote desktop add it to your
certificate stores. This solves this interruption.&lt;&#x2F;p&gt;
&lt;p&gt;However, this still happens each time the ip address changes.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;automatic-login&quot;&gt;Automatic login&lt;&#x2F;h2&gt;
&lt;p&gt;Start &lt;strong&gt;remote desktop&lt;&#x2F;strong&gt; GUI using the search or from the start menu.&lt;&#x2F;p&gt;
&lt;p&gt;Fill in the ip address returned by &lt;code&gt;wsl ip-address&lt;&#x2F;code&gt; and your username.
Enable the flag to store your password. Login and save the configuration
as e.g. &lt;strong&gt;emacs.rdp&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;We can now start emacs using&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;&amp;gt;_ cmdkey &#x2F;generic:$(wsl ip-address) &#x2F;user:&amp;lt;username&amp;gt; &#x2F;pass:&amp;lt;password&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;_ mstsc &#x2F;v:$(wsl ip-address)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We can assemble this is a small script &lt;strong&gt;wsl-emacs.ps1&lt;&#x2F;strong&gt; somewhere on
your path:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;powershell&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-powershell &quot;&gt;&lt;code class=&quot;language-powershell&quot; data-lang=&quot;powershell&quot;&gt;&lt;span&gt;wsl &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;u root &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;usr&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;local&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;bin&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;start-xrdp
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt;address &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;= $&lt;&#x2F;span&gt;&lt;span&gt;(wsl ip&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;address)
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt;userName &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;pti&amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt;userPwd &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;shht!Secret&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;cmdkey &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;generic:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt;address &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;user:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt;userName &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;pass:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt;userPwd
&lt;&#x2F;span&gt;&lt;span&gt;mstsc &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;v:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt;address
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Which allows us to start our &lt;strong&gt;wsl-emacs&lt;&#x2F;strong&gt; from powershell or as a
startup application with a shortcut. It ensures the &lt;strong&gt;xrdp&lt;&#x2F;strong&gt; daemons are
running (they are idempotent, so the script can be run multiple times),
then the credentials are created so they can be picked up by remote
desktop.&lt;&#x2F;p&gt;
&lt;p&gt;To add a shortcut to the start menu:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Type Win-R and open
*%AppData%&lt;code&gt;\Microsoft&lt;&#x2F;code&gt;{=latex}&lt;code&gt;\Windows&lt;&#x2F;code&gt;{=latex}&lt;code&gt;\Start&lt;&#x2F;code&gt;{=latex}
Menu&lt;code&gt;\Programs*&lt;&#x2F;code&gt;{=latex}&lt;&#x2F;li&gt;
&lt;li&gt;create a new shortcut&lt;&#x2F;li&gt;
&lt;li&gt;set as target *powershell.exe &quot;&amp;amp;
&#x27;&amp;lt;path-of-script&amp;gt;&lt;code&gt;\wsl&lt;&#x2F;code&gt;{=latex}-emacs.ps1&#x27;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Note the weird &lt;strong&gt;&quot;&amp;amp;&lt;&#x2F;strong&gt; on the command-line.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;a-note-on-security&quot;&gt;A note on security&lt;&#x2F;h2&gt;
&lt;p&gt;Since you can run any command from the windows command-line as root, the
current logged in person has full access to anything in the WSL Linux
machines. As such there is not a big hole added by adding your linux
password somewhere securely in your account files such as the startup
script.&lt;&#x2F;p&gt;
&lt;p&gt;This does not mean you should not have secure passwords, as your linux
box can expose its ports (not by default but just assume they are) and
allow e.g. ssh access. Since I assume a lot of WSL2 hosts will be used
fast and loose as a development box, there is a good chance that sooner
or later a port is opened for reasons.&lt;&#x2F;p&gt;
&lt;p&gt;So I would not worry too much your linux box password is exposed in the
emacs startup script as long as it is hard enough and not used anywhere
else. If you&#x27;d like to get it from some secure vault on your PC or from
your infrastructure, go for it.&lt;&#x2F;p&gt;
&lt;p&gt;tldr;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;use a strong password for your WSL box&lt;&#x2F;li&gt;
&lt;li&gt;do not reuse an existing password&lt;&#x2F;li&gt;
&lt;li&gt;secure your startup script so it is only readable by you.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</description>
      </item>
      <item>
          <title>Access NAS Drive using Windows 10 PIN login</title>
          <pubDate>Mon, 26 Oct 2020 00:00:00 +0000</pubDate>
          <author>Peter Tillemans</author>
          <link>https://www.snamellit.com/posts/access-nas-drive-using-windows10-pin-login/</link>
          <guid>https://www.snamellit.com/posts/access-nas-drive-using-windows10-pin-login/</guid>
          <description xml:base="https://www.snamellit.com/posts/access-nas-drive-using-windows10-pin-login/">&lt;p&gt;Each time I login using the PIN of my Microsoft account, my mounted
folders on the NAS are not mounted. After login I get a notification
that not all mounted drives could be connected. When double clicking on
the failed mount I get a silly error regarding duplicate sessions or
something, and I can access after logging in.&lt;&#x2F;p&gt;
&lt;p&gt;This is irritating, but also breaks automations like auto importing
notes and documents into evernote from the NAS folder.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;attempt-1&quot;&gt;Attempt 1&lt;&#x2F;h1&gt;
&lt;p&gt;This seems to be a known issue with PIN (and by extension face
recognition (?)) login.&lt;&#x2F;p&gt;
&lt;p&gt;On Windows answers I found a
&lt;a href=&quot;https:&#x2F;&#x2F;answers.microsoft.com&#x2F;en-us&#x2F;windows&#x2F;forum&#x2F;all&#x2F;unable-to-access-nas-drive-when-logged-in-using&#x2F;3587cf33-7ed9-403f-ac7c-d4158969412d&quot;&gt;workaround&lt;&#x2F;a&gt;
:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Open the &lt;strong&gt;Credential Manager&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Select &lt;strong&gt;Windows Credential&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Add a Windows Credential&lt;&#x2F;strong&gt; (it will actually modify the existing
one)&lt;&#x2F;li&gt;
&lt;li&gt;network address : \\ [your NAS]{.underline}&lt;&#x2F;li&gt;
&lt;li&gt;User name : &lt;del&gt;your&lt;&#x2F;del&gt; NAS_&lt;code&gt;\pti&lt;&#x2F;code&gt;{=latex}&lt;&#x2F;li&gt;
&lt;li&gt;Password : [your password on the NAS]{.underline}&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;From now on your drive should be mounted after rebooting.&lt;&#x2F;p&gt;
&lt;p&gt;Unfortunately, it does not.&lt;&#x2F;p&gt;
&lt;p&gt;Removing and adding again does not help either.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;attempt-2-remap-network-drives-on-login&quot;&gt;Attempt 2 : remap network drives on login&lt;&#x2F;h1&gt;
&lt;p&gt;In 2018 [another
workaround](https:&#x2F;&#x2F;support.microsoft.com&#x2F;en-us&#x2F;help&#x2F;4471218&#x2F;mapped-network-drive-may-fail-to-reconnect-in-windows-10-version-1809#:~:text=Workaround%201%3A%20Create%20a%20startup%20item&amp;amp;text=If%20the%20device%20has%20not,t%20automatically%20reconnect%20network%20drives.&amp;amp;text=A%20log%20file%20(StartupLog.,to%20open%20the%20mapped%20drives.)
was published.&lt;&#x2F;p&gt;
&lt;p&gt;This relies on a powershell script launched by a Command script to walk
over unavailable mapped drives and map them again.&lt;&#x2F;p&gt;
&lt;p&gt;It uses 2 scripts:&lt;&#x2F;p&gt;
&lt;h2 id=&quot;programdata-microsoft-latex-windows-latex-start-latex-menu-programs-latex-startup-latex-mapdrives-latex-cmd&quot;&gt;*%ProgramData%&lt;code&gt;\Microsoft&lt;&#x2F;code&gt;{=latex}&lt;code&gt;\Windows&lt;&#x2F;code&gt;{=latex}&lt;code&gt;\Start&lt;&#x2F;code&gt;{=latex} Menu&lt;code&gt;\Programs&lt;&#x2F;code&gt;{=latex}&lt;code&gt;\StartUp&lt;&#x2F;code&gt;{=latex}&lt;code&gt;\MapDrives&lt;&#x2F;code&gt;{=latex}.cmd&lt;&#x2F;h2&gt;
&lt;p&gt;A startup scrip to kickoff remapping after login&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;sh&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-sh &quot;&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;PowerShell&lt;&#x2F;span&gt;&lt;span&gt; -Command &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;Set-ExecutionPolicy -Scope CurrentUser Unrestricted&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;gt;&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;%TEMP%\StartupLog.txt&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;1
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;PowerShell&lt;&#x2F;span&gt;&lt;span&gt; -File &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;%SystemDrive%\Scripts\MapDrives.ps1&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;gt;&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;%TEMP%\StartupLog.txt&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;1
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;systemdrive-scripts-latex-mapdrives-latex-ps1&quot;&gt;%SystemDrive%&lt;code&gt;\Scripts&lt;&#x2F;code&gt;{=latex}&lt;code&gt;\MapDrives&lt;&#x2F;code&gt;{=latex}.ps1&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;sh&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-sh &quot;&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span&gt;$i&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;3
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;while&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt;True){
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt;error.clear()
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt;MappedDrives = Get-SmbMapping |where -property Status -Value Unavailable -EQ | select LocalPath&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt;RemotePath
&lt;&#x2F;span&gt;&lt;span&gt;    foreach( &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt;MappedDrive in &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt;MappedDrives)
&lt;&#x2F;span&gt;&lt;span&gt;    {
&lt;&#x2F;span&gt;&lt;span&gt;        try {
&lt;&#x2F;span&gt;&lt;span&gt;            New-SmbMapping -LocalPath &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt;MappedDrive.LocalPath -RemotePath &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt;MappedDrive.RemotePath -Persistent &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt;True
&lt;&#x2F;span&gt;&lt;span&gt;        } catch {
&lt;&#x2F;span&gt;&lt;span&gt;            Write-Host &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;There was an error mapping &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt;MappedDrive&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;.RemotePath to &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt;MappedDrive&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;.LocalPath&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt;i = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt;i - 1
&lt;&#x2F;span&gt;&lt;span&gt;    if(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt;error.Count -eq 0 -Or &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt;i -eq 0) {break}
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    Start-Sleep -Seconds 30
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;evaluation&quot;&gt;Evaluation&lt;&#x2F;h2&gt;
&lt;p&gt;After rebooting and logging in, I still get the error that not all
drives could be mounted, however, by the time I can check in the
explorer the volume is mounted and ready to be used.&lt;&#x2F;p&gt;
&lt;p&gt;Not very elegant as the notification still feels terribly yanky, but at
least it no longer interferes my workflows.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Setting Up Blogging with Emacs</title>
          <pubDate>Thu, 15 Oct 2020 00:00:00 +0000</pubDate>
          <author>Peter Tillemans</author>
          <link>https://www.snamellit.com/posts/setting-up-blogging-with-emacs/</link>
          <guid>https://www.snamellit.com/posts/setting-up-blogging-with-emacs/</guid>
          <description xml:base="https://www.snamellit.com/posts/setting-up-blogging-with-emacs/">&lt;p&gt;I&#x27;d like to blog more notes on stuff I do and it would be nice to have
a smooth workflow in my editor of choice.&lt;&#x2F;p&gt;
&lt;p&gt;It is too late to explain a lot, but all these things were proudly found
elsewhere. See the references list at the end of this post.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;creating-the-blog-project&quot;&gt;Creating the blog project&lt;&#x2F;h1&gt;
&lt;p&gt;To deploy to github as a personal blog you have to create a repo in the
form &lt;strong&gt;&amp;lt;username&amp;gt;.github.io&lt;&#x2F;strong&gt;. Since I name my projects the same as
the repos the name was a quick choice.&lt;&#x2F;p&gt;
&lt;p&gt;The structure is as follows:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;&amp;lt;root&amp;gt; -+- blog -+- posts -+- &amp;lt;blog posts&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;        |        +- org-template -+- &amp;lt;templates&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;        |        +- css -+- &amp;lt;css files&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;        +- public -+- &amp;lt;built website&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;        +- .github -+- workflow --- main.yml  &amp;lt;github actions&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;        +- publish.el
&lt;&#x2F;span&gt;&lt;span&gt;        +- Makefile  &amp;lt;local develop actions&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;configuring-org-publish&quot;&gt;Configuring org-publish&lt;&#x2F;h1&gt;
&lt;p&gt;This is what the &lt;strong&gt;publish.el&lt;&#x2F;strong&gt; file is for.&lt;&#x2F;p&gt;
&lt;p&gt;Prepare some snippets for the HTML pages&lt;&#x2F;p&gt;
&lt;p&gt;First off, a link to the CSS:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;lisp&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-lisp &quot;&gt;&lt;code class=&quot;language-lisp&quot; data-lang=&quot;lisp&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;setq&lt;&#x2F;span&gt;&lt;span&gt; website&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;html&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;head &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;&amp;lt;link rel=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;stylesheet&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt; href=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;css&#x2F;site.css&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;\&amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;  type=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;text&#x2F;css&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&#x2F;&amp;gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Let&#x27;s also add a navigation menu at the top of each page:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;lisp&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-lisp &quot;&gt;&lt;code class=&quot;language-lisp&quot; data-lang=&quot;lisp&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;setq&lt;&#x2F;span&gt;&lt;span&gt; website&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;html&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;preamble
&lt;&#x2F;span&gt;&lt;span&gt;      &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;&amp;lt;div class=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;nav&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;lt;ul&amp;gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;lt;li&amp;gt;&amp;lt;a href=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;gt;Home&amp;lt;&#x2F;a&amp;gt;&amp;lt;&#x2F;li&amp;gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;lt;li&amp;gt;&amp;lt;a href=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;ptillemans&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;gt;GitHub&amp;lt;&#x2F;a&amp;gt;&amp;lt;&#x2F;li&amp;gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;lt;&#x2F;ul&amp;gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;lt;&#x2F;div&amp;gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And a footer :&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;lisp&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-lisp &quot;&gt;&lt;code class=&quot;language-lisp&quot; data-lang=&quot;lisp&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;setq&lt;&#x2F;span&gt;&lt;span&gt; website&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;html&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;postamble &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;&amp;lt;div class=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;footer&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;gt; Copyright 2020 %a (%v
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;  HTML).&amp;lt;br&amp;gt; Last updated %C.&amp;lt;br&amp;gt; Built with %c.  &amp;lt;&#x2F;div&amp;gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And now we can all tie it together by creating the
&lt;strong&gt;org-publish-project-alist&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;lisp&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-lisp &quot;&gt;&lt;code class=&quot;language-lisp&quot; data-lang=&quot;lisp&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;setq&lt;&#x2F;span&gt;&lt;span&gt; org&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;publish&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;project&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;alist
&lt;&#x2F;span&gt;&lt;span&gt;      `((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;posts&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;         &lt;&#x2F;span&gt;&lt;span style=&quot;color:#616e88;&quot;&gt;;; configure project structure
&lt;&#x2F;span&gt;&lt;span&gt;         :base&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;directory &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;blog&#x2F;posts&#x2F;&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;         :base&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;extension &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;org&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;         :publishing&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;directory &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;public&#x2F;&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;         :recursive &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;t
&lt;&#x2F;span&gt;&lt;span&gt;         :publishing&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;function org&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;html&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;publish&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-to-&lt;&#x2F;span&gt;&lt;span&gt;html
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;         &lt;&#x2F;span&gt;&lt;span style=&quot;color:#616e88;&quot;&gt;;; configure index creation
&lt;&#x2F;span&gt;&lt;span&gt;         :auto&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;sitemap &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;t
&lt;&#x2F;span&gt;&lt;span&gt;         :sitemap&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;title &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;Blog Index&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;         :sitemap&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;filename &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;index.org&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;         :sitemap&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;style tree
&lt;&#x2F;span&gt;&lt;span&gt;         :sitemap&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;file&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;entry&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;format &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;%d - %t&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;         :sitemap&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;sort&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;files anti&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;chronologically
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;         :html&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;doctype &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;html5&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;         :html&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;html5&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;fancy &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;t
&lt;&#x2F;span&gt;&lt;span&gt;         :html&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;head ,website&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;html&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;head
&lt;&#x2F;span&gt;&lt;span&gt;         :html&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;preamble ,website&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;html&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;preamble
&lt;&#x2F;span&gt;&lt;span&gt;         :html&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;postamble ,website&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;html&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;postamble
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;         :author &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;Peter Tillemans&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;         :email &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;pti@snamellit.com&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;         :&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;with-&lt;&#x2F;span&gt;&lt;span&gt;creator &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;t&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;blog-static&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;         :base&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;directory &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;blog&#x2F;posts&#x2F;&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;         :base&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;extension &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;png&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;\\&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;|jpg&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;\\&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;|gif&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;\\&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;|pdf&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;\\&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;|mp3&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;\\&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;|ogg&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;\\&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;|swf&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;         :publishing&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;directory &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;public_html&#x2F;&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;         :recursive &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;t
&lt;&#x2F;span&gt;&lt;span&gt;         :publishing&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;function org&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;publish&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;attachment)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;css&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;         :base&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;directory &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;blog&#x2F;css&#x2F;&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;         :base&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;extension &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;css&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;         :publishing&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;directory &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;public&#x2F;css&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;         :publishing&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;function org&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;publish&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;attachment
&lt;&#x2F;span&gt;&lt;span&gt;         :recursive &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;t&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;all&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; :components (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;posts&amp;quot; &amp;quot;css&amp;quot; &amp;quot;blog-static&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;))))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;make-local-testing-easy&quot;&gt;Make local testing easy&lt;&#x2F;h1&gt;
&lt;p&gt;The commands to build the blog are not hard, but hard to remember and
hard to type.&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s make a makefile to help:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;makefile&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-makefile &quot;&gt;&lt;code class=&quot;language-makefile&quot; data-lang=&quot;makefile&quot;&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;.PHONY&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;all publish publish_no_init
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;all&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;publish
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;publish&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;publish.el
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;@&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;echo &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;Publishing... with current Emacs configurations.&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;emacs&lt;&#x2F;span&gt;&lt;span&gt; --batch --load publish.el --funcall org-publish-all
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;publish_no_init&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;@&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;echo &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;Publishing... with --no-init&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;emacs&lt;&#x2F;span&gt;&lt;span&gt; --batch --no-init --load publish.el --funcall org-publish-all
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;clean&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;@&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;echo &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;Cleaning up...&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;rm&lt;&#x2F;span&gt;&lt;span&gt; -rf public
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;@&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;rm&lt;&#x2F;span&gt;&lt;span&gt; -rvf &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;.elc
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;@&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;rm&lt;&#x2F;span&gt;&lt;span&gt; -rvf public
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;@&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;rm&lt;&#x2F;span&gt;&lt;span&gt; -rvf &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;~&lt;&#x2F;span&gt;&lt;span&gt;&#x2F;.org-timestamps&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;*
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;serve&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;publish
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;@&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;echo &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;Serving site&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;python&lt;&#x2F;span&gt;&lt;span&gt; -m http.server --directory public
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;For local testing just do:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;sh&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-sh &quot;&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt; make clean serve
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If the only change is new content then not cleaning is much faster.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;deploy-to-github-pages&quot;&gt;Deploy to Github Pages&lt;&#x2F;h1&gt;
&lt;p&gt;A slightly modified version of the initial workflow will do the
publishing:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;yaml&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-yaml &quot;&gt;&lt;code class=&quot;language-yaml&quot; data-lang=&quot;yaml&quot;&gt;&lt;span style=&quot;color:#616e88;&quot;&gt;# This is a basic workflow to help you get started with Actions
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;name&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;CI
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#616e88;&quot;&gt;# Controls when the action will run. Triggers the workflow on push or pull request
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#616e88;&quot;&gt;# events but only for the master branch
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;on&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;push&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;branches&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span&gt;[ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;master &lt;&#x2F;span&gt;&lt;span&gt;]
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;pull_request&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;branches&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span&gt;[ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;master &lt;&#x2F;span&gt;&lt;span&gt;]
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#616e88;&quot;&gt;# A workflow run is made up of one or more jobs that can run sequentially or in parallel
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;jobs&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#616e88;&quot;&gt;# This workflow contains a single job called &amp;quot;build&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;build&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#616e88;&quot;&gt;# The type of runner that the job will run on
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;runs-on&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;ubuntu-latest
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#616e88;&quot;&gt;# Steps represent a sequence of tasks that will be executed as part of the job
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;steps&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;      - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;uses&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;actions&#x2F;checkout@master
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;with&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;          &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;fetch-depth&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;1
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;      - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;name&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;build
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;uses&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;docker:&#x2F;&#x2F;iquiw&#x2F;alpine-emacs
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;github.event.deleted == false
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;with&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;          &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;args&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;emacs --batch --load publish.el --funcall org-publish-all
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;      - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;name&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;deploy
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;uses&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;peaceiris&#x2F;actions-gh-pages@v1.1.0
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;success()
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;env&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;          &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;GITHUB_TOKEN&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;${{ secrets.PERSONAL_ACCESS_TOKEN }}
&lt;&#x2F;span&gt;&lt;span&gt;          &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;PUBLISH_BRANCH&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;gh-pages
&lt;&#x2F;span&gt;&lt;span&gt;          &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;PUBLISH_DIR&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;.&#x2F;public
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Note that you need to put a secret &lt;strong&gt;PERSONAL~ACCESSTOKEN~&lt;&#x2F;strong&gt; with an
access token which has basic push access to the repo to push the built
site to the gh-pages branch.&lt;&#x2F;p&gt;
&lt;p&gt;For the emacs call, I just copied the command from the &lt;strong&gt;Makefile&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;After a push the site is usually up by the time I check, say in about a
minute.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;setting-up-a-capture-template&quot;&gt;Setting up a Capture Template&lt;&#x2F;h1&gt;
&lt;p&gt;This proved to be the hardest part to get working.&lt;&#x2F;p&gt;
&lt;p&gt;I am using &lt;strong&gt;Doom Emacs&lt;&#x2F;strong&gt; so I wrap everything in
&lt;strong&gt;with-eval-after-load&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The challenge was that the title is needed to create the slug for the
filename and then again as title for the post. So my ugly solution is to
stuff it in a variable and get the variable back in the template.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;lisp&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-lisp &quot;&gt;&lt;code class=&quot;language-lisp&quot; data-lang=&quot;lisp&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;with-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;eval&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;after&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;load&lt;&#x2F;span&gt;&lt;span&gt; &amp;#39;org&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;capture
&lt;&#x2F;span&gt;&lt;span&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;defvar&lt;&#x2F;span&gt;&lt;span&gt; snamellit&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;blog&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;title &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;test-title&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;setq&lt;&#x2F;span&gt;&lt;span&gt; snamellit&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;blog&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;template &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;#+title: %(progn snamellit-blog-title)
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;#+date: %t
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;#+author: Peter Tillemans
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;#+email: pti@snamellit.com
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;%?&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;defun &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;snamellit&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;capture&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;blog&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;post&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;file ()
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;let* &lt;&#x2F;span&gt;&lt;span&gt;((title (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;read&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-from-&lt;&#x2F;span&gt;&lt;span&gt;minibuffer &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;Post Title: &amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;))
&lt;&#x2F;span&gt;&lt;span&gt;           (slug (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;replace&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;regexp&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;in&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;string &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;[^a-z0-9]+&amp;quot; &amp;quot;-&amp;quot; &lt;&#x2F;span&gt;&lt;span&gt;(downcase title))))
&lt;&#x2F;span&gt;&lt;span&gt;      (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;setq&lt;&#x2F;span&gt;&lt;span&gt; snamellit&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;blog&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;title title)
&lt;&#x2F;span&gt;&lt;span&gt;      (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;format &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;~&#x2F;Projects&#x2F;ptillemans.github.io&#x2F;blog&#x2F;posts&#x2F;%s-%s.org&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;              (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;format&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;time&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;string &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;%Y-%m-%d&amp;quot; &lt;&#x2F;span&gt;&lt;span&gt;(current&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;time&lt;&#x2F;span&gt;&lt;span&gt;))
&lt;&#x2F;span&gt;&lt;span&gt;              slug)))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;  (add&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-to-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;list&lt;&#x2F;span&gt;&lt;span&gt; &amp;#39;org&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;capture&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;templates
&lt;&#x2F;span&gt;&lt;span&gt;               &amp;#39;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;b&amp;quot; &amp;quot;Blog Post&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; plain
&lt;&#x2F;span&gt;&lt;span&gt;                 (file snamellit&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;capture&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;blog&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;post&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;file)
&lt;&#x2F;span&gt;&lt;span&gt;                 (file &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;~&#x2F;.doom.d&#x2F;tpl-blog-post.org&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;))))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;strong&gt;tpl-blog-post.org&lt;&#x2F;strong&gt; template file :&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;#+title: %(progn snamellit&#x2F;blog-title)
&lt;&#x2F;span&gt;&lt;span&gt;#+date: %&amp;lt;%Y-%m-%d&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;%?
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;It is very minimal and I&#x27;d like to keep it that way.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;in-use&quot;&gt;In use&lt;&#x2F;h1&gt;
&lt;p&gt;To create a blog post&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;SPC-X b will create the post&lt;&#x2F;li&gt;
&lt;li&gt;Give a title for the post&lt;&#x2F;li&gt;
&lt;li&gt;A template file is created (unfortunately in plain text)&lt;&#x2F;li&gt;
&lt;li&gt;Enter the idea, hook and save with C-c C-c&lt;&#x2F;li&gt;
&lt;li&gt;Open the org file with SPC-f r (open recent file)&lt;&#x2F;li&gt;
&lt;li&gt;Flesh out the post using org-mode goodness&lt;&#x2F;li&gt;
&lt;li&gt;save, commit and push to git&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;After push the github action will bring it live&lt;&#x2F;p&gt;
&lt;h1 id=&quot;references&quot;&gt;References&lt;&#x2F;h1&gt;
&lt;p&gt;Following links were useful in setting this up:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;opensource.com&#x2F;article&#x2F;20&#x2F;3&#x2F;blog-emacs&quot;&gt;How to blog with Emacs Org
mode&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;docs.github.com&#x2F;en&#x2F;free-pro-team@latest&#x2F;github&#x2F;working-with-github-pages&#x2F;about-github-pages&quot;&gt;GitHub Pages
documentation&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;orgmode.org&#x2F;org.html&quot;&gt;The Org Mode Manual&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;meganrenae21.github.io&#x2F;Meg-in-Progress&#x2F;posts&#x2F;blogging-with-org-mode.html&quot;&gt;The Meg in Progress post on building a static blog with
org-mode.&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;thenybble.de&#x2F;projects&#x2F;orgsite.html&quot;&gt;Website with org-mode&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;rkallos.com&#x2F;blog&#x2F;2017&#x2F;01&#x2F;02&#x2F;static-site-generation-with-org-mode&#x2F;&quot;&gt;Richard Kallos&#x27; post on site generation with Org
Mode&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;www.brautaset.org&#x2F;articles&#x2F;2017&#x2F;blogging-with-org-mode.html&quot;&gt;Blogging with Org
mode&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;storax.github.io&#x2F;blog&#x2F;2016&#x2F;05&#x2F;02&#x2F;org-capture-tricks&#x2F;&quot;&gt;Org Capture Tricks from
Storax&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</description>
      </item>
      <item>
          <title>Add tap Escapt to HHKB</title>
          <pubDate>Tue, 08 Sep 2020 00:00:00 +0000</pubDate>
          <author>Peter Tillemans</author>
          <link>https://www.snamellit.com/posts/add-tap-escape-to-hhkb/</link>
          <guid>https://www.snamellit.com/posts/add-tap-escape-to-hhkb/</guid>
          <description xml:base="https://www.snamellit.com/posts/add-tap-escape-to-hhkb/">&lt;p&gt;I configure all apps I can to use &lt;em&gt;vim&lt;&#x2F;em&gt; keybindings. Which means I use
the &lt;em&gt;Escape&lt;&#x2F;em&gt; key very often.&lt;&#x2F;p&gt;
&lt;p&gt;On my custom keyboards I have usually QMK or similar available to remap
the keys and use a tap on the CapsLock to mean &lt;em&gt;Escape&lt;&#x2F;em&gt; and hold to mean
&lt;em&gt;Control&lt;&#x2F;em&gt;. On the macbook pro I used &lt;em&gt;Karabiner&lt;&#x2F;em&gt; to program the same
effect. And even on Windows I found a &lt;em&gt;AutoHotKey&lt;&#x2F;em&gt; script. On Linux I
use an event interceptor between the keyboard and the rest of the OS.&lt;&#x2F;p&gt;
&lt;p&gt;So either the keyboard does it natively or the useless CapsLock is
remapped to the much more useful Ctrl&#x2F;Esc combination.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;happy-hacking-keyboard&quot;&gt;Happy Hacking Keyboard&lt;&#x2F;h1&gt;
&lt;p&gt;This year I got a HHKB for my birthday. I have been wanting one of those
for a real long time, but choice anxiety and the new models arriving
last year prevented me from pulling the trigger so my family conspired
to end my suffering by buying me Hybrid Type-S. Super happy with it.&lt;&#x2F;p&gt;
&lt;p&gt;Of course it took some time to get used to the different location of the
backspace, and the practical use of the 2 keys top right. However my
muscle memory really expects the &lt;em&gt;Esc&lt;&#x2F;em&gt; to be under my pinky.&lt;&#x2F;p&gt;
&lt;p&gt;No problem I thought a quick Google will sort that out. Nope...&lt;&#x2F;p&gt;
&lt;p&gt;Been looking on and off for about a week before posting something in the
subreddit. No reply, probably because I forgot to add a nice picture.&lt;&#x2F;p&gt;
&lt;p&gt;The general consensus is to just buy an Hasu controller and use QMK to
implement the tap dance. However I do not want to rip out the guts of my
new keyboard, and ordering one will take some time too.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;my-solution&quot;&gt;My Solution&lt;&#x2F;h1&gt;
&lt;p&gt;A thought crossed my mind to just try to do the same with the Control as
I do to the CapsLock in my autohotkey script. So I copy pasted the
CapsLock remapping to the end of the file and replaced CapsLock with
Control in the copy. Reloaded the script and everything seemed to work.&lt;&#x2F;p&gt;
&lt;p&gt;Waited a few days to confirm, and wrote it down before I forget.&lt;&#x2F;p&gt;
&lt;p&gt;Here is the relevant part:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;sh&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-sh &quot;&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;Control::Send &lt;&#x2F;span&gt;&lt;span&gt;{esc}
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;Control &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;amp; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;a::Send&lt;&#x2F;span&gt;&lt;span&gt; ^a
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;Control &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;amp; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;b::Send&lt;&#x2F;span&gt;&lt;span&gt; ^b
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;Control &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;amp; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;c::Send&lt;&#x2F;span&gt;&lt;span&gt; ^c
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;Control &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;amp; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;d::Send&lt;&#x2F;span&gt;&lt;span&gt; ^d
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;Control &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;amp; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;e::Send&lt;&#x2F;span&gt;&lt;span&gt; ^e
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;Control &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;amp; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;f::Send&lt;&#x2F;span&gt;&lt;span&gt; ^f
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;Control &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;amp; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;g::Send&lt;&#x2F;span&gt;&lt;span&gt; ^g
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;Control &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;amp; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;h::Send&lt;&#x2F;span&gt;&lt;span&gt; ^h
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;Control &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;amp; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;i::Send&lt;&#x2F;span&gt;&lt;span&gt; ^i
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;Control &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;amp; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;j::Send&lt;&#x2F;span&gt;&lt;span&gt; ^j
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;Control &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;amp; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;k::Send&lt;&#x2F;span&gt;&lt;span&gt; ^k
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;Control &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;amp; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;l::Send&lt;&#x2F;span&gt;&lt;span&gt; ^l
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;Control &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;amp; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;m::Send&lt;&#x2F;span&gt;&lt;span&gt; ^m
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;Control &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;amp; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;n::Send&lt;&#x2F;span&gt;&lt;span&gt; ^n
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;Control &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;amp; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;o::Send&lt;&#x2F;span&gt;&lt;span&gt; ^o
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;Control &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;amp; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;p::Send&lt;&#x2F;span&gt;&lt;span&gt; ^p
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;Control &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;amp; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;q::Send&lt;&#x2F;span&gt;&lt;span&gt; ^q
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;Control &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;amp; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;r::Send&lt;&#x2F;span&gt;&lt;span&gt; ^r
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;Control &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;amp; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;s::Send&lt;&#x2F;span&gt;&lt;span&gt; ^s
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;Control &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;amp; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;t::Send&lt;&#x2F;span&gt;&lt;span&gt; ^t
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;Control &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;amp; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;u::Send&lt;&#x2F;span&gt;&lt;span&gt; ^u
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;Control &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;amp; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;v::Send&lt;&#x2F;span&gt;&lt;span&gt; ^v
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;Control &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;amp; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;w::Send&lt;&#x2F;span&gt;&lt;span&gt; ^w
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;Control &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;amp; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;x::Send&lt;&#x2F;span&gt;&lt;span&gt; ^x
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;Control &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;amp; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;y::Send&lt;&#x2F;span&gt;&lt;span&gt; ^y
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;Control &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;amp; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;z::Send&lt;&#x2F;span&gt;&lt;span&gt; ^z
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;Control &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;amp; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;0::Send&lt;&#x2F;span&gt;&lt;span&gt; ^0
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;Control &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;amp; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;1::Send&lt;&#x2F;span&gt;&lt;span&gt; ^1
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;Control &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;amp; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;2::Send&lt;&#x2F;span&gt;&lt;span&gt; ^2
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;Control &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;amp; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;3::Send&lt;&#x2F;span&gt;&lt;span&gt; ^3
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;Control &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;amp; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;4::Send&lt;&#x2F;span&gt;&lt;span&gt; ^4
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;Control &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;amp; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;5::Send&lt;&#x2F;span&gt;&lt;span&gt; ^5
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;Control &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;amp; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;6::Send&lt;&#x2F;span&gt;&lt;span&gt; ^6
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;Control &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;amp; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;7::Send&lt;&#x2F;span&gt;&lt;span&gt; ^7
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;Control &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;amp; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;8::Send&lt;&#x2F;span&gt;&lt;span&gt; ^8
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;Control &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;amp; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;9::Send&lt;&#x2F;span&gt;&lt;span&gt; ^9
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;Control &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;amp; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;#39;::Send ^&amp;#39;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;Control &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;amp; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;,::Send&lt;&#x2F;span&gt;&lt;span&gt; ^,
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;Control &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;amp; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;.::Send&lt;&#x2F;span&gt;&lt;span&gt; ^.
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;Control &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;amp; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;&#x2F;::Send&lt;&#x2F;span&gt;&lt;span&gt; ^&#x2F;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;Control &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;amp; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;-::Send&lt;&#x2F;span&gt;&lt;span&gt; ^-
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;Control &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;amp; =&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;::Send &lt;&#x2F;span&gt;&lt;span&gt;^&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;=
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;Control &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;amp; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;[::Send&lt;&#x2F;span&gt;&lt;span&gt; ^[
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;Control &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;amp; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;]::Send&lt;&#x2F;span&gt;&lt;span&gt; ^]
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Not elegant, but works fine for me.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Install Latex in Windows</title>
          <pubDate>Tue, 08 Sep 2020 00:00:00 +0000</pubDate>
          <author>Peter Tillemans</author>
          <link>https://www.snamellit.com/posts/install-latex-in-windows/</link>
          <guid>https://www.snamellit.com/posts/install-latex-in-windows/</guid>
          <description xml:base="https://www.snamellit.com/posts/install-latex-in-windows/">&lt;p&gt;I have some latex templates to format documents to create fancy formal
looking PDF versions of my plaintext mode documents I create in
&lt;em&gt;org-mode&lt;&#x2F;em&gt; in &lt;em&gt;emacs&lt;&#x2F;em&gt;, well &lt;em&gt;spacemacs&lt;&#x2F;em&gt; actually.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;installation&quot;&gt;Installation&lt;&#x2F;h1&gt;
&lt;p&gt;Since this are tools built in the UNIX world I expected a protracted
battle before I got all settings right, especially since there was no
version of Live Tex in the chocolatey repositories. I never tried MikTex
before.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;installing-miktex&quot;&gt;Installing MikTex&lt;&#x2F;h2&gt;
&lt;p&gt;That is easy, in an admin shell run :&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;sh&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-sh &quot;&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; choco &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;install&lt;&#x2F;span&gt;&lt;span&gt; miktex
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This will take a bit so we can already fetch the templates.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;installing-the-custom-latex-templates&quot;&gt;Installing the custom LaTeX templates&lt;&#x2F;h2&gt;
&lt;p&gt;I keep my templates in git repositories for easy updating. Some are
shared with others so new features are sometimes added. Let&#x27;s make a
place for these&lt;&#x2F;p&gt;
&lt;p&gt;In the msys terminal :&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;sh&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-sh &quot;&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt; cd
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt; mkdir -p .local&#x2F;texmf&#x2F;tex&#x2F;latex
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I want to use the &lt;em&gt;.local&#x2F;texmf&lt;&#x2F;em&gt; as the local extension folder, but
&lt;em&gt;MikTex&lt;&#x2F;em&gt; will not allow to select it if the &lt;em&gt;tex&#x2F;latex&lt;&#x2F;em&gt; folders are
missing. Also this is consistent with the Mac and Linux versions.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;installing-the-custom-templates&quot;&gt;Installing the custom templates&lt;&#x2F;h2&gt;
&lt;p&gt;Just add the repos for the &lt;em&gt;.sty&lt;&#x2F;em&gt; and &lt;em&gt;.cls&lt;&#x2F;em&gt; files to the folder we just
made:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;sh&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-sh &quot;&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt; cd &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;~&lt;&#x2F;span&gt;&lt;span&gt;&#x2F;.local&#x2F;texmf&#x2F;tex&#x2F;latex
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt; git clone git@gitlab.xomeplace.com:latex&#x2F;xomeplace-latex.git
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt; ... repeat for other templates ...
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;configuring-miktex&quot;&gt;Configuring MikTex&lt;&#x2F;h2&gt;
&lt;p&gt;After installation look for MikTex in the &lt;em&gt;Start Menu&lt;&#x2F;em&gt; to start the
config tool. It will complain that no update has been done yes, so I
humoured it by updating, none are available since it is just installed,
but it keeps regularly reminding me to update. I assume this&#x27;ll go away
once some update arrives.&lt;&#x2F;p&gt;
&lt;p&gt;Add the &lt;em&gt;texmf&lt;&#x2F;em&gt; folder we created :&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Press the &#x27;+&#x27; icon&lt;&#x2F;li&gt;
&lt;li&gt;Navigate the ~&#x2F;.local&#x2F;texmf&lt;&#x2F;li&gt;
&lt;li&gt;Confirm&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Keep the tool open because we need to copy the location of the &lt;em&gt;bin&lt;&#x2F;em&gt;
folder in the next step.&lt;&#x2F;p&gt;
&lt;p&gt;## Add the TeX tools to the PATH&lt;&#x2F;p&gt;
&lt;p&gt;I only use the TeX tools from Spacemacs so I&#x27;ll just add it there. The
Spacemacs dev team decided to make the environment variables, including
the path, load from a config file. Having been at the receiving end of
the confusion which follows from the subtle differences when launching
&lt;em&gt;Emacs&lt;&#x2F;em&gt; as daemon, from the GUI menu or from the command line, I
heartily applaud this approach.&lt;&#x2F;p&gt;
&lt;p&gt;In any case I just update the PATH in &lt;em&gt;Spacemacs&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Space f e e (to open the environment config file)&lt;&#x2F;li&gt;
&lt;li&gt;find the line with PATH= ( &lt;em&gt;&#x27;&lt;&#x2F;em&gt;&#x27; PATH Enter, maybe some &#x2F;n* to
find the one)&lt;&#x2F;li&gt;
&lt;li&gt;Copy the location from the config tool&lt;&#x2F;li&gt;
&lt;li&gt;Paste it in the PATH value (do not forget the &#x27;;&#x27; separator)&lt;&#x2F;li&gt;
&lt;li&gt;Esc : w (to save changes)&lt;&#x2F;li&gt;
&lt;li&gt;Space f e E (to reload the new value)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;using-it&quot;&gt;Using it&lt;&#x2F;h1&gt;
&lt;p&gt;Well nothing new here, it kind of just works:&lt;&#x2F;p&gt;
&lt;h2 id=&quot;creating-a-pdf&quot;&gt;Creating a PDF&lt;&#x2F;h2&gt;
&lt;p&gt;Open an org file with the &lt;em&gt;LaTeX headers&lt;&#x2F;em&gt; or add them with &lt;em&gt;, e e #&lt;&#x2F;em&gt;
and select latex from the list. Check the &lt;em&gt;LATEX~CLASS~&lt;&#x2F;em&gt; is one of the
custom classes.&lt;&#x2F;p&gt;
&lt;p&gt;Then &lt;em&gt;, e e l o&lt;&#x2F;em&gt; and ... nothing will happen, ..., well emacs tells it
is busy with the texfile. It takes a while, taskmaster shows processes
blinking in and of existence under the Emacs process. I assume MikTex is
compiling stuff in the background of first use.&lt;&#x2F;p&gt;
&lt;p&gt;Eventually it returns stating PDF export failed and to consult the log
file.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;fix-errors&quot;&gt;Fix Errors&lt;&#x2F;h2&gt;
&lt;p&gt;The end of the logfile showed scary things of not being able to write.
Let&#x27;s ignore those for now : I learned to treat the first errors in the
LaTeX log output first, and retry and move my way down the log till
there are no more errors.&lt;&#x2F;p&gt;
&lt;p&gt;First Error : &#x27;Libertine Font&#x27; was not found, a bit further the same
with &#x27;Lato&#x27;.&lt;&#x2F;p&gt;
&lt;p&gt;Download the fonts, unzip, select all &lt;em&gt;.ttf&lt;&#x2F;em&gt; files and right-click
install.&lt;&#x2F;p&gt;
&lt;p&gt;Try again and the PDF opens ... in the Edge Browser ??? And the Edge
Browser attached itself to the taskbar??? Again??? I need to tackle that
some time.&lt;&#x2F;p&gt;
&lt;p&gt;Well, it works. Take the document and send it to those you wanted to
impress.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Leveraging Env Vars in Rust Apps</title>
          <pubDate>Sun, 06 Sep 2020 00:00:00 +0000</pubDate>
          <author>Peter Tillemans</author>
          <link>https://www.snamellit.com/posts/leveraging-env-vars-in-rust-apps/</link>
          <guid>https://www.snamellit.com/posts/leveraging-env-vars-in-rust-apps/</guid>
          <description xml:base="https://www.snamellit.com/posts/leveraging-env-vars-in-rust-apps/">&lt;p&gt;Environment variable have gained a lot of importance since the rise of
the container based deployments and (consequently) the popularity of the
&lt;a href=&quot;https:&#x2F;&#x2F;12factor.net&#x2F;&quot;&gt;12 factor app&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;It also has become very practical with the widespread support of the
&lt;em&gt;.env&lt;&#x2F;em&gt; file in the project folder which makes configuring apps during
development very practical.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;using-environment-in-rust&quot;&gt;Using environment in Rust&lt;&#x2F;h1&gt;
&lt;p&gt;The &lt;a href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;std&#x2F;env&#x2F;index.html&quot;&gt;std::env&lt;&#x2F;a&gt; package
gives access to the environment variables, and also information about
the working directory, the location of the program executing, temp
folder, etc...&lt;&#x2F;p&gt;
&lt;p&gt;The method we really are interested in is
&lt;a href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;std&#x2F;env&#x2F;fn.var.html&quot;&gt;var&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;sh&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-sh &quot;&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;match&lt;&#x2F;span&gt;&lt;span&gt; env::var(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;MQTT_BROKER&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;) {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;Ok&lt;&#x2F;span&gt;&lt;span&gt;(mqtt_broker) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;=&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; mqtt_init(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;mqtt_broker&lt;&#x2F;span&gt;&lt;span&gt;).await,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;Err&lt;&#x2F;span&gt;&lt;span&gt;(e) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;=&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; error&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;No broker specified in MQTT_BROKER environment variable.({})&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, e)
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;It returns a &lt;em&gt;Result&amp;lt;String, VarError&amp;gt;&lt;&#x2F;em&gt; which we can easily pattern
match on and give readable feedback to the user.&lt;&#x2F;p&gt;
&lt;p&gt;I thing this is perfectly fine for simple, small apps I am likely to
write in the foreseeable future.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;controlling-logging-from-the-environment&quot;&gt;Controlling Logging from the Environment&lt;&#x2F;h1&gt;
&lt;p&gt;Another thing needed for smallisch apps is a logging system with the
following requirements:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Controllable via environment&lt;&#x2F;li&gt;
&lt;li&gt;Add a timestamp&lt;&#x2F;li&gt;
&lt;li&gt;Output to stdout or stderr (a 12 factor thing)&lt;&#x2F;li&gt;
&lt;li&gt;Namespace modules&lt;&#x2F;li&gt;
&lt;li&gt;Override config for specific modules&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Rust has a standard logging API defined in the &lt;a href=&quot;https:&#x2F;&#x2F;docs.rs&#x2F;log&#x2F;0.4.11&#x2F;log&#x2F;&quot;&gt;log
crate&lt;&#x2F;a&gt; crate for which a large
selection of implementations is available.&lt;&#x2F;p&gt;
&lt;p&gt;The first one on the &lt;a href=&quot;https:&#x2F;&#x2F;docs.rs&#x2F;log&#x2F;0.4.11&#x2F;log&#x2F;#available-logging-implementations&quot;&gt;list with
implementations&lt;&#x2F;a&gt;
fit all my requirements, so that&#x27;s fine.&lt;&#x2F;p&gt;
&lt;p&gt;All we need to do is initialize it after reading the environment
variables from the &lt;em&gt;.env&lt;&#x2F;em&gt; file :&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;sh&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-sh &quot;&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;async&lt;&#x2F;span&gt;&lt;span&gt; fn main() {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;dotenv::dotenv&lt;&#x2F;span&gt;&lt;span&gt;().ok();
&lt;&#x2F;span&gt;&lt;span&gt;    env_logger::init();
&lt;&#x2F;span&gt;&lt;span&gt;    ...
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;and we are logging using the standard &lt;code&gt;debug!&lt;&#x2F;code&gt;{.verbatim},
&lt;code&gt;info!&lt;&#x2F;code&gt;{.verbatim}, &lt;code&gt;warn!&lt;&#x2F;code&gt;{.verbatim}, ... macros.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;scaling-to-larger-apps&quot;&gt;Scaling to larger apps&lt;&#x2F;h1&gt;
&lt;p&gt;When apps grow (or just when they live long enough) they tend to
accumulate config options and layers of modules making logging also a
headache.&lt;&#x2F;p&gt;
&lt;p&gt;When confronted with these issues I saw that the &lt;em&gt;config&lt;&#x2F;em&gt; and &lt;em&gt;envy&lt;&#x2F;em&gt;
crates offer nice layered configuration support and straightforward
pouring in type safe structs.&lt;&#x2F;p&gt;
&lt;p&gt;Similarly there are more flexible, and consequently more complex,
logging frameworks like &lt;em&gt;log4rs&lt;&#x2F;em&gt;. There are also structured logging
libraries but I still need to see how these can work in containers
without adding additional hoops to jump through.&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s hope my apps stay small and simple and do not need this
additional complexity.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Relm on Windows</title>
          <pubDate>Fri, 04 Sep 2020 00:00:00 +0000</pubDate>
          <author>Peter Tillemans</author>
          <link>https://www.snamellit.com/posts/relm-on-windows/</link>
          <guid>https://www.snamellit.com/posts/relm-on-windows/</guid>
          <description xml:base="https://www.snamellit.com/posts/relm-on-windows/">&lt;p&gt;There are essentially 2 methods for compiling Gtk apps&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;using &lt;em&gt;msvc&lt;&#x2F;em&gt; compiler and .LIB files&lt;&#x2F;li&gt;
&lt;li&gt;using &quot;gnu&quot; backend and msys2 libraries&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;It is a pick your poison situation, the first option requires unpacking
zip files and organizing stuff so the rust compiler can find the
libraries and the runtime the DLLs.&lt;&#x2F;p&gt;
&lt;p&gt;The other option requires configuring rust to essentially cross compile
to the &lt;em&gt;x86~64~-pc-windows-gnu&lt;&#x2F;em&gt; target.&lt;&#x2F;p&gt;
&lt;p&gt;Since I know how to cross compile from my recent experiments with
compiling for embedded ARM processors and I generally know my way better
around the unixy msys environment, the latter it is.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;installing-gtk-in-msys2-mingw64&quot;&gt;Installing Gtk in Msys2&#x2F;Mingw64&lt;&#x2F;h1&gt;
&lt;p&gt;Installing gtk3 is easy as it can be installed with &lt;em&gt;pacman&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;sh&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-sh &quot;&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt; pacman -S mingw64&#x2F;mingw-w64-x86_64-gtk3
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Add some support for integrating with c libraries and linking, etc...&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;sh&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-sh &quot;&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt; pacman -S mingw-w64-x86_64-toolchain base-devel
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Being optimistic I installed glade. Probably wont need it today but it
is a good test to see if Gtk apps at least start.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;sh&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-sh &quot;&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt; pacman -S mingw-w64-x86_64-glade
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Glade starts and shows the GUI so the first milestone was reached.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;preparing-rust-and-cargo&quot;&gt;Preparing rust and cargo&lt;&#x2F;h1&gt;
&lt;p&gt;First install the cross compilation target&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;sh&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-sh &quot;&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt; rustup target add x86_64-pc-windows-gnu
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I can now compile with&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;sh&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-sh &quot;&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt; PKG_CONFIG_ALLOW_CROSS=1 cargo build --target&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;x86_64-pc-windows-gnu
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;To always enably this environment variable in the project folder I added
a &lt;em&gt;.env&lt;&#x2F;em&gt; file with&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;sh&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-sh &quot;&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span&gt;PKG_CONFIG_ALLOW_CROSS&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;1
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;which is picked up by the zsh dotenv plugin when I enter the folder.&lt;&#x2F;p&gt;
&lt;p&gt;Similarly we can change the default target for cargo with adding&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;sh&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-sh &quot;&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;build]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;target&lt;&#x2F;span&gt;&lt;span&gt; = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;x86_64-pc-windows-gnu&amp;quot;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;to *.cargo&#x2F;config.toml&lt;&#x2F;p&gt;
&lt;p&gt;We can now simply do&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;sh&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-sh &quot;&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt; rust build
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;or&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;sh&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-sh &quot;&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt; rust run
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;using-vscode&quot;&gt;Using VSCode&lt;&#x2F;h1&gt;
&lt;p&gt;When using &lt;em&gt;vscode&lt;&#x2F;em&gt; the rust language server needs to have this
enviroment setup too so it can do its magic. For debugging and running
you can do this in &lt;em&gt;launch.json&lt;&#x2F;em&gt; by setting the variables in the &lt;em&gt;env&lt;&#x2F;em&gt;
property, but this is (logically) not used for the language server.
There seem no way to have &lt;em&gt;vscode&lt;&#x2F;em&gt; respect the &lt;em&gt;.env&lt;&#x2F;em&gt; file soon enough
for the language server to pick it up.&lt;&#x2F;p&gt;
&lt;p&gt;The solution I settled on was to launch &lt;em&gt;vscode&lt;&#x2F;em&gt; from the command line
in the project folder:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;sh&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-sh &quot;&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt; code .
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The prompt returns immediately and &lt;em&gt;vscode&lt;&#x2F;em&gt; is seeing the same
environment as the shell. (This does imply that the vscode bin directory
is on the path.)&lt;&#x2F;p&gt;
&lt;p&gt;Of course this wisdom was gained by fixing 1 error message after another
while trying to build an example in a 2018 blogpost. In hindsight I
could have started with the examples provided with the relm sourcecode,
but where would be the fun in that?&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Logging Notification Messages in Ubuntu</title>
          <pubDate>Mon, 22 Jul 2013 11:48:16 +0000</pubDate>
          <author>Peter Tillemans</author>
          <link>https://www.snamellit.com/posts/logging-notification-in-ubuntu/</link>
          <guid>https://www.snamellit.com/posts/logging-notification-in-ubuntu/</guid>
          <description xml:base="https://www.snamellit.com/posts/logging-notification-in-ubuntu/">&lt;p&gt;Ubuntu contains a nice notification system to talk to the user about noteworthy events. However when the message dissappears, by default, it is gone. Often I am busy with something else when the notification pops up and I pay little notice. Then somewhere in my brain, something gets triggered by a word, and by the time I focus on the message to &lt;strong&gt;really&lt;&#x2F;strong&gt; read it, the message disappears. Some of these appear after booting or logging in, so it is not trivial to redisplay them. Then I really need a system for logging notification messages for reading what I missed. Ideally there was a scroll back buffer in the notification feature. Maybe there is, but I didn&#x27;t find it.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;standard-notification-logging&quot;&gt;Standard Notification Logging&lt;&#x2F;h2&gt;
&lt;p&gt;The developers provided a log in *~&#x2F;.cache&#x2F;notify-osd.log*. (see [[https:&#x2F;&#x2F;wiki.ubuntu.com&#x2F;NotifyOSD][NotifyOSD page an the ubuntu wiki]]) for logging notification messages. So this used to be a moot point as a quick $ tail ~&#x2F;.cache&#x2F;notify-osd gave me what I needed. However somewhere between 12.04 and 13.04 the default behavior was changed to no longer log to this file by default. My last entry was from December 2012. It was considered as a developer feature and was disabled for the general public, but controllable using an environment variable : LOG=1. To enable this globally, edit *&#x2F;etc&#x2F;environment* and add LOG=1 However, since this is such a vague variable, I guess that this will enable logging in more than just *notify-osd*. I am fine with this (at least until my disk runs out). The wiki, which actually contains a design document rather than documentation, makes no mention of it. It is also not very logical as the file is reset when logging in, so it should never pose a threat to the disk space. In any case, I dropped a small note in the wiki to point users in the right direction.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;logging-notifications-with-an-app&quot;&gt;Logging Notifications with an App&lt;&#x2F;h2&gt;
&lt;p&gt;There is also an app for that. You can install the package indicator-notifications which keeps track of notifcations that you receive. You can install with the following $ sudo add-apt-repository ppa:jconti&#x2F;recent-notifications $ sudo apt-get update $ sudo apt-get install indicator-notifications You&#x27;ll have to log out and log back in. It shows up as a mailbox in the top panel and turns green when you get new messages. For more info about logging notifications see &lt;a href=&quot;http:&#x2F;&#x2F;askubuntu.com&#x2F;questions&#x2F;288348&#x2F;how-can-i-read-notifyosd-messages-after-they-are-displayed&quot; title=&quot;this AskUbuntu Question&quot;&gt;http:&#x2F;&#x2F;askubuntu.com&#x2F;questions&#x2F;288348&#x2F;how-can-i-read-notifyosd-messages-after-they-are-displayed&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Uploading documents to Plone with WebDAV</title>
          <pubDate>Thu, 29 Mar 2012 22:03:41 +0000</pubDate>
          <author>Peter Tillemans</author>
          <link>https://www.snamellit.com/posts/uploading-documents-to-plone-with-webdav/</link>
          <guid>https://www.snamellit.com/posts/uploading-documents-to-plone-with-webdav/</guid>
          <description xml:base="https://www.snamellit.com/posts/uploading-documents-to-plone-with-webdav/">&lt;p&gt;Preparing &lt;strong&gt;Plone&lt;&#x2F;strong&gt; to start the WebDAV service and setting the
permissions to allow the users to make use of it is only half the
battle, actually using it, especially from automated systems like
build servers is another struggle.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;using-the-cadaver-webdav-client&quot;&gt;Using the &lt;em&gt;Cadaver&lt;&#x2F;em&gt; WebDAV client&lt;&#x2F;h2&gt;
&lt;p&gt;Although WebDAV is currently well integrated in modern desktop
environments, a CLI alternative is useful for automation, like
&lt;em&gt;Jenkins&lt;&#x2F;em&gt; build scripts.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;automatic-login&quot;&gt;Automatic Login&lt;&#x2F;h3&gt;
&lt;p&gt;Ideally we want password-less operation from script, both from a usability as from a security standpoint.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Cadaver&lt;&#x2F;em&gt; supports automatically logging in to servers requiring authentication via a .netrc file, like the &lt;em&gt;ftp&lt;&#x2F;em&gt; client. The syntax is such that the file can be shared for both tools.&lt;&#x2F;p&gt;
&lt;p&gt;The file ~&#x2F;.netrc may be used to automatically login to a server requiring authentication. The following tokens (separated by spaces, tabs or newlines) may be used:&lt;&#x2F;p&gt;
&lt;h4 id=&quot;machine-host&quot;&gt;machine host&lt;&#x2F;h4&gt;
&lt;p&gt;Identify a remote machine host which is compared with the hostname given on the command line or as an argument to the open command. Any subsequent tokens up to the end of file or the next machine or default token are associated with this entry.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;default&quot;&gt;default&lt;&#x2F;h4&gt;
&lt;p&gt;This is equivalent to the machine token but matches any hostname. Only one default token may be used and it must be after all machine tokens.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;login-username&quot;&gt;login &lt;em&gt;username&lt;&#x2F;em&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;Specifies the username to use when logging in to the remote machine.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;password-secret&quot;&gt;password &lt;em&gt;secret&lt;&#x2F;em&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;Specifies the password to use when logging in to the remote machine. (Alternatively the keyword &lt;strong&gt;passwd&lt;&#x2F;strong&gt; may be used)&lt;&#x2F;p&gt;
&lt;h4 id=&quot;example-netrc-file&quot;&gt;Example ~&#x2F;.netrc file&lt;&#x2F;h4&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;default
&lt;&#x2F;span&gt;&lt;span&gt;login jenkins
&lt;&#x2F;span&gt;&lt;span&gt;passwd secret 
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h4 id=&quot;example-session&quot;&gt;Example Session&lt;&#x2F;h4&gt;
&lt;h3 id=&quot;troubleshooting&quot;&gt;Troubleshooting&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;error-409-conflict&quot;&gt;Error 409 Conflict&lt;&#x2F;h4&gt;
&lt;p&gt;This can mean a lot of things, like a real conflict. However most of the time it means that the folder where the stuff is uploaded does not exist:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;dav:&#x2F;cmdb&#x2F;Members&#x2F;pti&#x2F;&amp;gt; mput Dropbox&#x2F;Apps&#x2F;Byword&#x2F;plone_webdav.md
&lt;&#x2F;span&gt;&lt;span&gt;Uploading Dropbox&#x2F;Apps&#x2F;Byword&#x2F;plone_webdav.md to `&#x2F;cmdb&#x2F;...&amp;#39;:
&lt;&#x2F;span&gt;&lt;span&gt;Progress: [=============================&amp;gt;] 100,0% of 1488 bytes failed:
&lt;&#x2F;span&gt;&lt;span&gt;409 Conflict 
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This actually tries to upload the file to a subfolder _Dropbox&#x2F;Apps&#x2F;Byword_which does not exist, causing this confusing error.&lt;&#x2F;p&gt;
&lt;p&gt;Simply changing the local directory solves the issue:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;dav:&#x2F;cmdb&#x2F;Members&#x2F;pti&#x2F;&amp;gt; lcd Dropbox&#x2F;Apps&#x2F;Byword
&lt;&#x2F;span&gt;&lt;span&gt;dav:&#x2F;cmdb&#x2F;Members&#x2F;pti&#x2F;&amp;gt; mput plone_webdav.md
&lt;&#x2F;span&gt;&lt;span&gt;Uploading plone_webdav.md to `&#x2F;cmdb&#x2F;Members&#x2F;pti&#x2F;plone_webdav.md&amp;#39;:
&lt;&#x2F;span&gt;&lt;span&gt;Progress: [=============================&amp;gt;] 100,0% of 1488 bytes succeeded. 
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h4 id=&quot;cannot-create-folders-using-webdav&quot;&gt;Cannot create folders using WebDAV&lt;&#x2F;h4&gt;
&lt;p&gt;Problem: The WebDAV &quot;make folder&quot; method, MKCOL, requires the &quot;Add Folders&quot; permission. This is not normally granted to Members or Owners on the site.&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;dav:&#x2F;cmdb&#x2F;Members&#x2F;jenkins&#x2F;&amp;gt; mkcol test2
&lt;&#x2F;span&gt;&lt;span&gt;Creating `test2&amp;#39;: Authentication required for Zope on server `cmdb-uat.elex.be&amp;#39;:
&lt;&#x2F;span&gt;&lt;span&gt;Username: 
&lt;&#x2F;span&gt;&lt;span&gt;Password: 
&lt;&#x2F;span&gt;&lt;span&gt;Retrying: Authentication required for Zope on server `cmdb-uat.elex.be&amp;#39;:
&lt;&#x2F;span&gt;&lt;span&gt;Username: Terminated by signal 2. 
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Plone asks to login again because the current user has insufficient rights.&lt;&#x2F;p&gt;
&lt;p&gt;Workaround: In the Zope Management Interface, under the &quot;Security&quot; tab for the Plone root, check the &quot;Owners&quot; and &quot;Managers&quot; box for the &quot;Add Folders&quot; permission setting.&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;~  ᐅ cadaver dav:&#x2F;&#x2F;cmdb-uat.elex.be:1980&#x2F;cmdb&#x2F;Members&#x2F;jenkins
&lt;&#x2F;span&gt;&lt;span&gt;dav:&#x2F;cmdb&#x2F;Members&#x2F;jenkins&#x2F;&amp;gt; mkcol test2
&lt;&#x2F;span&gt;&lt;span&gt;Creating `test2&amp;#39;: succeeded.
&lt;&#x2F;span&gt;&lt;span&gt;dav:&#x2F;cmdb&#x2F;Members&#x2F;jenkins&#x2F;&amp;gt; 
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Source: &lt;a href=&quot;http:&#x2F;&#x2F;plone.org&#x2F;documentation&#x2F;error&#x2F;unable-to-create-a-folder-through-webdav&quot;&gt;Members Can&#x27;t Create Folders Through WebDAV&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;automating-cadaver-with-davpush-pl&quot;&gt;Automating Cadaver with &lt;strong&gt;davpush.pl&lt;&#x2F;strong&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Cadaver uses an ftp like command language to interact with the WebDAV server. This is very flexible, but impractical when a large number of files and folders must be uploaded. This happens often when the documentation for a new release must replace the previous version.&lt;&#x2F;p&gt;
&lt;p&gt;Cadaver accepts its input on the &lt;strong&gt;stdin&lt;&#x2F;strong&gt; stream, which allows us to pipe a script of commands to it. Since it is non-trivial to create and maintain such a script by hand, a script generator is needed. The generator presented here is meant to be simple and easy to use and modify. No attempt was made to made to add advanced syncing (like removing deleted files), handle exceptions gracefully or &#x27;do the right thing&#x27;.&lt;&#x2F;p&gt;
&lt;p&gt;With that in mind, organize the docs in such a way that it is easy to delete the target folder and push a fresh copy to clean everything up. This is common (and good) practice anyway in order to effectively use relative links within a subsite.&lt;&#x2F;p&gt;
&lt;p&gt;The principle is to &lt;strong&gt;cd&lt;&#x2F;strong&gt; to the root directory of the documentation root and run the script there and point it to the target.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;usage&quot;&gt;Usage&lt;&#x2F;h3&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;davpush.pl dav:&#x2F;&#x2F;_hostname_:_port_&#x2F;_upload path_ 
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Uploads all files and folders recursively to the WebDAV folder passed in the url.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;code&quot;&gt;Code&lt;&#x2F;h3&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;#!&#x2F;usr&#x2F;bin&#x2F;perl
&lt;&#x2F;span&gt;&lt;span&gt;use File::Find;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;my $script = &amp;quot;&amp;quot;;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;sub wanted() {
&lt;&#x2F;span&gt;&lt;span&gt;  my $f = $File::Find::name;
&lt;&#x2F;span&gt;&lt;span&gt;  if (-f $f) {
&lt;&#x2F;span&gt;&lt;span&gt;    $script .= &amp;quot;put $fn&amp;quot;;
&lt;&#x2F;span&gt;&lt;span&gt;  } else {
&lt;&#x2F;span&gt;&lt;span&gt;    $script .= &amp;quot;cd $target_dirn&amp;quot;;
&lt;&#x2F;span&gt;&lt;span&gt;    $script .= &amp;quot;mkdir $fn&amp;quot;;
&lt;&#x2F;span&gt;&lt;span&gt;    $script .= &amp;quot;cd $fn&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;  }
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;my $url = $ARGV[0];
&lt;&#x2F;span&gt;&lt;span&gt;print &amp;quot;URL: $url&amp;quot;;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;if ($url =~ m#dav:&#x2F;&#x2F;.*?(&#x2F;S*)#) {
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;  my $target_url = &amp;quot;$0&amp;quot;;
&lt;&#x2F;span&gt;&lt;span&gt;  my $target_dir = &amp;quot;$1&amp;quot;;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;  find({&amp;#39;wanted&amp;#39;=&amp;gt;&amp;amp;wanted, &amp;#39;no_chdir&amp;#39; =&amp;gt; 1},   &amp;quot;.&amp;quot;);
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;  $pid = open(POUT, &amp;quot;| cadaver $url&amp;quot;);
&lt;&#x2F;span&gt;&lt;span&gt;  print POUT $script;
&lt;&#x2F;span&gt;&lt;span&gt;  print POUT &amp;quot;byen&amp;quot;;
&lt;&#x2F;span&gt;&lt;span&gt;  close POUT;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;} else {
&lt;&#x2F;span&gt;&lt;span&gt;  print &amp;quot;Usage: davpush.pl dav:&#x2F;&#x2F;&amp;lt;hostname&amp;gt;:&amp;lt;port&amp;gt;&#x2F;&amp;lt;upload path&amp;gt;n&amp;quot;;
&lt;&#x2F;span&gt;&lt;span&gt;  print &amp;quot;n&amp;quot;;
&lt;&#x2F;span&gt;&lt;span&gt;  print &amp;quot;Uploads all files and folders recursively to the WebDAV folder passed in the url.&amp;quot;;
&lt;&#x2F;span&gt;&lt;span&gt;} 
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;code-notes&quot;&gt;Code Notes&lt;&#x2F;h3&gt;
&lt;p&gt;The standard perl &lt;strong&gt;File::Find&lt;&#x2F;strong&gt; module traverses the folder tree in the right order to make sure all folders are created before other files or folders are created in them. Default behavior is to &lt;strong&gt;chdir&lt;&#x2F;strong&gt; to the directory, but then we lose the nice paths relative from the root, which would require additional administration entering and leaving the directory. Setting the &lt;strong&gt;no_chdir&lt;&#x2F;strong&gt; flag in the options keeps the paths like we want them in the script. (Look at the &lt;strong&gt;preprocess&lt;&#x2F;strong&gt; and &lt;strong&gt;postprocess&lt;&#x2F;strong&gt; options to help with the directory admin, but I think the added complexity will outweigh the gains for small to moderate trees)&lt;&#x2F;p&gt;
&lt;p&gt;For every file or folder, the &lt;strong&gt;wanted&lt;&#x2F;strong&gt; subroutine is called. For files we just add a &lt;strong&gt;mput&lt;&#x2F;strong&gt; command to copy the file over, because it keeps the path intact. If there is a file already (and the permissions are not screwed up) then it is overwritten. When we enter a new folder then we create the folder. If the folder already exists we get a (harmless) &lt;strong&gt;405 Method Not Allowed&lt;&#x2F;strong&gt; error. Here we make another offer to the &lt;em&gt;God of Simplicity&lt;&#x2F;em&gt;, and &lt;em&gt;ignore&lt;&#x2F;em&gt; it.&lt;&#x2F;p&gt;
&lt;p&gt;After walking the tree, we have the script in the &lt;strong&gt;$script&lt;&#x2F;strong&gt; variable. It is unceremoniously piped as input for &lt;strong&gt;cadaver&lt;&#x2F;strong&gt;. We add the &lt;strong&gt;bye&lt;&#x2F;strong&gt; command to close the session, and we&#x27;re done. The output of &lt;strong&gt;cadaver&lt;&#x2F;strong&gt; appears on the &lt;strong&gt;stdout&lt;&#x2F;strong&gt; for easy verification using a &lt;em&gt;MkI Eyeball&lt;&#x2F;em&gt; check or by piping it to &lt;strong&gt;grep&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;sample-session&quot;&gt;Sample session&lt;&#x2F;h3&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;~&#x2F;Dropbox&#x2F;Apps&#x2F;Byword  ᐅ perl ~&#x2F;tmp&#x2F;davpush.pl dav:&#x2F;&#x2F;cmdb-uat.elex.be:1980&#x2F;cmdb&#x2F;Members&#x2F;pti
&lt;&#x2F;span&gt;&lt;span&gt;URL: dav:&#x2F;&#x2F;cmdb-uat.elex.be:1980&#x2F;cmdb&#x2F;Members&#x2F;ptiCreating `.&amp;#39;: failed:
&lt;&#x2F;span&gt;&lt;span&gt;405 Method Not Allowed
&lt;&#x2F;span&gt;&lt;span&gt;Uploading .&#x2F;plone_webdav.html to `&#x2F;cmdb&#x2F;Members&#x2F;pti&#x2F;plone_webdav.html&amp;#39;:
&lt;&#x2F;span&gt;&lt;span&gt;Progress: [=============================&amp;gt;] 100,0% of 4007 bytes succeeded.
&lt;&#x2F;span&gt;&lt;span&gt;Uploading .&#x2F;plone_webdav.md to `&#x2F;cmdb&#x2F;Members&#x2F;pti&#x2F;plone_webdav.md&amp;#39;:
&lt;&#x2F;span&gt;&lt;span&gt;Progress: [=============================&amp;gt;] 100,0% of 6369 bytes succeeded.
&lt;&#x2F;span&gt;&lt;span&gt;Uploading .&#x2F;Untitled.txt to `&#x2F;cmdb&#x2F;Members&#x2F;pti&#x2F;Untitled.txt&amp;#39;:
&lt;&#x2F;span&gt;&lt;span&gt;Progress: [=============================&amp;gt;] 100,0% of 203 bytes succeeded.
&lt;&#x2F;span&gt;&lt;span&gt;Uploading .&#x2F;Uploading to `&#x2F;cmdb&#x2F;Members&#x2F;pti&#x2F;Uploading&amp;#39;: Could not open file: No such file or directory
&lt;&#x2F;span&gt;&lt;span&gt;Uploading documents to `&#x2F;cmdb&#x2F;Members&#x2F;pti&#x2F;documents&amp;#39;: Could not open file: No such file or directory
&lt;&#x2F;span&gt;&lt;span&gt;Uploading to to `&#x2F;cmdb&#x2F;Members&#x2F;pti&#x2F;to&amp;#39;: Could not open file: No such file or directory
&lt;&#x2F;span&gt;&lt;span&gt;Uploading Plone to `&#x2F;cmdb&#x2F;Members&#x2F;pti&#x2F;Plone&amp;#39;: Could not open file: No such file or directory
&lt;&#x2F;span&gt;&lt;span&gt;Uploading with to `&#x2F;cmdb&#x2F;Members&#x2F;pti&#x2F;with&amp;#39;: Could not open file: No such file or directory
&lt;&#x2F;span&gt;&lt;span&gt;Uploading WebDAV.md to `&#x2F;cmdb&#x2F;Members&#x2F;pti&#x2F;WebDAV.md&amp;#39;: Could not open file: No such file or directory
&lt;&#x2F;span&gt;&lt;span&gt;Creating `.&#x2F;foo&amp;#39;: failed:
&lt;&#x2F;span&gt;&lt;span&gt;405 Method Not Allowed
&lt;&#x2F;span&gt;&lt;span&gt;Creating `.&#x2F;foo&#x2F;bar&amp;#39;: failed:
&lt;&#x2F;span&gt;&lt;span&gt;405 Method Not Allowed
&lt;&#x2F;span&gt;&lt;span&gt;Creating `.&#x2F;foo&#x2F;bar&#x2F;baz&amp;#39;: failed:
&lt;&#x2F;span&gt;&lt;span&gt;405 Method Not Allowed
&lt;&#x2F;span&gt;&lt;span&gt;Uploading .&#x2F;foo&#x2F;bar&#x2F;baz&#x2F;plone_webdav.md to `&#x2F;cmdb&#x2F;Members&#x2F;pti&#x2F;foo&#x2F;bar&#x2F;baz&#x2F;plone_webdav.md&amp;#39;:
&lt;&#x2F;span&gt;&lt;span&gt;Progress: [=============================&amp;gt;] 100,0% of 3380 bytes succeeded.
&lt;&#x2F;span&gt;&lt;span&gt;Creating `.&#x2F;images&amp;#39;: failed:
&lt;&#x2F;span&gt;&lt;span&gt;405 Method Not Allowed
&lt;&#x2F;span&gt;&lt;span&gt;Uploading .&#x2F;images&#x2F;SJ09_1.jpg to `&#x2F;cmdb&#x2F;Members&#x2F;pti&#x2F;images&#x2F;SJ09_1.jpg&amp;#39;:
&lt;&#x2F;span&gt;&lt;span&gt;Progress: [=============================&amp;gt;] 100,0% of 31637 bytes succeeded.
&lt;&#x2F;span&gt;&lt;span&gt;Uploading .&#x2F;images&#x2F;SJ09_2.jpg to `&#x2F;cmdb&#x2F;Members&#x2F;pti&#x2F;images&#x2F;SJ09_2.jpg&amp;#39;:
&lt;&#x2F;span&gt;&lt;span&gt;Progress: [=============================&amp;gt;] 100,0% of 29182 bytes succeeded.
&lt;&#x2F;span&gt;&lt;span&gt;Uploading .&#x2F;images&#x2F;SJ09_3.jpg to `&#x2F;cmdb&#x2F;Members&#x2F;pti&#x2F;images&#x2F;SJ09_3.jpg&amp;#39;:
&lt;&#x2F;span&gt;&lt;span&gt;Progress: [=============================&amp;gt;] 100,0% of 31296 bytes succeeded.
&lt;&#x2F;span&gt;&lt;span&gt;Uploading .&#x2F;images&#x2F;SJ09_4.jpg to `&#x2F;cmdb&#x2F;Members&#x2F;pti&#x2F;images&#x2F;SJ09_4.jpg&amp;#39;:
&lt;&#x2F;span&gt;&lt;span&gt;Progress: [=============================&amp;gt;] 100,0% of 31094 bytes succeeded.
&lt;&#x2F;span&gt;&lt;span&gt;Uploading .&#x2F;images&#x2F;SJ09_5.jpg to `&#x2F;cmdb&#x2F;Members&#x2F;pti&#x2F;images&#x2F;SJ09_5.jpg&amp;#39;:
&lt;&#x2F;span&gt;&lt;span&gt;Progress: [=============================&amp;gt;] 100,0% of 26886 bytes succeeded.
&lt;&#x2F;span&gt;&lt;span&gt;Uploading .&#x2F;images&#x2F;SJ09_6.jpg to `&#x2F;cmdb&#x2F;Members&#x2F;pti&#x2F;images&#x2F;SJ09_6.jpg&amp;#39;:
&lt;&#x2F;span&gt;&lt;span&gt;Progress: [=============================&amp;gt;] 100,0% of 29373 bytes succeeded.
&lt;&#x2F;span&gt;&lt;span&gt;Uploading .&#x2F;images&#x2F;SJ09_7.jpg to `&#x2F;cmdb&#x2F;Members&#x2F;pti&#x2F;images&#x2F;SJ09_7.jpg&amp;#39;:
&lt;&#x2F;span&gt;&lt;span&gt;Progress: [=============================&amp;gt;] 100,0% of 34486 bytes succeeded.
&lt;&#x2F;span&gt;&lt;span&gt;Uploading .&#x2F;images&#x2F;SJ09_8.jpg to `&#x2F;cmdb&#x2F;Members&#x2F;pti&#x2F;images&#x2F;SJ09_8.jpg&amp;#39;:
&lt;&#x2F;span&gt;&lt;span&gt;Progress: [=============================&amp;gt;] 100,0% of 28561 bytes succeeded.
&lt;&#x2F;span&gt;&lt;span&gt;Uploading .&#x2F;images&#x2F;SJ09_9.jpg to `&#x2F;cmdb&#x2F;Members&#x2F;pti&#x2F;images&#x2F;SJ09_9.jpg&amp;#39;:
&lt;&#x2F;span&gt;&lt;span&gt;Progress: [=============================&amp;gt;] 100,0% of 27381 bytes succeeded.
&lt;&#x2F;span&gt;&lt;span&gt;Connection to `cmdb-uat.elex.be&amp;#39; closed. 
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</description>
      </item>
      <item>
          <title>Disable authentication for global proxy settings on Ubuntu</title>
          <pubDate>Fri, 22 Jul 2011 14:33:00 +0000</pubDate>
          <author>Peter Tillemans</author>
          <link>https://www.snamellit.com/posts/disiable-authentication-for-global-proxy-settings-on-ubuntu/</link>
          <guid>https://www.snamellit.com/posts/disiable-authentication-for-global-proxy-settings-on-ubuntu/</guid>
          <description xml:base="https://www.snamellit.com/posts/disiable-authentication-for-global-proxy-settings-on-ubuntu/">&lt;p&gt;2011-07-22 Fri 16:33 &lt;a href=&quot;https:&#x2F;&#x2F;www.snamellit.com&#x2F;posts&#x2F;disiable-authentication-for-global-proxy-settings-on-ubuntu&#x2F;snamellit.html#ID-c965ad9d-522b-4dfe-9574-b8d2a78c83a3&quot;&gt;Figure out proxy settings Linux&lt;&#x2F;a&gt; Ubuntu has a Network Proxy chooser which allows you to select a location (a la MacOSX). This works well enough except that the UI is a bit counter-intuitive (in my humble opinion)which causes me to regularly nuke some predefined setting inadvertently. This is not a big deal though. However for update manager (and several other tools) to pick up the new proxy settings you need to push the settings down to the system level. This takes 2 times typing your password. Now, this IS a big deal. When I go back and forth between work and home I have to change this at least 2 times per day. Also it irks me that a detail setting like the proxy is not auto-detected and I need to login to change this &#x27;system&#x27; setting. My laptop is essentially a single user system and I do not see switching the proxy as a serious security issue, even with 3 kids running around the home. To come back to auto-detection, while this works fine at work, it fails to figure out that at home that there is a direct connection to the Internet. I can probably fix this by replacing my aging wireless router with my Time Capsule as the Internet gateway router, but I prefer to have the Time Capsule close to my desk. In any case the &lt;strong&gt;Network proxy&lt;&#x2F;strong&gt; shows 2 times the authentication dialog box. A particularly nice feature (Is this new in Natty?) is that the dialog shows for which DBUS setting access is being asked. The first dialog asks access to &lt;strong&gt;com.ubuntu.systemservice.setProxy&lt;&#x2F;strong&gt;. This response is configured in the file &lt;strong&gt;&#x2F;usr&#x2F;share&#x2F;polkit-1&#x2F;actions&#x2F;com.ubuntu.systemservice.policy&lt;&#x2F;strong&gt;. This is a very readable XML file which contains a section for the &lt;strong&gt;setProxy&lt;&#x2F;strong&gt; action. I feel no reservation in allowing unchecked access to the &lt;strong&gt;setProxy&lt;&#x2F;strong&gt;. Although this might make a man-in-the-middle attack easier someone with the sophistication to pull this off, does not need to doctor my PC to do it.&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;&amp;lt;action id=&amp;quot;com.ubuntu.systemservice.setproxy&amp;quot;\&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;  &amp;lt;description&amp;gt;Set current global proxy&amp;lt;&#x2F;description&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;  &amp;lt;message&amp;gt;System policy prevents setting proxy settings&amp;lt;&#x2F;message&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;  &amp;lt;defaults&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &amp;lt;!-- PTI : original settings
&lt;&#x2F;span&gt;&lt;span&gt;    &amp;lt;allow\_inactive&amp;gt;no&amp;lt;&#x2F;allow\_inactive&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &amp;lt;allow\_active&amp;gt;auth\_admin\_keep&amp;lt;&#x2F;allow\_active&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;    --&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &amp;lt;allow\_inactive&amp;gt;yes&amp;lt;&#x2F;allow\_inactive&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &amp;lt;allow\_active&amp;gt;yes&amp;lt;&#x2F;allow\_active&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;  &amp;lt;&#x2F;defaults&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&#x2F;action&amp;gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Retrying, and indeed one of the authentication requests dropped. Note that the action was configured with &lt;strong&gt;auth_admin_keep&lt;&#x2F;strong&gt; which according to the docs would mean we should be authenticated for some time,so I would not expect the second authentication I am getting. Must be a subtlety which escapes me at the moment. The second action is more problematic since the &lt;strong&gt;set-system&lt;&#x2F;strong&gt; om the system gconf settings is much less fine-grained than &lt;strong&gt;setProxy&lt;&#x2F;strong&gt; and can potentially cause more damage to the system.
&amp;lt;action id=&quot;org.gnome.gconf.defaults.set-system&quot;&amp;gt;
&amp;lt;description gettext-domain=&quot;GConf2&quot;&amp;gt;Change GConf system values&lt;&#x2F;description&gt;
&amp;lt;message gettext-domain=&quot;GConf2&quot;&amp;gt;Privileges are required to change GConf system values&lt;&#x2F;message&gt;
&lt;defaults&gt;
&amp;lt;allow_inactive&amp;gt;no&amp;lt;&#x2F;allow_inactive&amp;gt;
&lt;!-- PTI: Original setting
        &lt;allow\_active&gt;auth\_admin&lt;&#x2F;allow\_active&gt;
        --&gt;
&amp;lt;allow_active&amp;gt;yes&amp;lt;&#x2F;allow_active&amp;gt;
&lt;&#x2F;defaults&gt;
&lt;&#x2F;action&gt;&lt;&#x2F;p&gt;
&lt;p&gt;After relaxing this second method, I can finally easily switch proxies between Locations. There are several things bugging me:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;The set-system method really is too wide in scope.&lt;&#x2F;li&gt;
&lt;li&gt;There should be a more elegant way that modifying files under &lt;strong&gt;&#x2F;usr&#x2F;share&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;li&gt;My system should actually switch location unaided.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;For the time being, I fixed a frustration and learned something in the process. The result is not yet fully satisfactory, but that will improve over time. **&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http:&#x2F;&#x2F;ubuntu.paslah.com&#x2F;policykit&#x2F;&quot;&gt;Tutorial explaining editing static files&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;http:&#x2F;&#x2F;hal.freedesktop.org&#x2F;docs&#x2F;polkit&#x2F;pklocalauthority.8.html&quot;&gt;pklocalauthority man page&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;http:&#x2F;&#x2F;forums.opensuse.org&#x2F;english&#x2F;get-technical-help-here&#x2F;applications&#x2F;433124-install-updates-unprivileged-user.html&quot;&gt;Install Updates as Unprivileged User&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Of course there is a more elegant solution than editing files under &lt;strong&gt;&#x2F;usr&#x2F;share&lt;&#x2F;strong&gt; folder. Everything is explained in the man pages &lt;strong&gt;pklocalauthority&lt;&#x2F;strong&gt; and &lt;strong&gt;PolicyKit.conf&lt;&#x2F;strong&gt; (among others). But that&#x27;s for another day...&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Making dotFiles visible on the Mac</title>
          <pubDate>Wed, 20 Jul 2011 20:56:00 +0000</pubDate>
          <author>Peter Tillemans</author>
          <link>https://www.snamellit.com/posts/making-dotfiles-visible-on-mac/</link>
          <guid>https://www.snamellit.com/posts/making-dotfiles-visible-on-mac/</guid>
          <description xml:base="https://www.snamellit.com/posts/making-dotfiles-visible-on-mac/">&lt;p&gt;Dotfiles, can&#x27;t live with &#x27;em, can&#x27;t live without &#x27;em. Dot files are the term for folders and files starting with a &#x27;.&#x27; so they do not show upwhen using plain &lt;strong&gt;ls&lt;&#x2F;strong&gt;. Tha Mac has a cool keycode to toggle visibility of dotfiles in the &lt;strong&gt;File Open&#x2F;Save&lt;&#x2F;strong&gt; dialog, but this does not work in the finder for one reason or another. In practice this meant I had to deal with dotFiles and dotDriectories I found on the net some incantation to force the setting for the finder to show&#x2F;hide the dotfiles. Upon restarting the finder the widows will reopen with the updated setting. I found on the net some snippets of sh script (but I forgot where and cannot immediately retrieve it), and I immediately dumped them in my &lt;strong&gt;~&#x2F;bin&lt;&#x2F;strong&gt; folder. ~&#x2F;bin&#x2F;hide-dotfiles :&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;#!&#x2F;bin&#x2F;sh
&lt;&#x2F;span&gt;&lt;span&gt;defaults write com.apple.finder AppleShowAllFiles -bool FALSE
&lt;&#x2F;span&gt;&lt;span&gt;killall Finder
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;~&#x2F;bin&#x2F;show-dotfile :```&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;#!&#x2F;bin&#x2F;sh
&lt;&#x2F;span&gt;&lt;span&gt;defaults write com.apple.finder AppleShowAllFiles -bool TRUE
&lt;&#x2F;span&gt;&lt;span&gt;killall Finder
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;So in order to toggle the setting in the graphical finderyou drop to the commandline set the flag in the desired state and restart the finders. Works nice… One remark : if you suddenly see strange icons on your desktop, then you probably still have the dotFiles visible selected. &lt;strong&gt;hide-dotfiles&lt;&#x2F;strong&gt; will clean your desktop up again. *&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Building debian packages in a cleanroom</title>
          <pubDate>Thu, 14 Jul 2011 16:19:00 +0000</pubDate>
          <author>Peter Tillemans</author>
          <link>https://www.snamellit.com/posts/building-debian-packages-in-a-cleanroom/</link>
          <guid>https://www.snamellit.com/posts/building-debian-packages-in-a-cleanroom/</guid>
          <description xml:base="https://www.snamellit.com/posts/building-debian-packages-in-a-cleanroom/">&lt;h3 id=&quot;overview-and-goals&quot;&gt;Overview and Goals&lt;&#x2F;h3&gt;
&lt;p&gt;We build our solutions mostly on Ubuntu Natty and we deploy to Debian (currently lenny). One problem we face is that Debian has a slow release cycle and the packages are dated. Before a new release is approved and deployed to our target servers it can still take many months causing us to have to use up to 3 year old technology. So we are often faced to &#x27;backport&#x27; packages or debianize existing packages if we want to use the current releases. In the past we had different build servers for the target architectures. However this is a heavy solution and scales poorly. It also makes upgrading to the next release that much heavier. So we need a system for building debian packages that is :&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Fully automated&lt;&#x2F;li&gt;
&lt;li&gt;Target multiple distributions Debian (lenny,squeeze) and Ubuntu(natty, maverick)&lt;&#x2F;li&gt;
&lt;li&gt;Build on development machines(a) and Jenkins&#x2F;Hudson CI servers(b)&lt;&#x2F;li&gt;
&lt;li&gt;easily configurable&lt;&#x2F;li&gt;
&lt;li&gt;memorizable process&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;The goal is to make packages for internal consumption, and the process outlined here falls short of the community standards.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;enter-pbuilder&quot;&gt;Enter pbuilder&lt;&#x2F;h3&gt;
&lt;p&gt;Of course we are not the first or only one with this issue. In fact we are laggards and there are excellent articles on the &#x27;net to help us with these goals. e.g.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http:&#x2F;&#x2F;www.netfort.gr.jp&#x2F;~dancer&#x2F;software&#x2F;pbuilder-doc&#x2F;pbuilder-doc.html&quot;&gt;PBuilder User Manual&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;http:&#x2F;&#x2F;wiki.debian.org&#x2F;PbuilderTricks&quot;&gt;Pbuilder Tricks on the Debian Wiki&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wiki.ubuntu.com&#x2F;PbuilderHowto&quot;&gt;PBuilder How To over at the Ubuntu Wiki&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The &lt;strong&gt;pbuilder&lt;&#x2F;strong&gt; program create a clean room environment of a freshly installed empty debian or ubuntu distro, chroot into it and starts building based on the project metadata, mostly from the &lt;strong&gt;debian&#x2F;control&lt;&#x2F;strong&gt; file. It does this by unpacking a preconfigured &lt;strong&gt;base&lt;&#x2F;strong&gt; image of the selectable target , installing the build dependencies, building the package in the cleanroom, moving the artifacts to the hosting machine and cleaning everything up again. And it does this actually surprisingly fast. This clearly satisfies goals 1 and 2 (and half of 3 if we assume a developer has full control over his laptop). The &lt;strong&gt;pbuilder&lt;&#x2F;strong&gt; is configured through commandline options, which are clear and friendly enough but you end up with commandlines of several lines long which are impossible to type in a shell and are a maintenance nightmare in build scripts (clearly conflicts with point 5). Also in the ideal world we would be able to retarget a build without touching the checked out files, e.g. with environment variable (see goals 3 and 4).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;configuring-pbuilder&quot;&gt;Configuring pbuilder&lt;&#x2F;h3&gt;
&lt;p&gt;On the Pbuilders Tricks page I found a big smart shell script to use as the &lt;strong&gt;pbuilder&lt;&#x2F;strong&gt; configuration file &lt;strong&gt;~&#x2F;.pbuilderrc&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;\# Codenames for Debian suites according to their alias. Update these when needed.
&lt;&#x2F;span&gt;&lt;span&gt;UNSTABLE\_CODENAME=&amp;quot;sid&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;TESTING\_CODENAME=&amp;quot;wheezy&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;STABLE\_CODENAME=&amp;quot;squeeze&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;OLDSTABLE\_CODENAME=&amp;quot;lenny&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;STABLE\_BACKPORTS\_SUITE=&amp;quot;$STABLE\_CODENAME-backports&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;\# List of Debian suites.
&lt;&#x2F;span&gt;&lt;span&gt;DEBIAN\_SUITES=($UNSTABLE\_CODENAME $TESTING\_CODENAME $STABLE\_CODENAME $OLDSTABLE\_CODENAME
&lt;&#x2F;span&gt;&lt;span&gt;    &amp;quot;unstable&amp;quot; &amp;quot;testing&amp;quot; &amp;quot;stable&amp;quot; &amp;quot;oldstable&amp;quot;)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;\# List of Ubuntu suites. Update these when needed.
&lt;&#x2F;span&gt;&lt;span&gt;UBUNTU\_SUITES=(&amp;quot;natty&amp;quot; &amp;quot;maverick&amp;quot; &amp;quot;jaunty&amp;quot; &amp;quot;intrepid&amp;quot; &amp;quot;hardy&amp;quot; &amp;quot;gutsy&amp;quot;)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;\# Mirrors to use. Update these to your preferred mirror.
&lt;&#x2F;span&gt;&lt;span&gt;DEBIAN\_MIRROR=&amp;quot;ftp.be.debian.org&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;UBUNTU\_MIRROR=&amp;quot;mirrors.kernel.org&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;\# Optionally use the changelog of a package to determine the suite to use if
&lt;&#x2F;span&gt;&lt;span&gt;\# none set.
&lt;&#x2F;span&gt;&lt;span&gt;if \[ -z &amp;quot;${DIST}&amp;quot; \] &amp;amp;&amp;amp; \[ -r &amp;quot;debian&#x2F;changelog&amp;quot; \]; then
&lt;&#x2F;span&gt;&lt;span&gt;    DIST=$(dpkg-parsechangelog | awk &amp;#39;&#x2F;^Distribution: &#x2F; {print $2}&amp;#39;)
&lt;&#x2F;span&gt;&lt;span&gt;    # Use the unstable suite for Debian experimental packages.
&lt;&#x2F;span&gt;&lt;span&gt;    if \[ &amp;quot;${DIST}&amp;quot; == &amp;quot;experimental&amp;quot; \]; then
&lt;&#x2F;span&gt;&lt;span&gt;        DIST=&amp;quot;unstable&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;    fi
&lt;&#x2F;span&gt;&lt;span&gt;fi
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;\# Optionally set a default distribution if none is used. Note that you can set
&lt;&#x2F;span&gt;&lt;span&gt;\# your own default (i.e. ${DIST:=&amp;quot;unstable&amp;quot;}).
&lt;&#x2F;span&gt;&lt;span&gt;: ${DIST:=&amp;quot;$(lsb\_release --short --codename)&amp;quot;}
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;\# Optionally set the architecture to the host architecture if none set. Note
&lt;&#x2F;span&gt;&lt;span&gt;\# that you can set your own default (i.e. ${ARCH:=&amp;quot;i386&amp;quot;}).
&lt;&#x2F;span&gt;&lt;span&gt;: ${ARCH:=&amp;quot;$(dpkg --print-architecture)&amp;quot;}
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;NAME=&amp;quot;$DIST&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;if \[ -n &amp;quot;${ARCH}&amp;quot; \]; then
&lt;&#x2F;span&gt;&lt;span&gt;    NAME=&amp;quot;$NAME-$ARCH&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;    DEBOOTSTRAPOPTS=(&amp;quot;--arch&amp;quot; &amp;quot;$ARCH&amp;quot; &amp;quot;${DEBOOTSTRAPOPTS\[@\]}&amp;quot;)
&lt;&#x2F;span&gt;&lt;span&gt;fi
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;BASETGZ=&amp;quot;&#x2F;var&#x2F;cache&#x2F;pbuilder&#x2F;$NAME-base.tgz&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;DISTRIBUTION=&amp;quot;$DIST&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;BUILDRESULT=&amp;quot;&#x2F;var&#x2F;cache&#x2F;pbuilder&#x2F;$NAME&#x2F;result&#x2F;&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;APTCACHE=&amp;quot;&#x2F;var&#x2F;cache&#x2F;pbuilder&#x2F;$NAME&#x2F;aptcache&#x2F;&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;BUILDPLACE=&amp;quot;&#x2F;var&#x2F;cache&#x2F;pbuilder&#x2F;build&#x2F;&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;\# make sure folders exist
&lt;&#x2F;span&gt;&lt;span&gt;mkdir -p $BUILDRESULT
&lt;&#x2F;span&gt;&lt;span&gt;mkdir -p $APTCACHE
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;echo &amp;quot;Target : $BUILDRESULT&amp;quot; &amp;gt;&amp;gt;&#x2F;tmp&#x2F;dist
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;if $(echo ${DEBIAN\_SUITES\[@\]} | grep -q $DIST); then
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    OTHERMIRROR=&amp;quot;deb file:&#x2F;&#x2F;&#x2F;var&#x2F;cache&#x2F;pbuilder&#x2F;$NAME&#x2F;result .&#x2F;&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;    BINDMOUNTS=&amp;quot;&#x2F;var&#x2F;cache&#x2F;pbuilder&#x2F;$NAME&#x2F;result&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;    HOOKDIR=&amp;quot;&#x2F;var&#x2F;cache&#x2F;pbuilder&#x2F;$NAME&#x2F;hooks&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;    EXTRAPACKAGES=&amp;quot;apt-utils&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;    # Debian configuration
&lt;&#x2F;span&gt;&lt;span&gt;    MIRRORSITE=&amp;quot;http:&#x2F;&#x2F;$DEBIAN\_MIRROR&#x2F;debian&#x2F;&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;    COMPONENTS=&amp;quot;main contrib non-free&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;    DEBOOTSTRAPOPTS=(&amp;quot;${DEBOOTSTRAPOPTS\[@\]}&amp;quot; &amp;quot;--keyring=&#x2F;usr&#x2F;share&#x2F;keyrings&#x2F;debian-archive-keyring.gpg&amp;quot;)
&lt;&#x2F;span&gt;&lt;span&gt;    if $(echo &amp;quot;$STABLE\_CODENAME stable&amp;quot; | grep -q $DIST); then
&lt;&#x2F;span&gt;&lt;span&gt;        EXTRAPACKAGES=&amp;quot;$EXTRAPACKAGES debian-backports-keyring&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;        OTHERMIRROR=&amp;quot;$OTHERMIRROR | deb http:&#x2F;&#x2F;www.backports.org&#x2F;debian $STABLE\_BACKPORTS\_SUITE $COMPONENTS&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;    fi
&lt;&#x2F;span&gt;&lt;span&gt;elif $(echo ${UBUNTU\_SUITES\[@\]} | grep -q $DIST); then
&lt;&#x2F;span&gt;&lt;span&gt;    # Ubuntu configuration
&lt;&#x2F;span&gt;&lt;span&gt;    MIRRORSITE=&amp;quot;http:&#x2F;&#x2F;$UBUNTU\_MIRROR&#x2F;ubuntu&#x2F;&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;    COMPONENTS=&amp;quot;main restricted universe multiverse&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;    DEBOOTSTRAPOPTS=(&amp;quot;${DEBOOTSTRAPOPTS\[@\]}&amp;quot; &amp;quot;--keyring=&#x2F;usr&#x2F;share&#x2F;keyrings&#x2F;ubuntu-archive-keyring.gpg&amp;quot;)
&lt;&#x2F;span&gt;&lt;span&gt;else
&lt;&#x2F;span&gt;&lt;span&gt;    echo &amp;quot;Unknown distribution: $DIST&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;    exit 1
&lt;&#x2F;span&gt;&lt;span&gt;fi
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I just updated the distribution names to the current situation and added the directory where the packages are collected as a repository so subsequent builds can use these packages as dependencies. I also specified the keyrings to use for Debian and Ubuntu and made sure the expected folders are created to mount them in the clean room. I created this in my account on my development laptop and added a symbolic link in ~root&#x2F;.pbuilderrc to this file so I can update it from my desktop environment and do not have to get my brain all twisted up to try to remember with which configuration I am busy in my shell, sudo, &lt;strong&gt;su -&lt;&#x2F;strong&gt;, … THe way the script works is that the configuration adapts itself to the content of the &lt;strong&gt;DIST&lt;&#x2F;strong&gt; and &lt;strong&gt;ARCH&lt;&#x2F;strong&gt; environment variables. So to configure &lt;strong&gt;lenny-amd64&lt;&#x2F;strong&gt; as target is sufficient to do&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;~ &amp;gt; export DIST=lenny
&lt;&#x2F;span&gt;&lt;span&gt;~ &amp;gt; export ARCH=amd64
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This approach is also perfect Jenkins or Hudson to determine the target build from checked out sources, since it can be specified in the build recipe. (satisfies goals 3b, 4 and 5) Since we have to run these programs using sudo we must make sure the environment variables are passed by sudo. We can do this in the &lt;strong&gt;Defaults&lt;&#x2F;strong&gt; line of the &lt;strong&gt;&#x2F;etc&#x2F;sudoers&lt;&#x2F;strong&gt; file with the &lt;strong&gt;envkeep&lt;&#x2F;strong&gt; instruction.&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;...
&lt;&#x2F;span&gt;&lt;span&gt;Defaults  env\_reset,env\_keep=&amp;quot;DIST ARCH http\_proxy ftp\_proxy 
&lt;&#x2F;span&gt;&lt;span&gt; https\_proxy no\_proxy&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;... snip ...
&lt;&#x2F;span&gt;&lt;span&gt;\# Cmnd alias specification
&lt;&#x2F;span&gt;&lt;span&gt;Cmnd\_Alias PBUILDER=&#x2F;usr&#x2F;sbin&#x2F;pbuilder, &#x2F;usr&#x2F;bin&#x2F;pdebuild
&lt;&#x2F;span&gt;&lt;span&gt;... snip to end of file ...
&lt;&#x2F;span&gt;&lt;span&gt;\# Allow members of group sudo to execute any command
&lt;&#x2F;span&gt;&lt;span&gt;%sudo   ALL=(ALL:ALL) ALL
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;pti     ALL=(ALL) NOPASSWD: PBUILDER
&lt;&#x2F;span&gt;&lt;span&gt;jenkins ALL=(ALL) NOPASSWD: PBUILDER
&lt;&#x2F;span&gt;&lt;span&gt;\#includedir &#x2F;etc&#x2F;sudoers.d
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;You add the &lt;strong&gt;DIST&lt;&#x2F;strong&gt; and &lt;strong&gt;ARCH&lt;&#x2F;strong&gt; variables there. I also included the environment variables for proxying so I can easily switch between environment on my laptop and these changes propagate to sudo (which is also useful for plain apt-get, by the way). I also added a line to show how to make the tools available for a user without having to give their password. This is not needed for interactive work, but very much so for the user as which the CI server is running (in our case &lt;strong&gt;jenkins&lt;&#x2F;strong&gt;). Note that the definition should be after the group definitions, otherwise these take precedence and jenkins has to provide his password (read: is hanging during the build).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;creating-the-target-base-images&quot;&gt;Creating the target base images&lt;&#x2F;h3&gt;
&lt;p&gt;The heavy lifting is now done. Let&#x27;s create an &lt;strong&gt;base.tgz&lt;&#x2F;strong&gt; for lenny-amd64.&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;~ &amp;gt; export DIST=lenny
&lt;&#x2F;span&gt;&lt;span&gt;~ &amp;gt; export ARCH=amd64
&lt;&#x2F;span&gt;&lt;span&gt;~ &amp;gt; sudo pbuilder create
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now go and have a cup of coffee (or read some emails). Rinse and repeat for the other target platforms.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;backporting-existing-packages&quot;&gt;Backporting existing packages&lt;&#x2F;h3&gt;
&lt;p&gt;In theory backporting would be as simple as&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;~  ᐅ cd tmp
&lt;&#x2F;span&gt;&lt;span&gt;~&#x2F;tmp  ᐅ apt-get source mongodb
&lt;&#x2F;span&gt;&lt;span&gt;Reading package lists... Done
&lt;&#x2F;span&gt;&lt;span&gt;Building dependency tree
&lt;&#x2F;span&gt;&lt;span&gt;Reading state information... Done
&lt;&#x2F;span&gt;&lt;span&gt;Need to get 1,316 kB of source archives.
&lt;&#x2F;span&gt;&lt;span&gt;Get:1 http:&#x2F;&#x2F;be.archive.ubuntu.com&#x2F;ubuntu&#x2F; natty&#x2F;universe mongodb 1:1.6.3-1ubuntu2 (dsc) \[2,276 B\]
&lt;&#x2F;span&gt;&lt;span&gt;Get:2 http:&#x2F;&#x2F;be.archive.ubuntu.com&#x2F;ubuntu&#x2F; natty&#x2F;universe mongodb 1:1.6.3-1ubuntu2 (tar) \[1,285 kB\]
&lt;&#x2F;span&gt;&lt;span&gt;Get:3 http:&#x2F;&#x2F;be.archive.ubuntu.com&#x2F;ubuntu&#x2F; natty&#x2F;universe mongodb 1:1.6.3-1ubuntu2 (diff) \[29.0 kB\]
&lt;&#x2F;span&gt;&lt;span&gt;Fetched 1,316 kB in 1s (679 kB&#x2F;s)
&lt;&#x2F;span&gt;&lt;span&gt;gpgv: Signature made Thu 17 Mar 2011 11:49:37 PM CET using RSA key ID D5946E0F
&lt;&#x2F;span&gt;&lt;span&gt;gpgv: Can&amp;#39;t check signature: public key not found
&lt;&#x2F;span&gt;&lt;span&gt;dpkg-source: warning: failed to verify signature on .&#x2F;mongodb\_1.6.3-1ubuntu2.dsc
&lt;&#x2F;span&gt;&lt;span&gt;dpkg-source: info: extracting mongodb in mongodb-1.6.3
&lt;&#x2F;span&gt;&lt;span&gt;dpkg-source: info: unpacking mongodb\_1.6.3.orig.tar.gz
&lt;&#x2F;span&gt;&lt;span&gt;dpkg-source: info: unpacking mongodb\_1.6.3-1ubuntu2.debian.tar.gz
&lt;&#x2F;span&gt;&lt;span&gt;dpkg-source: info: applying debian-changes-1:1.6.3-1
&lt;&#x2F;span&gt;&lt;span&gt;dpkg-source: info: applying build-process-remove-rpath
&lt;&#x2F;span&gt;&lt;span&gt;dpkg-source: info: applying mozjs185
&lt;&#x2F;span&gt;&lt;span&gt;~&#x2F;tmp  ᐅ DIST=lenny ARCH=amd64 sudo pbuilder build mongodb\_1.6.3-1ubuntu2.dsc
&lt;&#x2F;span&gt;&lt;span&gt;I: using fakeroot in build.
&lt;&#x2F;span&gt;&lt;span&gt;I: Current time: Thu Jul 14 14:28:17 CEST 2011
&lt;&#x2F;span&gt;&lt;span&gt;I: pbuilder-time-stamp: 1310646497
&lt;&#x2F;span&gt;&lt;span&gt;I: Building the build Environment
&lt;&#x2F;span&gt;&lt;span&gt;I: extracting base tarball \[&#x2F;var&#x2F;cache&#x2F;pbuilder&#x2F;lenny-amd64-base.tgz\]
&lt;&#x2F;span&gt;&lt;span&gt;...
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;and you should get a nice set of debian packages in *&#x2F;var&#x2F;cache&#x2F;pbuilder&#x2F;lenny-amd64. In practice you will often end up with errors like :&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;... snip ...
&lt;&#x2F;span&gt;&lt;span&gt;The following packages have unmet dependencies:
&lt;&#x2F;span&gt;&lt;span&gt;  pbuilder-satisfydepends-dummy: Depends: xulrunner-dev (&amp;gt;= 2.0~) but it is not installable
&lt;&#x2F;span&gt;&lt;span&gt;The following actions will resolve these dependencies:
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;Remove the following packages:
&lt;&#x2F;span&gt;&lt;span&gt;pbuilder-satisfydepends-dummy
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;Score is -9850
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;Writing extended state information... Done
&lt;&#x2F;span&gt;&lt;span&gt;... snip ...
&lt;&#x2F;span&gt;&lt;span&gt;I: cleaning the build env
&lt;&#x2F;span&gt;&lt;span&gt;I: removing directory &#x2F;var&#x2F;cache&#x2F;pbuilder&#x2F;build&#x2F;&#x2F;6279 and its subdirectories
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In these case you have to walk the dependency tree till you find the leafs, and walk back up the branches to the trunk. Note also that chances are that unless you target machines which only serve a very specific purpose, you might end up with packages which are uninstallable since you pull out the rug from other installed packages. However we have the principle to use 1 virtual host to deliver 1 service, hence there are very little packages deployed to them and nothing complicated like desktop environments. Simple leaf packages often build without a hitch:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;~&#x2F;tmp  ᐅ DIST=lenny sudo pbuilder build libevent\_1.4.13-stable-1.dsc
&lt;&#x2F;span&gt;&lt;span&gt;I: using fakeroot in build.
&lt;&#x2F;span&gt;&lt;span&gt;I: Current time: Thu Jul 14 14:44:00 CEST 2011
&lt;&#x2F;span&gt;&lt;span&gt;I: pbuilder-time-stamp: 1310647440
&lt;&#x2F;span&gt;&lt;span&gt;I: Building the build Environment
&lt;&#x2F;span&gt;&lt;span&gt;I: extracting base tarball \[&#x2F;var&#x2F;cache&#x2F;pbuilder&#x2F;lenny-amd64-base.tgz\]
&lt;&#x2F;span&gt;&lt;span&gt;I: creating local configuration
&lt;&#x2F;span&gt;&lt;span&gt;I: copying local configuration
&lt;&#x2F;span&gt;&lt;span&gt;I: mounting &#x2F;proc filesystem
&lt;&#x2F;span&gt;&lt;span&gt;I: mounting &#x2F;dev&#x2F;pts filesystem
&lt;&#x2F;span&gt;&lt;span&gt;I: Mounting &#x2F;var&#x2F;cache&#x2F;pbuilder&#x2F;ccache
&lt;&#x2F;span&gt;&lt;span&gt;... snip ...
&lt;&#x2F;span&gt;&lt;span&gt;dpkg-genchanges: including full source code in upload
&lt;&#x2F;span&gt;&lt;span&gt;dpkg-buildpackage: full upload (original source is included)
&lt;&#x2F;span&gt;&lt;span&gt;W: no hooks of type B found -- ignoring
&lt;&#x2F;span&gt;&lt;span&gt;I: Copying back the cached apt archive contents
&lt;&#x2F;span&gt;&lt;span&gt;I: unmounting &#x2F;var&#x2F;cache&#x2F;pbuilder&#x2F;lenny-amd64&#x2F;result filesystem
&lt;&#x2F;span&gt;&lt;span&gt;I: unmounting &#x2F;var&#x2F;cache&#x2F;pbuilder&#x2F;ccache filesystem
&lt;&#x2F;span&gt;&lt;span&gt;I: unmounting dev&#x2F;pts filesystem
&lt;&#x2F;span&gt;&lt;span&gt;I: unmounting proc filesystem
&lt;&#x2F;span&gt;&lt;span&gt;I: cleaning the build env
&lt;&#x2F;span&gt;&lt;span&gt;I: removing directory &#x2F;var&#x2F;cache&#x2F;pbuilder&#x2F;build&#x2F;&#x2F;15214 and its subdirectories
&lt;&#x2F;span&gt;&lt;span&gt;I: Current time: Thu Jul 14 14:49:57 CEST 2011
&lt;&#x2F;span&gt;&lt;span&gt;I: pbuilder-time-stamp: 1310647797
&lt;&#x2F;span&gt;&lt;span&gt;~&#x2F;tmp  ᐅ ls -al &#x2F;var&#x2F;cache&#x2F;pbuilder&#x2F;lenny-amd64&#x2F;result
&lt;&#x2F;span&gt;&lt;span&gt;total 5260
&lt;&#x2F;span&gt;&lt;span&gt;drwxr-xr-x 2 root root    4096 2011-07-13 19:47 .
&lt;&#x2F;span&gt;&lt;span&gt;drwxr-xr-x 5 root root    4096 2011-07-13 19:13 ..
&lt;&#x2F;span&gt;&lt;span&gt;-rw-r--r-- 1 pti  pti     2853 2011-07-14 14:49 libevent\_1.4.13-stable-1\_amd64.changes
&lt;&#x2F;span&gt;&lt;span&gt;-rw-r--r-- 1 pti  pti     9129 2011-07-14 14:49 libevent\_1.4.13-stable-1.diff.gz
&lt;&#x2F;span&gt;&lt;span&gt;-rw-r--r-- 1 pti  pti      907 2011-07-14 14:49 libevent\_1.4.13-stable-1.dsc
&lt;&#x2F;span&gt;&lt;span&gt;-rw-r--r-- 1 pti  pti   499603 2009-12-05 23:04 libevent\_1.4.13-stable.orig.tar.gz
&lt;&#x2F;span&gt;&lt;span&gt;-rw-r--r-- 1 pti  pti    61956 2011-07-14 14:49 libevent-1.4-2\_1.4.13-stable-1\_amd64.deb
&lt;&#x2F;span&gt;&lt;span&gt;-rw-r--r-- 1 pti  pti    31262 2011-07-14 14:49 libevent-core-1.4-2\_1.4.13-stable-1\_amd64.deb
&lt;&#x2F;span&gt;&lt;span&gt;-rw-r--r-- 1 pti  pti   172950 2011-07-14 14:49 libevent-dev\_1.4.13-stable-1\_amd64.deb
&lt;&#x2F;span&gt;&lt;span&gt;-rw-r--r-- 1 pti  pti    51588 2011-07-14 14:49 libevent-extra-1.4-2\_1.4.13-stable-1\_amd64.deb
&lt;&#x2F;span&gt;&lt;span&gt;-rw-r--r-- 1 root root    9051 2011-07-14 14:48 Packages
&lt;&#x2F;span&gt;&lt;span&gt;~&#x2F;tmp  ᐅ
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;using-pdebuild-for-building-packages&quot;&gt;Using &lt;strong&gt;pdebuild&lt;&#x2F;strong&gt; for building packages&lt;&#x2F;h3&gt;
&lt;p&gt;Many of our packages are debianized and can be build using &lt;strong&gt;debuild&lt;&#x2F;strong&gt;. I use here the Ubuntu sources of tokyocabinet as an example (which uses the libevent package we just built, btw):&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;~&#x2F;tmp&#x2F;tokyocabinet-1.4.37  ᐅ DIST=lenny ARCH=amd64 pdebuild
&lt;&#x2F;span&gt;&lt;span&gt;...snip...
&lt;&#x2F;span&gt;&lt;span&gt; dpkg-genchanges  &amp;gt;..&#x2F;tokyocabinet\_1.4.37-6ubuntu1\_amd64.changes
&lt;&#x2F;span&gt;&lt;span&gt;dpkg-genchanges: not including original source code in upload
&lt;&#x2F;span&gt;&lt;span&gt;dpkg-buildpackage: binary and diff upload (original source NOT included)
&lt;&#x2F;span&gt;&lt;span&gt;W: no hooks of type B found -- ignoring
&lt;&#x2F;span&gt;&lt;span&gt;I: Copying back the cached apt archive contents
&lt;&#x2F;span&gt;&lt;span&gt;I: unmounting &#x2F;var&#x2F;cache&#x2F;pbuilder&#x2F;lenny-amd64&#x2F;result filesystem
&lt;&#x2F;span&gt;&lt;span&gt;I: unmounting &#x2F;var&#x2F;cache&#x2F;pbuilder&#x2F;ccache filesystem
&lt;&#x2F;span&gt;&lt;span&gt;I: unmounting dev&#x2F;pts filesystem
&lt;&#x2F;span&gt;&lt;span&gt;I: unmounting proc filesystem
&lt;&#x2F;span&gt;&lt;span&gt;I: cleaning the build env
&lt;&#x2F;span&gt;&lt;span&gt;I: removing directory &#x2F;var&#x2F;cache&#x2F;pbuilder&#x2F;build&#x2F;&#x2F;4199 and its subdirectories
&lt;&#x2F;span&gt;&lt;span&gt;I: Current time: Thu Jul 14 15:05:27 CEST 2011
&lt;&#x2F;span&gt;&lt;span&gt;I: pbuilder-time-stamp: 1310648727
&lt;&#x2F;span&gt;&lt;span&gt;~&#x2F;tmp&#x2F;tokyocabinet-1.4.37  ᐅ ls &#x2F;var&#x2F;cache&#x2F;pbuilder&#x2F;lenny-amd64&#x2F;result
&lt;&#x2F;span&gt;&lt;span&gt;...snip...
&lt;&#x2F;span&gt;&lt;span&gt;tokyocabinet\_1.4.37-6ubuntu1\_amd64.changes
&lt;&#x2F;span&gt;&lt;span&gt;tokyocabinet\_1.4.37-6ubuntu1.debian.tar.gz
&lt;&#x2F;span&gt;&lt;span&gt;tokyocabinet\_1.4.37-6ubuntu1.dsc
&lt;&#x2F;span&gt;&lt;span&gt;tokyocabinet\_1.4.37.orig.tar.gz
&lt;&#x2F;span&gt;&lt;span&gt;tokyocabinet-bin\_1.4.37-6ubuntu1\_amd64.deb
&lt;&#x2F;span&gt;&lt;span&gt;tokyocabinet-doc\_1.4.37-6ubuntu1\_all.deb
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Sometimes the dependencies break on the version of debhelpers. This version is added conservatively by the dh* scripts and often is overly conservative. Many packages build just fine with older versions of the debhelpers.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;setting-up-automated-build&quot;&gt;Setting up automated build&lt;&#x2F;h3&gt;
&lt;p&gt;To set this up on the build server we have to replicate the steps above&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Create the ~&#x2F;.pbuilderrc file&lt;&#x2F;li&gt;
&lt;li&gt;Symbolic link to this file in ~root&#x2F;.pbuilderrc&lt;&#x2F;li&gt;
&lt;li&gt;Allow jenkins to use sudo for building packages&lt;&#x2F;li&gt;
&lt;li&gt;Create a jenkins job to (re)build the packages&lt;&#x2F;li&gt;
&lt;li&gt;Create jobs to build the packages&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
</description>
      </item>
      <item>
          <title>Enable real idletime for Org Mode on Ubuntu</title>
          <pubDate>Mon, 04 Jul 2011 09:11:00 +0000</pubDate>
          <author>Peter Tillemans</author>
          <link>https://www.snamellit.com/posts/enable-real-idletime-for-org-mode-on-ubuntu/</link>
          <guid>https://www.snamellit.com/posts/enable-real-idletime-for-org-mode-on-ubuntu/</guid>
          <description xml:base="https://www.snamellit.com/posts/enable-real-idletime-for-org-mode-on-ubuntu/">&lt;p&gt;Org Mode can use the idle time to correct time tracking entries. On the Mac this works on the idle time of the computer, on other platforms it uses the idle time of emacs. Hence if you do a significant task in another program it will be idle for org-mode. There is a little program delivered with org-mode sources to estimate the &quot;real&quot; idle time based on the information used by screensavers. Unfortunaltely it is in source code and needs to be compiled first. Everything is actually well documented, just scattered. Let&#x27;s see where that little program is located&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;$ locate x11idle
&lt;&#x2F;span&gt;&lt;span&gt;&#x2F;home&#x2F;pti&#x2F;.emacs.d&#x2F;vendor&#x2F;org-mode&#x2F;UTILITIES&#x2F;x11idle.c
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This conveniently shows the location of the source file. If you might find a &lt;strong&gt;x11info&lt;&#x2F;strong&gt; file (without .c) in a bin directory then it is already installed and you&#x27;re done. If you get no results and there is some remark that the database is too old then it is time to refresh it using &lt;strong&gt;sudo updatedb&lt;&#x2F;strong&gt;. Then the lookup should find the file. Now go to the folder where the file is located. In my case :&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;$ cd ~&#x2F;.emacs.d&#x2F;vendor&#x2F;org-mode&#x2F;UTILITIES
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We need to make sure we have the necessary X screensaver libraries for compiling :```&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;$ sudo apt-get install lib-xss-de
&lt;&#x2F;span&gt;&lt;span&gt;sudo apt-get install libxss-dev
&lt;&#x2F;span&gt;&lt;span&gt;Reading package lists... Done
&lt;&#x2F;span&gt;&lt;span&gt;Building dependency tree
&lt;&#x2F;span&gt;&lt;span&gt;Reading state information... Done
&lt;&#x2F;span&gt;&lt;span&gt;The following extra packages will be installed:
&lt;&#x2F;span&gt;&lt;span&gt;  x11proto-scrnsaver-dev
&lt;&#x2F;span&gt;&lt;span&gt;The following NEW packages will be installed:
&lt;&#x2F;span&gt;&lt;span&gt;  libxss-dev x11proto-scrnsaver-dev
&lt;&#x2F;span&gt;&lt;span&gt;0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
&lt;&#x2F;span&gt;&lt;span&gt;Need to get 34.1 kB of archives.
&lt;&#x2F;span&gt;&lt;span&gt;After this operation, 225 kB of additional disk space will be used.
&lt;&#x2F;span&gt;&lt;span&gt;Do you want to continue \[Y&#x2F;n\]?
&lt;&#x2F;span&gt;&lt;span&gt;Get:1 http:&#x2F;&#x2F;be.archive.ubuntu.com&#x2F;ubuntu&#x2F; natty&#x2F;main x11proto-scrnsaver-dev all 1.2.1-1 \[21.3 kB\]
&lt;&#x2F;span&gt;&lt;span&gt;Get:2 http:&#x2F;&#x2F;be.archive.ubuntu.com&#x2F;ubuntu&#x2F; natty&#x2F;main libxss-dev amd64 1:1.2.1-1 \[12.9 kB\]
&lt;&#x2F;span&gt;&lt;span&gt;Fetched 34.1 kB in 0s (200 kB&#x2F;s)
&lt;&#x2F;span&gt;&lt;span&gt;Selecting previously deselected package x11proto-scrnsaver-dev.
&lt;&#x2F;span&gt;&lt;span&gt;(Reading database ... 567603 files and directories currently installed.)
&lt;&#x2F;span&gt;&lt;span&gt;Unpacking x11proto-scrnsaver-dev (from ...&#x2F;x11proto-scrnsaver-dev\_1.2.1-1\_all.deb) ...
&lt;&#x2F;span&gt;&lt;span&gt;Selecting previously deselected package libxss-dev.
&lt;&#x2F;span&gt;&lt;span&gt;Unpacking libxss-dev (from ...&#x2F;libxss-dev\_1%3a1.2.1-1\_amd64.deb) ...
&lt;&#x2F;span&gt;&lt;span&gt;Processing triggers for man-db ...
&lt;&#x2F;span&gt;&lt;span&gt;Setting up x11proto-scrnsaver-dev (1.2.1-1) ...
&lt;&#x2F;span&gt;&lt;span&gt;Setting up libxss-dev (1:1.2.1-1) ...
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now we can compile &lt;strong&gt;x11idle&lt;&#x2F;strong&gt;. We need to specify to link against the X11 and X Screensaver libraries (Xss). I immediately place the resulting executable file in &lt;strong&gt;~&#x2F;bin&#x2F;x11idle&lt;&#x2F;strong&gt;. Alternatively you could use the &#x2F;usr&#x2F;local&#x2F;bin folder, but first compile to a temporary location like &lt;strong&gt;&#x2F;tmp&lt;&#x2F;strong&gt; and move it there : &lt;strong&gt;sudo mv &#x2F;tmp&#x2F;x11idle &#x2F;usr&#x2F;local&#x2F;bin&lt;&#x2F;strong&gt;.```&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;$ gcc -o ~&#x2F;bin&#x2F;x11idle -lX11 -lXss x11idle.c
&lt;&#x2F;span&gt;&lt;span&gt;x11idle.c: In function ‘main’:
&lt;&#x2F;span&gt;&lt;span&gt;x11idle.c:19:5: warning: format ‘%u’ expects type ‘unsigned int’, but argument 2 has type ‘long unsigned int’
&lt;&#x2F;span&gt;&lt;span&gt;$ x11idle
&lt;&#x2F;span&gt;&lt;span&gt;22
&lt;&#x2F;span&gt;&lt;span&gt;$ x11idle
&lt;&#x2F;span&gt;&lt;span&gt;20
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I tried to run it using the normal path and got 22 and 20 seconds idle time : it works !!! The orgmode code will now find and use it. For more background info see&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http:&#x2F;&#x2F;coderrr.wordpress.com&#x2F;2008&#x2F;04&#x2F;20&#x2F;getting-idle-time-in-unix&#x2F;&quot;&gt;Blogpost about getting idle time in linux.&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;http:&#x2F;&#x2F;osdir.com&#x2F;ml&#x2F;emacs-orgmode-gnu&#x2F;2009-10&#x2F;msg00545.html&quot;&gt;The message with the patch proposal for including it with org-mode&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;2011-07-04 Mon 11:11 &lt;a href=&quot;file:&#x2F;&#x2F;&#x2F;home&#x2F;pti&#x2F;org&#x2F;emacs.html&quot;&gt;Track down reason for Dangling Time References&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Organizing Windows using the Keyboard with Compiz Grid</title>
          <pubDate>Thu, 30 Jun 2011 11:44:00 +0000</pubDate>
          <author>Peter Tillemans</author>
          <link>https://www.snamellit.com/posts/organizing-windows-using-the-keyboard-with-compiz-grid/</link>
          <guid>https://www.snamellit.com/posts/organizing-windows-using-the-keyboard-with-compiz-grid/</guid>
          <description xml:base="https://www.snamellit.com/posts/organizing-windows-using-the-keyboard-with-compiz-grid/">&lt;p&gt;The Mac has a great utility called Divvy to easily map windows to
loacation on the screen using the keyboard. Fiddling with the mouse to
get multiple windows in the right location is a productivity killer
and a pain in the neck (or shoulder, or elbow, or …)&lt;&#x2F;p&gt;
&lt;p&gt;Ubuntu (and of course any other Linux distro with compiz) has a
similar feature built in as a plugin for compiz. Type Alt-F2 and enter
&lt;strong&gt;ccsm&lt;&#x2F;strong&gt; + Return in the command prompt to launch the CompizConfig
Settings manager.&lt;&#x2F;p&gt;
&lt;p&gt;Select the &lt;strong&gt;Window Management&lt;&#x2F;strong&gt; from the left menu and enable the
&lt;strong&gt;Grid&lt;&#x2F;strong&gt; plugin. Click on it so you can look at the key bindings in
the &lt;strong&gt;Bindings&lt;&#x2F;strong&gt; tab. If you are on a desktop or a big laptop with a
separate numeric keyboard you are set. As you can see the locations
for the windows are by default mapped in a logical fashion like the
arrow keys on the numeric keypad. However my laptop does not have a
separate numeric keyboard and enabling it before typing the key code
is a pain. Remapping them is easy by clicking on the button with the
key code. A window appears with a &lt;strong&gt;Grab key code&lt;&#x2F;strong&gt; button. Click it
and type the new keycode you want to assign it to.&lt;&#x2F;p&gt;
&lt;p&gt;If there is a conflict, you will get a window explaingin the conflict
and asking how to resolve it. My first attempt was to remap the laptop
numeric keys using the super keys. This conflicted with the unity
launcher since the top row 7-8-9 map to the apps in the launcher. To
avoid conflicts I use now Control-Super with the keys around the j-key
(which is the home key for the right hand) Also autokey (a text macro
expander) is mapped to Super-K&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Control-Super-j : 100% (maximize)&lt;&#x2F;li&gt;
&lt;li&gt;Control-Super-h : 50% left&lt;&#x2F;li&gt;
&lt;li&gt;Control-Super-k : 50% right&lt;&#x2F;li&gt;
&lt;li&gt;Control-Super-u : 50% top&lt;&#x2F;li&gt;
&lt;li&gt;Control-Super-m : 50% bottom&lt;&#x2F;li&gt;
&lt;li&gt;Control-Super-y : 25% top-left&lt;&#x2F;li&gt;
&lt;li&gt;Control-Super-i : 25% top-right&lt;&#x2F;li&gt;
&lt;li&gt;Control-Super-n : 25% bottom-left&lt;&#x2F;li&gt;
&lt;li&gt;Control-Super-, : 25% bottom-right&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;If Control-Super-j is used to maximize a window, clicking on one of
the other keys will first restore it to the original size and position
and only map it to its place on the second click. I consider this a
feature, but you are free to interprete it as a bug. Result, this is
now super practical way to divide my windows on my screen.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Proxy Support for Grails</title>
          <pubDate>Tue, 28 Jun 2011 11:59:43 +0000</pubDate>
          <author>Peter Tillemans</author>
          <link>https://www.snamellit.com/posts/proxy-support-for-grails/</link>
          <guid>https://www.snamellit.com/posts/proxy-support-for-grails/</guid>
          <description xml:base="https://www.snamellit.com/posts/proxy-support-for-grails/">&lt;p&gt;Not a big thing, actually for me it is. I am always struggling with
proxy settings. It requires a lot of different incantations to be
done, every program deals with it differently, support for platform
settings is flaky, ... Grails deals with this is a way which
pleasantly surprised me :&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;&amp;gt; grails add-proxy &amp;lt;name&amp;gt; --host=&amp;lt;hostname&amp;gt; --port=&amp;lt;portno&amp;gt; e.g. grails add-proxy client --host=proxy --port=3128
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;allows you to create a setting for a proxy and bind it to a name. It
also supports username&#x2F;password. Switching to the setting involves
only&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;&amp;gt; grails set-proxy client
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;to enable the proxy setting, and&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;&amp;gt; grails clear-proxy
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;when I get back in a transparent environment. (for completeness there
is a &lt;strong&gt;remove-proxy&lt;&#x2F;strong&gt; command which is useful to remove those
passwords after the need has passed). I particularly impressed  that
this was done in a simple and straightforward without the need fo
brain gymnastics trying to remember which arcane curse needs to be put
at what location in which file. Nice.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Fix for Sonar choking on &#x27;result returns more than one elements&#x27;</title>
          <pubDate>Thu, 23 Jun 2011 12:54:05 +0000</pubDate>
          <author>Peter Tillemans</author>
          <link>https://www.snamellit.com/posts/fix-for-sonar-choking-on-result-returns-more-than-one-elements/</link>
          <guid>https://www.snamellit.com/posts/fix-for-sonar-choking-on-result-returns-more-than-one-elements/</guid>
          <description xml:base="https://www.snamellit.com/posts/fix-for-sonar-choking-on-result-returns-more-than-one-elements/">&lt;p&gt;Recently our sonar installation on our Hudson CI choked again, this time with an error I have not seen before. It was just before the release of an important milestone for the team, so not being unable to publish new version on the test server could not come on a worse time.&lt;&#x2F;p&gt;
&lt;p&gt;In the Console Log of a failing built we found the message.&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;\[INFO\] ------------------------------------------------------------------------
&lt;&#x2F;span&gt;&lt;span&gt;\[INFO\] BUILD FAILURE
&lt;&#x2F;span&gt;&lt;span&gt;\[INFO\] ------------------------------------------------------------------------
&lt;&#x2F;span&gt;&lt;span&gt;\[INFO\] Total time: 5.791s
&lt;&#x2F;span&gt;&lt;span&gt;\[INFO\] Finished at: Thu Jun 23 09:20:05 CEST 2011
&lt;&#x2F;span&gt;&lt;span&gt;\[INFO\] Final Memory: 20M&#x2F;429M
&lt;&#x2F;span&gt;&lt;span&gt;\[INFO\] ------------------------------------------------------------------------
&lt;&#x2F;span&gt;&lt;span&gt;\[ERROR\] Failed to execute goal org.codehaus.mojo:sonar-maven-plugin:2.0-beta-2:sonar (default-cli) on project pfus: Can not execute Sonar: PicoLifecycleException: method &amp;#39;public void org.sonar.batch.ProjectTree.start() throws java.io.IOException&amp;#39;, instance &amp;#39;org.sonar.batch.ProjectTree@50a6023a, java.lang.RuntimeException: wrapper: result returns more than one elements -&amp;gt; \[Help 1\]
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Ok, apparently something returns 2 results which should only have one result and it stands to reason that it is coming from the database. Pity there is no indication on which table would be affected.&lt;&#x2F;p&gt;
&lt;p&gt;Some googling retrieved &lt;a href=&quot;http:&#x2F;&#x2F;old.nabble.com&#x2F;Can-not-execute-Sonar%3A-result-returns-more-than-one-elements-to31369733.html#a31369733&quot;&gt;this post&lt;&#x2F;a&gt; which points to the snapshots table and more specifically to records with the field islast set to true.&lt;&#x2F;p&gt;
&lt;p&gt;A quick check in &lt;strong&gt;...&#x2F;conf&#x2F;sonar.properties&lt;&#x2F;strong&gt; revealed the database connection parameters.&lt;&#x2F;p&gt;
&lt;p&gt;Ok, this is a good time to check you have an up-to-date backup of your database. (Or make one if you&#x27;re not sure)&lt;&#x2F;p&gt;
&lt;p&gt;Using your SQL query tool of choice (I used the built in Data Sources tool in IntelliJ) connect to the database.&lt;&#x2F;p&gt;
&lt;p&gt;The snapshots table contains a project_id which confusingly does not really contains projects, but actually all kinds of assets, artefacts, files, however you ike to call it. Unfortunately there are many thousands. Even if I limited to only the ones with &lt;strong&gt;islast=1&lt;&#x2F;strong&gt; there were close to 1000 records.&lt;&#x2F;p&gt;
&lt;p&gt;Narrowing further down with :&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;**select project\_id, cnt
&lt;&#x2F;span&gt;&lt;span&gt;  from (select project\_id,
&lt;&#x2F;span&gt;&lt;span&gt;          count(\*) as cnt
&lt;&#x2F;span&gt;&lt;span&gt;        from snapshots
&lt;&#x2F;span&gt;&lt;span&gt;        where islast=1
&lt;&#x2F;span&gt;&lt;span&gt;        group by project\_id) as cntsnap
&lt;&#x2F;span&gt;&lt;span&gt;  where cnt &amp;gt; 1**
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Gave me the project_id I&#x27;ve been looking for, in my case 2089 Now a quick&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;select * from snapshots where project_id=2089&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Gave the 2 offending rows. A quick glance showed that one of them was very suspicious : the parent_id was the same as his own project_id and there were lots of null columns. I deleted the row based on the &lt;strong&gt;id&lt;&#x2F;strong&gt;. Retriggered &lt;strong&gt;hudson&lt;&#x2F;strong&gt; to rebuild the project, and the build succeeded and sonar seems to be happy again. I hope there will be no other repercussions. For our purposes the sonar data is not really critical and we could also restart without any impact. If your sonar data is more critical a better choice would be to restore from backup before the build started failing.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Adding audit information to entities in the Seam framework.</title>
          <pubDate>Tue, 11 Nov 2008 13:15:51 +0000</pubDate>
          <author>Peter Tillemans</author>
          <link>https://www.snamellit.com/posts/adding-audit-information-to-entities-in-the-seam-framework/</link>
          <guid>https://www.snamellit.com/posts/adding-audit-information-to-entities-in-the-seam-framework/</guid>
          <description xml:base="https://www.snamellit.com/posts/adding-audit-information-to-entities-in-the-seam-framework/">&lt;p&gt;Since we write a lot of stuff for use in the production side of the business we need to comply with rules which allow effective control that the processes and procedures have been followed. In the automotive industry people take these measures seriously.&lt;&#x2F;p&gt;
&lt;p&gt;One of these requirements we often get is that all configuration data elements must contain information on who created this information and when, and similarly for the last update.&lt;&#x2F;p&gt;
&lt;p&gt;Since the advent of EJB3 and JPA we now have nice POJO entities which clearly show the structure of the data and the last thing we want is to add a bunch of boilerplate code which multiplies the number of code lines with redundant stuff.&lt;&#x2F;p&gt;
&lt;p&gt;This &lt;a href=&quot;http:&#x2F;&#x2F;www.mindbug.org&#x2F;2008&#x2F;04&#x2F;automatic-tracing-of-entity-changes.html&quot;&gt;blogpost of Daniel Pfeifer&lt;&#x2F;a&gt; shows how to do this using an entity listener. However, it does not work using Seam since we cannot get the user information through the EJBContext, at least not on JBoss 4.2.3.&lt;&#x2F;p&gt;
&lt;p&gt;After wasting the better part of an afternoon barking up the wrong tree, the answer came to me next morning during breakfast. I have the unhealthy habit of reading PDF-files between bites, in this case chapter 15 of the Seam manual. The security section. (Yes, I know, I hould have done this sooner, you know : &quot;if all else fails, read the manual.&quot;)&lt;&#x2F;p&gt;
&lt;p&gt;Seam provides a nice utility class aptly named &lt;em&gt;org.jboss.seam.security.Identity&lt;&#x2F;em&gt; which provides all we need to get the name of the person logged in the current session. So replacing the implementation of &lt;em&gt;getCallerIdentity()&lt;&#x2F;em&gt; with the following, we now have nice audit trails.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&#x2F;**&lt;br &#x2F;&gt;
* Get the name of the currently logged in user.&lt;br &#x2F;&gt;
*&lt;br &#x2F;&gt;
* This part contains the framework specific code to get the active username.&lt;br &#x2F;&gt;
* In this case we use the Seam provided Identity.instance() to get at this&lt;br &#x2F;&gt;
* information.&lt;br &#x2F;&gt;
*&lt;br &#x2F;&gt;
* @param t&lt;br &#x2F;&gt;
* @return&lt;br &#x2F;&gt;
*&#x2F;&lt;br &#x2F;&gt;
private String getCallerIdentity(Traceable t) {&lt;br &#x2F;&gt;
   try {&lt;br &#x2F;&gt;
     &#x2F;&#x2F; get the identity principal to get information about the current active user&lt;br &#x2F;&gt;
     Principal principal = Identity.instance().getPrincipal();&lt;br &#x2F;&gt;
     if (log.isDebugEnabled())&lt;br &#x2F;&gt;
       log.debug(&quot;AuditLogger.getCallerIdentity returned &quot; + principal.getName());&lt;&#x2F;p&gt;
&lt;p&gt;     return principal.getName();&lt;&#x2F;p&gt;
&lt;p&gt;   } catch (Exception e) {&lt;br &#x2F;&gt;
     log.error(&quot;Exception received : &quot; + e.getClass().getName() + &quot;:&quot; + e.getMessage());&lt;br &#x2F;&gt;
     return &quot;unknown&quot;;&lt;br &#x2F;&gt;
   }&lt;br &#x2F;&gt;
}&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;I provided both the interface and mapped superclass implementations for convenience. All what is now remaining is to extend our configuration POJO&#x27;s from the TraceableEntity class (and create an update script, and modify the UI to get at the audit info, ...) to make our stuff auditable.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Learnings from the PMI Benelux Day.</title>
          <pubDate>Sun, 28 Sep 2008 00:29:48 +0000</pubDate>
          <author>Peter Tillemans</author>
          <link>https://www.snamellit.com/posts/learnings-from-the-pmi-benelux-day/</link>
          <guid>https://www.snamellit.com/posts/learnings-from-the-pmi-benelux-day/</guid>
          <description xml:base="https://www.snamellit.com/posts/learnings-from-the-pmi-benelux-day/">&lt;p&gt;I went to the PMI Benelux Day today. The theme today was &lt;em&gt;A symphony of Knowledge,&lt;&#x2F;em&gt; a theme which ran through the plenary sessions topics. I choose to see the use of earned value techniques applied to the Galileo project presented by Francois Picaut. It was interesting to see how this technique was applied in a quite straightforward manner by just entereing the AC provided by the accountants and the EV provided by the products completed at roughly biweekly milestones. All other performance numbers were calculated from these numbers_._ One learning was that in the case of subcontracted work under a FFP contract, the EV = AC. Of course once you think it over this is evident, but this quarter took a while to drop. Some additional metrics were defined like the ES (Earned Schedule, or the time when the current EV should have been reached) and &#x27;To Complete Performance Indexes&#x27; in their cost and scope variations. Apprently these metrics should show the effectiveness of the project management when plotted over time.  He applied EVT on FFP projects with good success as part of project assurance. One anekdote was the case when the project manager presented a &#x27;project on track&#x27; report while the EV calculations showed the project would end with a 1.000.000EUR loss. This triggered a discussion about the variances which triggered corrective actions. As such this proved the value of the method to confirm the results from bottom-up or other estimates.  In the area of risk management presented Daniel vander Borcht a session about why the ABCD methodology works where so many other risk management approaches fail. ABCD stnds for Assumption Based Communication Dynamics and a key part is the central role of assumptions in this model. Next to the classic issue register and risk register a assumption register is introduced. I need to research this some more Jean Diederich presented the Test Monkeys and Banana Software talk. He made the case that thinking of testing still occurs way too late in the project. He proposes to involve tests at the earliest opportunity to help start the acceptance test design, release test design, ... in parallel to development rather than afterwards. This is the same story I heard from Suzanne Robertson a couple of weeks ago in the context of requirement gathering. This confirms again my conviction that a good requirements process will make life in the project considerably easier.  A last presentation was by Hedda Pahlson-Muller regarding KPO&#x27;s or knowledge process outsourcing. This was a very instructive talk which clarified this form of outsourcing. Roughly they provide analysts or other knowledge workers in the company the possibility to have an external team to do the legwork and provide collected data for further analysis by the company itself. Due to this business model they face a glass ceiling to the service they cannot deliver analysis or recommendations. For this they are looking for PM&#x2F;Consultants to use their experience to analyse and interprete the data for the companies which ask this. Nice interesting day, bought a couple of books, talked PM with other people. Time well spent.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Java is a First Class Citizen on Ubuntu Hardy Linux</title>
          <pubDate>Fri, 08 Aug 2008 18:07:52 +0000</pubDate>
          <author>Peter Tillemans</author>
          <link>https://www.snamellit.com/posts/java-is-a-first-class-citizen-on-ubuntu-hardy-linux/</link>
          <guid>https://www.snamellit.com/posts/java-is-a-first-class-citizen-on-ubuntu-hardy-linux/</guid>
          <description xml:base="https://www.snamellit.com/posts/java-is-a-first-class-citizen-on-ubuntu-hardy-linux/">&lt;p&gt;Lately I hear a lot of Java bashing from a very vocal part of the Linux community. I do a lot of Java, I use Linux on my main laptop and I like this just fine. I use daily freemind (Java mindmapper) and openoffice (which is Java enabled). I was doing this for the past years since Windows XP ate my C-drive for the N-th time (and now it did the same on my gaming rig at home, grrr... ).&lt;&#x2F;p&gt;
&lt;p&gt;I keep a &#x27;Tools&#x27; directory in my home drive and place there the Java tools and libraries I get from the net. Creating a little bash script in &lt;em&gt;~&#x2F;bin&lt;&#x2F;em&gt; which calls the startup script from the java tools almost always does the right thing, so I was contented. Well, I need to do some LDAP hacking. Last times I did that in perl, python, ruby and Java so it was groovy&#x27;s turn.&lt;&#x2F;p&gt;
&lt;p&gt;On a whim I type :&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;pti@pti-laptop:~&#x2F;workspace&#x2F;salesforce$ sudo apt-get install groovy
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;and to my big surprise I get :```&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;Reading package lists... Done
&lt;&#x2F;span&gt;&lt;span&gt;Building dependency tree
&lt;&#x2F;span&gt;&lt;span&gt;Reading state information... Done
&lt;&#x2F;span&gt;&lt;span&gt;The following extra packages will be installed:
&lt;&#x2F;span&gt;&lt;span&gt;  antlr junit4 libasm2-java libbcel-java libbsf-java libclassworlds-java  libcommons-cli-java
&lt;&#x2F;span&gt;&lt;span&gt;libcommons-collections3-java libcommons-lang-java libcommons-logging-java liblog4j1.2-java
&lt;&#x2F;span&gt;&lt;span&gt;libmockobjects-java libmx4j-java  libregexp-java libservlet2.3-java libxpp3-java libxstream-java
&lt;&#x2F;span&gt;&lt;span&gt;Suggested packages:
&lt;&#x2F;span&gt;&lt;span&gt;  groovy-doc libbcel-java-doc jython rhino libclassworlds-java-doc
&lt;&#x2F;span&gt;&lt;span&gt;  libcommons-collections3-java-doc liblogkit-java libavalon-framework-java
&lt;&#x2F;span&gt;&lt;span&gt;  libgnumail-java
&lt;&#x2F;span&gt;&lt;span&gt;Recommended packages:
&lt;&#x2F;span&gt;&lt;span&gt;  liblog4j1.2-java-gcj
&lt;&#x2F;span&gt;&lt;span&gt;The following NEW packages will be installed:
&lt;&#x2F;span&gt;&lt;span&gt;  antlr groovy junit4 libasm2-java libbcel-java libbsf-java
&lt;&#x2F;span&gt;&lt;span&gt;  libclassworlds-java libcommons-cli-java libcommons-collections3-java
&lt;&#x2F;span&gt;&lt;span&gt;  libcommons-lang-java libcommons-logging-java liblog4j1.2-java
&lt;&#x2F;span&gt;&lt;span&gt;  libmockobjects-java libmx4j-java libregexp-java libservlet2.3-java
&lt;&#x2F;span&gt;&lt;span&gt;  libxpp3-java libxstream-java
&lt;&#x2F;span&gt;&lt;span&gt;0 upgraded, 18 newly installed, 0 to remove and 0 not upgraded.
&lt;&#x2F;span&gt;&lt;span&gt;Need to get 7025kB of archives.
&lt;&#x2F;span&gt;&lt;span&gt;After this operation, 14.7MB of additional disk space will be used.
&lt;&#x2F;span&gt;&lt;span&gt;Do you want to continue \[Y&#x2F;n\]?
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Ok, this was not what I expected... Of course I type &#x27;Y&#x27; and let it rip. Now my curiosity take the upper hand and I try some more :```&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;pti@pti-laptop:~&#x2F;workspace&#x2F;salesforce$ sudo apt-get install maven
&lt;&#x2F;span&gt;&lt;span&gt;Reading package lists... Done
&lt;&#x2F;span&gt;&lt;span&gt;Building dependency tree       
&lt;&#x2F;span&gt;&lt;span&gt;Reading state information... Done
&lt;&#x2F;span&gt;&lt;span&gt;E: Couldn&amp;#39;t find package maven
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Tough luck. But wait, there are 2 mavens, let&#x27;s try :```&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;pti@pti-laptop:~&#x2F;workspace&#x2F;salesforce$ sudo apt-get install maven2
&lt;&#x2F;span&gt;&lt;span&gt;Reading package lists... Done
&lt;&#x2F;span&gt;&lt;span&gt;Building dependency tree       
&lt;&#x2F;span&gt;&lt;span&gt;Reading state information... Done
&lt;&#x2F;span&gt;&lt;span&gt;The following extra packages will be installed:
&lt;&#x2F;span&gt;&lt;span&gt;  ant libcommons-codec-java libcommons-collections-java
&lt;&#x2F;span&gt;&lt;span&gt;  libcommons-httpclient-java libcommons-net-java libcommons-openpgp-java
&lt;&#x2F;span&gt;&lt;span&gt;  libdoxia-java libganymed-ssh2-java libjdom0-java libjsch-java libjtidy-java
&lt;&#x2F;span&gt;&lt;span&gt;  liblogkit-java liboro-java libplexus-classworlds-java
&lt;&#x2F;span&gt;&lt;span&gt;  libplexus-component-api-java libplexus-container-default-java
&lt;&#x2F;span&gt;&lt;span&gt;  libplexus-interactivity-api-java libplexus-utils-java
&lt;&#x2F;span&gt;&lt;span&gt;  libplexus-velocity-java libslide-webdavclient-java libwagon-java
&lt;&#x2F;span&gt;&lt;span&gt;  libwerken.xpath-java velocity
&lt;&#x2F;span&gt;&lt;span&gt;Suggested packages:
&lt;&#x2F;span&gt;&lt;span&gt;  ant-doc libcommons-httpclient-java-doc libcommons-openpgp-java-doc
&lt;&#x2F;span&gt;&lt;span&gt;  libdoxia-java-doc libjtidy-java-doc libgnumail-java
&lt;&#x2F;span&gt;&lt;span&gt;  libplexus-classworlds-java-doc libplexus-component-api-java-doc
&lt;&#x2F;span&gt;&lt;span&gt;  libplexus-container-default-java-doc libplexus-interactivity-api-java-doc
&lt;&#x2F;span&gt;&lt;span&gt;  libplexus-utils-java-doc libplexus-velocity-java-doc libwagon-java-doc
&lt;&#x2F;span&gt;&lt;span&gt;  velocity-doc
&lt;&#x2F;span&gt;&lt;span&gt;Recommended packages:
&lt;&#x2F;span&gt;&lt;span&gt;  ant-optional ant-gcj
&lt;&#x2F;span&gt;&lt;span&gt;The following NEW packages will be installed:
&lt;&#x2F;span&gt;&lt;span&gt;  ant libcommons-codec-java libcommons-collections-java
&lt;&#x2F;span&gt;&lt;span&gt;  libcommons-httpclient-java libcommons-net-java libcommons-openpgp-java
&lt;&#x2F;span&gt;&lt;span&gt;  libdoxia-java libganymed-ssh2-java libjdom0-java libjsch-java libjtidy-java
&lt;&#x2F;span&gt;&lt;span&gt;  liblogkit-java liboro-java libplexus-classworlds-java
&lt;&#x2F;span&gt;&lt;span&gt;  libplexus-component-api-java libplexus-container-default-java
&lt;&#x2F;span&gt;&lt;span&gt;  libplexus-interactivity-api-java libplexus-utils-java
&lt;&#x2F;span&gt;&lt;span&gt;  libplexus-velocity-java libslide-webdavclient-java libwagon-java 
&lt;&#x2F;span&gt;&lt;span&gt;  libwerken.xpath-java maven2 velocity
&lt;&#x2F;span&gt;&lt;span&gt;0 upgraded, 24 newly installed, 0 to remove and 0 not upgraded.
&lt;&#x2F;span&gt;&lt;span&gt;Need to get 6211kB of archives.
&lt;&#x2F;span&gt;&lt;span&gt;After this operation, 25.2MB of additional disk space will be used.
&lt;&#x2F;span&gt;&lt;span&gt;Do you want to continue \[Y&#x2F;n\]? 
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Hmmmmm....... This is better.... There is some refence to ant.. Yep, that too... Jedit, jython, jruby, scala (I did not do LDAP with scala yet...) follow in quick succession... Well, time to fire up synaptic and search for Java. A seemingly endless list of packages appears. App Servers :&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;glassfish&lt;&#x2F;li&gt;
&lt;li&gt;tomcat (actually I knew that from before)&lt;&#x2F;li&gt;
&lt;li&gt;jetty&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Dev Tools:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Emma&lt;&#x2F;li&gt;
&lt;li&gt;Junit&lt;&#x2F;li&gt;
&lt;li&gt;Junit4&lt;&#x2F;li&gt;
&lt;li&gt;JMock&lt;&#x2F;li&gt;
&lt;li&gt;...&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;A bunch of the commons libraries, ... Half a dozen of jdk&#x27;s. Java bindings for all the windowing toolkits out there : Gtk, Qt-jambi, ... I also finally found the jdbc driver for postgresql which I was frantically looking for a couple of weeks ago and finally downloaded from the postgres site. There is an old eclipse version, but actually this is a tool which I prefer to live in my Tools directory for updating the plugins. The only thing I did not find was findbugs. Well there is probably a lot more missing, but my inspiration dried up. I could clear out half of my tools folders because they are replaced with ubuntu version. I am now even more contented than I was. I just love to type &#x27;apt-get install &lt;something&gt;&#x27; when I want something, and now I found more of what I want.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Deliverables and Activities Ahah!! Moment</title>
          <pubDate>Tue, 15 Jul 2008 01:32:39 +0000</pubDate>
          <author>Peter Tillemans</author>
          <link>https://www.snamellit.com/posts/deliverables-and-activities-ahah-moment/</link>
          <guid>https://www.snamellit.com/posts/deliverables-and-activities-ahah-moment/</guid>
          <description xml:base="https://www.snamellit.com/posts/deliverables-and-activities-ahah-moment/">&lt;p&gt;Something I already knew became suddenly clear today : the product or
product pieces in the WBS and the relation to the activities. Although
I already knew for a long time that it is good practice to make the
WBS deliverable oriented instead of activity oriented it remained
always a gradient where activities blended seamlessly in
deliverables.&lt;&#x2F;p&gt;
&lt;p&gt;The key was that I used a mental trick derived from &#x27;Getting Things
Done&#x27;, which says that you must write your activities action oriented,
with a verb, active voice, i.e. do something. I was rephrasing the
activities this way (more bang per spreadsheet cell). &lt;&#x2F;p&gt;
&lt;p&gt;Now I applied this reasoning to the WBS work packages, but I rewrote
it as things, or part of things. Again the clarity improved
considerably and wordiness got down. And then : klabammm.... flash of
light : activities were clearly separated from the WBS work packages,
the grey area between them was gone!!!.&lt;&#x2F;p&gt;
&lt;p&gt;I am quite sure if I read my PM books again I will find this trick in
every single one, but I had to &quot;invent&quot; it myself before I understood
and felt it, instead of just knowing it.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Eclipse Ganymede crashes on 64-bit Ubuntu Hardy Herron</title>
          <pubDate>Sat, 12 Jul 2008 06:56:04 +0000</pubDate>
          <author>Peter Tillemans</author>
          <link>https://www.snamellit.com/posts/eclipse-ganymede-crashes-on-64-bit-ubuntu-hardy-herron-2/</link>
          <guid>https://www.snamellit.com/posts/eclipse-ganymede-crashes-on-64-bit-ubuntu-hardy-herron-2/</guid>
          <description xml:base="https://www.snamellit.com/posts/eclipse-ganymede-crashes-on-64-bit-ubuntu-hardy-herron-2/">&lt;p&gt;In java6 there is a bug in the 64-bit linux version of the jvm which causes eclipse to crash when opening projects with some aditional plugins installed. Both the openjdk as the sun versions are affected. for more info see :&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;bugs.launchpad.net&#x2F;ubuntu&#x2F;+source&#x2F;openjdk-6&#x2F;+bug&#x2F;206620&quot;&gt;Bug #206620 in openjdk-6 (Ubuntu)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;http:&#x2F;&#x2F;groups.google.com&#x2F;group&#x2F;linux.debian.bugs.dist&#x2F;browse_thread&#x2F;thread&#x2F;d081a6b4113c9ee4&quot;&gt;Bug#478560: sun-java6-jdk: SIGSEGV when loading Eclipse workspace&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;In the mean time this has been fixed in openjdk7, but this might take a while before this shows up in the repositories. In the mean time the jdk5 does not have this problem and works perfectly well with eclipse. So a quick&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;sudo aptitude install sun-java5-jdk
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;installs the needed software. However if the java6 is still installed, chances are it will be preferred over the java5 version of the programs. There are 2 ways to make sure eclipse uses java5 &lt;strong&gt;Use java5 for ALL programs.&lt;&#x2F;strong&gt; To change the preference tell the alternatives system to use the java5 version.&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;pti@pti-laptop:~$ **sudo update-alternatives --config java**
&lt;&#x2F;span&gt;&lt;span&gt;\[sudo\] password for pti: 
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;There are 3 alternatives which provide `java&#x27;.&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt; Selection    Alternative
&lt;&#x2F;span&gt;&lt;span&gt;-----------------------------------------------
&lt;&#x2F;span&gt;&lt;span&gt;          1    &#x2F;usr&#x2F;lib&#x2F;jvm&#x2F;java-6-sun&#x2F;jre&#x2F;bin&#x2F;java
&lt;&#x2F;span&gt;&lt;span&gt;          2    &#x2F;usr&#x2F;lib&#x2F;jvm&#x2F;java-1.5.0-sun&#x2F;jre&#x2F;bin&#x2F;java 
&lt;&#x2F;span&gt;&lt;span&gt;       \*  3    &#x2F;usr&#x2F;lib&#x2F;jvm&#x2F;java-6-openjdk&#x2F;jre&#x2F;bin&#x2F;java
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Press enter to keep the default[*], or type selection number: &lt;strong&gt;2&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;Using &amp;#39;&#x2F;usr&#x2F;lib&#x2F;jvm&#x2F;java-1.5.0-sun&#x2F;jre&#x2F;bin&#x2F;java&amp;#39; to provide &amp;#39;java&amp;#39;. 
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;To choose the alternatives with a GUI it is a good idea to install &lt;strong&gt;galternatives&lt;&#x2F;strong&gt;. &lt;strong&gt;Tell only eclipse to use java5.&lt;&#x2F;strong&gt; Since the bug only shows up on my system (so far) in eclipse, I prefer the speedier java6 as default. Luckiliy we can tell eclipse to use a specific jvm in the &lt;strong&gt;eclipse.ini&lt;&#x2F;strong&gt; file. Open &lt;strong&gt;eclipse.ini&lt;&#x2F;strong&gt; in your eclipse home with your favorite editor and add the following 2 lines to the beginning of the file&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt; -vm
&lt;&#x2F;span&gt;&lt;span&gt;    &#x2F;usr&#x2F;lib&#x2F;jvm&#x2F;java-1.5.0-sun&#x2F;jre&#x2F;bin&#x2F;java
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This will tell the eclipse launcher to use java5 to launch eclipse.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>OpenProj Locks up with Blank Grey Windows</title>
          <pubDate>Wed, 11 Jun 2008 11:20:02 +0000</pubDate>
          <author>Peter Tillemans</author>
          <link>https://www.snamellit.com/posts/openproj-locks-up-with-blank-grey-windows/</link>
          <guid>https://www.snamellit.com/posts/openproj-locks-up-with-blank-grey-windows/</guid>
          <description xml:base="https://www.snamellit.com/posts/openproj-locks-up-with-blank-grey-windows/">&lt;p&gt;The symptom is that after starting sometimes there is some blurp
dialog and afterwards the &lt;em&gt;&lt;strong&gt;Tip of the Day&lt;&#x2F;strong&gt;&lt;&#x2F;em&gt; dialog appears. This
stays grey and the application accepts no more events. You need to
kill it to get out of there.&lt;&#x2F;p&gt;
&lt;p&gt;This happens at the place which is protected by a firewall and has no
transparent proxy. At home it worked fine albeit on my Macbook and not
on my Ubuntu laptop.&lt;&#x2F;p&gt;
&lt;p&gt;The reason  is that there is some phone home
functionality built in and with wireshark I could see the application
trying to connect to a webserver. Probably to get the tips of the
day. Behind the firewall this did not work and the application is just
hanging there.&lt;&#x2F;p&gt;
&lt;p&gt;I suspect that sooner or later it will time out, but I
am not that patient. Since this is a regular occurence with java
applications I also immediately knew that I had to tell it where the
proxy can be found. In the file &lt;strong&gt;~&#x2F;.openproj&#x2F;run.conf&lt;&#x2F;strong&gt; file replace
the line :&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;JAVA\_OPTS=&amp;quot;-Xms128m -Xmx768m&amp;quot; 
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;with&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;JAVA\_OPTS=&amp;quot;-Dhttp.proxyHost=proxy -Dhttp.proxyPort=3128 -Xms128m
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;-Xmx768m&quot;&lt;&#x2F;p&gt;
&lt;p&gt;This directs the java runtime library to use the proxy
&lt;strong&gt;http:&#x2F;&#x2F;proxy:3128&#x2F;.&lt;&#x2F;strong&gt; And voila!  ... Openproj starts immediately
and in its full glory?&lt;&#x2F;p&gt;
</description>
      </item>
    </channel>
</rss>
