<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>Tech @ languidnights</title><link href="https://blog.languidnights.com/tech/" rel="alternate"></link><link href="https://blog.languidnights.com/tech/feeds/all.atom.xml" rel="self"></link><id>https://blog.languidnights.com/tech/</id><updated>2024-08-30T00:00:00-04:00</updated><entry><title>Tmux + SSH</title><link href="https://blog.languidnights.com/tech/tmux-ssh.html" rel="alternate"></link><published>2024-08-30T00:00:00-04:00</published><updated>2024-08-30T00:00:00-04:00</updated><author><name>Christopher R. Nelson</name></author><id>tag:blog.languidnights.com,2024-08-30:/tech/tmux-ssh.html</id><summary type="html">&lt;div class="contents topic" id="contents"&gt;
&lt;p class="topic-title"&gt;&lt;a class="reference internal" href="#top"&gt;Contents&lt;/a&gt;&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference internal" href="#problem-statement" id="toc-entry-1"&gt;Problem Statement&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#v-and-the-terrible-horrible-no-good-very-bad-solution" id="toc-entry-2"&gt;V and the Terrible, Horrible, No Good, Very Bad Solution&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#so-s-good-solution" id="toc-entry-3"&gt;SO's good solution&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#why-write-this-post" id="toc-entry-4"&gt;Why write this post?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="problem-statement"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#contents"&gt;Problem Statement&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I like ssh (I have servers I do not physically sit at, and I pay for their
usages, so I'd rather not uselessly invoke a rdp/vnc server …&lt;/p&gt;&lt;/div&gt;</summary><content type="html">&lt;div class="contents topic" id="contents"&gt;
&lt;p class="topic-title"&gt;&lt;a class="reference internal" href="#top"&gt;Contents&lt;/a&gt;&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference internal" href="#problem-statement" id="toc-entry-1"&gt;Problem Statement&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#v-and-the-terrible-horrible-no-good-very-bad-solution" id="toc-entry-2"&gt;V and the Terrible, Horrible, No Good, Very Bad Solution&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#so-s-good-solution" id="toc-entry-3"&gt;SO's good solution&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#why-write-this-post" id="toc-entry-4"&gt;Why write this post?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="problem-statement"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#contents"&gt;Problem Statement&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I like ssh (I have servers I do not physically sit at, and I pay for their
usages, so I'd rather not uselessly invoke a rdp/vnc server). I like tmux,
because terminal multiplexing is right and proper. I pretty much always do
&lt;tt class="docutils literal"&gt;tmux attach &lt;span class="pre"&gt;-t&lt;/span&gt; admin || tmux new &lt;span class="pre"&gt;-t&lt;/span&gt; admin&lt;/tt&gt; upon logging in. Automation is
good, &lt;a class="reference external" href="https://xkcd.com/1205/"&gt;generally&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="v-and-the-terrible-horrible-no-good-very-bad-solution"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#contents"&gt;V and the Terrible, Horrible, No Good, Very Bad Solution&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;You /can/ do the following in your .bashrc. You shouldn't, for a varienty of
reasons, but you can...&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;tmux&lt;span class="w"&gt; &lt;/span&gt;attach&lt;span class="w"&gt; &lt;/span&gt;-t&lt;span class="w"&gt; &lt;/span&gt;admin&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;||&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;tmux&lt;span class="w"&gt; &lt;/span&gt;new&lt;span class="w"&gt; &lt;/span&gt;-t&lt;span class="w"&gt; &lt;/span&gt;admin
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;What? You don't ever use scp? or git? or pelican's &lt;cite&gt;make ssh_upload&lt;/cite&gt;? I like
all three, so this is a dirty nasty hack for me.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="so-s-good-solution"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#contents"&gt;SO's good solution&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a class="reference external" href="https://stackoverflow.com"&gt;StackOverflow&lt;/a&gt; not Significant Other (though as a hobbyist dev/sysadmin, may
as well be the same) had the &lt;a class="reference external" href="https://stackoverflow.com/a/27614878"&gt;correct answer&lt;/a&gt;. Use 'new' ssh and tmux! Inside
&amp;quot;$HOME&amp;quot;/.ssh/config:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="na"&gt;Host &amp;lt;host&amp;gt;+tmux&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="na"&gt;Hostname &amp;lt;host&amp;gt;.&amp;lt;tld&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="na"&gt;User &amp;lt;user&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="na"&gt;RequestTTY yes&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="na"&gt;RemoteCommand tmux new -A -s admin&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Tells ssh to execute tmux new with the '-A' flag, with tells it to attempt to
attach to the admin session, then create it if the session doesn't exist.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="why-write-this-post"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#contents"&gt;Why write this post?&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I predict this site will disappear before SO, but my memory is fickle and bad,
and this site is kinda like a notebook of important info for me.&lt;/p&gt;
&lt;/div&gt;
</content><category term="server"></category></entry><entry><title>cgit+gitolite+nginx</title><link href="https://blog.languidnights.com/tech/cgitgitolitenginx.html" rel="alternate"></link><published>2024-01-21T00:00:00-05:00</published><updated>2024-01-21T00:00:00-05:00</updated><author><name>Christopher R. Nelson</name></author><id>tag:blog.languidnights.com,2024-01-21:/tech/cgitgitolitenginx.html</id><summary type="html">&lt;div class="section" id="our-goal"&gt;
&lt;h2&gt;Our Goal&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="section" id="the-easy-part"&gt;
&lt;h2&gt;The Easy Part&lt;/h2&gt;
&lt;p&gt;Nginx is fun, and I've used it before with fastcgi. Let's do the easy
parts. I've already set gitolite3's UMASK to be a bit less righteous for
interoperability with git-daemon+xinited, so we'll move on to the new
configuration.&lt;/p&gt;
&lt;pre class="code bash literal-block"&gt;
apt-get&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;fcgiwrap&lt;span class="w"&gt;
&lt;/span&gt;systemctl&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;enable&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;fcgiwrap …&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;div class="section" id="our-goal"&gt;
&lt;h2&gt;Our Goal&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="section" id="the-easy-part"&gt;
&lt;h2&gt;The Easy Part&lt;/h2&gt;
&lt;p&gt;Nginx is fun, and I've used it before with fastcgi. Let's do the easy
parts. I've already set gitolite3's UMASK to be a bit less righteous for
interoperability with git-daemon+xinited, so we'll move on to the new
configuration.&lt;/p&gt;
&lt;pre class="code bash literal-block"&gt;
apt-get&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;fcgiwrap&lt;span class="w"&gt;
&lt;/span&gt;systemctl&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;enable&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;fcgiwrap&lt;span class="w"&gt;
&lt;/span&gt;chmod&lt;span class="w"&gt; &lt;/span&gt;-R&lt;span class="w"&gt; &lt;/span&gt;go-rwx&lt;span class="w"&gt; &lt;/span&gt;/var/lib/gitolite3&lt;span class="w"&gt;
&lt;/span&gt;chmod&lt;span class="w"&gt; &lt;/span&gt;-R&lt;span class="w"&gt; &lt;/span&gt;g+rx&lt;span class="w"&gt; &lt;/span&gt;/var/lib/gitolite3&lt;span class="w"&gt;
&lt;/span&gt;adduser&lt;span class="w"&gt; &lt;/span&gt;www-data&lt;span class="w"&gt; &lt;/span&gt;gitolite3
&lt;/pre&gt;
&lt;pre class="code nginx literal-block"&gt;
&lt;span class="k"&gt;server&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
       &lt;/span&gt;&lt;span class="kn"&gt;server_name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;projects.languidnights.com&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
       &lt;/span&gt;&lt;span class="kn"&gt;listen&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;443&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;ssl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
       &lt;/span&gt;&lt;span class="kn"&gt;list&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;[::]:443&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;ssl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;

       &lt;/span&gt;&lt;span class="kn"&gt;gzip&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;off&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;

       &lt;/span&gt;&lt;span class="kn"&gt;location&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;/cgit/&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
           &lt;/span&gt;&lt;span class="kn"&gt;root&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;/usr/lib/cgit/&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
           &lt;/span&gt;&lt;span class="kn"&gt;include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;fastcgi_params&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
           &lt;/span&gt;&lt;span class="kn"&gt;fastcgi_param&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;SCRIPT_FILENAME&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;/usr/lib/cgit/cgit.cgi&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
           &lt;/span&gt;&lt;span class="kn"&gt;fastcgi_pass&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s"&gt;unix:/run/fcgiwrap.socket&lt;/span&gt;&lt;span class="w"&gt;
           &lt;/span&gt;&lt;span class="s"&gt;fastcgi_param&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;QUERY_STRING&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$args&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
           &lt;/span&gt;&lt;span class="kn"&gt;fastcgi_param&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;HTTP_HOST&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$server_name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
       &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

       &lt;/span&gt;&lt;span class="kn"&gt;location&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;/cgit-css/&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
           &lt;/span&gt;&lt;span class="kn"&gt;root&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;/usr/share/cgit/&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
       &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class="section" id="problem-numero-uno"&gt;
