<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>Tribaal&#x27;s blog</title>
    <subtitle>A blog dedicated to fighting tribal knowledge, one topic at a time.</subtitle>
    <link rel="self" type="application/atom+xml" href="/atom.xml"/>
    <link rel="alternate" type="text/html" href="/"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2024-01-01T00:00:00+00:00</updated>
    <id>/atom.xml</id>
    <entry xml:lang="en">
        <title>Archive</title>
        <published>2024-01-01T00:00:00+00:00</published>
        <updated>2024-01-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/archive/"/>
        <id>/archive/</id>
        
        <content type="html" xml:base="/archive/"></content>
        
    </entry>
    <entry xml:lang="en">
        <title>Setting up a ZNC bouncer on OpenBSD 6.4</title>
        <published>2020-05-27T00:00:00+00:00</published>
        <updated>2020-05-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/posts/znc-on-openbsd-64/"/>
        <id>/posts/znc-on-openbsd-64/</id>
        
        <content type="html" xml:base="/posts/znc-on-openbsd-64/">&lt;p&gt;The latest version of OpenBSD contains everything you might need to create a
really powerful (SSL) ZNC bouncer in just a few simple steps, fully secured by
you very own letsencrypt certificate.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;openbsd_bouncer.png&quot; alt=&quot;The arms of a bouncer with an OpenBSD logo&quot; title=&quot;I said no sneakers!&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;create-an-openbsd-machine&quot;&gt;Create an OpenBSD machine&lt;&#x2F;h2&gt;
&lt;p&gt;Nothing could be more simple using Exoscale&#x27;s &quot;exo&quot; command line client.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;firewall-considerations&quot;&gt;Firewall considerations&lt;&#x2F;h3&gt;
&lt;p&gt;We&#x27;ll want to make sure the following ports are let through to our OpenBSD instance:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;22&#x2F;TCP: of course, we&#x27;ll need to SSH into our machine, so port 22 needs to be
allowed through.&lt;&#x2F;li&gt;
&lt;li&gt;80&#x2F;TCP: We&#x27;ll use the default HTTP port in the process to obtain our Let&#x27;s
Encrypt certificate (to serve the challenge response).&lt;&#x2F;li&gt;
&lt;li&gt;6697&#x2F;TCP: The actual IRC port! You could pick something else here, as long as
it&#x27;s used consistently during the rest of this article.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;This configuration can be easily applied using Exoscale security groups:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;shell&quot; class=&quot;language-shell &quot;&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;exo firewall create bouncer -d &amp;quot;The firewall rules for our bouncer&amp;quot;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This created a new security group, but it lacks rules for now. Let&#x27;s fix that:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;shell&quot; class=&quot;language-shell &quot;&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;exo firewall add bouncer ssh
exo firewall add bouncer http
exo firewall add bouncer -P 6697 -p tcp -c &amp;quot;0.0.0.0&amp;#x2F;0&amp;quot; -d &amp;quot;IRC over SSL&amp;quot;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We&#x27;re good to go! On with the actual instance.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;creating-an-openbsd-cloud-instance&quot;&gt;Creating an OpenBSD cloud instance&lt;&#x2F;h3&gt;
&lt;p&gt;Once again, the Exoscale CLI tool makes this easy for us:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;shell&quot; class=&quot;language-shell &quot;&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;VM_NAME=&amp;quot;my-bouncer&amp;quot;
exo vm create -t OpenBSD $VM_NAME -s bouncer
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Once deployed, connecting to the machine is as simple as:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;shell&quot; class=&quot;language-shell &quot;&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;exo ssh $VM_NAME
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;That should drop you right into an OpenBSD root shell. Nice!&lt;&#x2F;p&gt;
&lt;p&gt;You might want to install vim (or your favorite editor) now:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;shell&quot; class=&quot;language-shell &quot;&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;pkg_add vim
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;You can otherwise rely on vi.&lt;&#x2F;p&gt;
&lt;p&gt;Now is also a good time to setup a normal user. ZNC refuses to run as root
(rightfully so), and this is good practice anyway.&lt;&#x2F;p&gt;
&lt;p&gt;Since our user will have to read the SSL private key (in order to let ZNC use it),
let&#x27;s prepare the ground and add the user to the wheel group as well.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;shell&quot; class=&quot;language-shell &quot;&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;adduser $USERNAME wheel
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;setting-up-the-acme-ssl-with-letsencrypt&quot;&gt;Setting up the acme&#x2F;SSL with letsencrypt&lt;&#x2F;h2&gt;
&lt;p&gt;OpenBSD comes preinstalled with all the tools we&#x27;ll need to setup a proper SSL
certificate for our instance.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;setting-up-dns&quot;&gt;Setting up DNS&lt;&#x2F;h3&gt;
&lt;p&gt;This is a little bit outside of the scope of this article - but since we&#x27;ll ask
for a real Let&#x27;s Encrypt certificate, now is the time for you to make sure your
machine has a proper DNS name.&lt;&#x2F;p&gt;
&lt;p&gt;The DNS name will be henceforth refered to as &lt;code&gt;$DOMAIN_NAME&lt;&#x2F;code&gt; in the rest of this
article.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;using-httpd-to-serve-the-let-s-encrypt-challenge&quot;&gt;Using httpd to serve the Let&#x27;s Encrypt challenge&lt;&#x2F;h3&gt;
&lt;p&gt;The way Let&#x27;s Encrypt works is to send the acme client a challenge, that the
requesting machine must then answer by placing a signed file in an HTTP
accessible folder.&lt;&#x2F;p&gt;
&lt;p&gt;OpenBSD ships with a very capable web server in main, and it will be more than
suited to serve the simple challenge. &lt;code&gt;acme-client&lt;&#x2F;code&gt; even comes with
documentation on how to set it up!&lt;&#x2F;p&gt;
&lt;p&gt;First, let&#x27;s enable httpd:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;shell&quot; class=&quot;language-shell &quot;&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;echo &amp;quot;httpd_flags=&amp;quot; &amp;gt; &amp;#x2F;etc&amp;#x2F;rc.conf.local
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Before it can start, it will need a config file. Thankfully it&#x27;s a very simple
one, and is almost a perfect copy of the example given in acme-client&#x27;s man
page.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;shell&quot; class=&quot;language-shell &quot;&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;cat &amp;gt; &amp;#x2F;etc&amp;#x2F;httpd.conf &amp;lt;&amp;lt;EOF
server &amp;quot;default&amp;quot; {
        listen on * port 80

        location &amp;quot;&amp;#x2F;.well-known&amp;#x2F;acme-challenge&amp;#x2F;*&amp;quot; { 
                root &amp;quot;&amp;#x2F;acme&amp;quot; 
                request strip 2 
        }
}
EOF
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Once the config is there, we can enable the service (so it survives reboots),
and start it:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;shell&quot; class=&quot;language-shell &quot;&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;rcctl enable httpd
rcctl start httpd
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;setting-up-and-using-acme-client-on-openbsd&quot;&gt;Setting up and using acme client on OpenBSD&lt;&#x2F;h3&gt;
&lt;p&gt;Thankfully, OpenBSD includes an acme client in base, so there&#x27;s nothing for us
to install!&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s configure it:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;shell&quot; class=&quot;language-shell &quot;&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;# &amp;#x2F;etc&amp;#x2F;acme-client.conf
domain $DOMAIN_NAME {
        domain key &amp;quot;&amp;#x2F;etc&amp;#x2F;ssl&amp;#x2F;private&amp;#x2F;$DOMAIN_NAME.key&amp;quot;
        domain certificate &amp;quot;&amp;#x2F;etc&amp;#x2F;ssl&amp;#x2F;$DOMAIN_NAME.crt&amp;quot;
        domain full chain certificate &amp;quot;&amp;#x2F;etc&amp;#x2F;ssl&amp;#x2F;$DOMAIN_NAME.fullchain.pem&amp;quot;
        sign with letsencrypt
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now that we told acme client how to get a certificate for us and that we are
ready to serve up the challenge it will send us, we should be all set to get a
Let&#x27;s Encrypt certificate.&lt;&#x2F;p&gt;
&lt;p&gt;To actually make the client request one for us, simply invoke, as root:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;shell&quot; class=&quot;language-shell &quot;&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;acme-client -vAD $DOMAIN_NAME
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;adding-the-renewal-to-a-cron&quot;&gt;Adding the renewal to a cron&lt;&#x2F;h3&gt;
&lt;p&gt;OpenBSd makes managing cron jobs very simple - daily crons can be added to the
&lt;code&gt;&#x2F;etc&#x2F;daily.local&lt;&#x2F;code&gt; file (the file itself is the script).&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;shell&quot; class=&quot;language-shell &quot;&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;echo &amp;#x27;acme-client $DOMAIN_NAME&amp;#x27; &amp;gt;&amp;gt; &amp;#x2F;etc&amp;#x2F;daily.local
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;ensure-your-user-can-see-the-key&quot;&gt;Ensure your user can see the key&lt;&#x2F;h3&gt;
&lt;p&gt;We will run ZNC as a regular user (it even refuses to run as root), so we need
to ensure that the user we selected to run our ZNC session can see the acme
private key (the ZNC server needs to see the key to sign packets, of course).&lt;&#x2F;p&gt;
&lt;p&gt;Since the user we created is already in the wheel group, we just need to change
the key&#x27;s ownership:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;shell&quot; class=&quot;language-shell &quot;&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;chown $USERNAME &amp;#x2F;etc&amp;#x2F;ssl&amp;#x2F;private&amp;#x2F;$DOMAIN_NAME.key
chmod g+rx &amp;#x2F;etc&amp;#x2F;ssl&amp;#x2F;private  # This allows wheel members to list the dir.
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;install-znc&quot;&gt;Install znc&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;shell&quot; class=&quot;language-shell &quot;&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;pkg_add znc
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Make sure the configuration file does &lt;em&gt;not&lt;&#x2F;em&gt; have ipv6 enable as it apparently
makes assumptions that are not valid on OpenBSD.&lt;&#x2F;p&gt;
&lt;p&gt;The last step is to simply run ZNC as your user! Or, of course, importing your
configuration to &lt;code&gt;~&#x2F;.znc&#x2F;&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;enjoy&quot;&gt;Enjoy :)&lt;&#x2F;h2&gt;
&lt;p&gt;As usual don&#x27;t hesitate to let me know if you found this helpful!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Magic URLs in the Ubuntu ecosystem</title>
        <published>2017-12-13T00:00:00+00:00</published>
        <updated>2017-12-13T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/posts/magic-urls/"/>
        <id>/posts/magic-urls/</id>
        
        <content type="html" xml:base="/posts/magic-urls/">&lt;p&gt;Because of the distributed nature of Ubuntu development, it is sometimes a
little difficult for me to keep track of the &quot;special&quot; URLs for various
actions or reports that I&#x27;m regularly interested in.&lt;&#x2F;p&gt;
&lt;p&gt;Therefore I started gathering them in my personal wiki (I use the excellent
&lt;a href=&quot;http:&#x2F;&#x2F;zim-wiki.org&#x2F;&quot;&gt;&quot;zim&quot; desktop wiki&lt;&#x2F;a&gt;), and realized some of my colleagues
and friends would be interested in that list as well. I&#x27;ll do my best to keep
this blog post up-to-date as I discover new ones.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;magic.png&quot; alt=&quot;A magic book&quot; title=&quot;Not quite a list of spells&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;If you know of other candidates for this list, please don&#x27;t hesitate to &lt;a href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;3baal&quot;&gt;get in
touch&lt;&#x2F;a&gt;!&lt;&#x2F;p&gt;
&lt;p&gt;Behold, tribaal&#x27;s &quot;secret URL&quot; list!&lt;&#x2F;p&gt;
&lt;h3 id=&quot;pending-srus&quot;&gt;Pending SRUs&lt;&#x2F;h3&gt;
&lt;p&gt;Once a package has been uploaded to a -proposed pocket, it needs to be verified
as per &lt;a href=&quot;https:&#x2F;&#x2F;wiki.ubuntu.com&#x2F;StableReleaseUpdates&quot;&gt;the SRU process&lt;&#x2F;a&gt;.
Packages pending
&lt;a href=&quot;https:&#x2F;&#x2F;wiki.ubuntu.com&#x2F;QATeam&#x2F;PerformingSRUVerification&quot;&gt;verification&lt;&#x2F;a&gt; end up
in this list.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;people.canonical.com&#x2F;~ubuntu-archive&#x2F;pending-sru.html&quot;&gt;https:&#x2F;&#x2F;people.canonical.com&#x2F;~ubuntu-archive&#x2F;pending-sru.html&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;sponsorship-queue&quot;&gt;Sponsorship queue&lt;&#x2F;h3&gt;
&lt;p&gt;People who don&#x27;t have upload rights for the package they fixed need to request
sponsorship. This queue is the place to check if you&#x27;re waiting for someone to
pick it up and upload it.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;reqorts.qa.ubuntu.com&#x2F;reports&#x2F;sponsoring&#x2F;&quot;&gt;http:&#x2F;&#x2F;reqorts.qa.ubuntu.com&#x2F;reports&#x2F;sponsoring&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;upload-queue&quot;&gt;Upload queue&lt;&#x2F;h3&gt;
&lt;p&gt;A log of what got uploaded (and to which pocket) for a particular release, and
also a queue of packages that have been uploaded and are now waiting for review
before entering the archive.&lt;&#x2F;p&gt;
&lt;p&gt;For the active development release this is for brand new packages, for frozen
releases these are SRU packages. Once approved at this step, the packages
enter -proposed.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;launchpad.net&#x2F;ubuntu&#x2F;xenial&#x2F;+queue?queue_state=1&quot;&gt;https:&#x2F;&#x2F;launchpad.net&#x2F;ubuntu&#x2F;xenial&#x2F;+queue?queue_state=1&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-launchpad-build-farm&quot;&gt;The launchpad build farm&lt;&#x2F;h3&gt;
&lt;p&gt;A list of all the builders Launchpad currently has, broken down by
architecture. You can look at jobs being built in real time, and the occupation
level of the whole build farm in here as well.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;launchpad.net&#x2F;builders&quot;&gt;https:&#x2F;&#x2F;launchpad.net&#x2F;builders&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;proposed-migration-excuses&quot;&gt;Proposed migration excuses&lt;&#x2F;h3&gt;
&lt;p&gt;For the currently in-development Ubuntu release, packages are first uploaded to
-proposed, then a set of conditions need to be met before it can be promoted to
the released pockets. The list of packages that have failed this automatic
migration and the reason why they haven&#x27;t can be found on this page.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;people.canonical.com&#x2F;~ubuntu-archive&#x2F;proposed-migration&#x2F;update_excuses.html&quot;&gt;https:&#x2F;&#x2F;people.canonical.com&#x2F;~ubuntu-archive&#x2F;proposed-migration&#x2F;update_excuses.html&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;merge-o-matic&quot;&gt;Merge-O-matic&lt;&#x2F;h3&gt;
&lt;p&gt;Not really a &quot;magic&quot; URL, but this system gathers information and lists for the
automatic merging system, that merges debian packages to the development
release of Ubuntu.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;merges.ubuntu.com&#x2F;&quot;&gt;https:&#x2F;&#x2F;merges.ubuntu.com&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;transitions-tracker&quot;&gt;Transitions tracker&lt;&#x2F;h3&gt;
&lt;p&gt;This page tracks transitions, which are toolchain changes or other package
updates with &quot;lots&quot; of dependencies. This tracks the dependencies build status.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;people.canonical.com&#x2F;~ubuntu-archive&#x2F;transitions&#x2F;html&#x2F;&quot;&gt;https:&#x2F;&#x2F;people.canonical.com&#x2F;~ubuntu-archive&#x2F;transitions&#x2F;html&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;component-mismatches&quot;&gt;Component mismatches&lt;&#x2F;h3&gt;
&lt;p&gt;This file tracks which packages are depended upon by packages in main via the
&quot;Recommends&quot; stanza. Some more documentation is available in the &lt;a href=&quot;https:&#x2F;&#x2F;wiki.ubuntu.com&#x2F;ArchiveAdministration#Component_Mismatches_and_Changing_Overrides&quot;&gt;Archive Admin
section of the ubuntu wiki&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;people.canonical.com&#x2F;~ubuntu-archive&#x2F;component-mismatches.txt&quot;&gt;http:&#x2F;&#x2F;people.canonical.com&#x2F;~ubuntu-archive&#x2F;component-mismatches.txt&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;A similar file is generated with proposed enabled.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;people.canonical.com&#x2F;~ubuntu-archive&#x2F;component-mismatches-proposed.txt&quot;&gt;http:&#x2F;&#x2F;people.canonical.com&#x2F;~ubuntu-archive&#x2F;component-mismatches-proposed.txt&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;kernel-sru-workflow&quot;&gt;Kernel SRU workflow&lt;&#x2F;h3&gt;
&lt;p&gt;A page tracking the state of various kernel SRUs&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;kernel.ubuntu.com&#x2F;sru&#x2F;kernel-sru-workflow.html&quot;&gt;http:&#x2F;&#x2F;kernel.ubuntu.com&#x2F;sru&#x2F;kernel-sru-workflow.html&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Serving a static blog from a Snap</title>
        <published>2017-11-29T00:00:00+00:00</published>
        <updated>2017-11-29T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/posts/serving-a-static-blog-from-a-snap/"/>
        <id>/posts/serving-a-static-blog-from-a-snap/</id>
        
        <content type="html" xml:base="/posts/serving-a-static-blog-from-a-snap/">&lt;p&gt;Out of curiosity, I decided to try and package this blog as a &lt;a href=&quot;https:&#x2F;&#x2F;snapcraft.io&quot;&gt;snap
package&lt;&#x2F;a&gt;, and it turns out to be an extremely easy and
convenient way to deploy a static blog!&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;awsnap.png&quot; alt=&quot;An image of fingers snapping, with the caption &amp;quot;aw snap&amp;quot;&quot; title=&quot;Yes, it really is that simple.&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;why&quot;&gt;Why?&lt;&#x2F;h1&gt;
&lt;p&gt;There are several advantages that the snappy packaging format bring to the
table as far as applications developers are concerned (which I am, my
application in this case being my blog).&lt;&#x2F;p&gt;
&lt;p&gt;Snapcraft makes it very easy to package things, there&#x27;s per-application jails
preventing&#x2F;sandboxing your applications&#x2F;services that basically comes for free,
and it also comes with a distribution mechanism that takes care of
auto-upgrading your snap on any platform.&lt;&#x2F;p&gt;
&lt;p&gt;Sweet!&lt;&#x2F;p&gt;
&lt;h1 id=&quot;how&quot;&gt;How?&lt;&#x2F;h1&gt;
&lt;p&gt;Since this blog is generated using &lt;a href=&quot;https:&#x2F;&#x2F;blog.getpelican.com&#x2F;&quot;&gt;the excellent &quot;pelican&quot; static blog
generator&lt;&#x2F;a&gt; from a bunch of markdown articles and
a theme, there&#x27;s not a lot of things to package in the first place :)&lt;&#x2F;p&gt;
&lt;h2 id=&quot;a-webserver-for-the-container-age&quot;&gt;A webserver for the container age&lt;&#x2F;h2&gt;
&lt;p&gt;A static blog obviously needs to be served by a webserver.&lt;&#x2F;p&gt;
&lt;p&gt;Packaging a &quot;full&quot; traditional webserver like apache2 (what I used before) or
nginx is a little outside the scope of what I would have liked to do with my
spare time, so I looked around for another way to serve it.&lt;&#x2F;p&gt;
&lt;p&gt;Requirements:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;A static files webserver.&lt;&#x2F;li&gt;
&lt;li&gt;Able to set headers for cache control and HSTS.&lt;&#x2F;li&gt;
&lt;li&gt;Ideally self-contained &#x2F; statically linked (because snapping the whole would
be much faster&#x2F;easier this way)&lt;&#x2F;li&gt;
&lt;li&gt;SSL ready. I&#x27;ve had an A+ rating on SSLlabs for years and intend to keep it
that way.&lt;&#x2F;li&gt;
&lt;li&gt;Easy to configure.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;After toying with the idea to write my own in
&lt;a href=&quot;https:&#x2F;&#x2F;www.rust-lang.org&quot;&gt;rust&lt;&#x2F;a&gt;, I instead settled on an already existing
project that fits the bill perfectly and is amazingly easy to deploy and
configure - &lt;a href=&quot;https:&#x2F;&#x2F;caddyserver.com&#x2F;&quot;&gt;Caddy&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;a-little-bit-of-snapcraft-magic&quot;&gt;A little bit of snapcraft magic&lt;&#x2F;h2&gt;
&lt;p&gt;Of course, a little bit of code was needed in the snapcraft recipe to make it
all happen.&lt;&#x2F;p&gt;
&lt;p&gt;All of the code is available on &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;chrisglass&#x2F;pelican-snap&quot;&gt;a github
project&lt;&#x2F;a&gt;, and most of the logic can
be found in &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;chrisglass&#x2F;pelican-snap&#x2F;blob&#x2F;master&#x2F;snap&#x2F;snapcraft.yaml&quot;&gt;the snapcraft.yaml
file&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Simply copying the &lt;em&gt;Caddyfile&lt;&#x2F;em&gt; and the &lt;em&gt;snap&#x2F;&lt;&#x2F;em&gt; subfolder to your existing
pelican project should be all you need to get going, then run the following to
get a snap package:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;shell&quot; class=&quot;language-shell &quot;&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;# On an Ubuntu system.
snap install snapcraft
snapcraft
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;With your site&#x27;s FQDN added to the Caddyfile and pushed to production, you can
marvel at all the code and configuration you did &lt;em&gt;not&lt;&#x2F;em&gt; have to write to get &lt;a href=&quot;https:&#x2F;&#x2F;www.ssllabs.com&#x2F;ssltest&#x2F;analyze.html?d=tribaal.io&quot;&gt;an
A+ rating&lt;&#x2F;a&gt; with
SSLlabs :)&lt;&#x2F;p&gt;
&lt;h2 id=&quot;questions-comments&quot;&gt;Questions? Comments?&lt;&#x2F;h2&gt;
&lt;p&gt;As usual, feel free to &lt;a href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;3baal&quot;&gt;reach out&lt;&#x2F;a&gt; with any question
or comment you may have!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Running an Ubuntu mirror with Juju!</title>
        <published>2017-08-31T00:00:00+00:00</published>
        <updated>2017-08-31T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/posts/running-an-ubuntu-mirror-with-juju/"/>
        <id>/posts/running-an-ubuntu-mirror-with-juju/</id>
        
        <content type="html" xml:base="/posts/running-an-ubuntu-mirror-with-juju/">&lt;p&gt;Running a mirror for your favorite distribution is much easier than it sounds
when leveraging the right tools (and the work of others, including yours
truly).&lt;&#x2F;p&gt;
&lt;p&gt;You might be interested to see what we (the Public Cloud team and Web
Operations team at Canonical) developed over the years to mirror the Ubuntu
archives for our cloud partners (taking a hybrid cache approach).&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s been available as free software from the start but perhaps lacked a little
bit of visibility, not being &lt;a href=&quot;https:&#x2F;&#x2F;launchpad.net&#x2F;ubuntu-repository-cache&quot;&gt;a top-level project in
launchpad&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;objects-in-mirror.png&quot; alt=&quot;A rear view mirror&quot; title=&quot;They *are*
closer!&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;traditional-approaches-to-building-local-archive-mirrors&quot;&gt;Traditional approaches to building local archive mirrors&lt;&#x2F;h2&gt;
&lt;p&gt;There are generally two main strategies when it comes to archive mirroring: an
actual mirror of everything, or a cache of everything.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;1-mirroring-everything&quot;&gt;1. Mirroring everything&lt;&#x2F;h3&gt;
&lt;p&gt;The go-to solution for this particular strategy is either to roll your own sync
scripts, or use something like &lt;a href=&quot;https:&#x2F;&#x2F;launchpad.net&#x2F;ubumirror&quot;&gt;ubumirror&lt;&#x2F;a&gt; as
I&#x27;ve &lt;a href=&quot;https:&#x2F;&#x2F;tribaal.io&#x2F;full-ubuntu-mirror-trusty.html&quot;&gt;written about in a previous blog
post&lt;&#x2F;a&gt;, to rsync all of the
archive&#x27;s contents to a local disk.&lt;&#x2F;p&gt;
&lt;p&gt;This might be a good solution for places with very limited bandwidth (the
initial sync being done with a good old hard drive, for example), but has a few
drawbacks:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;It&#x27;s very big. The whole Ubuntu archive (for amd64 and i386) sits at around
2.5Tb. That&#x27;s a lot of disk space and bandwidth.&lt;&#x2F;li&gt;
&lt;li&gt;A simple rsync script won&#x27;t usually check the consistency of the metadata,
and since the metadata transfer can take some time, it&#x27;s likely to introduce
inconsistencies. These typically manifest by &quot;hashsum mismatches&quot; errors on
the apt client side.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;2-caching-everything&quot;&gt;2. Caching everything&lt;&#x2F;h3&gt;
&lt;p&gt;This strategy usually means running squid or another caching proxy specifically
configured to be aware of debian packages and metadata layout. One such
project is &lt;a href=&quot;https:&#x2F;&#x2F;launchpad.net&#x2F;squid-deb-proxy&quot;&gt;squid-deb-proxy&lt;&#x2F;a&gt;, that will
happily cache debian packages in a sensible way.&lt;&#x2F;p&gt;
&lt;p&gt;More viable than the &quot;full mirror&quot; case, this currently still exhibits the same
metadata inconsistency problem as the full mirror option.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;3-our-strategy-a-hybrid&quot;&gt;3. Our strategy: a hybrid&lt;&#x2F;h3&gt;
&lt;p&gt;In the charm&#x27;s case, a hybrid approach was taken: the metadata (roughly, this
is everything except &lt;em&gt;pool&#x2F;&lt;&#x2F;em&gt;) is mirrored locally on a schedule, and only
served to clients once its internal consistency has been established. Thus the
package indices never produce &quot;hashsum mismatch&quot; errors.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;em&gt;pool&#x2F;&lt;&#x2F;em&gt; part of the archive is then cached using squid3. This means that
with default settings disk space requirements are much lower than a full
mirror, and the hit rate much better than mirroring everything under the sun
(most packages having a very small chance of being used - even more so in a
cloud environment).&lt;&#x2F;p&gt;
&lt;p&gt;As an added benefit, running the charm means you&#x27;re running the exact same
software that our infrastructure team runs in the biggest public clouds in the
world - and benefit from the same vigilance and expertise that we apply to our
own systems. For free.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;deploying-your-own-caching-mirror-with-juju&quot;&gt;Deploying your own caching mirror with juju&lt;&#x2F;h2&gt;
&lt;p&gt;For this deployment we&#x27;ll first need to configure Juju. If it&#x27;s not your first
time playing with Juju you can skip right ahead to the juicy bits :)&lt;&#x2F;p&gt;
&lt;p&gt;This is intended to kick-start a deployment on a local LXD (as an example), but
of course will work on any other cloud supported by juju. For a more detailed
introduction to juju please refer to &lt;a href=&quot;https:&#x2F;&#x2F;jujucharms.com&#x2F;docs&#x2F;stable&#x2F;getting-started&quot;&gt;the juju
documentation&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;To make sure we&#x27;re up-to-date, let&#x27;s install juju from the snap package:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo snap install --classic juju
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Juju comes with a &quot;localhost&quot; cloud leveraging LXD, since that is free
(both as in speech &lt;em&gt;and&lt;&#x2F;em&gt; as in beer), we&#x27;ll use this as a reference cloud, but
the instructions should work for any other supported cloud provider (see &lt;code&gt;juju list-clouds&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# This gives you a local LXD backed juju environment
juju bootstrap localhost
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;creating-a-charm-configuration-file&quot;&gt;Creating a charm configuration file&lt;&#x2F;h3&gt;
&lt;p&gt;Let&#x27;s ask our test deployment to only care about xenial, in order to speed up
initial sync with the upstream archives and save disk space:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;cat &amp;gt; cache.yaml &amp;lt;&amp;lt; EOF
ubuntu-repository-cache
  mirror-series: xenial
EOF
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Each series will download around 2.4Gb of metadata on creation, and then
download it again every hour. It keeps at most two copies of the metadata on disk and therefore
about 5Gb per series should be planned.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;actually-deploying-the-charms&quot;&gt;Actually deploying the charms&lt;&#x2F;h3&gt;
&lt;p&gt;As usual in Juju land, the actual deployment couldn&#x27;t be easier!&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;juju deploy --config=cache.yaml ubuntu-repository-cache
juju deploy haproxy
juju add-relation ubuntu-repository-cache haproxy
juju expose haproxy
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If you&#x27;re using a local deployment, you can see that juju spawned 3 LXD
containers: one juju controller, an HAproxy machine and the archive charm
itself.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;scaling-our-deployment&quot;&gt;Scaling our deployment&lt;&#x2F;h3&gt;
&lt;p&gt;You can then scale the archive cluster up by simply running&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;juju add-unit ubuntu-repository-charm
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;using-our-fresh-new-archive&quot;&gt;Using our fresh new archive&lt;&#x2F;h2&gt;
&lt;p&gt;Simply pointing apt at the newly exposed HAproxy (public) IP address should
just work!&lt;&#x2F;p&gt;
&lt;p&gt;Here&#x27;s an example snippet to add to your sources.list configuration file:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;deb http:&amp;#x2F;&amp;#x2F;&amp;lt;HAproxy&amp;#x27;s IP address&amp;gt;&amp;#x2F;ubuntu&amp;#x2F; xenial main universe
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;our-deployments-in-the-clouds&quot;&gt;Our deployments in the clouds&lt;&#x2F;h2&gt;
&lt;p&gt;This is the charm that serves the Ubuntu archives for most of the cloud
instances you boot on the major cloud providers. We have one deployment per
cloud region, and make sure &lt;a href=&quot;https:&#x2F;&#x2F;cloud-init.io&#x2F;&quot;&gt;cloud-init&lt;&#x2F;a&gt; sets the
default ubuntu archive&#x27;s address to them when relevant.&lt;&#x2F;p&gt;
&lt;p&gt;For a production deployment we use at least 2 ubuntu-repository-cache instances
(&lt;strong&gt;juju deploy -n 2 ubuntu-repository-cache&lt;&#x2F;strong&gt;) behind 2 HAproxy instances
(&lt;strong&gt;juju deploy -n 2 haproxy&lt;&#x2F;strong&gt;) that are balanced with DNS round-robin.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;ubuntu-repository-cache-diagram.png&quot; alt=&quot;A diagram of our deployments in the clouds&quot; title=&quot;Thanks for the
drawing, Francis!&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;disk-and-memory-sizing-for-the-ubuntu-repository-cache-units&quot;&gt;Disk and memory sizing for the ubuntu-repository-cache units&lt;&#x2F;h3&gt;
&lt;p&gt;The squid cache space is computed based on available memory and disk space.&lt;&#x2F;p&gt;
&lt;p&gt;On a machine with 12Gb of RAM and 300Gb of root disk, the following usage is
observed: &lt;strong&gt;~200Gb&lt;&#x2F;strong&gt; of disk space dedicated to package caching, plus about
&lt;strong&gt;22Gb&lt;&#x2F;strong&gt; of disk for the default series metadata (the default behavior, in
other words, what you get without passing a configuration file when deploying).&lt;&#x2F;p&gt;
&lt;p&gt;You can replicate this setup easily with the following deployment command:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;juju deploy --constraints &amp;quot;mem=12G, root-disk=300G&amp;quot; ubuntu-repository-cache
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This unfortunately doesn&#x27;t work with the local LXD provider right now, but
should work with most other cloud options offered by juju.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;a-note-on-disk-size-for-the-local-provider&quot;&gt;A note on disk size for the local provider&lt;&#x2F;h3&gt;
&lt;p&gt;At the time of writing, the local substrate does not honour disk size
constraints unfortunately, so all LXD containers are created with
&lt;a href=&quot;https:&#x2F;&#x2F;bugs.launchpad.net&#x2F;juju&#x2F;+bug&#x2F;1701500&quot;&gt;a root disk of 10Gb regardless of what is specified&lt;&#x2F;a&gt;.
This only applies to the LXD substrate however, and I&#x27;m sure the problem will
be fixed in a future version.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;more-information&quot;&gt;More information&lt;&#x2F;h2&gt;
&lt;p&gt;More information about the myriad of deployment options for monitoring and
general configuration can be found in &lt;a href=&quot;https:&#x2F;&#x2F;jujucharms.com&#x2F;ubuntu-repository-cache&#x2F;&quot;&gt;the charm&#x27;s store
page&lt;&#x2F;a&gt; or by &lt;a href=&quot;https:&#x2F;&#x2F;bazaar.launchpad.net&#x2F;~tribaal&#x2F;ubuntu-repository-cache&#x2F;trunk&#x2F;files&quot;&gt;browsing the
code&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;comments-questions&quot;&gt;Comments? Questions?&lt;&#x2F;h2&gt;
&lt;p&gt;Don&#x27;t hesitate to leave a comment &lt;a href=&quot;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;Ubuntu&#x2F;comments&#x2F;6x756q&#x2F;running_an_ubuntu_mirror_with_juju&#x2F;&quot;&gt;on
Reddit&lt;&#x2F;a&gt;!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Fixing a lost right-click after switching to 17.10&#x27;s Gnome 3 and Wayland</title>
        <published>2017-08-25T00:00:00+00:00</published>
        <updated>2017-08-25T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/posts/fixing-right-click-with-gnome3-in-1710/"/>
        <id>/posts/fixing-right-click-with-gnome3-in-1710/</id>
        
        <content type="html" xml:base="/posts/fixing-right-click-with-gnome3-in-1710/">&lt;p&gt;As you are probably aware, Ubuntu decided to drop my beloved Unity desktop
environment to &lt;a href=&quot;http:&#x2F;&#x2F;www.omgubuntu.co.uk&#x2F;2017&#x2F;04&#x2F;ubuntu-will-run-wayland-default&quot;&gt;switch to Gnome 3 and
Wayland&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The transition went much smoother than I expected, and the Gnome 3 experience
delivered by the desktop team is amazing!&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;my-gnome3-desktop.png&quot; alt=&quot;My Gnome3 desktop as of today&quot; title=&quot;Nothing fancy or impressive, but it&amp;#39;s mine.&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;the-lost-right-click&quot;&gt;The lost right-click&lt;&#x2F;h1&gt;
&lt;p&gt;One small bump I hit when making the switch was that I lost the ability to
right-click with my &lt;a href=&quot;https:&#x2F;&#x2F;system76.com&quot;&gt;System76&lt;&#x2F;a&gt; Galago Ultrapro.&lt;&#x2F;p&gt;
&lt;p&gt;After looking around for a while, it turns out that the fix is very simple, but
a little hard to find: 17.10 is not released yet so any &quot;lost my
right-click&quot; post are for previous releases :)&lt;&#x2F;p&gt;
&lt;p&gt;Here&#x27;s what I had to do to get my right-click back.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;install-gnome-tweak-tool&quot;&gt;Install gnome-tweak-tool&lt;&#x2F;h2&gt;
&lt;p&gt;You can find the tool by searching for &quot;gnome tweak&quot; in the system search -
this will find the appropriate entry in the app store and allow you to download
it graphically, but otherwise you can simply use apt, as usual:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo apt install gnome-tweak-tool
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;changing-the-touchpad-settings&quot;&gt;Changing the touchpad settings&lt;&#x2F;h2&gt;
&lt;p&gt;Change your touchpad&#x27;s &quot;click method&quot; in gnome-tweak-tools to &quot;Areas&quot;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;gnome3-touchpad-properties.png&quot; alt=&quot;The gnome-tweak-tool mouse and touchpad tab&quot; title=&quot;Turns out it was that simple!&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Notice that you can set the touchpad to &quot;disabled while typing&quot; here as well,
it wasn&#x27;t set for me, although I can&#x27;t remember if that&#x27;s because I messed
around with settings before or if that&#x27;s default.&lt;&#x2F;p&gt;
&lt;p&gt;Et voilà!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Upgrading your Ubuntu-on-Windows install to the app version</title>
        <published>2017-07-11T00:00:00+00:00</published>
        <updated>2017-07-11T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/posts/upgrading-ubuntu-on-windows/"/>
        <id>/posts/upgrading-ubuntu-on-windows/</id>
        
        <content type="html" xml:base="/posts/upgrading-ubuntu-on-windows/">&lt;p&gt;Our team &lt;a href=&quot;https:&#x2F;&#x2F;blogs.msdn.microsoft.com&#x2F;commandline&#x2F;2017&#x2F;07&#x2F;10&#x2F;ubuntu-now-available-from-the-windows-store&#x2F;&quot;&gt;and
Microsoft&lt;&#x2F;a&gt;
released Ubuntu as a Windows app store application today!&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;ubuntu-on-windows.png&quot; alt=&quot;Ubuntu in the Windows store&quot; title=&quot;I never thought I&amp;#39;d see the day...&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;If you, like me, toyed with the &quot;bash on Ubuntu on Windows&quot; version before and
would like to try the latest and greatest, read on!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;saving-your-data&quot;&gt;Saving your data&lt;&#x2F;h2&gt;
&lt;p&gt;If you &quot;bash on ubuntu on windows&quot; environment has some data you&#x27;d like to
keep, make sure you back it up now. The uninstall process will nuke everything.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;uninstall-the-old-way&quot;&gt;Uninstall the old way&lt;&#x2F;h2&gt;
&lt;p&gt;This is relatively simple. Opening a command line (cmd.exe) terminal and typing&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;lxrun &amp;#x2F;uninstall
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;will destroy your previous environment.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;installing-the-new-way&quot;&gt;Installing the new way&lt;&#x2F;h2&gt;
&lt;p&gt;To find &lt;a href=&quot;https:&#x2F;&#x2F;www.microsoft.com&#x2F;en-us&#x2F;store&#x2F;p&#x2F;ubuntu&#x2F;9nblggh4msv6&quot;&gt;the app in the Microsoft
store&lt;&#x2F;a&gt;, just type
&quot;Ubuntu&quot; in the search bar.&lt;&#x2F;p&gt;
&lt;p&gt;Click install. Voilà!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Building a very simple debian package</title>
        <published>2017-06-07T00:00:00+00:00</published>
        <updated>2017-06-07T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/posts/very-simple-debian-package/"/>
        <id>/posts/very-simple-debian-package/</id>
        
        <content type="html" xml:base="/posts/very-simple-debian-package/">&lt;p&gt;I sometimes read &quot;building packages X is much easier than building .debs&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;While it is probably true that building a debian package is a little more
involved than other systems, the debian packaging system adds a lot of value
for end users, and properly packaged applications is what makes the Debian and
Ubuntu ecosystems extremely powerful.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;package.png&quot; alt=&quot;A package&quot; title=&quot;Did I tell you about snaps yet?&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This blog post will guide you through making a very simple debian package from
scratch, that simply &quot;copies&quot; files (a wallpaper, for example) where you
specify them on the target file system. That is of course not how most packages
in the Debian &amp;amp; Ubuntu archives are created since it skips a lot of the
necessary subtleties, but it is hopefully a good first step to build further
articles upon.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;tl-dr&quot;&gt;TL; DR&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# Prerequisites
apt install devscripts
name=foo
ppa_address=&amp;#x27;ppa:myuser&amp;#x2F;myppa&amp;#x27;
version=0.1
# Packaging
mkdir $package-$version
cd $package-$version
dh_make --indep --createorig
mkdir essentials
mv debian&amp;#x2F;{changelog,compat,rules,control} essentials
rm -r debian
mv essentials debian
# edit debian&amp;#x2F;control
mkdir tree
echo &amp;#x27;.&amp;#x2F;tree&amp;#x2F;* .&amp;#x2F;&amp;#x27; &amp;gt; debian&amp;#x2F;$name.install
# Add files to tree&amp;#x2F; as if &amp;#x2F;tree was &amp;#x2F; on target system
dch
debuild -S
dput $ppa_address ..&amp;#x2F;*.changes
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;anatomy-of-a-package-tree&quot;&gt;Anatomy of a package tree&lt;&#x2F;h1&gt;
&lt;p&gt;In a nutshell, a debian package tree is:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;an untarred source bundle of the upstream program&#x27;s source code.&lt;&#x2F;li&gt;
&lt;li&gt;a debian&#x2F; subdirectory that the packager&#x2F;maintainer adds to it. This
subdirectory contains all the information needed to build the surrounding
program.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;generating-a-package-skeleton-with-dh-make&quot;&gt;Generating a package skeleton with dh_make&lt;&#x2F;h1&gt;
&lt;p&gt;dh_make is a handy program that will generate a &lt;em&gt;debian&#x2F;&lt;&#x2F;em&gt; subdirectory for you,
a bit like &lt;em&gt;paster&lt;&#x2F;em&gt; would do for ruby on rails projects. It asks for questions
interactively, but for such a simple project, we don&#x27;t need most of its
features.  As usual in Ubuntu land, it all starts with:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# That pulls way more than you need, poke around!
sudo apt install devscripts
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Start by picking a package name, and a version you want you package to be. I&#x27;ll
go with the class &quot;foo&quot; and &quot;0.1&quot;, but feel free to chose something more
relevant:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;mkdir foo-0.1
cd foo-0.1
# Here we pick &amp;quot;indep&amp;quot; to specify that the package is architecture independant.
dh_make --indep --createorig
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This will have created a debian&#x2F; subdirectory in you foo-0.1 directory. You can
have a peek inside, but again, we won&#x27;t need most of it for our simple example.
Let&#x27;s narrow it down to the essentials:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;mkdir essentials
mv debian&amp;#x2F;{changelog,compat,rules,control} essentials
rm -r debian
mv essentials debian
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Our little gymnastic here recreated the debian&#x2F; subdirectory, this time with
only the most important files present.&lt;&#x2F;p&gt;
&lt;p&gt;You folder should now look like:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;foo-0.1&amp;#x2F;
└── debian
    ├── changelog
    ├── compat
    ├── control
    └── rules
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;filing-the-generated-control-file&quot;&gt;Filing the generated control file&lt;&#x2F;h1&gt;
&lt;p&gt;The control file is the file that lists all the package&#x27;s metadata, and,
roughly everything that will show up for your users when they use apt-cache to
query information about it.&lt;&#x2F;p&gt;
&lt;p&gt;While the generated control file is almost useable as-is, we&#x27;ll need to quickly
edit a couple of fields for our new package:&lt;&#x2F;p&gt;
&lt;h2 id=&quot;choosing-a-section&quot;&gt;Choosing a Section&lt;&#x2F;h2&gt;
&lt;p&gt;Sections are used to group packages related to a particular topic. You should
pick one &lt;a href=&quot;https:&#x2F;&#x2F;packages.debian.org&#x2F;unstable&#x2F;&quot;&gt;from the list&lt;&#x2F;a&gt; .&lt;&#x2F;p&gt;
&lt;p&gt;For a wallpaper package the &quot;universe&#x2F;graphics&quot; section is probably
appropriate.&lt;&#x2F;p&gt;
&lt;p&gt;This is optional however, so you as well just remove the &quot;Section:&quot; line for
our dead simple package.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;editing-the-homepage&quot;&gt;Editing the homepage&lt;&#x2F;h2&gt;
&lt;p&gt;Either add a link to a relevant website, or remove the line altogether.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;adding-a-source-control-link&quot;&gt;Adding a source control link&lt;&#x2F;h2&gt;
&lt;p&gt;If you are planning to maintain this package with a version control system
(which is a pretty good idea in general), you should add the URL to it in the
control file, as modern &lt;em&gt;dh_make&lt;&#x2F;em&gt; will have pre-filled for you.&lt;&#x2F;p&gt;
&lt;p&gt;Users of your package will get a warning message when getting the package&#x27;s
source (using &quot;apt-get source&quot; for example) telling them where the package is
maintained, and will therefore help potential contributors know how and where
to submit packaging fixes.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;adding-description-fields&quot;&gt;Adding description fields&lt;&#x2F;h2&gt;
&lt;p&gt;The most important part of this exercise: add a short and long description of
what your package does.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;adding-the-actual-files&quot;&gt;Adding the actual files&lt;&#x2F;h1&gt;
&lt;p&gt;It&#x27;s time to add the files we want to ship. For this, let&#x27;s prepare the ground
and add a &quot;tree&quot; directory in our foo-0.1 folder. That folder will be
&quot;translated&quot; into our target system&#x27;s root by the install rules we&#x27;ll create
just now:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;mkdir tree
echo &amp;#x27;.&amp;#x2F;tree&amp;#x2F;* .&amp;#x2F;&amp;#x27; &amp;gt; debian&amp;#x2F;foo.install
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Make sure to replace &quot;foo.install&quot; by &quot;&amp;lt;your_package_name&amp;gt;.install&quot;!&lt;&#x2F;p&gt;
&lt;p&gt;You can now add your files in the &quot;tree&quot; subdirectory, as if it was the target
system&#x27;s root.&lt;&#x2F;p&gt;
&lt;p&gt;For example, adding a wallpaper to a desktop install:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;mkdir -p tree&amp;#x2F;usr&amp;#x2F;share&amp;#x2F;backgrounds&amp;#x2F;
cp my_penguin_picture.png tree&amp;#x2F;usr&amp;#x2F;share&amp;#x2F;backgrounds&amp;#x2F;.
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;On the installed system, the penguin picture file will be installed in
&#x2F;usr&#x2F;share&#x2F;backgrounds&lt;&#x2F;p&gt;
&lt;p&gt;Your tree should now look like something like this:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;foo-0.1&amp;#x2F;
├── debian
│   ├── changelog
│   ├── compat
│   ├── control
│   ├── rules
│   └── foo.install
└── tree
    └── usr
        └── share
            └── backgrounds
                └── my_penguin_picture.png
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;create-a-changelog-entry&quot;&gt;Create a changelog entry&lt;&#x2F;h1&gt;
&lt;p&gt;Time to add a changelog entry to your package.&lt;&#x2F;p&gt;
&lt;p&gt;The Debian changelog is the file that tracks what changes in your package, in a
machine-readable way, and is also the file that determines what the version
number for  particular build will be.&lt;&#x2F;p&gt;
&lt;p&gt;The &quot;dch&quot; program will help you greatly in this task by doing most of the grunt
work for you. If your package were a &quot;real&quot; package to be distributed with
Ubuntu proper, you&#x27;d need to pay special attention to the version number, but
for now, we&#x27;ll just go for the easy scheme and number things like &quot;0.1&quot; then
&quot;0.2&quot; and so on.&lt;&#x2F;p&gt;
&lt;p&gt;Doing things this way is called creating a &quot;native package&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;Here&#x27;s what my example changelog looks like after editing it:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;foo (0.1) zesty; urgency=low

* Initial release. Add whatever is relevant here.

-- Christopher Glass &amp;lt;email.redacted@ubuntu.com&amp;gt;  Thu, 23 Jul 2015 18:26:05 +0300
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Make sure your name matches your GPG key&#x27;s identity exactly here, that will
make signing the packages more simple.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Important&lt;&#x2F;strong&gt;: Make sure you replace the default &quot;unstable&quot; by whatever
Ubuntu version you target! It&#x27;s a classic source of failing builds (at least
for me).&lt;&#x2F;p&gt;
&lt;h1 id=&quot;building-and-uploading-the-package&quot;&gt;Building and uploading the package&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;making-a-test-binary-deb&quot;&gt;Making a test binary deb&lt;&#x2F;h2&gt;
&lt;p&gt;Before we think about publishing our work, let&#x27;s build a test .deb file. Simply
running the following command in your top-level directory should take care of
the deb file creation:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;debuild
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;em&gt;debuild&lt;&#x2F;em&gt; will ask you for your GPG key&#x27;s passphrase, since packages are always
signed.&lt;&#x2F;p&gt;
&lt;p&gt;It will leave a fresh new debian package &lt;strong&gt;one directory up&lt;&#x2F;strong&gt; from your &lt;em&gt;foo&lt;&#x2F;em&gt;
folder. You can copy this to a test system (I suggest &lt;a href=&quot;https:&#x2F;&#x2F;linuxcontainers.org&#x2F;lxd&#x2F;introduction&#x2F;&quot;&gt;a LXD
container&lt;&#x2F;a&gt;), and install it
there, for example with &lt;em&gt;gdebi&lt;&#x2F;em&gt; or &lt;em&gt;dpkg&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;making-and-uploading-a-source-deb-to-a-ppa&quot;&gt;Making and uploading a source deb to a PPA&lt;&#x2F;h2&gt;
&lt;p&gt;Once you are happy with you test deb, it&#x27;s time to think about publishing your
work (if you want to)!&lt;&#x2F;p&gt;
&lt;p&gt;The easiest way to do this in the Ubuntu world is to create and use a free PPA
(&lt;em&gt;Personal Packages Archive&lt;&#x2F;em&gt;) on Launchpad. In &lt;a href=&quot;https:&#x2F;&#x2F;launchpad.net&#x2F;~&#x2F;&quot;&gt;your user
account&lt;&#x2F;a&gt; simply create a new PPA, and note down the
name you give it.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;ppa_button.png&quot; alt=&quot;The &amp;quot;create a PPA&amp;quot; button&quot; title=&quot;Look for this
button on the page&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;From there, you simply need to invoke the following command from your top level
foo directory to build a &lt;em&gt;source package&lt;&#x2F;em&gt;, suitable for upload to Launchpad:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# The -S stands for &amp;quot;source&amp;quot; here. Build a source package.
debuild -S
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;That will build the source package for you to upload to a PPA, and as for the
binary package, all the needed files will be stored &lt;em&gt;one directory up&lt;&#x2F;em&gt; from
your top-level directory.&lt;&#x2F;p&gt;
&lt;p&gt;PPAs do not accept binary packages, and will build the binary packages from
that source package for you. While it is trivial for this example, it is a very
nice feature for compiled programs since the Launchpad build farm will build
your packages for many different architectures for you automatically!&lt;&#x2F;p&gt;
&lt;p&gt;As for the upload itself: simply move to one level above your work directory
(where the build artifacts are put), and invoke the following command:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;dput ppa:user-name&amp;#x2F;ppa-name name_of_your_package_0.1_source.changes
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;You will receive an email at your main launchpad email address telling you that
your package was received, and that it (hopefully) build successfully!&lt;&#x2F;p&gt;
&lt;p&gt;You can then install your package by adding the PPA to your machine and
installing it using apt, as you&#x27;d expect.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo add-apt-repository --update ppa:user-name&amp;#x2F;ppa-name
sudo apt install name_of_your_package
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;next-up&quot;&gt;Next up&lt;&#x2F;h1&gt;
&lt;p&gt;Next in this series of posts, I&#x27;ll guide you through making a simple python
package, that should hopefully be more &quot;shippable&quot;, and how to do equivalent
things using &lt;a href=&quot;https:&#x2F;&#x2F;snapcraft.io&quot;&gt;snaps&lt;&#x2F;a&gt;!&lt;&#x2F;p&gt;
&lt;h1 id=&quot;comments&quot;&gt;Comments&lt;&#x2F;h1&gt;
&lt;p&gt;You can comment on this article &lt;a href=&quot;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;Ubuntu&#x2F;comments&#x2F;6fprq9&#x2F;building_a_very_simple_debian_package&#x2F;&quot;&gt;on
Reddit&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Switching themes, and Disqus</title>
        <published>2017-06-02T00:00:00+00:00</published>
        <updated>2017-06-02T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/posts/new-theme-and-disqus/"/>
        <id>/posts/new-theme-and-disqus/</id>
        
        <content type="html" xml:base="/posts/new-theme-and-disqus/">&lt;h1 id=&quot;theme-change&quot;&gt;Theme change&lt;&#x2F;h1&gt;
&lt;p&gt;As you can see, I switched themes!&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s based on &lt;a href=&quot;http:&#x2F;&#x2F;fle.github.io&#x2F;&quot;&gt;fle&lt;&#x2F;a&gt;&#x27;s very nice pelican theme,
&quot;&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;fle&#x2F;pelican-sober&quot;&gt;pelican-sober&lt;&#x2F;a&gt;&quot;. I finally
admitted to myself that maintaining a pelican theme was not a good use of my
time, nor did my blog look exceptionally nice.&lt;&#x2F;p&gt;
&lt;p&gt;I think this is a major improvement.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;comments&quot;&gt;Comments?&lt;&#x2F;h1&gt;
&lt;p&gt;This update  was also supposed to introduce &lt;a href=&quot;https:&#x2F;&#x2F;disqus.com&quot;&gt;disqus
comments&lt;&#x2F;a&gt; to this blog, a long overdue feature. I reverted
the changes because I was a little bit out of touch with recent developments -
and it turns out disqus has a pretty bad reputation for tracking users and
other &quot;nice&quot; things.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>A nicer way to mount your &#x2F;home in LXD</title>
        <published>2017-01-11T00:00:00+00:00</published>
        <updated>2017-01-11T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/posts/nicer-mounting-home-in-lxd/"/>
        <id>/posts/nicer-mounting-home-in-lxd/</id>
        
        <content type="html" xml:base="/posts/nicer-mounting-home-in-lxd/">&lt;p&gt;Some time ago I &lt;a href=&quot;https:&#x2F;&#x2F;tribaal.io&#x2F;mounting-home-in-lxd.html&quot;&gt;blogged about mounting your &#x2F;home&lt;&#x2F;a&gt; directory inside a LXD container,
and that required some slightly dirty tricks and privileged containers for it
to work.&lt;&#x2F;p&gt;
&lt;p&gt;Hopefully my colleagues working on LXD now &lt;a href=&quot;https:&#x2F;&#x2F;insights.ubuntu.com&#x2F;2016&#x2F;12&#x2F;08&#x2F;mounting-your-home-directory-in-lxd&#x2F;&quot;&gt;made it much easier&lt;&#x2F;a&gt; and cleaner to
do so, even without requiring privileged containers.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;pony.jpg&quot; alt=&quot;A pony&quot; title=&quot;But... why a pony?&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s go through things step by step, and try to provide information about how
things work along the way.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;mounting-home-read-only&quot;&gt;Mounting &#x2F;home read-only&lt;&#x2F;h1&gt;
&lt;p&gt;The basic idea is to use LXD&#x27;s devices handling to mount your host&#x27;s &#x2F;home
directory to the guest&#x27;s &#x2F;home:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;lxc init ubuntu-daily:z unmapped
lxc config device add unmapped homedir disk source=$HOME path=&amp;#x2F;home&amp;#x2F;ubuntu
lxc start unmapped
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If you need it to be read-only, then that is the only step you need to take,
since the guest&#x27;s Ubuntu user (UID 1000 inside the guest) will see your &#x2F;home
files just fine, although they will be owned by a UID and GID of &quot;65534&quot; -
nobody. The guest&#x27;s ubuntu can therefore not write to that directory, but can
see files according to normal &quot;other&quot; permissions.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;mounting-home-read-write&quot;&gt;Mounting &#x2F;home read-write&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;allowing-lxd-to-remap-your-user-id&quot;&gt;Allowing LXD to remap your user ID&lt;&#x2F;h2&gt;
&lt;p&gt;The first step for that is to allow LXD to remap your user ID.
Remember, LXD uses linux namespaces to isolate processes, and by default even
root is not allowed to reuse UIDs from the host inside containers.&lt;&#x2F;p&gt;
&lt;p&gt;We want to allow the LXD demon (running as root) to remap our host&#x27;s user ID
inside a container:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# Note: $UID is likely to be 1000 on an Ubuntu system if you&amp;#x27;re the only user.
echo &amp;quot;root:$UID:1&amp;quot; | sudo tee -a &amp;#x2F;etc&amp;#x2F;subuid &amp;#x2F;etc&amp;#x2F;subgid
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This is a one time step, you&#x27;ll never need to do this again on your host.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;remapping-your-user-id-inside-the-container&quot;&gt;Remapping your user ID inside the container&lt;&#x2F;h2&gt;
&lt;p&gt;Once LXD is allowed to remap your UID, we need to actually tell it to do it
on a per-container basis:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;lxd init ubuntu-daily:z remapped
lxc config set remapped raw.idmap &amp;quot;both $UID 1000&amp;quot;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;There is a little bit of magic-looking syntax there, but &quot;both $UID 1000&quot;
simply means &quot;map both the UID and the GID, from the host&#x27;s $UID to the guest&#x27;s
1000&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;We could instead set &quot;uid $UID 1000&quot; and &quot;gid $(id -g) 1000&quot; to be more explicit,
but the &quot;both&quot; syntax is convenient.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;mounting-home&quot;&gt;Mounting &#x2F;home&lt;&#x2F;h2&gt;
&lt;p&gt;As before, we can now mount &#x2F;home inside our container, and we should hopefully
be able to access it read-write from inside the container:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;lxc config device add remapped homedir disk source=$HOME path=&amp;#x2F;home&amp;#x2F;ubuntu
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Let&#x27;s try it now:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;lxc start remapped
# Get a root shell
lxc exec remapped &amp;#x2F;bin&amp;#x2F;bash
# Switch to our ubuntu user inside the container
su ubuntu
# create a file in &amp;#x2F;home&amp;#x2F;ubuntu inside the container
echo &amp;#x27;Opeth rocks&amp;#x27; &amp;gt;&amp;gt; $HOME&amp;#x2F;message
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Let&#x27;s look at our message form outside the container now:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;cat $HOME&amp;#x2F;message
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;putting-it-all-together&quot;&gt;Putting it all together&lt;&#x2F;h1&gt;
&lt;p&gt;Here&#x27;s a more script-like summary:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;container_name=remapped
lxc init ubuntu-daily:z $container_name
lxc config set $container_name raw.idmap &amp;quot;both $UID 1000&amp;quot;
lxc config device add $container_name homedir disk source=$HOME path=&amp;#x2F;home&amp;#x2F;ubuntu
lxc start $container_name
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Easy!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Making LXD fly on Ubuntu!</title>
        <published>2016-10-27T00:00:00+00:00</published>
        <updated>2016-10-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/posts/make-lxd-fly-on-ubuntu-as-well/"/>
        <id>/posts/make-lxd-fly-on-ubuntu-as-well/</id>
        
        <content type="html" xml:base="/posts/make-lxd-fly-on-ubuntu-as-well/">&lt;p&gt;deployment times.&lt;&#x2F;p&gt;
&lt;p&gt;Since &lt;a href=&quot;&#x2F;posts&#x2F;make-lxd-fly-on-ubuntu-as-well&#x2F;%7Bstatic%7D&#x2F;technical&#x2F;make-lxc-fly-on-ubuntu.rst&quot;&gt;my last article&lt;&#x2F;a&gt;,
lots of things happened in the container world! Instead of using LXC, I find
myself using the next great thing much much more now, namely LXC&#x27;s big
brother, &lt;a href=&quot;https:&#x2F;&#x2F;www.ubuntu.com&#x2F;cloud&#x2F;lxd&quot;&gt;LXD&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;As some people asked me, here&#x27;s my trick to make containers use my host as an
apt proxy, significantly speeding up deployment times for both manual and
juju-based workloads.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;metal_as_an_attitude.png&quot; alt=&quot;Metal As An Attitude&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;setting-up-a-cache-on-the-host&quot;&gt;Setting up a cache on the host&lt;&#x2F;h1&gt;
&lt;p&gt;First off, we&#x27;ll want to setup an apt cache on the host. As is usually the
case in the Ubuntu world, it all starts with an apt-get```&lt;&#x2F;p&gt;
&lt;p&gt;sudo apt-get install squid-deb-proxy&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;This will setup a [squid caching proxy](http:&amp;#x2F;&amp;#x2F;www.squid-cache.org&amp;#x2F;) on your
host, with a specific apt configuration listening on port 8000.

Since it is tuned for larger machines by default, I find myself wanting to make
it use a slightly smaller disk cache, using 2Gb instead of the default 40Gb is
way more reasonable on my laptop.

Simply editing the config file takes care of that```

$EDITOR &amp;#x2F;etc&amp;#x2F;squid-deb-proxy&amp;#x2F;squid-deb-proxy.conf
# Look for the &amp;quot;cache_dir aufs&amp;quot; line and replace with:
cache_dir aufs &amp;#x2F;var&amp;#x2F;cache&amp;#x2F;squid-deb-proxy 2000 16 256 # 2 gb

&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Of course you&#x27;ll need to restart the service after that```&lt;&#x2F;p&gt;
&lt;p&gt;sudo service squid-deb-proxy restart&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;# Setting up LXD

Compared to the similar procedure on LXC, setting up LXD is a breeze! LXD comes
with configuration templates, and so we can conveniently either create a new
template if we want to use the proxy selectively, or simply add the configuration
to the &amp;quot;default&amp;quot; template, and all our containers will use the proxy, always!

## In the default template

Since I never turn the proxy off on my laptop I saw no reason to apply the
proxy selectively, and simply added it to the default profile```

export LXD_ADDRESS=$(ifconfig lxdbr0 | grep &amp;#x27;inet addr:&amp;#x27; | cut -d: -f2 | awk &amp;#x27;{ print $1}&amp;#x27;)
echo -e &amp;quot;#cloud-config\napt:\n proxy: http:&amp;#x2F;&amp;#x2F;$LXD_ADDRESS:8000&amp;quot; | lxc profile set default user.user-data -

&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Of course the first part of the first command line automates the discovery of
your IP address, conveniently, as long as your LXD bridge is called &quot;lxdbr0&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;Once set in the default template, all LXD containers you start now have an apt
proxy pointing to your host set up!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;in-a-new-template&quot;&gt;In a new template&lt;&#x2F;h2&gt;
&lt;p&gt;Should you not want to alter the default template, you can easily create a new
one```&lt;&#x2F;p&gt;
&lt;p&gt;export PROFILE_NAME=proxy
lxc profile create $PROFILE_NAME&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;Then substitute the newly created profile in the previous command line. It
becomes```

export LXD_ADDRESS=$(ifconfig lxdbr0 | grep &amp;#x27;inet addr:&amp;#x27; | cut -d: -f2 | awk &amp;#x27;{ print $1}&amp;#x27;)
echo -e &amp;quot;#cloud-config\napt:\n proxy: http:&amp;#x2F;&amp;#x2F;$LXD_ADDRESS:8000&amp;quot; | lxc profile set $PROFILE_NAME user.user-data -

&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Launching a new container needs to add this configuration template, so that the
container benefits form the proxy configuration```&lt;&#x2F;p&gt;
&lt;p&gt;lxc launch ubuntu:xenial -p $PROFILE_NAME -p default&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;## Reverting

If for some reason you don&amp;#x27;t want to use your host as a proxy anymore, it is
quite easy to revert the changes to the template```

lxc profile set &amp;lt;template&amp;gt; user.user-data

&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;that-s-it&quot;&gt;That&#x27;s it!&lt;&#x2F;h1&gt;
&lt;p&gt;As you can see it is trivial to set an apt proxy on LXD, and using squid-deb-proxy
on the host makes that configuration trivial.&lt;&#x2F;p&gt;
&lt;p&gt;Hope this helps!&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;LXD&#x2F;comments&#x2F;59qmgv&#x2F;making_lxd_fly_on_ubuntu&#x2F;&quot;&gt;Discussion and&#x2F;or comments welcome on Reddit!&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Brewing my first batch of mead</title>
        <published>2016-03-20T00:00:00+00:00</published>
        <updated>2016-03-20T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/posts/brewing-my-first-batch-of-mead/"/>
        <id>/posts/brewing-my-first-batch-of-mead/</id>
        
        <content type="html" xml:base="/posts/brewing-my-first-batch-of-mead/">&lt;p&gt;Our last team sprint took place in London, and there I (re) discovered mead, in
a light carbonated form. It&#x27;s bottled by &lt;a href=&quot;http:&#x2F;&#x2F;www.gosnells.co.uk&#x2F;&quot;&gt;Gosnells Mead&lt;&#x2F;a&gt;
and is absolutely delicious. This sparked my interest, and I
decided to get started brewing mead myself, since it&#x27;s almost impossible to
find in Switzerland.&lt;&#x2F;p&gt;
&lt;p&gt;Good news: mead is apparently super easy to brew - it&#x27;s been done for millenia
using the most primitive tools and equipment, so surely, I can brew my own as
well!&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;science_dog.jpg&quot; alt=&quot;I have no idea what I&amp;#39;m doing.&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;choosing-a-recipe&quot;&gt;Choosing a recipe&lt;&#x2F;h1&gt;
&lt;p&gt;Since it&#x27;s my first batch ever of anything at all and I have no idea what
I&#x27;m doing, I decided to go for &lt;a href=&quot;http:&#x2F;&#x2F;gotmead.com&#x2F;blog&#x2F;making-mead&#x2F;mead-newbee-guide&#x2F;the-newbee-guide-to-making-mead-chapter-6-the-basic-recipe&#x2F;&quot;&gt;a foolproof spiced mead recipe&lt;&#x2F;a&gt; that uses very
easy to find ingredients, including trivially found baker&#x27;s yeast instead of
harder to acquire brewer&#x27;s yeast. Real mead brewers will probably think it&#x27;s
wrong (or worse), but hey, I&#x27;ll learn how to drive before I start worrying about
tuning my engine :)&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;em&gt;carboy&lt;&#x2F;em&gt; (yay, new vocabulary!) I bought is 15 liters, so about 4 gallons. I
therefore scaled my recipe as follows:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;6.5 Kg of honey (I picked &quot;forest honey&quot; because it&#x27;s more liquid and tastes great)&lt;&#x2F;li&gt;
&lt;li&gt;3 full oranges&lt;&#x2F;li&gt;
&lt;li&gt;4 cloves&lt;&#x2F;li&gt;
&lt;li&gt;1 stick of cinnamon&lt;&#x2F;li&gt;
&lt;li&gt;Originally, 2 &quot;handfuls&quot; of raisins, increased to 4 later on.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;gathering-the-equipment&quot;&gt;Gathering the equipment&lt;&#x2F;h1&gt;
&lt;p&gt;Yet another advantage to living in the countryside: my local farming equipment
store offers everything you might need to brew your own stuff. I suspect my
neighbours (actual farmers) to all brew their own apples, prunes or grapes and
then illegally distill them for giggles. I&#x27;m not going that far, but the equipment
was easy to get anyway.&lt;&#x2F;p&gt;
&lt;p&gt;I bought the smallest &lt;em&gt;carboys&lt;&#x2F;em&gt; I could find (two of them), sealed food-grade plastic
containers of 15 liters.
The same store had the same brand of containers up to &quot;big enough for me to walk in&quot;.
I didn&#x27;t exactly have space for that in my car, so I went with the safe and
reasonable first batch size of &quot;as small as I can&quot; :)&lt;&#x2F;p&gt;
&lt;p&gt;I plan to brew a single &lt;em&gt;carboy&lt;&#x2F;em&gt;, but they were cheap so I bought a second just
in case.&lt;&#x2F;p&gt;
&lt;p&gt;Other items needed are airlocks. There are deceptively simple mechanisms, basically
liquid-filled &lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Trap_%28plumbing%29&quot;&gt;plumbing trap&lt;&#x2F;a&gt;
that lets fermentation CO² out when the vessel&#x27;s pressure is high enough.&lt;&#x2F;p&gt;
&lt;p&gt;I also needed some powerful sanitizer that doesn&#x27;t leave a taste. I went the
nuclear route and bought bleach, that I used in obviously very diluted form.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;gathering-the-ingredients&quot;&gt;Gathering the ingredients&lt;&#x2F;h1&gt;
&lt;p&gt;Obviously, getting large quantities of honey is not cheap, but I can certainly
get that relatively easily form neighbouring farms. However, raw honey can have
its own yeast and impurities, so since it&#x27;s my very first batch, I went with
homogenized, store-bought honey.&lt;&#x2F;p&gt;
&lt;p&gt;I bought 8 kg of honey from my local supermarket. All of whatever they had most
and looked tasty and liquid.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m pretty sure I&#x27;m on some sort of watch list now.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ll use only 6,5 kgs, but I originally miscalculated the quantity (I thought
the carboys were 19l instead of 15, and didn&#x27;t double check before leaving for
the store).&lt;&#x2F;p&gt;
&lt;p&gt;The rest of the ingredients were easy enough to buy - oranges, cinnamon, raisins,
and cloves.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;mead_brewing_ingredients.jpg&quot; alt=&quot;Here&amp;#39;s all my equipment and ingredients. Plastic dinosaur optional.&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I did spend a long time considering whether to buy specialist yeast (brewer&#x27;s yeast,
ideally champagne yeast or mead-specific yeast), but all the Swiss online stores
were sold out, and Amazon won&#x27;t ship yeast to me (probably because of tricky customs).&lt;&#x2F;p&gt;
&lt;p&gt;The only place that would ship them to me gave me a delivery estimate of several
weeks.&lt;&#x2F;p&gt;
&lt;p&gt;I decided to go with my locally made baker&#x27;s yeast, as the recipe I chose said it&#x27;d
be OK.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;putting-it-all-together&quot;&gt;Putting it all together&lt;&#x2F;h1&gt;
&lt;p&gt;Shopping is over, time for preparation.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;sterilization&quot;&gt;Sterilization&lt;&#x2F;h2&gt;
&lt;p&gt;As every brewing website on the planet will tell you, it&#x27;s super super important.&lt;&#x2F;p&gt;
&lt;p&gt;I went with a good old fashioned vinegar-bleach mix, since again, &quot;professional&quot;
sterilizer was hard to order&#x2F;get (although looks awesome and certainly is much
safer). Unscented bleach, of course.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Warning&lt;&#x2F;strong&gt;: mixing bleach and vinegar is a very VERY bad idea. Never do this
directly (it creates very toxic fumes - as in chemical weapon level of toxic).&lt;&#x2F;p&gt;
&lt;p&gt;I filled my &lt;em&gt;carboy&lt;&#x2F;em&gt; with tap water (15 liters), and put everything I needed to
sterilize in there. A couple of pieces didn&#x27;t fit so I also filled a salad bowl
full of water next to it.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;mead_brewing_sterilizing_carboy.jpg&quot; alt=&quot;A carboy full of home-made sanitizer.&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Add 2 table spoons of bleach to the &lt;em&gt;carboy&lt;&#x2F;em&gt;, and one to the salad bowl. Same with
vinegar (2 and 1 table spoons respectively).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;mead_brewing_sterilizing_bowl.jpg&quot; alt=&quot;A salad bowl full of sanitizer.&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Let it sit for a while (30 minutes).&lt;&#x2F;p&gt;
&lt;p&gt;Once it sat long enough, empty everything of water and let it air dry for a few
minutes (I waited 10).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;diluting-the-honey&quot;&gt;Diluting the honey&lt;&#x2F;h2&gt;
&lt;p&gt;Diluting the honey is much easier with hot water, so I filled my electric kettle
and boiled a bunch of water. I put about 2 liters of boiling water in the &lt;em&gt;carboy&lt;&#x2F;em&gt;,
then had fun emptying as much of the honey pots in there as I could.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;mead_brewing_messy_carboy.jpg&quot; alt=&quot;The carboy, full of must.&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Of course, honey is super sticky, so there was still quite a lot of it in the
almost empty pots. Another kettle of boiling water was spread between the almost
empty pots to dissolve the remaining, honey, and all of it was poured in the &lt;em&gt;carboy&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Yummy!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;adding-extras&quot;&gt;Adding extras&lt;&#x2F;h2&gt;
&lt;p&gt;As per the recipe, I washed my oranges very well, and cut them in eights before
throwing them (skin and all) in the &lt;em&gt;carboy&lt;&#x2F;em&gt;. The cloves and cinnamon were added,
and I ended up putting the very scientific &quot;2 handfuls&quot; of raisins in there.&lt;&#x2F;p&gt;
&lt;p&gt;No idea how much that actually is :)&lt;&#x2F;p&gt;
&lt;p&gt;I filled the &lt;em&gt;carboy&lt;&#x2F;em&gt; to almost the top (leaving room for eventual foam to form)
with cold water. The temperature was about 30°C, and I let it cool down further
to about 25°C before adding the yeast.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;pitching-the-yeast&quot;&gt;Pitching the yeast&lt;&#x2F;h2&gt;
&lt;p&gt;Yeast came in a gooey-doughey cube, and I put half of it in the &lt;em&gt;carboy&lt;&#x2F;em&gt; (about
20 grams).&lt;&#x2F;p&gt;
&lt;p&gt;That&#x27;s it.&lt;&#x2F;p&gt;
&lt;p&gt;I closed the airlock and put that in a corner of the room while I cleaned the
huge mess I created.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;fermentation&quot;&gt;Fermentation&lt;&#x2F;h1&gt;
&lt;p&gt;Fermentation being a very chaotic process, most websites give a rather large time
frame for your &lt;em&gt;must&lt;&#x2F;em&gt; (the mixture of honey and water) to start fermenting: between
20 minutes and 3 hours. Some website tell you to wait 24 hours, up to 72 hours (!)
before you start wondering what&#x27;s up.&lt;&#x2F;p&gt;
&lt;p&gt;The way you can tell whether fermentation is occurring is to check your airlock for
bubbles - fermentation creates CO² as a byproduct, and the purpose of your airlock
is to let it escape, while preventing potentially contaminated air from entering.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;oh-noes-nothing-happens&quot;&gt;Oh noes! Nothing happens&lt;&#x2F;h2&gt;
&lt;p&gt;I left my &lt;em&gt;carboy&lt;&#x2F;em&gt; overnight, and came back in the morning to an airlock still showing
no signs of any bubbles.&lt;&#x2F;p&gt;
&lt;p&gt;Assuming the fermentation failed for some reason, I stirred my &lt;em&gt;must&lt;&#x2F;em&gt; and added
another two handfuls of raisins (their sugar is easier for the yeast to eat, so
it acts as a natural booster in case your yeast is struggling).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;how-to-properly-fit-an-airlock&quot;&gt;How to properly fit an airlock&lt;&#x2F;h2&gt;
&lt;p&gt;I finally realised I installed my 3 parts airlock wrong - silly me!&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;mead_brewing_notice_anything_missing.jpg&quot; alt=&quot;Notice something?&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I misunderstood how the airlock worked, and supposed it was enough
to let gravity push the mobile part of the lock (the red cylinder on top) back
down, but as it turns out, it isn&#x27;t. The CO² pressure accumulating under that
part is strong enough to lift the light plastic piece completely out of the
water, and therefore, no bubbles are visible.&lt;&#x2F;p&gt;
&lt;p&gt;Duh!&lt;&#x2F;p&gt;
&lt;p&gt;Adding a rubber band to hold the mobile part in place yields immediate results:
after a few seconds, a large bubble sprayed water in my face. The airlock needs
just a little bit of liquid to work properly - and I put way too much in, so
it splashed out happily until reaching the optimal level.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;mead_brewing_airlock_with_rubberband.jpg&quot; alt=&quot;The airlock with its rubber band, properly installed. Still has way too much water.&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;letting-it-sit&quot;&gt;Letting it sit&lt;&#x2F;h2&gt;
&lt;p&gt;The last part was to find a suitable place to leave the &lt;em&gt;carboy&lt;&#x2F;em&gt; for two months.&lt;&#x2F;p&gt;
&lt;p&gt;Space is rarely an issue here (I live in an old foundry), but finding a room
that would stay at a relatively stable 20°C proved to be a bit more challenging
than I thought, especially during the cold months of winter and spring. Of course,
the old foundry is not heated...&lt;&#x2F;p&gt;
&lt;p&gt;Fortunately I bought the smallest possible &lt;em&gt;carboy&lt;&#x2F;em&gt;, so I managed to fit it in a cabinet,
close to a radiator. Since yeast doesn&#x27;t like light, the fact that it&#x27;s a
seldom-used cabinet makes it even more appropriate.&lt;&#x2F;p&gt;
&lt;p&gt;If that batch succeeds, I might start looking at refurbishing
part of the foundry into a brewery - but that&#x27;ll be if and when :)&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;mead_brewing_carboy_in_its_cabinet.jpg&quot; alt=&quot;The carboy sitting in a cabinet. Notice the lower water level in the airlock.&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;see-you-in-two-months&quot;&gt;See you in two months!&lt;&#x2F;h1&gt;
&lt;p&gt;That&#x27;s it for the preparation, I now have to do pretty much nothing at all for
a couple of months!&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ll write another blog post when it&#x27;s time to see what mother nature brewed for
me. In the mean time, feel free to &lt;a href=&quot;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;mead&#x2F;comments&#x2F;4bbh6d&#x2F;my_first_mead_a_newbies_blog_post&#x2F;&quot;&gt;leave a comment on Reddit&lt;&#x2F;a&gt; !&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Mount your &#x2F;home in LXD</title>
        <published>2016-03-14T00:00:00+00:00</published>
        <updated>2016-03-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/posts/mount-home-lxd/"/>
        <id>/posts/mount-home-lxd/</id>
        
        <content type="html" xml:base="/posts/mount-home-lxd/">&lt;p&gt;&lt;strong&gt;UPDATE&lt;&#x2F;strong&gt;: There is now &lt;a href=&quot;https:&#x2F;&#x2F;tribaal.io&#x2F;nicer-mounting-home-in-lxd.html&quot;&gt;a nicer way to mount &#x2F;home in your LXD containers&lt;&#x2F;a&gt;, please read my updated article instead.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ve used LXC to host my development environment for a long time, and since the amazing LXD is the new kid on the block I decided to go ahead and see if I could equally easily use it for my day to day usage.&lt;&#x2F;p&gt;
&lt;p&gt;Good news! I can! One feature is slightly less obvious with LXD than it was with LXC however, so after picking my colleague&#x27;s brains on this, I decided to go ahead and write this blog post.&lt;&#x2F;p&gt;
&lt;p&gt;One very convenient feature of LXC is the &lt;code&gt;-b&lt;&#x2F;code&gt; option to the container creation command line, which allows the container to mount the host user&#x27;s home inside the container. This allows, for example, several containers to work from the same files in different environments, saving disk space but allowing for testing different operating system versions or set of installed packages.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;privileged-containers&quot;&gt;Privileged containers&lt;&#x2F;h2&gt;
&lt;p&gt;For this feature to work, we&#x27;ll need to run privileged containers, since we&#x27;ll need to do mounts, and that requires root. So unfortunately we won&#x27;t be using LXD&#x27;s awesome security and isolation features for this container, but I figure that is a limitation I can live with for a development machine.&lt;&#x2F;p&gt;
&lt;p&gt;Also, remember that this will only work for the local case - the client can just as well connect to remote machines, but obviously your &#x2F;home folder won&#x27;t be present there. And you can&#x27;t migrate the container either, of course.&lt;&#x2F;p&gt;
&lt;p&gt;With all these disclaimers out of the way, telling LXD that you want a privileged container is easy:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;lxc launch ubuntu:xenial &amp;lt;container name&amp;gt; -c security.privileged=true
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;user-mangling&quot;&gt;User mangling&lt;&#x2F;h2&gt;
&lt;p&gt;The default Ubuntu images will give you a locked down machine with a single user, the &lt;code&gt;ubuntu&lt;&#x2F;code&gt; user, and no means to SSH into your new machine. You can however simply ask LXD to execute a command in your fresh container, and therefore can get a root shell there by executing &lt;code&gt;&#x2F;bin&#x2F;bash&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;We want our user inside the container to be called the same as the one outside the container, so we&#x27;ll rename the ubuntu user to whatever the outside user is called.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Warning&lt;&#x2F;strong&gt;: This &lt;code&gt;probably&lt;&#x2F;code&gt; only works if your host&#x27;s user has the same UID than the &lt;code&gt;ubuntu&lt;&#x2F;code&gt; user inside the container. This should be the case if your laptop&#x2F;dev machine has a single user, but beware of this limitation.&lt;&#x2F;p&gt;
&lt;p&gt;Getting a shell inside the container is easy:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;lxc exec &amp;lt;container name&amp;gt; &amp;#x2F;bin&amp;#x2F;bash
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Tadaaa! Root!&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s now rename the &lt;code&gt;ubuntu&lt;&#x2F;code&gt; user to whatever your user is called:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sed -i &amp;#x27;s&amp;#x2F;ubuntu&amp;#x2F;&amp;lt;new user name&amp;gt;&amp;#x2F;g&amp;#x27; &amp;#x2F;etc&amp;#x2F;{passwd,shadow,group,gshadow}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;It feels a bit dirty but it should work. And of course, like one of my colleagues so eloquently said: &quot;the beauty with containers is that if it doesn&#x27;t work, you can trash them and start again&quot; :)&lt;&#x2F;p&gt;
&lt;h2 id=&quot;resetting-the-user-password&quot;&gt;Resetting the user password&lt;&#x2F;h2&gt;
&lt;p&gt;The newly renamed &lt;code&gt;ubuntu&lt;&#x2F;code&gt; user has a locked password by default (a sane choice), so you might want to re-enable it from your in-container root shell before you log out:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;passwd &amp;lt;new user name&amp;gt;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;mounting-your-home&quot;&gt;Mounting your home&lt;&#x2F;h2&gt;
&lt;p&gt;LXD now includes a nifty feature allowing you to create &quot;devices&quot; and mount them into containers, and that is precisely what we&#x27;ll use to mount our host&#x27;s &#x2F;home&#x2F; into the container&#x27;s:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;lxc config device add &amp;lt;container name&amp;gt; homedir disk source=&amp;#x2F;home&amp;#x2F;$USER path=&amp;#x2F;home&amp;#x2F;&amp;lt;new user name you chose at the previous step&amp;gt;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This should hopefully work its magic - and you can now try to either SSH login into your instance (because &lt;code&gt;.authorized_keys&lt;&#x2F;code&gt; from your &#x2F;home should now be inside the container&#x27;s &#x2F;home folder too!), or inspect what happened with root again by executing &lt;code&gt;&#x2F;bin&#x2F;bash&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;As long as your UIDs stay in sync between the outside host and the inside container, you should be good to go.&lt;&#x2F;p&gt;
&lt;p&gt;Comments? Questions? Get in touch, or &lt;a href=&quot;https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=11290396&quot;&gt;discuss on hackernews&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Flashing a Samsung Galaxy S5 from Ubuntu</title>
        <published>2016-02-24T00:00:00+00:00</published>
        <updated>2016-02-24T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/posts/flashing-cyanogenmod-to-galaxy-s5-from-ubuntu/"/>
        <id>/posts/flashing-cyanogenmod-to-galaxy-s5-from-ubuntu/</id>
        
        <content type="html" xml:base="/posts/flashing-cyanogenmod-to-galaxy-s5-from-ubuntu/">&lt;p&gt;Unfortunately, it&#x27;s a little more involved to flash a Samsung S5 using the Heimdall
software suite on Ubuntu than it should, so I&#x27;ve compiled a list of necessary steps
to get it all working together.&lt;&#x2F;p&gt;
&lt;p&gt;The general process should normally looks like the following, as per
&lt;a href=&quot;http:&#x2F;&#x2F;wiki.cyanogenmod.org&#x2F;w&#x2F;Install_CM_for_klte&quot;&gt;Cyanogenmod&#x27;s flashing guide&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Install Heimdall&lt;&#x2F;li&gt;
&lt;li&gt;Flash &lt;a href=&quot;https:&#x2F;&#x2F;dl.twrp.me&#x2F;klte&#x2F;twrp-2.8.7.0-klte.img&quot;&gt;a custom recovery&lt;&#x2F;a&gt; partition to your phone&lt;&#x2F;li&gt;
&lt;li&gt;Copy the image you want to flash to your phone&#x27;s SD card&lt;&#x2F;li&gt;
&lt;li&gt;Copy the google applications package to your phone&#x27;s SD card&lt;&#x2F;li&gt;
&lt;li&gt;Flash both the &lt;a href=&quot;https:&#x2F;&#x2F;download.cyanogenmod.org&#x2F;?device=klte&quot;&gt;new ROM&lt;&#x2F;a&gt; and &lt;a href=&quot;http:&#x2F;&#x2F;wiki.cyanogenmod.org&#x2F;w&#x2F;Google_Apps&quot;&gt;the google apps package&lt;&#x2F;a&gt; to your device.&lt;&#x2F;li&gt;
&lt;li&gt;Reboot the phone&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;I found that the first step is actually a little more involved than it should because
the Heimdall version packaged with Ubuntu is old, so I had to compile Heimdall
from source and add some custom udev rules so that I could flash successfully.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;compiling-heimdall-from-sources-from-git-master&quot;&gt;Compiling Heimdall from sources (from git master)&lt;&#x2F;h1&gt;
&lt;p&gt;First of all, let&#x27;s get &lt;a href=&quot;https:&#x2F;&#x2F;gitlab.com&#x2F;BenjaminDobell&#x2F;Heimdall&quot;&gt;the latest sources&lt;&#x2F;a&gt; on our machine```&lt;&#x2F;p&gt;
&lt;p&gt;sudo apt-get install git
git clone https:&#x2F;&#x2F;gitlab.com&#x2F;BenjaminDobell&#x2F;Heimdall.git
cd Heimdall&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;Of course, we&amp;#x27;ll need a few build dependencies before we can actually build```

sudo apt-get install build-essential cmake zlib1g-dev qt5-default libusb-1.0-0-dev libgl1-mesa-glx libgl1-mesa-dev

&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I&#x27;m not sure why the openGL dependencies are needed, but I followed the HOWTO to
the letter and it worked.&lt;&#x2F;p&gt;
&lt;p&gt;The build step itself is a standard cmake workflow, no surprises```&lt;&#x2F;p&gt;
&lt;p&gt;mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
make&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;That will create a set of `heimdall` binaries in the current directory&amp;#x27;s bin&amp;#x2F; subfolder.

Let&amp;#x27;s check that everything worked OK with a quick test```

bin&amp;#x2F;heimdall version  # That should return whatever is the current version

&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;adding-custom-temporary-udev-rules&quot;&gt;Adding custom (temporary) udev rules&lt;&#x2F;h1&gt;
&lt;p&gt;Before we can actually flash anything we need to tell udev not to use the USB
modem driver with our phone. To do this, we simply add a custom udev rule in
&#x2F;etc&#x2F;udev&#x2F;rules.d```&lt;&#x2F;p&gt;
&lt;p&gt;sudo su -
cat &amp;gt; &#x2F;etc&#x2F;udev&#x2F;rules.d&#x2F;90-temp-samsung.rules &amp;lt;&amp;lt;EOF
ATTRS{idVendor}==&quot;04e8&quot;, ENV{ID_MM_DEVICE_IGNORE}=&quot;1&quot;
EOF&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;This bit is a bit cryptic, especially the vendor magic number. But take my word
for it, &amp;quot;**04e8**&amp;quot; is actually whatever a Samsung Galaxy S5 advertises as vendorId.

You need to restart udev and re-plug your phone in for this to work```

sudo service udev restart

&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;actually-flashing&quot;&gt;Actually flashing!&lt;&#x2F;h1&gt;
&lt;p&gt;Hurray! We should now be able to flash the downloaded recovery file to our phone with```&lt;&#x2F;p&gt;
&lt;p&gt;bin&#x2F;heimdall flash --RECOVERY &#x2F;path&#x2F;to&#x2F;the&#x2F;recovery.img --no-reboot&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;Put the custom image you intend to flash on the SD card. I didn&amp;#x27;t manage to
workaround adb not being able to adb push to teamwin&amp;#x27;s recovery image, maybe
my udev rule up there interferes with it somehow, I got stuck with adb complaining
about a lack of permissions. No worries. I&amp;#x27;ll put the file on the actual SD card
(like, plugging it in another computer, physically).

You can now reboot into recovery mode (volume up + home + power) and use the recovery
UI to flash your new system and the google apps bundle you downloaded previously.

# Remove the custom udev rule

It&amp;#x27;s now time for our custom udev rule to be removed (or commented out), since
that will otherwise prevent the system from detecting the phone as a USB modem.

If you can live without the functionality feel free to leave the rule as-is,
but I personally love to be able to just plug the phone in and let it serve as
and extra line to the world.

That&amp;#x27;s all folks! As usual, if you have questions or comments feel free to
[tweet](https:&amp;#x2F;&amp;#x2F;twitter.com&amp;#x2F;3baal) or email me.
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Back to Ubuntu and Apache2 (and a couple of suggestions)</title>
        <published>2015-10-13T00:00:00+00:00</published>
        <updated>2015-10-13T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/posts/back-to-ubuntu-and-apache2/"/>
        <id>/posts/back-to-ubuntu-and-apache2/</id>
        
        <content type="html" xml:base="/posts/back-to-ubuntu-and-apache2/">&lt;p&gt;As some of you probably &lt;a href=&quot;https:&#x2F;&#x2F;tribaal.io&#x2F;this-now-served-by-openbsd.html&quot;&gt;have read&lt;&#x2F;a&gt;, I switched this blog to using OpenBSD&#x27;s
httpd server a few days ago, because I wanted to try new things and it seemed
that httpd offered a pretty good out-of-the-box experience, with security and
sanity of the code being the main focus.&lt;&#x2F;p&gt;
&lt;p&gt;There are, however, rough edges I&#x27;ve encountered in the form of
missing features before my (simple) use case is entirely satisfied, and before
httpd can be considered a truly great webserver for static content.&lt;&#x2F;p&gt;
&lt;p&gt;Therefore I&#x27;m back on Ubuntu and Apache2 for now, until my use case can be fully
satisfied with OpenBSD&#x27;s httpd server.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;the-missing-pieces-for-me&quot;&gt;The missing pieces (for me)&lt;&#x2F;h1&gt;
&lt;p&gt;For my particular use case two features are missing from httpd before I can consider
it for production: cache control settings and client-side SSL renegotiation.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;allow-disabling-client-side-ssl-renegotiation&quot;&gt;Allow disabling client-side SSL renegotiation&lt;&#x2F;h2&gt;
&lt;p&gt;Client-side SSL renegotiation is a know vector for CPU-bound denial-of-service
attacks, where a single connection socket can be used to make the server spend
a lot of CPU cycles quite easily.&lt;&#x2F;p&gt;
&lt;p&gt;Most other HTTP servers let administrators disable client-side renegotiation to
mitigate this problem. The downside is that some applications &lt;em&gt;need&lt;&#x2F;em&gt; client-side
renegotiation, but they are a minority use case.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;suggestion&quot;&gt;Suggestion&lt;&#x2F;h3&gt;
&lt;p&gt;The relayd server (off which httpd is based) received a patch to add configuration
syntax to disable client-side renegotiation:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;text&quot; class=&quot;language-text &quot;&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;- ssl [no] client-renegotiation
    -&amp;gt; allows the interception of (&amp;quot;secure&amp;quot;) client initiated
        renegotioations, which are considered a risk in DDoS scenarios
        because many CPU cycles can be burned this way on a single TCP
        connection without an obvious way for the administrator to 
        immediately know what&amp;#x27;s happening.
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Porting this patch to httpd seems like a relatively straightforward ordeal to my
unfamiliar-with-the-code eyes.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;tracking&quot;&gt;Tracking&lt;&#x2F;h3&gt;
&lt;p&gt;Being new to OpenBSD, I wasn&#x27;t sure where to report this, but it seems that
reky&#x27;s github mirror of the http portion of the OpenBSD tree is actively looked
at, so I openened &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;reyk&#x2F;httpd&#x2F;issues&#x2F;53&quot;&gt;a github issue&lt;&#x2F;a&gt;
on there.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;cache-control-headers&quot;&gt;Cache-Control headers&lt;&#x2F;h2&gt;
&lt;p&gt;When serving static content it makes a lot of sense to let the webserver set Cache-Control
headers for some of the assets (images and CSS don&#x27;t change often in my case, if at
all). This of course allows browsers to skip some of the requests they need
to make to the webserver, since they know how long a piece of information can be
considered &quot;fresh&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;Httpd doesn&#x27;t currently support setting headers, and I can understand that it&#x27;s
a complex feature to implement that might not ever make it to the roadmap (if
there is such a thing).&lt;&#x2F;p&gt;
&lt;h1 id=&quot;i-ll-be-back&quot;&gt;I&#x27;ll be back!&lt;&#x2F;h1&gt;
&lt;p&gt;My venture in the OpenBSD universe was a positive experience, I&#x27;ll keep an eye
on the community for a bit and see if the features I&#x27;m missing get implemented.&lt;&#x2F;p&gt;
&lt;p&gt;In that case I&#x27;d of course try it again!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>This blog now served by OpenBSD!</title>
        <published>2015-07-21T00:00:00+00:00</published>
        <updated>2015-07-21T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/posts/running-on-openbsd/"/>
        <id>/posts/running-on-openbsd/</id>
        
        <content type="html" xml:base="/posts/running-on-openbsd/">&lt;p&gt;While Ubuntu is still the OS of my heart, I decided to give &lt;a href=&quot;http:&#x2F;&#x2F;www.openbsd.org&quot;&gt;OpenBSD&lt;&#x2F;a&gt; another
look, and especially their new httpd webserver, since it is extremely secure,
and like everything else on OpenBSD, extremely simple to use!&lt;&#x2F;p&gt;
&lt;p&gt;Here&#x27;s what I did to get rolling:&lt;&#x2F;p&gt;
&lt;h1 id=&quot;install-openbsd&quot;&gt;Install OpenBSD&lt;&#x2F;h1&gt;
&lt;p&gt;I decided to follow &lt;a href=&quot;http:&#x2F;&#x2F;www.tubsta.com&#x2F;2015&#x2F;04&#x2F;openbsd-on-digital-ocean&#x2F;&quot;&gt;Tubsta&#x27;s article&lt;&#x2F;a&gt;
to install OpenBSD on a &lt;a href=&quot;https:&#x2F;&#x2F;digitalocean.com&quot;&gt;DigitalOcean&lt;&#x2F;a&gt; droplet.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;configure-httpd&quot;&gt;Configure httpd&lt;&#x2F;h1&gt;
&lt;p&gt;Configuring httpd to serve my blog (a bunch of static files, generated by
&lt;a href=&quot;http:&#x2F;&#x2F;getpelican.com&quot;&gt;Pelican&lt;&#x2F;a&gt;) was a piece of cake. Here&#x27;s the complete configuration file:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;
# &amp;#x2F;etc&amp;#x2F;httpd.conf
# &amp;quot;egress&amp;quot; means &amp;quot;use the interface of the default route&amp;quot;
ext_if=&amp;quot;egress&amp;quot;
# A simple macro defining my domain name. DRY
domain=&amp;quot;tribaal.io&amp;quot;
# Run 6 child processes. The default is 3, and since I have plenty
# of RAM, I&amp;#x27;m not sacrificing much here.
prefork 6
# Set mime type according to the file name.
types { include &amp;quot;&amp;#x2F;usr&amp;#x2F;share&amp;#x2F;misc&amp;#x2F;mime.types&amp;quot; }
server $domain {
    listen on $ext_if tls port 443
    # Enable HTTP Strict Transport Security (defaults to 1 year).
    hsts
    # The webroot folder (where the static content will be served from).
    # This is in a chroot under &amp;#x2F;var&amp;#x2F;www&amp;#x2F;
    root &amp;quot;&amp;#x2F;htdocs&amp;#x2F;tribaal.io&amp;quot;
}
server $domain {
    listen on $ext_if port 80 
    # Redirect non-SSL connections to the SSL endpoint.
    block return 301 &amp;quot;https:&amp;#x2F;&amp;#x2F;$SERVER_NAME$REQUEST_URI&amp;quot;
}

&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;adding-ssl-certificates&quot;&gt;Adding SSL certificates&lt;&#x2F;h1&gt;
&lt;p&gt;My freshly renewed certificate in hand (thanks, &lt;a href=&quot;http:&#x2F;&#x2F;gandi.net&#x2F;&quot;&gt;Gandi&lt;&#x2F;a&gt;!), I simply put the files
in the default httpd locations (since that&#x27;s the only SSL service running on
the machine)```&lt;&#x2F;p&gt;
&lt;h1 id=&quot;make-a-combined-cert-with-gandhi-s-intermediate-and-my-own-certificate&quot;&gt;Make a combined cert with gandhi&#x27;s intermediate and my own certificate&lt;&#x2F;h1&gt;
&lt;p&gt;cat server.crt &amp;gt; combined.crt
cat GandiStandardSSLCA2.pem &amp;gt;&amp;gt; combined.crt
mv combined.crt &#x2F;etc&#x2F;ssl&#x2F;server.crt
mv server.key &#x2F;etc&#x2F;ssl&#x2F;private&#x2F;server.key&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;The default configuration, plus adding the hsts stanza in the configuration file
[will get you an A+ grade on SSLlabs](https:&amp;#x2F;&amp;#x2F;www.ssllabs.com&amp;#x2F;ssltest&amp;#x2F;analyze.html?d=tribaal.io).

# Add the actual blog files

Of course, I needed to scp my blog files to the correct place in the
`&amp;#x2F;var&amp;#x2F;www&amp;#x2F;htdocs&amp;#x2F;tribaal.io&amp;#x2F;` folder.

# Enable httpd

By default, nothing runs on your OpenBSD install - so simply run the following
as root to get httpd running```

# Enable running the service
echo &amp;#x27;httpd_flags=&amp;quot;&amp;quot;&amp;#x27; &amp;gt;&amp;gt; &amp;#x2F;etc&amp;#x2F;rc.conf.local
# Actually run the service
&amp;#x2F;etc&amp;#x2F;rc.d&amp;#x2F;httpd start

&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;Edit&lt;&#x2F;strong&gt;: As Mischa Peters &lt;a href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;mischapeters&#x2F;status&#x2F;623511281526571008&quot;&gt;pointed out on twitter&lt;&#x2F;a&gt;, the more canonical way to
achieve this in OpenBSD would be to use```&lt;&#x2F;p&gt;
&lt;p&gt;rcctl enable httpd # Enable the service to run
rcctl start httpd # Actually start the service&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;# And that&amp;#x27;s it!

That&amp;#x27;s all. Piece of cake :)
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Monitoring Apache2 with Landscape</title>
        <published>2014-10-24T00:00:00+00:00</published>
        <updated>2014-10-24T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/posts/monitoring-apache-connections-with-landscape/"/>
        <id>/posts/monitoring-apache-connections-with-landscape/</id>
        
        <content type="html" xml:base="/posts/monitoring-apache-connections-with-landscape/">&lt;p&gt;It is important for most sysadmins to have a clear view of the overall trend
in their production system.&lt;&#x2F;p&gt;
&lt;p&gt;Since I work on the &lt;a href=&quot;https:&#x2F;&#x2F;landscape.canonical.com&quot;&gt;Landscape&lt;&#x2F;a&gt; project,
I wanted to use it&#x27;s nifty custom graphing feature to get an understanding of
the general trends of apache connections for this blog.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;enter-custom-graphs&quot;&gt;Enter custom graphs&lt;&#x2F;h1&gt;
&lt;p&gt;Custom monitoring graph scripts are Landscape&#x27;s solution to arbitrary trend
graphing.
You can create one by navigating to &quot;Custom graphs&quot; from your main account page:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;landscape_custom_graphs.png&quot; alt=&quot;Landscape custom graph creation form&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Basically, it&#x27;s a script that is expected to return a numeric value to standard
out, that Landscape will run every 5 minutes and plot the results
in the monitoring tab of your account.&lt;&#x2F;p&gt;
&lt;p&gt;Simple as pie!&lt;&#x2F;p&gt;
&lt;h1 id=&quot;writing-a-script-to-monitor-apache-connections&quot;&gt;Writing a script to monitor apache connections&lt;&#x2F;h1&gt;
&lt;p&gt;The following script, written in Python, should allow you to plot the number of
connections to your website with minimal changes: adapt the location of
access.log to match your site, and make sure the TEMP_FILE path is unique per
machine.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;python&quot; class=&quot;language-python &quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;
#!&amp;#x2F;usr&amp;#x2F;bin&amp;#x2F;env python
import os

ACCESS_LOG=&amp;quot;&amp;#x2F;var&amp;#x2F;log&amp;#x2F;apache2&amp;#x2F;access.log&amp;quot;  # Adapt this to your needs
TEMP_FILE=&amp;quot;&amp;#x2F;tmp&amp;#x2F;apache_last_line_reqs&amp;quot;  # This should be unique per machine

last_line = None
last_line_index = None
result = 0

if os.path.exists(TEMP_FILE):
    with open(TEMP_FILE, &amp;quot;r&amp;quot;) as line_file:
        last_line = line_file.read()

logs = []
with open(ACCESS_LOG, &amp;quot;r&amp;quot;) as log_file:
    logs = log_file.readlines()

if last_line in logs:
    last_line_index = logs.index(last_line)

if last_line_index and last_line_index != len(logs) -1:
    new_logs = logs[last_line_index+1:]
    result = len(new_logs)

# Write the last line we saw in the special file for next run.
with open(TEMP_FILE, &amp;quot;w&amp;quot;) as line_file:
    line_file.write(logs[-1])

print result

&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Landscape will take care of distributing this to your machines automatically,
and will start gathering results for you.&lt;&#x2F;p&gt;
&lt;p&gt;Hope this helps!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Setting up a full Ubuntu mirror on Trusty</title>
        <published>2014-10-22T00:00:00+00:00</published>
        <updated>2014-10-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/posts/installing-an-ubuntu-mirror/"/>
        <id>/posts/installing-an-ubuntu-mirror/</id>
        
        <content type="html" xml:base="/posts/installing-an-ubuntu-mirror/">&lt;h2 id=&quot;why&quot;&gt;Why?&lt;&#x2F;h2&gt;
&lt;p&gt;As some of my readers might know, I have recently moved to live in Tanzania.
While the network here is much better than in neighbouring countries (thanks
to a big investment to roll out a shiny national fiber optics backbone), there
is no official Ubuntu archives in the country at this point, and installing
new machines daily thanks to LXC containers can get a little slow.&lt;&#x2F;p&gt;
&lt;p&gt;Since &lt;a href=&quot;http:&#x2F;&#x2F;habari.co.tz&quot;&gt;my awesome ISP&lt;&#x2F;a&gt; is running Ubuntu on pretty much
anything that is not a router, they already had a deb proxy - and they were
happy to provide bandwidth to go one step further!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-you-need&quot;&gt;What you need&lt;&#x2F;h2&gt;
&lt;p&gt;Installing a full Ubuntu mirror (full package archive, but also cdimages, the
release images, and possibly ports of Ubuntu to other architectures) is pretty
simple.&lt;&#x2F;p&gt;
&lt;p&gt;You&#x27;ll need to check a few things before we get started:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;A lot of storage space - around 1Tb without the ports, as of June 2014. While speed doesn&#x27;t hurt, the most important is that it&#x27;s safe and big.&lt;&#x2F;li&gt;
&lt;li&gt;A reasonably powerful machine, but no need for a very beefy monster either since all the machine will be doing is serving static content with apache&lt;&#x2F;li&gt;
&lt;li&gt;A lot of bandwidth for the initial sync, and a lot of time. Or a friend with an full mirror on a USB disk :)&lt;&#x2F;li&gt;
&lt;li&gt;Ideally, a set of caches between your clients and your mirror.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;using-ubumirror&quot;&gt;Using Ubumirror&lt;&#x2F;h2&gt;
&lt;p&gt;The easiest way to get a full mirror is to install the &lt;a href=&quot;https:&#x2F;&#x2F;launchpad.net&#x2F;ubumirror&quot;&gt;ubumirror package&lt;&#x2F;a&gt;.
It basically installs a few shell scripts in &lt;code&gt;&#x2F;usr&#x2F;bin&lt;&#x2F;code&gt; that wrap rsync, and a
config file in &lt;code&gt;&#x2F;etc&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Since the ubumirror in the trusty archives is unfortunately a little outdated,
let&#x27;s use the latest and greatest instead:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo add-apt-repository ppa:ubumirror-devs&amp;#x2F;ubumirror
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The package was backported from utopic, so it also sits in backports, but the
PPA is probably a safer bet (I&#x27;m the maintainer for ubumirror).&lt;&#x2F;p&gt;
&lt;p&gt;As usual in the Debian&#x2F;Ubuntu world, it all starts with a:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo apt-get install ubumirror
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;configuring-ubumirror&quot;&gt;Configuring ubumirror&lt;&#x2F;h3&gt;
&lt;p&gt;That&#x27;s the meat of the problem here, but hopefully the configuration should be
pretty straightforward.&lt;&#x2F;p&gt;
&lt;p&gt;The four most important variables to set (rather, uncomment) are the ones
controlling the actual sync: &lt;code&gt;UBUARC_DIR&lt;&#x2F;code&gt;, &lt;code&gt;UBUCDI_DIR&lt;&#x2F;code&gt;, &lt;code&gt;UBUREL_DIR&lt;&#x2F;code&gt;,
&lt;code&gt;UBUPOR_DIR&lt;&#x2F;code&gt;.
If one of these is not set, the mirror scripts won&#x27;t sync this particular
component.
Make sure the directories point to a partition with plenty of space (1Tb should
be just enough for deb packages and releases, but 2Tb is recommended).
Ports and cdimages do take quite some space, too.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;a-word-about-components&quot;&gt;A word about components&lt;&#x2F;h3&gt;
&lt;p&gt;The four components are:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;UBUARC&lt;&#x2F;strong&gt;: The ubuntu package archive. This means you can then point your
sources.list entries to your newly created mirror.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;UBUCDI&lt;&#x2F;strong&gt;: The CD archives. This includes most cd images, including cds for
flavors (kubuntu, xubuntu etc...). This includes the daily builds for the
in-development release, too, so they change relatively often (daily).&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;UBUREL&lt;&#x2F;strong&gt;: The CD images for the released distribution (the main &quot;Ubuntu&quot;
flavor).&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;UBUPOR&lt;&#x2F;strong&gt;: The ports. These are the packages for alternative architectures, such
as ARM, Power, Sparc... These will use a lot of space (roughly half a Tb per
architecture).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;running-the-initial-sync&quot;&gt;Running the initial sync&lt;&#x2F;h3&gt;
&lt;p&gt;Now that the mirror is configured, it&#x27;s time to start the sync process itself!
This will take a long, long time.
Of course, it is much faster to get the contents of &lt;code&gt;&#x2F;srv&#x2F;mirror&#x2F;&lt;&#x2F;code&gt; from a friend&#x27;s
USB disk, but even this will take a while (a USB 2 disk took more than 14 hours
last time I tried):&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo &amp;#x2F;usr&amp;#x2F;bin&amp;#x2F;ubuarchive
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This should take care of the archive sync. In a similar fashion, you can run the
other sync components:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo &amp;#x2F;usr&amp;#x2F;bin&amp;#x2F;uburelease
sudo &amp;#x2F;usr&amp;#x2F;bin&amp;#x2F;ubucdimage
sudo &amp;#x2F;usr&amp;#x2F;bin&amp;#x2F;ubuports
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;setting-up-a-regular-sync&quot;&gt;Setting up a regular sync&lt;&#x2F;h2&gt;
&lt;p&gt;Ubumirror ships with an example cron configuration file that syncs all the
components at regular, sensible intervals.&lt;&#x2F;p&gt;
&lt;p&gt;The following will copy the shipped crontab file to the relevant place:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo cp &amp;#x2F;usr&amp;#x2F;share&amp;#x2F;doc&amp;#x2F;ubumirror&amp;#x2F;examples&amp;#x2F;ubumirror.crontab &amp;#x2F;etc&amp;#x2F;cron.d&amp;#x2F;.
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Please take a second and tweak the minutes to avoid overloading the main archives
artificially at set minutes. Picking something to your liking or random is just fine.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;serving-the-content&quot;&gt;Serving the content&lt;&#x2F;h2&gt;
&lt;p&gt;We&#x27;ll use Apache for this, and the configuration is pretty simple since basically
it will be serving static content. As such, installing apache2 with the &quot;worker&quot;
model is a good idea:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo apt-get install apache2-mpm-worker
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This will pull apache2 and required dependencies.&lt;&#x2F;p&gt;
&lt;p&gt;An example apache2 configuration file that can be used almost as-is can be found
in &lt;code&gt;&#x2F;usr&#x2F;share&#x2F;doc&#x2F;ubumirror&#x2F;examples&#x2F;apache2-ubuntu-mirror.conf&lt;&#x2F;code&gt;. You can
drop it in sites-available and enable it with:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo cp &amp;#x2F;usr&amp;#x2F;share&amp;#x2F;doc&amp;#x2F;ubumirror&amp;#x2F;examples&amp;#x2F;apache2-ubuntu-mirror.conf &amp;#x2F;etc&amp;#x2F;apache2&amp;#x2F;sites-available&amp;#x2F;mirror.conf
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Remove the default website in there and don&#x27;t forget to enable the &quot;headers&quot; and
&quot;expires&quot; modules, then enable the site itself:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo a2enmod headers expires
sudo a2ensite mirror
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Restarting or reloading apache2 should do the trick.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;checking-it-all-works&quot;&gt;Checking it all works&lt;&#x2F;h2&gt;
&lt;p&gt;At this point, you should have a working mirror! Check by pointing your web
browser to the mirror on port 80, and then by pointing your sources.list entries
to it!&lt;&#x2F;p&gt;
&lt;p&gt;Don&#x27;t hesitate to get in touch if you find errors or would like some more
information about running your own mirror. I disabled comments on the blog for
now.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>GPG: Restoring a private key&#x27;s UID from a pubkey&#x27;s UID</title>
        <published>2014-07-10T00:00:00+00:00</published>
        <updated>2014-07-10T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/posts/restoring-a-private-key-uid/"/>
        <id>/posts/restoring-a-private-key-uid/</id>
        
        <content type="html" xml:base="/posts/restoring-a-private-key-uid/">&lt;h1 id=&quot;the-problem&quot;&gt;The problem&lt;&#x2F;h1&gt;
&lt;p&gt;When creating a new keypair since my old key was getting old (and insecure),
I decided to backup my private key to an undisclosed location for security.&lt;&#x2F;p&gt;
&lt;p&gt;Unfortunately I did then add a UID to my private key and forgot to re-backup
the key, which resulted in my public key have several UIDs, but my private key
showing only one when restored from backup. I did try the restore procedure,
but maybe a little &lt;em&gt;too&lt;&#x2F;em&gt; zealously and ended up nuking my .gnupg directory.&lt;&#x2F;p&gt;
&lt;p&gt;Yeah, get some sleep before you mess with gpg :)&lt;&#x2F;p&gt;
&lt;h1 id=&quot;the-solution&quot;&gt;The solution&lt;&#x2F;h1&gt;
&lt;p&gt;It is actually pretty simple to solve the problem of &quot;importing&quot; your pubkey&#x27;s
UIDs to your privkey.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;first-backup&quot;&gt;First, backup!&lt;&#x2F;h2&gt;
&lt;p&gt;Let&#x27;s not mess things any further and start with a good ol&#x27; backup of your
~&#x2F;.gnupg directory```&lt;&#x2F;p&gt;
&lt;p&gt;cp -rp ~&#x2F;.gnupg ~&#x2F;BACKUP.gnupg&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;## The plan

The idea is that the public portion of the UID is created simply as a function
of your private key and the UID string. That means recreating a UID with the
same string and the same key will be mathematically equivalent, and since
the signatures you collected are function of the public key and the UID, they
will be valid if we recreate a UID with the exact same string.

So the plan is to delete the missing UID in the *pubkey*, and then recreate the
exact same UID, which will insert it in both the pubkey and the private key.

## Deleting the missing UID(s) from the pubkey

Let&amp;#x27;s delete the missing UID from the pubkey.

It starts by editing the key```

gpg --edit-key &amp;lt;key ID&amp;gt;

&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;At the GPG prompt, select the UID that is missing in the private key. Make sure
you note down the &lt;em&gt;full&lt;&#x2F;em&gt; UID, &lt;em&gt;exactly as it appears&lt;&#x2F;em&gt;```&lt;&#x2F;p&gt;
&lt;p&gt;uid &lt;unid number&gt;&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;This will echo your pubkey UIDs back to you, and you should notice a little &amp;quot;*&amp;quot;
next to the key you selected.
Now, let&amp;#x27;s nuke it```

deluid

&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;recreating-the-same-uid&quot;&gt;Recreating the same UID&lt;&#x2F;h2&gt;
&lt;p&gt;Now that the UID is gone, let&#x27;s re-add the exact same UID to the keypair```&lt;&#x2F;p&gt;
&lt;p&gt;adduid&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;Make sure you fill in the exact same UID information as you had before!

## Don&amp;#x27;t forget to save

At the GPG prompt, make sure you save your work by issuing the following aptly
named command```

save

&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;make-sure-it-worked&quot;&gt;Make sure it worked&lt;&#x2F;h1&gt;
&lt;p&gt;You should now have your missing UIDs back in your private keyring!
Let&#x27;s check with```&lt;&#x2F;p&gt;
&lt;p&gt;gpg --list-private-keys&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;Make sure it all outputs what you expect (all the UIDs are there).

That&amp;#x27;s all! Hope it helps!
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Making LXC (and Juju) fly on Ubuntu</title>
        <published>2014-01-14T00:00:00+00:00</published>
        <updated>2014-01-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/posts/make-lxc-fly-on-ubuntu/"/>
        <id>/posts/make-lxc-fly-on-ubuntu/</id>
        
        <content type="html" xml:base="/posts/make-lxc-fly-on-ubuntu/">&lt;p&gt;you might have also been frustrated about how network-hungry LXC is,
in particular when used with Juju. I will show you how to make it
automagically use a deb packages cache, to drastically speed up
subsequent downloads and installations.&lt;&#x2F;p&gt;
&lt;p&gt;If like me you use LXC containers a lot, and are often on the road, you might
have also been frustrated about how network-hungry LXC is, in particular when
used with Juju.
I will show you how to make it automagically use a deb packages cache,
to drastically speed up subsequent downloads and installations.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;installing-the-cache-client&quot;&gt;Installing the cache client&lt;&#x2F;h1&gt;
&lt;p&gt;We&#x27;ll use a clever piece of software called &quot;squid-deb-proxy-client&quot; to do the
heavy lifting for us. On the &lt;em&gt;host&lt;&#x2F;em&gt; of your LXC installation, simply pull in
and install it with```&lt;&#x2F;p&gt;
&lt;p&gt;sudo apt-get install squid-deb-proxy-client&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;This will add a little script that detects squid-deb-proxies on your networks
via multicast DNS, so that APT will use a proxy if it finds one. More
information about this awesome piece of software [can be found here](http:&amp;#x2F;&amp;#x2F;www.linuxjournal.com&amp;#x2F;content&amp;#x2F;presenting-squid-deb-proxy-speed-your-update-downloads) .

It&amp;#x27;s great - I have a small local cache (10Gb) on my laptop (inside an LXC
container), and a bigger one on my home network (40Gb). This allows APT to
always know what is available.

# Enter LXC hooks

We don&amp;#x27;t want to have to install the package on every LXC container we spawn,
so instead, we&amp;#x27;ll inject the detected proxy setting in the container&amp;#x27;s apt
config when it boots. LXC provides a very handy &amp;quot;hooks&amp;quot; mechanism for that, so
we simply need to drop a script somewhere and add a simple config line in the
container&amp;#x27;s config file```

# In &amp;#x2F;var&amp;#x2F;lib&amp;#x2F;lxc&amp;#x2F;&amp;lt;container name&amp;gt;&amp;#x2F;config,
lxc.hook.pre-start=&amp;#x2F;path&amp;#x2F;to&amp;#x2F;an&amp;#x2F;executable&amp;#x2F;script

&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The script will now be run before LXC starts a new container. It is passed
some handy environment variables to help us tweak the container&#x27;s apt config
before it starts.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-code&quot;&gt;The code&lt;&#x2F;h2&gt;
&lt;p&gt;It&#x27;s not rocket science - simply query the little executable provided by
squid-apt-proxy-client, and write the found URLs in the container&#x27;s
&#x2F;etc&#x2F;apt&#x2F;apt.conf.d&#x2F; directory (in an aptly named &quot;50squid-deb-proxy&quot; file).&lt;&#x2F;p&gt;
&lt;p&gt;Instead of reproducing the code here, I encourage you to download it from
github instead```&lt;&#x2F;p&gt;
&lt;p&gt;curl -L http:&#x2F;&#x2F;git.io&#x2F;YlfYIQ | sudo tee &#x2F;usr&#x2F;share&#x2F;lxc&#x2F;hooks&#x2F;squid-deb-proxy-client
sudo chmod +x &#x2F;usr&#x2F;share&#x2F;lxc&#x2F;hooks&#x2F;squid-deb-proxy-client&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;As an added bonus, the script checks for similar config files in the host,
and forwards it directly to the guest. That means nested containers will also
benefit from the caches the host can see :)

You just need to edit your container&amp;#x27;s config file and point it at the hook```

# Append the following to &amp;#x2F;var&amp;#x2F;lib&amp;#x2F;lxc&amp;#x2F;&amp;lt;container&amp;gt;&amp;#x2F;config
lxc.hook.pre-start=&amp;#x2F;usr&amp;#x2F;share&amp;#x2F;lxc&amp;#x2F;hooks&amp;#x2F;squid-deb-proxy-client

&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;A small workaround is needed for the time being, where you need to grant the
pre-start hook apparmor privileges to interact with dbus. It&#x27;s quite easy
however, as simply adding```&lt;&#x2F;p&gt;
&lt;p&gt;dbus,&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;to the beginning of the `&amp;#x2F;etc&amp;#x2F;apparmor.d&amp;#x2F;abstractions&amp;#x2F;lxc&amp;#x2F;start-container` file
will do the trick. That will not be necessary in future releases of LXC in
Ubuntu, but is required at the time of this writing.

# More awesome with templates!

Even better, we can use the same technique to make creating completely new LXC
images much faster too!
Creating a container for a new Ubuntu release can take a little bit of time
since debootstrap needs to download all of the base packages, that can take
a while on a slow internet connection or when you do this several times a day.

Changing the base Ubuntu template to check for `squid-deb-proxy` servers using
the same mechanism when it&amp;#x27;s not supplied any other HTTP or apt proxy (we don&amp;#x27;t
want to override user input obviously) solves that problem.

## The code

It is a little more involved than simply adding a pre-start hook, as you&amp;#x27;ll
need to modify the Ubuntu template for this to work.

Here is an already patched version you can immediately use```

# backup your existing template
sudo mv &amp;#x2F;usr&amp;#x2F;share&amp;#x2F;lxc&amp;#x2F;templates&amp;#x2F;lxc-ubuntu &amp;#x2F;usr&amp;#x2F;share&amp;#x2F;lxc&amp;#x2F;templates&amp;#x2F;BACKUP.lxc-ubuntu
curl -L http:&amp;#x2F;&amp;#x2F;git.io&amp;#x2F;VJ7ZUQ | sudo tee &amp;#x2F;usr&amp;#x2F;share&amp;#x2F;lxc&amp;#x2F;templates&amp;#x2F;lxc-ubuntu
sudo chmod +x &amp;#x2F;usr&amp;#x2F;share&amp;#x2F;lxc&amp;#x2F;templates&amp;#x2F;lxc-ubuntu

&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Creating a new LXC container will now use the proxy for the debootstrap phase
as well!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;playing-with-juju&quot;&gt;Playing with Juju&lt;&#x2F;h2&gt;
&lt;p&gt;It all comes together quite nicely when adding the proxy pre-start hook on the
&lt;code&gt;lxc-ubuntu-cloud&lt;&#x2F;code&gt; template as well, since that will make all new containers
spawned with Juju use the cache too! Great for when you need to rapidly spawn
environments for development!```&lt;&#x2F;p&gt;
&lt;h1 id=&quot;backup-your-existing-template&quot;&gt;backup your existing template&lt;&#x2F;h1&gt;
&lt;p&gt;sudo mv &#x2F;usr&#x2F;share&#x2F;lxc&#x2F;templates&#x2F;lxc-ubuntu-cloud &#x2F;usr&#x2F;share&#x2F;lxc&#x2F;templates&#x2F;BACKUP.lxc-ubuntu-cloud
curl -L http:&#x2F;&#x2F;git.io&#x2F;CIAkrA | sudo tee &#x2F;usr&#x2F;share&#x2F;lxc&#x2F;templates&#x2F;lxc-ubuntu-cloud
sudo chmod +x &#x2F;usr&#x2F;share&#x2F;lxc&#x2F;templates&#x2F;lxc-ubuntu-cloud&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;# Conclusion

These tricks really save me a considerable amount of time on my daily business
deploying containers, and since I hope it&amp;#x27;ll help other people too I&amp;#x27;ll submit
the patched templates and new hook to the core LXC code.

Hope this helps!
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Using the i3 window manager</title>
        <published>2013-09-28T00:00:00+00:00</published>
        <updated>2013-09-28T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/posts/using-i3/"/>
        <id>/posts/using-i3/</id>
        
        <content type="html" xml:base="/posts/using-i3/">&lt;p&gt;A colleague of mine suggested that I should try tiling window managers, and
proceeded to produce a list of them, including &lt;a href=&quot;https:&#x2F;&#x2F;i3wm.org&quot;&gt;i3&lt;&#x2F;a&gt;,
&lt;a href=&quot;http:&#x2F;&#x2F;awesome.naquadah.org&#x2F;&quot;&gt;awesome&lt;&#x2F;a&gt;,
&lt;a href=&quot;https:&#x2F;&#x2F;code.google.com&#x2F;p&#x2F;wmii&#x2F;&quot;&gt;wmii&lt;&#x2F;a&gt; and &lt;a href=&quot;http:&#x2F;&#x2F;xmonad.org&#x2F;&quot;&gt;xmonad&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Having not used any tiling window manager for more than 5 seconds before, I
decided to try them, and finally settled for i3, because I got it to work in
less than 5 minutes, and it just feel &quot;right&quot; to me.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;installation&quot;&gt;Installation&lt;&#x2F;h1&gt;
&lt;p&gt;As usual on debian-based systems, it all starts with an```&lt;&#x2F;p&gt;
&lt;p&gt;sudo apt-get install i3&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;Pretty straightforward :)

The installer guides you through some kind of wizard, where the only meaningful
decision is whether to have your &amp;quot;modifier&amp;quot; key be Alt or the famous &amp;quot;windows&amp;quot;
key.

# Running i3 for the first time

i3&amp;#x27;s interface is quite minimal (to say the least). First good news, it picks
up multiple monitors without hiccups. Launching a terminal is as simple as
mod+enter.

[The documentation](http:&amp;#x2F;&amp;#x2F;i3wm.org&amp;#x2F;docs&amp;#x2F;) is great, simple but direct. I highly encourage the reader to
bookmark it for future reference.

# Some tweaks

Here&amp;#x27;s a list of tweaks I had to make to the default i3 config to make the
system behave as I wanted.

## GTK theme

i3 does not come with the GNOME bells and whistles, and so the default look for
GTK programs is quite ugly.

Hopefully, a simple edit of the i3 config file (in ~&amp;#x2F;.i3&amp;#x2F;config) makes it
beautiful again, and painless. Add the following to the bottom of that file```

exec --no-startup-id gnome-settings-daemon

&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;All &quot;exec&quot; additions need you to restart i3 to take effect (log out by pressing
mod-shift-e - &quot;e&quot; for exit).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;network-mangement&quot;&gt;Network mangement&lt;&#x2F;h2&gt;
&lt;p&gt;Out of the box, i3 has no provision for a wireless selection mechanism. While
possible, I would rather not have to fill in wireless details by hand in a
config file every time (it&#x27;s 2013!).&lt;&#x2F;p&gt;
&lt;p&gt;Adding the following exec line to the config file did the trick```&lt;&#x2F;p&gt;
&lt;p&gt;exec --no-startup-id nm-applet&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;You need to restart i3 for the change to take effect.
i3 supports gnome applets in its bottom status bar, so all is well and you can
interact with the NetworkManager applet just as you would in Unity or GNOME.

## Sound management

In the same idea, I use a lot of different pulseaudio sinks, and I wanted to be
able to switch from one output to the other easily.

Again, adding an exec line to the i3 config file was the charm```

exec --no-startup-id gnome-sound-applet

&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;You know the drill - you need to restart i3 for this to work.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;desktop-background&quot;&gt;Desktop background&lt;&#x2F;h2&gt;
&lt;p&gt;While completely unnecessary with a tiling VM since you don&#x27;t see your
background picture very often by design, I like having one, so I decided to use
&lt;code&gt;feh&lt;&#x2F;code&gt; to set the root X window (what &quot;the background&quot; is in i3) to my
favorite picture of the month. So here&#x27;s the magic exec line (as usual) to put
in your &lt;code&gt;.i3&#x2F;config&lt;&#x2F;code&gt; file, after the obvious `sudo apt-get install feh````&lt;&#x2F;p&gt;
&lt;p&gt;exec --no-startup-id feh --bg-fill &#x2F;path&#x2F;to&#x2F;penguin&#x2F;picture.jpg&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;## Locking your screen

A last nitpick for the perfect i3 desktop for me was the ability to quickly
lock my screen, ideally using the default Ubuntu lockscreen.

It&amp;#x27;s very easy, and as usual a small line in your `~&amp;#x2F;.i3&amp;#x2F;config` file does
the trick```

bindsym $mod+Shift+o exec &amp;quot;gnome-screensaver-command --lock &amp;quot;

&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Since by default $mod-shift-l is already bound to &quot;move the active window down&quot;
I opted to bind the lock to O instead. But feel free to set it to anything
else of course :)&lt;&#x2F;p&gt;
&lt;h1 id=&quot;more-tweaks&quot;&gt;More tweaks?&lt;&#x2F;h1&gt;
&lt;p&gt;I&#x27;m sure some more could be done or added to this, but so far, this was all I
needed to use i3 on a day-to-day basis.&lt;&#x2F;p&gt;
&lt;p&gt;Feel free to get in touch with me if you have more tips to share!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Steam on LXC, on Saucy</title>
        <published>2013-09-19T00:00:00+00:00</published>
        <updated>2013-09-19T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/posts/installing-steam-in-an-lxc-container-on-saucy/"/>
        <id>/posts/installing-steam-in-an-lxc-container-on-saucy/</id>
        
        <content type="html" xml:base="/posts/installing-steam-in-an-lxc-container-on-saucy/">&lt;p&gt;Steam is an awesome game and content distribution platform, but unfortunately
only runs on 32bit systems.&lt;&#x2F;p&gt;
&lt;p&gt;If like me you like to keep your main install as pure 64bits as possible, it is
possible to run Steam inside an LXC container!&lt;&#x2F;p&gt;
&lt;p&gt;The
&lt;a href=&quot;https:&#x2F;&#x2F;www.stgraber.org&#x2F;2012&#x2F;11&#x2F;16&#x2F;running-steam-in-a-lxc-container&#x2F;&quot;&gt;original article and source code by Stephane Graber&lt;&#x2F;a&gt;
works wonders in Raring, but an API change makes it fail on Saucy. I recently
repackaged the software for Saucy, so it is now trivial to have a working
Steam LXC container again!&lt;&#x2F;p&gt;
&lt;h1 id=&quot;installation&quot;&gt;Installation&lt;&#x2F;h1&gt;
&lt;p&gt;Quite simply add the &lt;code&gt;tribaal&#x2F;steam-lxc&lt;&#x2F;code&gt; PPA to your system```&lt;&#x2F;p&gt;
&lt;p&gt;sudo apt-add-repository ppa:tribaal&#x2F;steam-lxc
sudo apt-get update &amp;amp;&amp;amp; sudo apt-get install steam-lxc lxc&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;# Creating a steam LXC container

Again, creating a steam LXC container is quite easy```

sudo steam-lxc create

&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This might take a while, since it will download a base 12.04 image, update it,
install all the required libraries and finally install Steam.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;running-the-container&quot;&gt;Running the container&lt;&#x2F;h1&gt;
&lt;p&gt;Once the container is built, you can start it with the command```&lt;&#x2F;p&gt;
&lt;p&gt;sudo steam-lxc run&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;Of course, all the normal LXC commands work with the steam container, so you
can for example make sure it&amp;#x27;s running or get its IP address with the usual
listing command```

sudo lxc-ls --fancy

&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;destroying-the-container&quot;&gt;Destroying the container&lt;&#x2F;h1&gt;
&lt;p&gt;When (if) you get tired of Steam and want to reclaim the used space on your
system, you can quite simply delete the container you created using the
following```&lt;&#x2F;p&gt;
&lt;p&gt;sudo steam-lxc destroy&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;Running Steam in a container is a great idea, and hopefully the simple fix for
it to run seamlessly on Saucy will make it to the main repository to avoid
doing the PPA dance :)

Have fun!

&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Rebuilding an Ubuntu package</title>
        <published>2013-07-05T00:00:00+00:00</published>
        <updated>2013-07-05T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/posts/rebuilding-ubuntu-packages/"/>
        <id>/posts/rebuilding-ubuntu-packages/</id>
        
        <content type="html" xml:base="/posts/rebuilding-ubuntu-packages/">&lt;p&gt;In this first article about debian&#x2F;ubuntu packaging, we will learn to rebuild any
existing ubuntu package locally, to get more familiar with the various tools used
to build debian pacakges.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;getting-the-package-source&quot;&gt;Getting the package source&lt;&#x2F;h2&gt;
&lt;p&gt;Provided your &lt;code&gt;&#x2F;etc&#x2F;apt&#x2F;sources.list&lt;&#x2F;code&gt; file contains &lt;code&gt;deb-src&lt;&#x2F;code&gt; entries,
you can do the following:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;mkdir tmp
cd tmp
apt-get source $package_name
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Getting examples goes a long way in understanding something, and these simple steps
give you access to a &lt;strong&gt;lot&lt;&#x2F;strong&gt; of them.&lt;&#x2F;p&gt;
&lt;p&gt;If you don&#x27;t have deb-src entries in your sources.list file (if you are working
inside a default LXC container for example), you can easily add them with the
following command:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo sed -i &amp;#x27;s&amp;#x2F;^deb \(.*\)&amp;#x2F;deb \1\ndeb-src \1&amp;#x2F;g&amp;#x27; &amp;#x2F;etc&amp;#x2F;apt&amp;#x2F;sources.list
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;getting-the-required-tools&quot;&gt;Getting the required tools&lt;&#x2F;h2&gt;
&lt;p&gt;The second obvious step is to try and build the package you just obtained. We need
a few tools in order to do that:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo apt-get install build-essential pbuilder
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;These packages install the following:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;build-essential&lt;&#x2F;code&gt; package contains most of the useful tools to build
binaries, like a compiler, linker, and plenty of other goodies.&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;code&gt;pbuilder&lt;&#x2F;code&gt; package has all you need for the packaging itself.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Once you have the necessary tools, you will need to get the package&#x27;s &lt;em&gt;build dependencies&lt;&#x2F;em&gt;.
Build dependencies are packages needed to build a package, but not to run it. A common
example of this would be the &lt;code&gt;python-setuptools&lt;&#x2F;code&gt; package to build python pacakges, while
paramount at package building time, it is not necessary to actually use the python package.&lt;&#x2F;p&gt;
&lt;p&gt;It is quite easy to resolve and install build-dependencies for an arbitrary package:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo apt-get build-dep $package_name
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This will fetch and install all the package&#x27;s build dependencies.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rebuilding-the-package&quot;&gt;Rebuilding the package&lt;&#x2F;h2&gt;
&lt;p&gt;Packages in Debian based systems are either source packages or binary packages.
It is advisable to start by building the source pacakge, since that will allow
you to distribute your changes to a number of architectures, and to send your
newly build package to a PPA, for example.&lt;&#x2F;p&gt;
&lt;p&gt;Building a source package is easy, just cd into the pacakge&#x27;s source directory
(the directory that was created for you with the &lt;code&gt;apt-get source&lt;&#x2F;code&gt; command), and
run the following:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;debuild -S
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This will create a &lt;code&gt;*.changes&lt;&#x2F;code&gt; file in the &lt;code&gt;..&#x2F;&lt;&#x2F;code&gt; directory. You can upload this
file to a PPA pretty easily to let launchpad build the package for several
different architectures easily.&lt;&#x2F;p&gt;
&lt;p&gt;To build the corresponding binary package (at least the one for your current
architecture), run the following command instead:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;debuild
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This will create the debian package(s) in th &lt;code&gt;..&#x2F;&lt;&#x2F;code&gt; directory, once again.
You can now install these newly built packages just like you would any other
&lt;code&gt;*.deb&lt;&#x2F;code&gt; file.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;next-time&quot;&gt;Next time&lt;&#x2F;h2&gt;
&lt;p&gt;Now that we know how to rebuild packages, we&#x27;ll learn how to modify them before
rebuilding them (which is more interesting), as well as how to make your changes
available to the world using a PPA.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Hello world!</title>
        <published>2013-07-03T00:00:00+00:00</published>
        <updated>2013-07-03T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/posts/new-blog/"/>
        <id>/posts/new-blog/</id>
        
        <content type="html" xml:base="/posts/new-blog/">&lt;p&gt;A new blog is born!&lt;&#x2F;p&gt;
&lt;p&gt;I meant to do this for years, but today marks the debut of my new blog! A few
tech-related articles will be coming up.&lt;&#x2F;p&gt;
&lt;p&gt;See you soon ;)&lt;&#x2F;p&gt;
</content>
        
    </entry>
</feed>