&lt;h2&gt;Problem Numero Uno&lt;/h2&gt;
&lt;p&gt;What do you mean I can't see the stylesheets and images? Oh, you want it
to be an alias, not a directory. I got it&lt;/p&gt;
&lt;p&gt;/etc/nginx/sites-enabled/projects&lt;/p&gt;
&lt;pre class="code diff literal-block"&gt;
&lt;span class="gd"&gt;--- a        2024-01-21 05:54:37.553311062 +0000&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="gi"&gt;+++ b        2024-01-21 05:54:54.113321210 +0000&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="gu"&gt;&amp;#64;&amp;#64; -48,6 +48,6 &amp;#64;&amp;#64;&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;      }&lt;span class="w"&gt;

 &lt;/span&gt;      location /cgit-css/ {&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="gd"&gt;-            root /usr/share/cgit/;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="gi"&gt;+            alias /usr/share/cgit/;&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;      }&lt;span class="w"&gt;
&lt;/span&gt;}
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class="section" id="let-s-configure-cgit"&gt;
&lt;h2&gt;Let's configure cgit&lt;/h2&gt;
&lt;p&gt;It's got a pretty good man page &lt;code&gt;man 5 cgitrc&lt;/code&gt; and I did this in
the before times with gitolite2, so let's go.&lt;/p&gt;
&lt;pre class="code cfg literal-block"&gt;
&lt;span class="na"&gt;css&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;/cgit-css/cgit.css&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="na"&gt;logo&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;/cgit-css/cgit.png&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="na"&gt;favicon&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;/cgit-css/favicon.ico&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="na"&gt;root-title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;LanguidNights' Git Repositories&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="na"&gt;root-desc&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;various and sundry&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="na"&gt;enable-index-links&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="na"&gt;enable-git-config&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="na"&gt;remove-suffix&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;1&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="na"&gt;project-list&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;/var/lib/gitolite3/projects.list&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="na"&gt;scan-path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;/var/lib/gitolite3/repositories&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class="section" id="so-far"&gt;
&lt;h2&gt;So Far&lt;/h2&gt;
&lt;p&gt;It works beautifully. That is, if you happen to be sitting on the server
and part of the www-data group.&lt;/p&gt;
&lt;pre class="code bash literal-block"&gt;
sudo&lt;span class="w"&gt; &lt;/span&gt;-u&lt;span class="w"&gt; &lt;/span&gt;www-data&lt;span class="w"&gt; &lt;/span&gt;/usr/lib/cgit/cgit.cgi
&lt;/pre&gt;
&lt;p&gt;If, like me, you want your &lt;em&gt;website&lt;/em&gt; for your git repos to be viewable
on the &lt;em&gt;web&lt;/em&gt;, still no joy. It just says 'no repositories found'. I know
that's a lie, cgit! Give me your secrets, I'm going mad and it's past
midnight! Nothing in my error logs, nothings in my access logs, nothing
in my syslog. What is going on?&lt;/p&gt;
&lt;pre class="code bash literal-block"&gt;
ls&lt;span class="w"&gt; &lt;/span&gt;-l&lt;span class="w"&gt; &lt;/span&gt;/var/lib/gitolite3&lt;span class="w"&gt;
&lt;/span&gt;cat&lt;span class="w"&gt; &lt;/span&gt;/var/lib/gitolite3/projects.list&lt;span class="w"&gt;
&lt;/span&gt;systemctl&lt;span class="w"&gt; &lt;/span&gt;restart&lt;span class="w"&gt; &lt;/span&gt;fcgiwrap.socket&lt;span class="w"&gt; &lt;/span&gt;fcgiwrap.service&lt;span class="w"&gt; &lt;/span&gt;nginx.service
&lt;/pre&gt;
&lt;p&gt;And no joy! You're lucky I'm bald, or I'd have thrown handfuls of my own
hair at you!&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="the-final-pieces"&gt;
&lt;h2&gt;The Final Pieces&lt;/h2&gt;
&lt;p&gt;Courtesy of &lt;a class="reference external" href="https://bbs.archlinux.org/viewtopic.php?id=194743"&gt;The Arch Linux BBS&lt;/a&gt; I finally got the last piece, which I
missed in all the relevant documentation. It consisted of two parts&lt;/p&gt;
&lt;p&gt;/etc/cgitrc&lt;/p&gt;
&lt;pre class="code diff literal-block"&gt;
&lt;span class="gd"&gt;--- a        2024-01-21 05:42:37.240863180 +0000&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="gi"&gt;+++ b        2024-01-21 05:42:28.244857393 +0000&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="gu"&gt;&amp;#64;&amp;#64; -6,6 +6,7 &amp;#64;&amp;#64;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;logo=/cgit-css/cgit.png&lt;span class="w"&gt;
&lt;/span&gt;favicon=/cgit-css/favicon.ico&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="gi"&gt;+virtual-root=/cgit/&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;root-title=LanguidNight's Git Repositories&lt;span class="w"&gt;
&lt;/span&gt;root-desc=various and sundry&lt;span class="w"&gt;
&lt;/span&gt;enable-index-links=1
&lt;/pre&gt;
&lt;p&gt;/etc/nginx/sites-enabled/projects&lt;/p&gt;
&lt;pre class="code diff literal-block"&gt;
&lt;span class="gd"&gt;--- a        2024-01-21 05:32:23.356460060 +0000&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="gi"&gt;+++ b        2024-01-21 05:32:12.704453273 +0000&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="gu"&gt;&amp;#64;&amp;#64; -43,6 +43,8 &amp;#64;&amp;#64;&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;      fastcgi_param SCRIPT_FILENAME /usr/lib/cgit/cgit.cgi;&lt;span class="w"&gt;
 &lt;/span&gt;      fastcgi_pass  unix:/run/fcgiwrap.socket;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="gi"&gt;+    fastcgi_split_path_info         ^(/cgit/?)(.+)$;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="gi"&gt;+    fastcgi_param   PATH_INFO       $fastcgi_path_info;&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;      fastcgi_param QUERY_STRING    $args;&lt;span class="w"&gt;
 &lt;/span&gt;      fastcgi_param HTTP_HOST       $server_name;&lt;span class="w"&gt;
&lt;/span&gt;}
&lt;/pre&gt;
&lt;p&gt;And, we have joy. My life is now better than it was a 3:00pm at least,
and I can finally go to bed. Well, just as soon as I write this up for
posterity.&lt;/p&gt;
&lt;/div&gt;
</content><category term="server"></category></entry><entry><title>Neovim and Sundry</title><link href="https://blog.languidnights.com/tech/neovim-and-sundry.html" rel="alternate"></link><published>2022-09-01T00:00:00-04:00</published><updated>2022-11-03T00:00:00-04:00</updated><author><name>Christopher R. Nelson</name></author><id>tag:blog.languidnights.com,2022-09-01:/tech/neovim-and-sundry.html</id><summary type="html">&lt;a class="reference external image-reference" href="https://neovim.io"&gt;
&lt;img alt="Neovim logo" class="align-left" src="images/neovim-logo-flat.png" style="width: 30%;" /&gt;
&lt;/a&gt;
&lt;p&gt;&lt;a class="footnote-reference" href="#jason-long" id="footnote-reference-1"&gt;[1]&lt;/a&gt;&lt;/p&gt;
&lt;div class="contents topic" id="table-of-contents"&gt;
&lt;p class="topic-title"&gt;&lt;a class="reference internal" href="#top"&gt;Table of Contents&lt;/a&gt;&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference internal" href="#what-is-neovim" id="toc-entry-1"&gt;What is Neovim&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#luajit-with-arm64-and-debian" id="toc-entry-2"&gt;LuaJit with arm64 and Debian&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="what-is-neovim"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#table-of-contents"&gt;What is Neovim&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a class="reference external" href="https://neovim.io/"&gt;Neovim&lt;/a&gt; is the new vim! (Okay, not exactly but sort of?). It's vim, but
specialized for more modern systems and not as dependent on maintaining
compatibility. It's also ehanced with lua scripting, lsp integration,
and …&lt;/p&gt;&lt;/div&gt;</summary><content type="html">&lt;a class="reference external image-reference" href="https://neovim.io"&gt;
&lt;img alt="Neovim logo" class="align-left" src="images/neovim-logo-flat.png" style="width: 30%;" /&gt;
&lt;/a&gt;
&lt;p&gt;&lt;a class="footnote-reference" href="#jason-long" id="footnote-reference-1"&gt;[1]&lt;/a&gt;&lt;/p&gt;
&lt;div class="contents topic" id="table-of-contents"&gt;
&lt;p class="topic-title"&gt;&lt;a class="reference internal" href="#top"&gt;Table of Contents&lt;/a&gt;&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference internal" href="#what-is-neovim" id="toc-entry-1"&gt;What is Neovim&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#luajit-with-arm64-and-debian" id="toc-entry-2"&gt;LuaJit with arm64 and Debian&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="what-is-neovim"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#table-of-contents"&gt;What is Neovim&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a class="reference external" href="https://neovim.io/"&gt;Neovim&lt;/a&gt; is the new vim! (Okay, not exactly but sort of?). It's vim, but
specialized for more modern systems and not as dependent on maintaining
compatibility. It's also ehanced with lua scripting, lsp integration,
and treesitter integration.&lt;/p&gt;
&lt;p&gt;or, as the website &lt;em&gt;oh so helpfully&lt;/em&gt; calls is: &amp;quot;hyperextensible
Vim-based text editor&amp;quot;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="luajit-with-arm64-and-debian"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#table-of-contents"&gt;LuaJit with arm64 and Debian&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Debian ships a version of neovim for the arm64 platform. This, you might
say, is great! And it is, so long as you don't need to use any of the
luajit integration points, either of your editor or of your plugins.
Let's fix this. I'll show you the easy (and best!) way first, then the
hard way.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;dpkg&lt;span class="w"&gt; &lt;/span&gt;--add-architecture&lt;span class="w"&gt; &lt;/span&gt;armhf
apt-get&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;neovim:armhf
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Yup. That's all that you really need to do. It's all I should have done.
But, I didn't, and we'll be going into what I've done next. First,
things that didn't work quite so well...&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;flatpak: it doesn't have access to your path and all your lovely lsp
servers&lt;/li&gt;
&lt;li&gt;&lt;dl class="first docutils"&gt;
&lt;dt&gt;appimage: it's built for an x86_64 machine (nvim is trying to support&lt;/dt&gt;
&lt;dd&gt;the future, but I happen to think the future is arm and not amd64)&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;li&gt;building from source directly: it'll work just fine, but it'll be a
bear to maintain in the long run.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So, what should I do? Build myself a deb package with luajit instead of
base lua. We'll start by installing pbuilder and creating an
environment.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;apt-get&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;pbuilder
pbuilder&lt;span class="w"&gt; &lt;/span&gt;create
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then, we'll download the source code for the debian package, as well as
its build dependencies.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;apt-get&lt;span class="w"&gt; &lt;/span&gt;build-dep&lt;span class="w"&gt; &lt;/span&gt;neovim
apt-get&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;source&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;neovim
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;and update the build files for arm64's compiler and the use of luajit
(one test ails on ARM architectures, so patch that out too. ideally, I'd
fix it but it also fails on armhf, so I'm not going to spend too much
time digging today)&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="gd"&gt;--- debian/control.old      2022-09-01 17:06:48.797215829 -0400&lt;/span&gt;
&lt;span class="gi"&gt;+++ debian/control  2022-09-01 17:05:48.843040845 -0400&lt;/span&gt;
&lt;span class="gu"&gt;@@ -11,7 +11,7 @@&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt; less &amp;lt;!nocheck&amp;gt;,
&lt;span class="w"&gt; &lt;/span&gt; libacl1-dev,
&lt;span class="w"&gt; &lt;/span&gt; libkvm-dev [kfreebsd-any],
&lt;span class="gd"&gt;- libluajit-5.1-dev [amd64 armel armhf hurd-i386 i386] | liblua5.1-dev,&lt;/span&gt;
&lt;span class="gi"&gt;+ libluajit-5.1-dev [amd64 arm64 armel armhf hurd-i386 i386] | liblua5.1-dev,&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt; libmsgpack-dev (&amp;gt;= 1.0.0),
&lt;span class="w"&gt; &lt;/span&gt; libnss-wrapper &amp;lt;!nocheck&amp;gt;,
&lt;span class="w"&gt; &lt;/span&gt; libtermkey-dev,
&lt;span class="gu"&gt;@@ -27,7 +27,7 @@&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt; lua-lpeg,
&lt;span class="w"&gt; &lt;/span&gt; lua-luv-dev (&amp;gt;= 1.43.0),
&lt;span class="w"&gt; &lt;/span&gt; lua-nvim (&amp;gt;= 0.0.1-26-1~) [!hurd-i386] &amp;lt;!nocheck&amp;gt;,
&lt;span class="gd"&gt;- luajit [amd64 armel armhf hurd-i386 i386],&lt;/span&gt;
&lt;span class="gi"&gt;+ luajit [amd64 arm64 armel armhf hurd-i386 i386],&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt; lua5.1,
&lt;span class="w"&gt; &lt;/span&gt; ninja-build,
&lt;span class="w"&gt; &lt;/span&gt; pkg-config,

&lt;span class="gd"&gt;--- a/debian/rules&lt;/span&gt;
&lt;span class="gi"&gt;+++ b/debian/rules&lt;/span&gt;
&lt;span class="gu"&gt;@@ -37,6 +37,9 @@ FUNCTEST_FILTER_OUT=&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;ifneq (,$(filter armhf,$(DEB_HOST_ARCH)))
&lt;span class="w"&gt; &lt;/span&gt;  FUNCTEST_FILTER_OUT=&amp;#39;memory usage releases memory when closing windows when folds exist&amp;#39;
&lt;span class="w"&gt; &lt;/span&gt;endif
&lt;span class="gi"&gt;+ifneq (,$(filter arm64,$(DEB_HOST_ARCH)))&lt;/span&gt;
&lt;span class="gi"&gt;+  FUNCTEST_FILTER_OUT=&amp;#39;memory usage releases memory when closing windows when folds exist&amp;#39;&lt;/span&gt;
&lt;span class="gi"&gt;+endif&lt;/span&gt;

&lt;span class="w"&gt; &lt;/span&gt;export USERNAME = team+vim
&lt;span class="w"&gt; &lt;/span&gt;export HOSTNAME = tracker.debian.org

&lt;span class="gd"&gt;--- a/test/unit/helpers.lua&lt;/span&gt;
&lt;span class="gi"&gt;+++ b/test/unit/helpers.lua&lt;/span&gt;
&lt;span class="gu"&gt;@@ -135,6 +135,8 @@ local function filter_complex_blocks(body)&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;    if not (string.find(line, &amp;quot;(^)&amp;quot;, 1, true) ~= nil
&lt;span class="w"&gt; &lt;/span&gt;            or string.find(line, &amp;quot;_ISwupper&amp;quot;, 1, true)
&lt;span class="w"&gt; &lt;/span&gt;            or string.find(line, &amp;quot;_Float&amp;quot;)
&lt;span class="gi"&gt;+            or string.find(line, &amp;quot;_Float128&amp;quot;)&lt;/span&gt;
&lt;span class="gi"&gt;+            or string.find(line, &amp;quot;__uint128&amp;quot;)&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;            or string.find(line, &amp;quot;msgpack_zone_push_finalizer&amp;quot;)
&lt;span class="w"&gt; &lt;/span&gt;            or string.find(line, &amp;quot;msgpack_unpacker_reserve_buffer&amp;quot;)
&lt;span class="w"&gt; &lt;/span&gt;            or string.find(line, &amp;quot;UUID_NULL&amp;quot;)  -- static const uuid_t UUID_NULL = {...}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;and finally, build&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;pdebuild
dpkg&lt;span class="w"&gt; &lt;/span&gt;-i&lt;span class="w"&gt; &lt;/span&gt;/var/cache/pbuilder/result/neovim_0.7.2-3_arm64.deb
dpkg&lt;span class="w"&gt; &lt;/span&gt;-i&lt;span class="w"&gt; &lt;/span&gt;/var/cache/pbuilder/result/neovim-runtime_0.7.2-3_all.deb
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;a class="reference external" href="#table-of-contents"&gt;top&lt;/a&gt;&lt;/p&gt;
&lt;table class="docutils footnote" frame="void" id="jason-long" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#footnote-reference-1"&gt;[1]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;logo released under CC-BY-3.0 by &lt;a class="reference external" href="https://twitter.com/jasonlong"&gt;Jason Long&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
</content><category term="packaging"></category></entry><entry><title>KDE Applications under Sway</title><link href="https://blog.languidnights.com/tech/kde-applications-under-sway.html" rel="alternate"></link><published>2022-07-11T00:00:00-04:00</published><updated>2022-07-11T00:00:00-04:00</updated><author><name>Christopher R. Nelson</name></author><id>tag:blog.languidnights.com,2022-07-11:/tech/kde-applications-under-sway.html</id><summary type="html">&lt;div class="contents topic" id="table-of-contents"&gt;
&lt;p class="topic-title"&gt;&lt;a class="reference internal" href="#top"&gt;Table of Contents&lt;/a&gt;&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference internal" href="#problem-statement" id="toc-entry-1"&gt;Problem Statement&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#what-doesn-t-work" id="toc-entry-2"&gt;What doesn't work&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#what-does-work" id="toc-entry-3"&gt;What does work&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="problem-statement"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#table-of-contents"&gt;Problem Statement&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I'm using &lt;a class="reference external" href="https://swaywm.org"&gt;Sway&lt;/a&gt; as my &amp;quot;window manager&amp;quot; in my daily workflow. I happen to
like Wayland and am used to tiling window managers, so it's a good fit.
I also think the &lt;a class="reference external" href="https://kde.org"&gt;KDE&lt;/a&gt; project makes &lt;em&gt;excellent&lt;/em&gt; software …&lt;/p&gt;&lt;/div&gt;</summary><content type="html">&lt;div class="contents topic" id="table-of-contents"&gt;
&lt;p class="topic-title"&gt;&lt;a class="reference internal" href="#top"&gt;Table of Contents&lt;/a&gt;&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference internal" href="#problem-statement" id="toc-entry-1"&gt;Problem Statement&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#what-doesn-t-work" id="toc-entry-2"&gt;What doesn't work&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#what-does-work" id="toc-entry-3"&gt;What does work&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="problem-statement"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#table-of-contents"&gt;Problem Statement&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I'm using &lt;a class="reference external" href="https://swaywm.org"&gt;Sway&lt;/a&gt; as my &amp;quot;window manager&amp;quot; in my daily workflow. I happen to
like Wayland and am used to tiling window managers, so it's a good fit.
I also think the &lt;a class="reference external" href="https://kde.org"&gt;KDE&lt;/a&gt; project makes &lt;em&gt;excellent&lt;/em&gt; software, which I like
using in my day-to-day computing. There, however, is not a
&lt;em&gt;well-documented&lt;/em&gt; way to make qt or KDE applications use their KDE style
outside of KDE itself.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="what-doesn-t-work"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#table-of-contents"&gt;What doesn't work&lt;/a&gt;&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;qt5ct (or qt6ct). Don't get me wrong, they both do what they
advertise, but they don't really let you use your beautiful
breeze(-dark) theme in non-KDE environments.&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://lxqt-project.org"&gt;LXQT&lt;/a&gt;. My favorite desktop environment has its own styling/themeing
support which is not the same as KDE's. It allows you to create quite
beautiful qt setups, but if I want dolphin or okular to follow
breeze(-dark), I'm out of luck. This is what I used for a long time to
work around my lack of KDE style.&lt;/li&gt;
&lt;li&gt;XDG_DESKTOP_ENVIRONMENT=kde. Ooo, now we're getting close! This
&lt;em&gt;technically&lt;/em&gt; does what I asked it to do, but it has unfortunate side
effects. Various things start to break as xdg-desktop-portals get
confused as to which variants they should be using. As I'm using Sway,
this needs to be XDG_DESKTOP_ENVIRONMENT=wlr since the compositor and
portal base is not kwin but rather wlroots.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="what-does-work"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#table-of-contents"&gt;What does work&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I can not find this referenced anywhere with my meagre ddg-foo, so I'm
setting it here for future wanderers to find. After exhausting what I
could find online, I went back to the qt5ct setup. I wondered, is it
possible to set QT_QPA_PLATFORMTHEME to something else sensible? Yes! It
just so happens you can. I discovered, by trial-and-erroring my way
though it (breeze, Breeze, Fusion, and plasma all fail), that you can
set it to kde, allowing your qt and KDE apps to follow the themeing you
set up in ksytemsettings. Lovely good time!&lt;/p&gt;
&lt;p&gt;While it wasn't my answer, I couldn't have found it without &lt;a class="reference external" href="https://sourceforge.net/projects/qt5ct/"&gt;qt5ct&lt;/a&gt; and
the &lt;a class="reference external" href="https://www.reddit.com/r/kde"&gt;reddit&lt;/a&gt; community's guides.&lt;/p&gt;
&lt;p&gt;Here's hoping someone else can pull out a little less of their hair than
did I. I didn't have enough to start with ;-)&lt;/p&gt;
&lt;/div&gt;
</content><category term="config"></category></entry><entry><title>libvirt lessons</title><link href="https://blog.languidnights.com/tech/libvirt-lessons.html" rel="alternate"></link><published>2022-03-19T00:00:00-04:00</published><updated>2022-11-03T00:00:00-04:00</updated><author><name>Christopher R. Nelson</name></author><id>tag:blog.languidnights.com,2022-03-19:/tech/libvirt-lessons.html</id><summary type="html">&lt;div class="contents topic" id="contents"&gt;
&lt;p class="topic-title"&gt;&lt;a class="reference internal" href="#top"&gt;Contents&lt;/a&gt;&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference internal" href="#background" id="toc-entry-1"&gt;Background&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#automagic-configs" id="toc-entry-2"&gt;Automagic Configs&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="reference internal" href="#networking" id="toc-entry-3"&gt;networking&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#qemu-command-line" id="toc-entry-4"&gt;qemu command line&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#storage" id="toc-entry-5"&gt;Storage&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#video-acceleration" id="toc-entry-6"&gt;Video Acceleration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#freedos-specific" id="toc-entry-7"&gt;FreeDOS Specific&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="background"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#contents"&gt;Background&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;On my powerhouse machine, I use virtual machines to contain experiments
and code I don't trust into little self-contained sandboxes. I also
separate some concerns into their own machines. Here, we'll go over
things I've learned …&lt;/p&gt;&lt;/div&gt;</summary><content type="html">&lt;div class="contents topic" id="contents"&gt;
&lt;p class="topic-title"&gt;&lt;a class="reference internal" href="#top"&gt;Contents&lt;/a&gt;&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference internal" href="#background" id="toc-entry-1"&gt;Background&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#automagic-configs" id="toc-entry-2"&gt;Automagic Configs&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="reference internal" href="#networking" id="toc-entry-3"&gt;networking&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#qemu-command-line" id="toc-entry-4"&gt;qemu command line&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#storage" id="toc-entry-5"&gt;Storage&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#video-acceleration" id="toc-entry-6"&gt;Video Acceleration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#freedos-specific" id="toc-entry-7"&gt;FreeDOS Specific&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="background"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#contents"&gt;Background&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;On my powerhouse machine, I use virtual machines to contain experiments
and code I don't trust into little self-contained sandboxes. I also
separate some concerns into their own machines. Here, we'll go over
things I've learned in the course of my setups.&lt;/p&gt;
&lt;p&gt;First off, I'm using linux, so my base layer is &lt;a class="reference external" href="https://www.qemu.org"&gt;qemu&lt;/a&gt; + &lt;a class="reference external" href="https://www.linux-kvm.org/page/Main_Page"&gt;kvm&lt;/a&gt;. The
perfect tool to manage your virtualization is &lt;a class="reference external" href="https://libvirt.org"&gt;libvirt&lt;/a&gt;. For my graphical
management, I'm using the absolutely amazing &lt;a class="reference external" href="https://virt-manager.org"&gt;virt-manager&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="automagic-configs"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#contents"&gt;Automagic Configs&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;There are a few things that, if you use libvirt and virt-manager, you no
longer have to worry about configuring. Advancements is the tooling and
automation have come far since most tutorials.&lt;/p&gt;
&lt;div class="section" id="networking"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#contents"&gt;networking&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;A lot of documentation asks you to create a bridge interface and add it
to your &lt;tt class="docutils literal"&gt;/etc/network/interfaces&lt;/tt&gt; or create a systemd service for it.
This is no longer necessary. Simply right-click your qemu+kvm connection
details, navigate to the &lt;tt class="docutils literal"&gt;Virtual Networks&lt;/tt&gt; tab, and click the &lt;tt class="docutils literal"&gt;run
button&lt;/tt&gt; at the bottom. Boom! Network setup. For the individual users,
this is all you'll have cause to user; you're not an enterprise
sysadmin, you don't need to learn networking managements details for a
simple project.&lt;/p&gt;
&lt;img alt="illustration of network setup" src="images/libvirt_network.png" style="width: 960px; height: 540px;" /&gt;
&lt;/div&gt;
&lt;div class="section" id="qemu-command-line"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#contents"&gt;qemu command line&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;I don't know about you, but I never could type the qemu command line
properly, so I ended up writing a script and triple checking where I'd
modified an example to do the setup, and still get it wrong one time out
of three. This is messy and error-prone, and kind of silly to still be
doing manually. Luckily, if you use virt-manager, it'll write out a
pretty standard startup and connection string for you, as well as the
libvirt xml to match it. I'm a software engineer by training, not an
enterprise sysadmin, I'm really grateful that I don't have to anymore.&lt;/p&gt;
&lt;img alt="example of autogenerated xml" src="images/libvirt_xml.png" style="width: 960px; height: 540px;" /&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="storage"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#contents"&gt;Storage&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Almost any virtual machine needs a backing store. The default way for
virt-manager is to use a qcow2 file in &lt;tt class="docutils literal"&gt;/var/lib/libvirt/images/&lt;/tt&gt;. I
am already using &lt;a class="reference external" href="https://sourceware.org/lvm2/"&gt;lvm&lt;/a&gt; (&lt;a class="reference external" href="https://www.debian.org/releases/testing/amd64/ch06s03.en.html#di-partition"&gt;see here&lt;/a&gt;)
for managing my host system, so may well use it for virtual systems too.
This is a fairly easy setup if you've already set up your volume group.
In the 'add storage' dialog, the left pane in your storage pools. Click
the add button on the lower left. Then, under the &lt;tt class="docutils literal"&gt;Type&lt;/tt&gt; dropdown,
select &lt;tt class="docutils literal"&gt;logical: LVM Volume Group&lt;/tt&gt;. Your volume groups should be
populated in the &lt;tt class="docutils literal"&gt;Volgroup Name:&lt;/tt&gt; dropdown. Select the proper volume
group, and you can then create a new logical volume using default
settings (no need to call &lt;tt class="docutils literal"&gt;lvcreate &lt;span class="pre"&gt;--size&lt;/span&gt; xx &lt;span class="pre"&gt;--name&lt;/span&gt; volume_name
volume_group_name&lt;/tt&gt; yourself).&lt;/p&gt;
&lt;img alt="storage pool configuration illustration" src="images/libvirt_storage_pool.png" style="width: 758px; height: 524px;" /&gt;
&lt;/div&gt;
&lt;div class="section" id="video-acceleration"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#contents"&gt;Video Acceleration&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In the before times, to get gpu acceleration in a virtual machine you
had to pass through an unused phsycial graphics card. For Windows VMs,
you probably still have to. These days, if your host and guest graphics
stack uses &lt;a class="reference external" href="https://mesa3d.org/"&gt;Mesa&lt;/a&gt;, you have the ability to use the hosts gpu acceleration
on the guest's window. I originally had to build various bits myself,
but after I came across &lt;a class="reference external" href="https://ryan.himmelwright.net/post/virtio-3d-vms/"&gt;Ryan Himmelwright's&lt;/a&gt; blog I discovered the
stuff was already built in. Just set the graphics type to &lt;tt class="docutils literal"&gt;virtio&lt;/tt&gt;,
tick the &lt;tt class="docutils literal"&gt;3d Acceleration&lt;/tt&gt; box, and set your &lt;tt class="docutils literal"&gt;Display&lt;/tt&gt; to Spice and
tick &lt;tt class="docutils literal"&gt;OpenGL&lt;/tt&gt;. Yes, these two settings will complain until they match.
That's fine, just match them :-)&lt;/p&gt;
&lt;img alt="Spice server configuration illustration" src="images/libvirt_spice_server.png" style="width: 960px; height: 540px;" /&gt;
&lt;/div&gt;
&lt;div class="section" id="freedos-specific"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#contents"&gt;FreeDOS Specific&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I installed a working &lt;a class="reference external" href="https://freedos.org/"&gt;FreeDOS&lt;/a&gt; install. Everything worked out of the
box, except for the audio device. I manually changed the &lt;tt class="docutils literal"&gt;audio&lt;/tt&gt;
setting to sb16 by manually editing the xml snippet to &lt;tt class="docutils literal"&gt;sb16&lt;/tt&gt;.&lt;/p&gt;
&lt;img alt="FreeDOS sound setting illustration" src="images/libvirt_freedos_audio.png" style="width: 645px; height: 550px;" /&gt;
&lt;p&gt;I then had to add a soundblaster driver in FreeDOS itself. I got the
Win3.11.zip archive from this &lt;a class="reference external" href="https://volitank.com/linux/"&gt;URL&lt;/a&gt; from
this &lt;a class="reference external" href="https://www.youtube.com/watch?v=XEBMWiLBKuI"&gt;YouTube video&lt;/a&gt;
(warning, possible audio issues). I pulled the soundblaster directory
and passed it through to FreeDOS, then ran the executable and it set up
autoexec.bat and everything else for me. (Don't be surprised if that
link goes away, the video author owns it, and it appears to be a
personal website). The &lt;a class="reference external" href="https://oemdrivers.com/sound-sb16"&gt;oemdrivers&lt;/a&gt;
site may be a good backup. Now I can hear that glorious (?) crunchy
sound of Doomguy shooting his pistol.&lt;/p&gt;
&lt;/div&gt;
</content><category term="config"></category></entry><entry><title>Home Directory in Git</title><link href="https://blog.languidnights.com/tech/home-directory-in-git.html" rel="alternate"></link><published>2022-03-18T00:00:00-04:00</published><updated>2022-11-03T00:00:00-04:00</updated><author><name>Christopher R. Nelson</name></author><id>tag:blog.languidnights.com,2022-03-18:/tech/home-directory-in-git.html</id><summary type="html">&lt;p&gt;Keeping my $HOME in git.&lt;/p&gt;
&lt;div class="contents topic" id="table-of-contents"&gt;
&lt;p class="topic-title"&gt;&lt;a class="reference internal" href="#top"&gt;Table of Contents&lt;/a&gt;&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference internal" href="#living-in-git-or-why-are-we-here" id="toc-entry-1"&gt;Living in Git, or Why are we Here?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#other-implementations" id="toc-entry-2"&gt;Other Implementations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#conceptual-design" id="toc-entry-3"&gt;Conceptual Design&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#implementation" id="toc-entry-4"&gt;Implementation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#i-want-it" id="toc-entry-5"&gt;I want it!&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="living-in-git-or-why-are-we-here"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#table-of-contents"&gt;Living in Git, or Why are we Here?&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Over time I've accumulated a massive amount of built-up configurations
and other cruft in my home directory, and …&lt;/p&gt;&lt;/div&gt;</summary><content type="html">&lt;p&gt;Keeping my $HOME in git.&lt;/p&gt;
&lt;div class="contents topic" id="table-of-contents"&gt;
&lt;p class="topic-title"&gt;&lt;a class="reference internal" href="#top"&gt;Table of Contents&lt;/a&gt;&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference internal" href="#living-in-git-or-why-are-we-here" id="toc-entry-1"&gt;Living in Git, or Why are we Here?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#other-implementations" id="toc-entry-2"&gt;Other Implementations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#conceptual-design" id="toc-entry-3"&gt;Conceptual Design&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#implementation" id="toc-entry-4"&gt;Implementation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#i-want-it" id="toc-entry-5"&gt;I want it!&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="living-in-git-or-why-are-we-here"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#table-of-contents"&gt;Living in Git, or Why are we Here?&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Over time I've accumulated a massive amount of built-up configurations
and other cruft in my home directory, and whenever I need to bring a new
computer online I have to copy my desktop configuration to it, like a
game of software config telephone. (this happens to me more often that
you'd think, as I have a number of &lt;a class="reference external" href="https://www.raspberrypi.org"&gt;Raspberry Pi&lt;/a&gt; boards I use as
desktops until I have a need for it in an embedded solution). I figured
there had to be a better way, using the tools I picked up as a
developer. Turns out there is :-)&lt;/p&gt;
&lt;p&gt;I remembered &lt;em&gt;A Long Time Ago™&lt;/em&gt; reading about &lt;a class="reference external" href="https://etckeeper.branchable.com/"&gt;Joey Hess&lt;/a&gt; writing
etckeeper to keep the configuration files in /etc/ under, ahem, control.
I also remember vaguely seeing similar software for home directories,
but those software projects are lost to years of imperfect memory, and
so I couldn't find them. Hence, my writing a new one.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="other-implementations"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#table-of-contents"&gt;Other Implementations&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;There are probably many, many, &lt;em&gt;many&lt;/em&gt; implementations to keeping your
home directory in git. Most of them would probably even work for my
personal setup, but &lt;a class="reference external" href="https://en.wikipedia.org/wiki/Not_invented_here"&gt;NIH&lt;/a&gt; and all. So I wrote my own! I'm actually kind
of proud of it, but if the gods are kind it stays pretty much the way it
is for the foreseeable future, as I've settled somewhat in my 'config'
churn and am running &lt;a class="reference external" href="https://www.debian.org"&gt;Debian Stable&lt;/a&gt; anyway so my software shouldn't be
changing its config syntax weekly.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="conceptual-design"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#table-of-contents"&gt;Conceptual Design&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;My requirements are the following:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;the configuration files should be in version control&lt;/li&gt;
&lt;li&gt;the configuration files must be able to be kept separate from the live
config files&lt;/li&gt;
&lt;li&gt;the script must be able to be executed on any system I might call home
(this means POSIX compliant shells, such as &lt;a class="reference external" href="http://gondor.apana.org.au/~herbert/dash/"&gt;DASH&lt;/a&gt;, or &lt;a class="reference external" href="https://www.perl.org/"&gt;perl&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;ideally, allows symlinking so as to make changes easily pushed
upstream&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="implementation"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#table-of-contents"&gt;Implementation&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To achieve this, I went with &lt;a class="reference external" href="https://git-scm.com/about"&gt;git&lt;/a&gt; for version control. This allows me
to utilize the git setup framework I already had installed for my
software projects (it's &lt;a class="reference external" href="https://projects.languidnights.com/cgit"&gt;here&lt;/a&gt; if you're interested). It's also quite
well documented and recipes exist for almost every scenario on either
&lt;a class="reference external" href="https://serverfault.com/questions"&gt;Server Fault&lt;/a&gt; or &lt;a class="reference external" href="https://www.reddit.com/r/git/"&gt;reddit&lt;/a&gt;. I initialized a new git repository on my
server for this to live in, calling it l-homedir after a bit of
self-serving names :-)&lt;/p&gt;
&lt;p&gt;In my shiny new git repo copy, I moved (as in &lt;tt class="docutils literal"&gt;mv&lt;/tt&gt;) the interesting
and non-private configurations into it. I maintained the directory
structure you would find in my home directory (for example, my
&lt;tt class="docutils literal"&gt;.zshrc&lt;/tt&gt; file is in &lt;tt class="docutils literal"&gt;$REPO_ROOT&lt;/tt&gt; and my &lt;tt class="docutils literal"&gt;nvim&lt;/tt&gt; config lives in
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;$REPO_ROOT/.config/nvim&lt;/span&gt;&lt;/tt&gt;). This allows me to separate the files I
care about from those that I do not care if get lost, or those that
contain private information (ssh private keys and such).&lt;/p&gt;
&lt;p&gt;To accomplish the copying/linking files (linking in this case) I wrote a
mildly complicated shell file, and a corresponding config file.
&lt;tt class="docutils literal"&gt;linked_files&lt;/tt&gt; contains a list of files I want to maintain here---in
case something accidentally ends up in the repo. &lt;tt class="docutils literal"&gt;make_links&lt;/tt&gt; is the
shell script. The script follows this basic flow&lt;/p&gt;
&lt;ol class="arabic simple" id="loop-top"&gt;
&lt;li&gt;iterate over each line in &lt;tt class="docutils literal"&gt;linked_files&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;if it is blank or starts with a hash (#) ignore it&lt;/li&gt;
&lt;li&gt;check if the file already exists?&lt;/li&gt;
&lt;li&gt;if the file already exists, is it running in destructive mode?&lt;/li&gt;
&lt;li&gt;if in destructive mode, &lt;tt class="docutils literal"&gt;rm&lt;/tt&gt; the original file, otherwise skip it&lt;/li&gt;
&lt;li&gt;if skipped, return to &lt;a class="reference internal" href="#loop-top"&gt;Loop Top&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;ln &lt;span class="pre"&gt;-s&lt;/span&gt;&lt;/tt&gt; the file in the repository to the home directory&lt;/li&gt;
&lt;li&gt;Return to &lt;a class="reference internal" href="#loop-top"&gt;Loop Top&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I wrote a README and brought in a license file to top it off, and I have
a shiny new home-in-git solution :-D&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="i-want-it"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#table-of-contents"&gt;I want it!&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Assuming you're not trolling me, get it &lt;a class="reference external" href="git://languidnights.com/l-homedir.git"&gt;right here&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
</content><category term="config"></category></entry><entry><title>Mail Server Setup</title><link href="https://blog.languidnights.com/tech/mail-server-setup.html" rel="alternate"></link><published>2022-03-18T00:00:00-04:00</published><updated>2022-11-03T00:00:00-04:00</updated><author><name>Christopher R. Nelson</name></author><id>tag:blog.languidnights.com,2022-03-18:/tech/mail-server-setup.html</id><summary type="html">&lt;p&gt;I've taken great pains to get my mail server set up both the way I want
it and correctly. I'm now sharing that knowledge with the internet as a
whole, as well as myself when I need to figure out &lt;a class="reference external" href="https://www.nimh.nih.gov/health/topics/bipolar-disorder"&gt;wtf&lt;/a&gt; I did.&lt;/p&gt;
&lt;div class="contents topic" id="table-of-contents"&gt;
&lt;p class="topic-title"&gt;&lt;a class="reference internal" href="#top"&gt;Table of Contents&lt;/a&gt;&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference internal" href="#note" id="toc-entry-1"&gt;NOTE&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#setting-up-virtual-mail-users-and-authentication-through-dovecot" id="toc-entry-2"&gt;Setting up virtual …&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;</summary><content type="html">&lt;p&gt;I've taken great pains to get my mail server set up both the way I want
it and correctly. I'm now sharing that knowledge with the internet as a
whole, as well as myself when I need to figure out &lt;a class="reference external" href="https://www.nimh.nih.gov/health/topics/bipolar-disorder"&gt;wtf&lt;/a&gt; I did.&lt;/p&gt;
&lt;div class="contents topic" id="table-of-contents"&gt;
&lt;p class="topic-title"&gt;&lt;a class="reference internal" href="#top"&gt;Table of Contents&lt;/a&gt;&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference internal" href="#note" id="toc-entry-1"&gt;NOTE&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#setting-up-virtual-mail-users-and-authentication-through-dovecot" id="toc-entry-2"&gt;Setting up virtual mail users and authentication through Dovecot&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#setting-up-postfix-to-authenticate-through-dovecot" id="toc-entry-3"&gt;Setting up Postfix to authenticate through Dovecot&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#amavis-spamassassin-and-clamav" id="toc-entry-4"&gt;Amavis: Spamassassin and ClamAV&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#thanks" id="toc-entry-5"&gt;Thanks&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="note"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#table-of-contents"&gt;NOTE&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;This article should be considered archived as of 2023-02-09. I have
abandoned the maintenance of my own email solution for &lt;a class="reference external" href="https://proton.me"&gt;ProtonMail&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="setting-up-virtual-mail-users-and-authentication-through-dovecot"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#table-of-contents"&gt;Setting up virtual mail users and authentication through Dovecot&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;My goal here was to use LDAP for authentication and creation of
mailboxes for &amp;quot;virtual users&amp;quot; (ie, they don't exist in /etc/password and
have home directory). I set it up this way so that I could set up
mailboxes for application accounts and get their mail delivered to a
predictable place and be able to access it through IMAP without having
to have it clutter my actual mailbox.&lt;/p&gt;
&lt;p&gt;The bulk of the 'fun stuff' is in /etc/dovecot/dovecot-ldap.conf.ext -
it's well commented, so I'm just going to list the settings I changed.
For purposes of cleanliness, I'm going to use 'example.com' and 'not the
real password' where appropriate :-) I'm using a fairly standard simple
bind.&lt;/p&gt;
&lt;pre class="literal-block"&gt;
hosts = localhost
dn = cn=admin,dc=example,dc=com
dnpass = not the real password
auth_bind_userdn = uid=%u,ou=People,dc=example,dc=com
&lt;/pre&gt;
&lt;p&gt;Here's I'm checking the users and passwords against the mail attribute
on the LDAP account. I'm then &lt;em&gt;ignoring&lt;/em&gt; interesting parts of the
results to store all mail under a 'vmail' user with uid and gid of 5000
and a subdirectory named after the real users. Dovecot finds this
location both when delivering and serving, so no further setup here
needed.&lt;/p&gt;
&lt;pre class="literal-block"&gt;
base = dc=example,dc=com
user_attrs = 5000=uid,5000=gid,home=/var/vmail/%u
user_filter = (&amp;amp;objectClass=posixAccount)(mail=%n&amp;#64;example.com)
pass_attrs = uid=user,userPassword=password,homeDirectory=/var/vmail/%u
pass_filter = (&amp;amp;objectClass=posixAccount)(mail=%n&amp;#64;example.com)
&lt;/pre&gt;
&lt;p&gt;After this, I just have to wire it up in conf.d/auth-ldap.conf.ext to
use ldap for password lookups and semi-hardcoded user lookups---don't
validate the user and assume they get mail to /var/vmail/{username}&lt;/p&gt;
&lt;pre class="literal-block"&gt;
passdb {
      driver = ldap
      args = /etc/dovecot/dovecot-ldap.conf.ext
}
userdb {
      driver = static
      args = uid=vmail gid=vmail home=/var/vmail/%u
}
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class="section" id="setting-up-postfix-to-authenticate-through-dovecot"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#table-of-contents"&gt;Setting up Postfix to authenticate through Dovecot&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Because I spent so much time getting authentication working for Dovecot,
let's just re-use it for postfix because the same users are trying to
send mail as are receiving it.&lt;/p&gt;
&lt;p&gt;In /etc/dovecot/conf.d/10-master.conf&lt;/p&gt;
&lt;pre class="literal-block"&gt;
# Setup the socket for postfix to authentical against
service auth {
      unix-listener /var/spool/postfix/private/auth {
              mode = 0666
      }
}
&lt;/pre&gt;
&lt;p&gt;In /etc/postfix/main.cf for authentication&lt;/p&gt;
&lt;pre class="literal-block"&gt;
# SASL authentication
smtpd_sasl_type = dovecot
smtpd_sasl_auth_enable = yes
smtpd_recipient_restrictions = permit_sasl_authenticated,permit_mynetworks,reject_unauth_destination
smtpd_sasl_path = private/auth
&lt;/pre&gt;
&lt;p&gt;In /etc/postfix/main.cf for mail delivery&lt;/p&gt;
&lt;pre class="literal-block"&gt;
# Postfix MDA
mailbox_transport = dovecot
mailbox_commant = /usr/lib/dovecot/dovecot-lda -a &amp;quot;$RECIPIENT&amp;quot;
virtual_transport = dovecot
dovecot_destination_recipient_limit = 1
&lt;/pre&gt;
&lt;p&gt;In /etc/postfix/master.cf before the non-posix services&lt;/p&gt;
&lt;pre class="literal-block"&gt;
dovecot   unix  -       n       n       -       -       pipe
  flags=DRhu user=vmail:vmail argv=/usr/lib/dovecot/dovecot-lda -f ${sender} -d ${user} -a ${recipient}
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class="section" id="amavis-spamassassin-and-clamav"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#table-of-contents"&gt;Amavis: Spamassassin and ClamAV&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Install but &lt;em&gt;do not&lt;/em&gt; enable spamassassin. Amavis will take care of
launching a scanner as it scans emails. When I &lt;em&gt;enabled&lt;/em&gt; the
spamassassin daemon, I ended up with all cpu cores fully utilized.&lt;/p&gt;
&lt;p&gt;Install and &lt;em&gt;do&lt;/em&gt; enable clamav-daemon. Amavis can use the daemon for a
bit of a computational advantage.&lt;/p&gt;
&lt;p&gt;Install Amavis and configure it to use spamassassin and clamav. As I'm
using Debian, I updated the 15-content_filter_mode to uncomment the
virus_checks and spam_checks lines&lt;/p&gt;
&lt;pre class="literal-block"&gt;
use strict;

# You can modify this file to re-enable SPAM checking through spamassassin
# and to re-enable antivirus checking.

# Default antivirus checking mode
# Please note, that anti-virus checking is DISABLED by
# default.
# If you wish to enable it, please uncomment the following line:

&amp;#64;bypass_virus_checks_maps = (
  %bypass_virus_checks, &amp;#64;bypass_virus_checks_acl,
  $bypass_virus_checks_re);

# Default SPAM checking mode
# Please note, that anti-spam checking is DISABLED by
# default.
# If You wish to enable it, please uncomment the following lines:
&amp;#64;bypass_spam_checks_maps = (
  %bypass_spam_checks, &amp;#64;bypass_spam_checks_acl,
  $bypass_spam_checks_re);

1;  # ensure a defined return
&lt;/pre&gt;
&lt;p&gt;At the end of the postfix &lt;cite&gt;master.cf&lt;/cite&gt; file, I added the following lines
to shunt the email to Amavis.&lt;/p&gt;
&lt;pre class="literal-block"&gt;
smtp-amavis  unix       -      -       -       -       2       smtp
  -o smtp_data_done_timeout=1200
  -o smtp_send_xforward_command=yes
  -o disable_dns_lookups=yes
  -o max_use=20

127.0.0.1:10025 inet    n      -       -       -       -       smtpd
     -o content_filter=
     -o smtpd_delay_reject=no
     -o smtpd_client_restrictions=permit_mynetworks,reject
     -o smtpd_helo_restrictions=
     -o smtpd_sender_restrictions=
     -o smtpd_recipient_restrictions=permit_mynetworks,reject
     -o smtpd_data_restrictions=reject_unauth_pipelining
     -o smtpd_end_of_data_restrictions=
     -o smtpd_restriction_classes=
     -o mynetworks=127.0.0.0/8
     -o smtpd_error_sleep_time=0
     -o smtpd_soft_error_limit=1001
     -o smtpd_hard_error_limit=1000
     -o smtpd_client_connection_count_limit=0
     -o smtpd_client_connection_rate_limit=0
     -o receive_override_options=no_header_body_checks,no_unknown_recipient_checks,no_milters
     -o local_header_rewrite_clients=
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class="section" id="thanks"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#table-of-contents"&gt;Thanks&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;These fine projects have been used as my tools of choice in serving
mail.&lt;/p&gt;
&lt;a class="reference external image-reference" href="https://dovecot.org"&gt;
&lt;img alt="Dovecot logo" src="https://dovecot.org/dovecot.png" style="width: 10%;" /&gt;
&lt;/a&gt;
&lt;a class="reference external image-reference" href="http://www.postfix.org"&gt;
&lt;img alt="Postfix logo" src="images/mysza.gif" style="width: 10%;" /&gt;
&lt;/a&gt;
&lt;a class="reference external image-reference" href="https://www.clamav.net"&gt;
&lt;img alt="clamav logo" src="https://www.clamav.net/assets/clamav-trademark.png" style="width: 10%;" /&gt;
&lt;/a&gt;
&lt;a class="reference external image-reference" href="https://spamassassin.apache.org"&gt;
&lt;img alt="spamassassin logo" src="images/spamassassin.png" style="width: 10%;" /&gt;
&lt;/a&gt;
&lt;/div&gt;
</content><category term="server"></category></entry><entry><title>(open)LDAP lessons</title><link href="https://blog.languidnights.com/tech/openldap-lessons.html" rel="alternate"></link><published>2022-03-18T00:00:00-04:00</published><updated>2022-11-03T00:00:00-04:00</updated><author><name>Christopher R. Nelson</name></author><id>tag:blog.languidnights.com,2022-03-18:/tech/openldap-lessons.html</id><summary type="html">&lt;a class="reference external image-reference" href="https://openldap.org"&gt;
&lt;img alt="openLDAP logo" src="https://openldap.org/images/headers/LDAPworm.gif" style="width: 20%;" /&gt;
&lt;/a&gt;
&lt;p&gt;I've set up LDAP a couple times in a personal capacity, and I'm sharing
this if anyone's interested, or if I need to come back to it.&lt;/p&gt;
&lt;div class="contents topic" id="table-of-contents"&gt;
&lt;p class="topic-title"&gt;&lt;a class="reference internal" href="#top"&gt;Table of Contents&lt;/a&gt;&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference internal" href="#adding-a-search-index-field" id="toc-entry-1"&gt;Adding a search index field&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#add-a-user" id="toc-entry-2"&gt;Add A User&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#thanks-to" id="toc-entry-3"&gt;Thanks to&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="adding-a-search-index-field"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#table-of-contents"&gt;Adding a search index field&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I've had slapd running for …&lt;/p&gt;&lt;/div&gt;</summary><content type="html">&lt;a class="reference external image-reference" href="https://openldap.org"&gt;
&lt;img alt="openLDAP logo" src="https://openldap.org/images/headers/LDAPworm.gif" style="width: 20%;" /&gt;
&lt;/a&gt;
&lt;p&gt;I've set up LDAP a couple times in a personal capacity, and I'm sharing
this if anyone's interested, or if I need to come back to it.&lt;/p&gt;
&lt;div class="contents topic" id="table-of-contents"&gt;
&lt;p class="topic-title"&gt;&lt;a class="reference internal" href="#top"&gt;Table of Contents&lt;/a&gt;&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference internal" href="#adding-a-search-index-field" id="toc-entry-1"&gt;Adding a search index field&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#add-a-user" id="toc-entry-2"&gt;Add A User&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#thanks-to" id="toc-entry-3"&gt;Thanks to&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="adding-a-search-index-field"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#table-of-contents"&gt;Adding a search index field&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I've had slapd running for a long time without any &lt;em&gt;functional&lt;/em&gt; errors,
but the daemon would often tell me that the mail field wasn't indexed
and it could be. Now, I'm not the sort of target that would be worth
denial-of-service attacks against my LDAP database, but it's still
worthwhile to clean it up (if for no other reason that to tidy syslog!).&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;slapd&lt;span class="o"&gt;[&lt;/span&gt;pid&lt;span class="o"&gt;]&lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;&amp;lt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;mdb_equality_candidates:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;mail&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;not&lt;span class="w"&gt; &lt;/span&gt;indexed
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To fix this, I set about scouring the internet. Most of the results I
found were how to fix the issue in the 1995-era technical reference or
discussions about modifying &amp;quot;slapd.conf&amp;quot; and running slaptest. I didn't
use a semi-modern version of openldap just to resurrect the old config
format, use it, then throw it back away! There had to be a better
option. And there is! I found hints on &lt;a class="reference external" href="https://wiki.debian.org/LDAP/OpenLDAPSetup"&gt;Debian's wiki&lt;/a&gt; which led me to
my ultimate solution to this annoyance. Debian used a heredoc but I'm
nowhere near confident in either my typing nor my copy-pasting to use
one, so I created a file with the interesting index.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;dn:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;olcDatabase&lt;/span&gt;&lt;span class="o"&gt;={&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;mdb,cn&lt;span class="o"&gt;=&lt;/span&gt;config
changetype:&lt;span class="w"&gt; &lt;/span&gt;modify
add:&lt;span class="w"&gt; &lt;/span&gt;olcDbIndex
olcDbIndex:&lt;span class="w"&gt; &lt;/span&gt;mail&lt;span class="w"&gt; &lt;/span&gt;pres,sub,eq
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then, I used ldapmodify to update add the index to the LDAP directory.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;ldapmodify&lt;span class="w"&gt; &lt;/span&gt;-Y&lt;span class="w"&gt; &lt;/span&gt;EXTERNAL&lt;span class="w"&gt; &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;ldapi:///&lt;span class="w"&gt; &lt;/span&gt;-f&lt;span class="w"&gt; &lt;/span&gt;add_index.ldif
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;All good now, nice clean logfiles and an LDAP doesn't have to struggle
so much!&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="add-a-user"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#table-of-contents"&gt;Add A User&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Create an adduser.ldif file with the following info (for my mail and
user setup, yours may vary). Substite the values in &lt;tt class="docutils literal"&gt;${ .. }&lt;/tt&gt; with
pertinent details of your site. Then execute the ldapmodify command.
This will ask for your password on the command line.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;ldapmodify&lt;span class="w"&gt; &lt;/span&gt;-x&lt;span class="w"&gt; &lt;/span&gt;-D&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;admin&lt;/span&gt;&lt;span class="p"&gt; LDAP path&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-W&lt;span class="w"&gt; &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;ldapi:///&lt;span class="w"&gt; &lt;/span&gt;-f&lt;span class="w"&gt; &lt;/span&gt;adduser.ldif
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Example adduser.ldif&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;dn:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;uid&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;username&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;,ou&lt;span class="o"&gt;=&lt;/span&gt;People,dc&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;domain&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;,dc&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;tld&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
changetype:&lt;span class="w"&gt; &lt;/span&gt;add
objectClass:&lt;span class="w"&gt; &lt;/span&gt;inetOrgPerson
objectClass:&lt;span class="w"&gt; &lt;/span&gt;person
objectClass:&lt;span class="w"&gt; &lt;/span&gt;posixAccount
ou:&lt;span class="w"&gt; &lt;/span&gt;People
uid:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;username&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
cn:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;user&lt;/span&gt;&lt;span class="p"&gt; given name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
sn:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;user&lt;/span&gt;&lt;span class="p"&gt; family name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
givenName:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;user&lt;/span&gt;&lt;span class="p"&gt; given name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
displayName:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;user&lt;/span&gt;&lt;span class="p"&gt; display name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
initials:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;user&lt;/span&gt;&lt;span class="p"&gt; initials&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
uidNumber:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;user&lt;/span&gt;&lt;span class="p"&gt; numeric uid&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
gidNumber:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;user&lt;/span&gt;&lt;span class="p"&gt; numeric gid&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
homeDirectory:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;full&lt;/span&gt;&lt;span class="p"&gt; path to user home directory&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
loginShell:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;full&lt;/span&gt;&lt;span class="p"&gt; path to user login shell&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
mail:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;user&lt;/span&gt;&lt;span class="p"&gt; email address&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="thanks-to"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#table-of-contents"&gt;Thanks to&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I'd like to thanks &lt;a class="reference external" href="https://openldap.org"&gt;openLDAP&lt;/a&gt; for the relatively simple directory
servers/clients and &lt;a class="reference external" href="https://wiki.debian.org/LDAP/OpenLDAPSetup"&gt;Debian's wiki&lt;/a&gt; for the information I needed to
make sense of the configuration.&lt;/p&gt;
&lt;/div&gt;
</content><category term="server"></category></entry><entry><title>ReST in Jekyll</title><link href="https://blog.languidnights.com/tech/rest-in-jekyll.html" rel="alternate"></link><published>2022-03-18T00:00:00-04:00</published><updated>2023-02-09T00:00:00-05:00</updated><author><name>Christopher R. Nelson</name></author><id>tag:blog.languidnights.com,2022-03-18:/tech/rest-in-jekyll.html</id><summary type="html">&lt;div class="contents topic" id="contents"&gt;
&lt;p class="topic-title"&gt;&lt;a class="reference internal" href="#top"&gt;Contents&lt;/a&gt;&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference internal" href="#note" id="toc-entry-1"&gt;NOTE&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#a-story-of-markup" id="toc-entry-2"&gt;A Story of Markup&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#a-story-of-dependencies" id="toc-entry-3"&gt;A Story of Dependencies&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#a-story-of-gems" id="toc-entry-4"&gt;A Story of Gems&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#a-story-of-reference" id="toc-entry-5"&gt;A Story of Reference&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#a-story-of-the-future" id="toc-entry-6"&gt;A Story of the Future&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#tl-dr" id="toc-entry-7"&gt;TL;DR&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="note"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#contents"&gt;NOTE&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;This article should be considered archived. No further updates are
expected. For ReST-flavoured blogging, please see &lt;a class="reference external" href="https://docs.getpelican.com/en/latest/index.html"&gt;Pelican&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="a-story-of-markup"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#contents"&gt;A Story of Markup&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a class="reference external" href="https://jekyllrb.com/"&gt;Jekyll&lt;/a&gt;, by default …&lt;/p&gt;&lt;/div&gt;</summary><content type="html">&lt;div class="contents topic" id="contents"&gt;
&lt;p class="topic-title"&gt;&lt;a class="reference internal" href="#top"&gt;Contents&lt;/a&gt;&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference internal" href="#note" id="toc-entry-1"&gt;NOTE&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#a-story-of-markup" id="toc-entry-2"&gt;A Story of Markup&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#a-story-of-dependencies" id="toc-entry-3"&gt;A Story of Dependencies&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#a-story-of-gems" id="toc-entry-4"&gt;A Story of Gems&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#a-story-of-reference" id="toc-entry-5"&gt;A Story of Reference&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#a-story-of-the-future" id="toc-entry-6"&gt;A Story of the Future&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#tl-dr" id="toc-entry-7"&gt;TL;DR&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="note"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#contents"&gt;NOTE&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;This article should be considered archived. No further updates are
expected. For ReST-flavoured blogging, please see &lt;a class="reference external" href="https://docs.getpelican.com/en/latest/index.html"&gt;Pelican&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="a-story-of-markup"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#contents"&gt;A Story of Markup&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a class="reference external" href="https://jekyllrb.com/"&gt;Jekyll&lt;/a&gt;, by default, does not support writing your static page/blog in
Restructured Text, or &lt;a class="reference external" href="https://docutils.sourceforge.io/rst.html"&gt;ReST&lt;/a&gt;. I came at my personal projects from the
Python world, where ReST is commonly used. I, therefore, am much more
comfortable in the ReST world than am I in the &lt;a class="reference external" href="https://daringfireball.net/projects/markdown/"&gt;Markdown&lt;/a&gt; or
&lt;a class="reference external" href="https://textile-lang.com/"&gt;Textile&lt;/a&gt;. Naturally, I went looking for a Jekyll RST plugin. There was
only one I could find, and it was sufficiently old as to no longer work
with modern docutils setups, so, rather than tie myself down to an
ancient docutils, I decided to modernize it.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="a-story-of-dependencies"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#contents"&gt;A Story of Dependencies&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The github repository I found listed as dependencies Pygmentize and
Docutils. It turns out, however, that the important parts of both
projects were included in the repository itself. Seeing this as a waste,
I first remove Pygmentize, discovering to my joy that the docutils
converter I was using would do that for me! I then set about removing
the glue that tied that Pygmentize to the rst2html in the repository.
Simple, and it &lt;strong&gt;Just Worked™&lt;/strong&gt;. Now that I was here, with a
bog-standard rst2html, I tested things. Nope, UTF-8 conversions weren't
handled automatically in this wrapper class. No problem, let's just
bring in the modern one. Wait, what? If I'm directly including the
modern one, and also listing it as a dependency, it would be much
cleaner to just use the version brought in, no? So it went away, leaving
just the ruby=&amp;gt;python bridge. Much cleaner, if a bit of a trivial
product now.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="a-story-of-gems"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#contents"&gt;A Story of Gems&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Ouch! There was a ticket on the original project I forked asking for it
to be made available as a gem. I'm a sucker for interesting projects, so
I set about to make it so. Create a branch, switch to it, and get on
with the gem creation! Except, no. There's multiple different
educational resources each containing the correct instructions for the
version of &lt;tt class="docutils literal"&gt;gem&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;bundle&lt;/tt&gt; that were current when they went live.
None of these versions were anything resembling current, so I'd have to
go deeper. I'd have to go to the &lt;a class="reference external" href="https://bundler.io/guides/creating_gem.html"&gt;source of truth&lt;/a&gt; about these topics,
the official documents at the &lt;a class="reference external" href="https://bundler.io/"&gt;Bundler&lt;/a&gt; itself. This got me
bootstrapped with, ironically enough, a bootstrap routine. A few more
tweaks of configuration, and I could build a gem. It was just a shame
that it did nothing at all...&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="a-story-of-reference"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#contents"&gt;A Story of Reference&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;By gum, somebody had to have done this before me! I checked out the
&lt;a class="reference external" href="https://jekyllrb.com/"&gt;Jekyll&lt;/a&gt; site again, and sure enough they released one of their
official parser/converters at the &lt;a class="reference external" href="https://github.com/jekyll/jekyll-textile-converter"&gt;Textile github repository&lt;/a&gt;! Thanks
and praise be to the gods of documentation! Anyway, I adapted their
configuration to match the code I already had, using the Ruby
underscores &lt;a class="reference external" href="https://guides.rubygems.org/name-your-gem/"&gt;naming convention&lt;/a&gt; (though this is purely a aesthetic
change, as I consider this its own thing and they consider theirs an
extension). I also had some Jekyll plumbing to adapt. Luckily their code
is &lt;cite&gt;MIT license`&lt;/cite&gt; and so is mine. A few code changes and framework
force-fitting and I'm off to the races!&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="a-story-of-the-future"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#contents"&gt;A Story of the Future&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Where do we go from here, my dear readers? That's a good question. The
inclusion of the plugin is now dead-simple, so we could just let it be.
We also could include it in an official &lt;a class="reference external" href="https://rubygems.org/"&gt;Gems repositories&lt;/a&gt;, or one of
the &lt;a class="reference external" href="https://github.com/planetjekyll/awesome-jekyll-plugins"&gt;Jekyll plugin&lt;/a&gt; repositories. These decisions await a more
permanent answer in &lt;em&gt;the future™&lt;/em&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="tl-dr"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#contents"&gt;TL;DR&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Go to &lt;a class="reference external" href="https://github.com/languidnights/jekyll-rst-ng"&gt;this repository&lt;/a&gt; and get blogging in rst files.&lt;/p&gt;
&lt;/div&gt;
</content><category term="server"></category></entry></feed>