<?xml version="1.0" encoding="utf-8" ?>

<rss version="2.0" 
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:admin="http://webns.net/mvcb/"
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
   xmlns:wfw="http://wellformedweb.org/CommentAPI/"
   xmlns:content="http://purl.org/rss/1.0/modules/content/"
   >
<channel>
    
    <title>Code V.igoro.us</title>
    <link>http://code.v.igoro.us/</link>
    <description>Dustin J. Mitchell</description>
    <dc:language>en</dc:language>
    <generator>Serendipity 1.6 - http://www.s9y.org/</generator>
    <pubDate>Sun, 20 May 2012 14:24:17 GMT</pubDate>

    <image>
        <url>http://code.v.igoro.us/templates/default/img/s9y_banner_small.png</url>
        <title>RSS: Code V.igoro.us - Dustin J. Mitchell</title>
        <link>http://code.v.igoro.us/</link>
        <width>100</width>
        <height>21</height>
    </image>

<item>
    <title>Trapped in Google?</title>
    <link>http://code.v.igoro.us/archives/73-Trapped-in-Google.html</link>
            <category>mozilla</category>
    
    <comments>http://code.v.igoro.us/archives/73-Trapped-in-Google.html#comments</comments>
    <wfw:comment>http://code.v.igoro.us/wfwcomment.php?cid=73</wfw:comment>

    <slash:comments>1</slash:comments>
    <wfw:commentRss>http://code.v.igoro.us/rss.php?version=2.0&amp;type=comments&amp;cid=73</wfw:commentRss>
    

    <author>nospam@example.com (Dustin J. Mitchell)</author>
    <content:encoded>
    &lt;p&gt;Whenever I search in Aurora on my phone, I&#039;m taken to a stripped-down version of the page with the header &quot;this page adapted for your browser&quot;.&lt;/p&gt;

&lt;p&gt;How do I fix this?  I&#039;d rather fix it with a Google preference, but barring that I expect that Firefox has a way for me to regain control of my online experience? &lt;/p&gt;
 
    </content:encoded>

    <pubDate>Sat, 19 May 2012 18:33:24 -0500</pubDate>
    <guid isPermaLink="false">http://code.v.igoro.us/archives/73-guid.html</guid>
    
</item>
<item>
    <title>TIL about SSL certificate chains</title>
    <link>http://code.v.igoro.us/archives/72-TIL-about-SSL-certificate-chains.html</link>
            <category>mozilla</category>
            <category>Sysadmin</category>
    
    <comments>http://code.v.igoro.us/archives/72-TIL-about-SSL-certificate-chains.html#comments</comments>
    <wfw:comment>http://code.v.igoro.us/wfwcomment.php?cid=72</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://code.v.igoro.us/rss.php?version=2.0&amp;type=comments&amp;cid=72</wfw:commentRss>
    

    <author>nospam@example.com (Dustin J. Mitchell)</author>
    <content:encoded>
    &lt;p&gt;I&#039;m laying some SSL groundwork for a project to allow puppet clients to move between puppet servers without requiring a central CA, and without requiring each client to be aware of all masters.  More on that in a future post.&lt;/p&gt;

&lt;p&gt;Based on &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/projects.puppetlabs.com/projects/puppet/wiki/Multiple_Certificate_Authorities&#039;]);&quot;  href=&quot;http://projects.puppetlabs.com/projects/puppet/wiki/Multiple_Certificate_Authorities&quot;&gt;&quot;Multiple Certificate Authorities&quot;&lt;/a&gt;, I would like to have certificate chains that look like this:&lt;/p&gt;

&lt;pre&gt;
      +-puppetmaster1 CA--+-puppetmaster1 server cert
      |                   |
      |                   +-client 1 server cert
root--+                   :
      |                   
      +-puppetmaster2 CA--+-puppetmaster2 server cert
                          |
                          +-client 10 server cert
                          :
&lt;/pre&gt;

&lt;p&gt;Then all of the certificate validation would be done with the root CA certificate as the trusted certificate.  A server certificate signed by puppetmaster2&#039;s CA cert should then validate on puppetmaster1.&lt;/p&gt;

&lt;p&gt;Building the certificates wasn&#039;t all that difficult - see &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/bugzilla.mozilla.org/show_bug.cgi?id=733110#c8&#039;]);&quot;  href=&quot;https://bugzilla.mozilla.org/show_bug.cgi?id=733110#c8&quot;&gt;my comment on the bug&lt;/a&gt; for the script.  However, while making sure the verification worked, I ran into some non-obvious limitations of OpenSSL that are worth writing down.&lt;/p&gt;

&lt;p&gt;I began by running &quot;openssl verify&quot;:&lt;/p&gt;

&lt;pre&gt;
[root@relabs-puptest1 ~]# openssl verify -verbose -CAfile puptest-certs/root-ca.crt -purpose sslclient puptest-certs/relabs08.build.mtv1.mozilla.com.crt 
puptest-certs/relabs08.build.mtv1.mozilla.com.crt: CN = relabs08.build.mtv1.mozilla.com, emailAddress = release@mozilla.com, O = &quot;Mozilla, Inc.&quot;, OU = Release Engineering
error 20 at 0 depth lookup:unable to get local issuer certificate
&lt;/pre&gt;

&lt;p&gt;the problem here is that the intermediate certificate is not available to the verification tool.  Sources suggest to include it with the server cert, by concatention, with the server cert last:&lt;/p&gt;

&lt;pre&gt;
cat puptest-certs/relabs-puptest1.build.mtv1.mozilla.com-ca.crt puptest-certs/relabs08.build.mtv1.mozilla.com.crt &gt; relabs08-with-intermed.crt
&lt;/pre&gt;

&lt;p&gt;However, after some struggle I learned that &quot;openssl verify&quot; does not recognize this format -- it will only look at the first certificate in the file (the intermediate), and if you don&#039;t look carefully you&#039;ll find that it successfully verifies the intermediate, not the server certificate!  Sadly, s&lt;em&gt;client and s&lt;/em&gt;sever don&#039;t support it either.  Apache httpd supports it with &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/httpd.apache.org/docs/2.2/mod/mod_ssl.html#sslcacertificatepath&#039;]);&quot;  href=&quot;http://httpd.apache.org/docs/2.2/mod/mod_ssl.html#sslcacertificatepath&quot;&gt;SSLCACertificatePath&lt;/a&gt;.  This will feed the certificate chain to the client, and also allow httpd to verify client certificates without requiring the clients to support an intermediate.&lt;/p&gt;

&lt;p&gt;The Apache config is&lt;/p&gt;

&lt;pre&gt;
Listen 1443

&amp;lt;VirtualHost *:1443&gt;
        ServerName relabs-puptest1.build.mtv1.mozilla.com
        SSLEngine on
        SSLProtocol -ALL +SSLv3 +TLSv1
        SSLCipherSuite ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:-LOW:-SSLv2:-EXP

        SSLCertificateFile /etc/httpd/relabs-puptest1.build.mtv1.mozilla.com.crt
        SSLCertificateKeyFile /etc/httpd/relabs-puptest1.build.mtv1.mozilla.com.key
        SSLCACertificatePath /etc/httpd/ca-path

        # If Apache complains about invalid signatures on the CRL, you can try disabling
        # CRL checking by commenting the next line, but this is not recommended.
        #SSLCARevocationFile     /etc/puppet/ssl/ca/ca_crl.pem
        SSLVerifyClient require
        SSLVerifyDepth  2

&amp;lt;/VirtualHost&gt;
&lt;/pre&gt;

&lt;p&gt;While you&#039;re getting that set up, you&#039;re probably wondering where to get this fancy &quot;c_rehash&quot; utility.  Don&#039;t bother.  It&#039;s about as simple as:&lt;/p&gt;

&lt;pre&gt;
for i in *.crt; do
        h=`openssl x509 -hash -noout -in $i`
        rm -f $h.0
        ln -s $i $h.0
done
&lt;/pre&gt;

&lt;p&gt;As a side-note, the results of verification by s&lt;em&gt;client and s&lt;/em&gt;server are not very obvious.  Look for the overall error message near the bottom of the output.  Here&#039;s the result of a client verification once I had everything put together, with some long uselessness elided:&lt;/p&gt;

&lt;pre&gt;
[root@relabs-puptest1 ~]# openssl s_client -verify 2 -CAfile puptest-certs/root-ca.crt -cert puptest-certs/relabs08.build.mtv1.mozilla.com.crt -key puptest-certs/relabs08.build.mtv1.mozilla.com.key -pass pass:clientpass -connect localhost:1443
verify depth is 2
CONNECTED(00000003)
depth=2 CN = PuppetAgain Root CA, emailAddress = release@mozilla.com, OU = Release Engineering, O = &quot;Mozilla, Inc.&quot;
verify return:1
depth=1 CN = CA on relabs-puptest1.build.mtv1.mozilla.com, emailAddress = release@mozilla.com, O = &quot;Mozilla, Inc.&quot;, OU = Release Engineering
verify return:1
depth=0 CN = relabs-puptest1.build.mtv1.mozilla.com, emailAddress = release@mozilla.com, O = &quot;Mozilla, Inc.&quot;, OU = Release Engineering
verify return:1
---
Certificate chain
 0 s:/CN=relabs-puptest1.build.mtv1.mozilla.com/emailAddress=release@mozilla.com/O=Mozilla, Inc./OU=Release Engineering
   i:/CN=CA on relabs-puptest1.build.mtv1.mozilla.com/emailAddress=release@mozilla.com/O=Mozilla, Inc./OU=Release Engineering
 1 s:/CN=CA on relabs-puptest1.build.mtv1.mozilla.com/emailAddress=release@mozilla.com/O=Mozilla, Inc./OU=Release Engineering
   i:/CN=PuppetAgain Root CA/emailAddress=release@mozilla.com/OU=Release Engineering/O=Mozilla, Inc.
 2 s:/CN=PuppetAgain Root CA/emailAddress=release@mozilla.com/OU=Release Engineering/O=Mozilla, Inc.
   i:/CN=PuppetAgain Root CA/emailAddress=release@mozilla.com/OU=Release Engineering/O=Mozilla, Inc.
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIEeTCCA2GgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBkTE1MDMGA1UEAxMsQ0Eg
...
H90rZMVxsVyPHjjfXkeeFcSWyUnV/z3G9osrI9I9SaQ1o9bDc7ZheyHbWbhn
-----END CERTIFICATE-----
subject=/CN=relabs-puptest1.build.mtv1.mozilla.com/emailAddress=release@mozilla.com/O=Mozilla, Inc./OU=Release Engineering
issuer=/CN=CA on relabs-puptest1.build.mtv1.mozilla.com/emailAddress=release@mozilla.com/O=Mozilla, Inc./OU=Release Engineering
---
Acceptable client certificate CA names
/CN=PuppetAgain Root CA/emailAddress=release@mozilla.com/OU=Release Engineering/O=Mozilla, Inc.
/CN=CA on relabs-puptest1.build.mtv1.mozilla.com/emailAddress=release@mozilla.com/O=Mozilla, Inc./OU=Release Engineering
/CN=CA on relabs-puptest2.build.mtv1.mozilla.com/emailAddress=release@mozilla.com/O=Mozilla, Inc./OU=Release Engineering
---
SSL handshake has read 5379 bytes and written 1716 bytes
---
---
New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: zlib compression
Expansion: zlib compression
SSL-Session:
    Protocol  : TLSv1
    Cipher    : DHE-RSA-AES256-SHA
    Session-ID: E30634D9CFCC2FA327282DA813BB550C24ACDF18194E5F13C4981AA55914B5F0
    Session-ID-ctx: 
    Master-Key: 013EB09B066418694D36D74B414BBA42E52DBF0066314B60FC7A74662A60934282B6C37C5C82026F70287E60F4FF9472
    Key-Arg   : None
    Krb5 Principal: None
    PSK identity: None
    PSK identity hint: None
    TLS session ticket:
    0000 - 82 5f 17 72 97 bd f3 1e-ec 24 de 69 ab 1e cd 1d   ._.r.....$.i....
    ....
    0520 - 40 05 b3 27 20 00 8d ce-93 a9 48 81 8f 0c 16 5b   @..&#039; .....H....[

    Compression: 1 (zlib compression)
    Start Time: 1336582165
    Timeout   : 300 (sec)
    Verify return code: 0 (ok)
---
&lt;/pre&gt;

&lt;p&gt;note the &quot;Verify return code&quot; at the bottom. &lt;/p&gt;

&lt;p&gt;By way of demonstration that the server is actually checking those certs:&lt;/p&gt;

&lt;pre&gt;
[root@relabs-puptest1 ~]# openssl s_client -verify 2 -CAfile puptest-certs/root-ca.crt -cert bogus.crt -key bogus.key -pass pass:boguspass -connect localhost:1443
verify depth is 2
CONNECTED(00000003)
depth=2 CN = PuppetAgain Root CA, emailAddress = release@mozilla.com, OU = Release Engineering, O = &quot;Mozilla, Inc.&quot;
verify return:1
depth=1 CN = CA on relabs-puptest1.build.mtv1.mozilla.com, emailAddress = release@mozilla.com, O = &quot;Mozilla, Inc.&quot;, OU = Release Engineering
verify return:1
depth=0 CN = relabs-puptest1.build.mtv1.mozilla.com, emailAddress = release@mozilla.com, O = &quot;Mozilla, Inc.&quot;, OU = Release Engineering
verify return:1
140283463366472:error:14094418:SSL routines:SSL3_READ_BYTES:tlsv1 alert unknown ca:s3_pkt.c:1193:SSL alert number 48
140283463366472:error:140790E5:SSL routines:SSL23_WRITE:ssl handshake failure:s23_lib.c:184:
---
Certificate chain
 0 s:/CN=relabs-puptest1.build.mtv1.mozilla.com/emailAddress=release@mozilla.com/O=Mozilla, Inc./OU=Release Engineering
   i:/CN=CA on relabs-puptest1.build.mtv1.mozilla.com/emailAddress=release@mozilla.com/O=Mozilla, Inc./OU=Release Engineering
 1 s:/CN=CA on relabs-puptest1.build.mtv1.mozilla.com/emailAddress=release@mozilla.com/O=Mozilla, Inc./OU=Release Engineering
   i:/CN=PuppetAgain Root CA/emailAddress=release@mozilla.com/OU=Release Engineering/O=Mozilla, Inc.
 2 s:/CN=PuppetAgain Root CA/emailAddress=release@mozilla.com/OU=Release Engineering/O=Mozilla, Inc.
   i:/CN=PuppetAgain Root CA/emailAddress=release@mozilla.com/OU=Release Engineering/O=Mozilla, Inc.
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIEeTCCA2GgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBkTE1MDMGA1UEAxMsQ0Eg
...
H90rZMVxsVyPHjjfXkeeFcSWyUnV/z3G9osrI9I9SaQ1o9bDc7ZheyHbWbhn
-----END CERTIFICATE-----
subject=/CN=relabs-puptest1.build.mtv1.mozilla.com/emailAddress=release@mozilla.com/O=Mozilla, Inc./OU=Release Engineering
issuer=/CN=CA on relabs-puptest1.build.mtv1.mozilla.com/emailAddress=release@mozilla.com/O=Mozilla, Inc./OU=Release Engineering
---
Acceptable client certificate CA names
/CN=PuppetAgain Root CA/emailAddress=release@mozilla.com/OU=Release Engineering/O=Mozilla, Inc.
/CN=CA on relabs-puptest1.build.mtv1.mozilla.com/emailAddress=release@mozilla.com/O=Mozilla, Inc./OU=Release Engineering
/CN=CA on relabs-puptest2.build.mtv1.mozilla.com/emailAddress=release@mozilla.com/O=Mozilla, Inc./OU=Release Engineering
---
SSL handshake has read 3984 bytes and written 997 bytes
---
New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: zlib compression
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1
    Cipher    : DHE-RSA-AES256-SHA
    Session-ID: 
    Session-ID-ctx: 
    Master-Key: 07E536F1C69A856857EA95DFD821BD6BBD499B5710642F9396D9525637EAD17C03064D5115B3D7F517EDE189E7AF40F8
    Key-Arg   : None
    Krb5 Principal: None
    PSK identity: None
    PSK identity hint: None
    Compression: 1 (zlib compression)
    Start Time: 1336582289    Timeout   : 300 (sec)
    Verify return code: 0 (ok)
---
&lt;/pre&gt;

&lt;p&gt;Note the handshake failures near the top, where httpd closed the connection on the client.&lt;/p&gt;

&lt;p&gt;The next step is to make CRLs work properly, since Puppet uses them extensively. &lt;/p&gt;
 
    </content:encoded>

    <pubDate>Wed, 09 May 2012 15:43:01 -0500</pubDate>
    <guid isPermaLink="false">http://code.v.igoro.us/archives/72-guid.html</guid>
    
</item>
<item>
    <title>Setting up a buildslave instance remotely on OS X Lion</title>
    <link>http://code.v.igoro.us/archives/71-Setting-up-a-buildslave-instance-remotely-on-OS-X-Lion.html</link>
            <category>buildbot</category>
            <category>mozilla</category>
            <category>Sysadmin</category>
    
    <comments>http://code.v.igoro.us/archives/71-Setting-up-a-buildslave-instance-remotely-on-OS-X-Lion.html#comments</comments>
    <wfw:comment>http://code.v.igoro.us/wfwcomment.php?cid=71</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://code.v.igoro.us/rss.php?version=2.0&amp;type=comments&amp;cid=71</wfw:commentRss>
    

    <author>nospam@example.com (Dustin J. Mitchell)</author>
    <content:encoded>
    &lt;p&gt;Byrce Lelbach has generously offered access to an OS X system as a &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/buildbot.net/metabuildbot&#039;]);&quot;  href=&quot;http://buildbot.net/metabuildbot&quot;&gt;metabuildbot&lt;/a&gt; slave.  As I went about setting it up today, the process was not obvious, so I thought I&#039;d share.  This was interesting mostly because I only have SSH access to the host, so I cannot download things from the Apple Store or do any of the fancy point-and-click stuff that would make this easier.&lt;/p&gt;

&lt;p&gt;First, I needed to get XCode installed.  Note that the (much quicker to download) XCode command-line tools are not sufficient to build everything in MacPorts -- in particular, they do not support building zlib, which is required for git-core.&lt;/p&gt;

&lt;p&gt;I got my hands on a copy of &quot;Install XCode.app&quot;, and:&lt;/p&gt;

&lt;pre&gt;
host:Downloads buildbot$ cd Install\ Xcode.app/Contents/
host:Contents buildbot$ sudo installer -package Resources/Xcode.mpkg -target /
Password:
installer: Package name is Xcode
installer: Upgrading at base path /
installer: The upgrade was successful.
&lt;/pre&gt;

&lt;p&gt;Once this was done, I installed MacPorts:&lt;/p&gt;

&lt;pre&gt;
host:Downloads buildbot$ hdiutil mount MacPorts-2.0.4-10.7-Lion.dmg
Checksumming Driver Descriptor Map (DDM : 0)…
     Driver Descriptor Map (DDM : 0): verified   CRC32 $A913D2D8
Checksumming Apple (Apple_partition_map : 1)…
....
     Apple (Apple_partition_map : 1): verified   CRC32 $A1DF5DC1
Checksumming disk image (Apple_HFS : 2)…
...... (...) .....
          disk image (Apple_HFS : 2): verified   CRC32 $5A3E74A0
Checksumming  (Apple_Free : 3)…
                    (Apple_Free : 3): verified   CRC32 $00000000
verified   CRC32 $D9641854
/dev/disk2              Apple_partition_scheme
/dev/disk2s1            Apple_partition_map
/dev/disk2s2            Apple_HFS                       /Volumes/MacPorts-2.0.4
host:Downloads buildbot$ pushd /Volumes/MacPorts-2.0.4/
/Volumes/MacPorts-2.0.4 ~/Downloads
host:MacPorts-2.0.4 buildbot$ sudo installer -package MacPorts-2.0.4.pkg/ -target /
Password:
installer: Package name is MacPorts-2.0.4
installer: Installing at base path /
installer: The install was successful.
host:MacPorts-2.0.4 buildbot$ popd
host:Downloads buildbot$ hdiutil unmount /Volumes/MacPorts-2.0.4
&lt;/pre&gt;

&lt;p&gt;and we&#039;re off to the races.&lt;/p&gt;

&lt;p&gt;I added &lt;tt&gt;/opt/local/bin&lt;/tt&gt; to my path as suggested, and then followed the normal MacPorts setup process.&lt;/p&gt;

&lt;p&gt;Finishing up the buildslave install required installing Git (which manages to pull in unreasonable amounts of other stuff!)&lt;/p&gt;

&lt;pre&gt;
host:Contents buildbot$ sudo  /opt/local/bin/port install git-core -credential_osxkeychain-doc-pcre-python27
&lt;/pre&gt;

&lt;p&gt;which is required for the source steps, then creating a virtualenv to install buildbot-slave:&lt;/p&gt;

&lt;pre&gt;
host:~ buildbot$ virtualenv sandbox
New python executable in sandbox/bin/python
Installing setuptools............done.
Installing pip...............done.
host:~ buildbot$ source sandbox/bin/activate
(sandbox)host:~ buildbot$ pip install buildbot-slave
...
&lt;/pre&gt;

&lt;p&gt;and then create and start a slave:&lt;/p&gt;

&lt;pre&gt;
(sandbox)host:~ buildbot$ buildslave create-slave buildslave buildbot.buildbot.net:9989 HOSTNAME PASS
...
(sandbox)host:~ buildbot$ buildslave start buildslave
...
&lt;/pre&gt;

&lt;p&gt;I then followed the helpful advice &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/kb.askmonty.org/en/buildbot-setup-buildbot-setup-for-macosx&#039;]);&quot;  href=&quot;http://kb.askmonty.org/en/buildbot-setup-buildbot-setup-for-macosx&quot;&gt;here&lt;/a&gt; to set up a plist that will start the daemon on boot. &lt;/p&gt;
 
    </content:encoded>

    <pubDate>Sat, 17 Mar 2012 18:05:47 -0500</pubDate>
    <guid isPermaLink="false">http://code.v.igoro.us/archives/71-guid.html</guid>
    
</item>
<item>
    <title>IT and Community</title>
    <link>http://code.v.igoro.us/archives/70-IT-and-Community.html</link>
            <category>mozilla</category>
            <category>Sysadmin</category>
    
    <comments>http://code.v.igoro.us/archives/70-IT-and-Community.html#comments</comments>
    <wfw:comment>http://code.v.igoro.us/wfwcomment.php?cid=70</wfw:comment>

    <slash:comments>3</slash:comments>
    <wfw:commentRss>http://code.v.igoro.us/rss.php?version=2.0&amp;type=comments&amp;cid=70</wfw:commentRss>
    

    <author>nospam@example.com (Dustin J. Mitchell)</author>
    <content:encoded>
    &lt;p&gt;Mozilla&#039;s IT team is pivoting to a more community-focused approach.  Our director of IT, mrz, has been &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/blog.mozilla.com/mrz/2011/10/06/my-job-after-5-558-years/&#039;]);&quot;  href=&quot;http://blog.mozilla.com/mrz/2011/10/06/my-job-after-5-558-years/&quot;&gt;writing&lt;/a&gt; &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/blog.mozilla.com/mrz/2011/10/12/step-1-community-it/&#039;]);&quot;  href=&quot;http://blog.mozilla.com/mrz/2011/10/12/step-1-community-it/&quot;&gt;extensively&lt;/a&gt; &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/blog.mozilla.com/mrz/2011/10/28/step-1-01-mozilla-it-mozcamp/&#039;]);&quot;  href=&quot;http://blog.mozilla.com/mrz/2011/10/28/step-1-01-mozilla-it-mozcamp/&quot;&gt;about&lt;/a&gt; &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/htmlpad.org/community-IT-slides/#&#039;]);&quot;  href=&quot;http://htmlpad.org/community-IT-slides/#&quot;&gt;it&lt;/a&gt; over the last few weeks.&lt;/p&gt;

&lt;p&gt;As you can imagine, the difficult part of this is to balance security with accessibility.  We&#039;d like to be open, but we can&#039;t give the keys to the kingdom out to anyone who promises to help.  The approach we&#039;re taking is to treat volunteers as we would part-time employees - post positions, interview, and then supervise to gain trust.  This is a fairly common model, actually, for any organization with volunteers and a need for security.  Youth programs, for example, generally do an interview and background check with new volunteers, and those volunteers will be paired with senior volunteers or staff for a while.&lt;/p&gt;

&lt;p&gt;However, it&#039;s a bit cumbersome, both for Mozilla and for potential volunteers.  We must design entire positions - ongoing tasks or roles that a volunteer can work on for an extended period of time - and then select a limited number of volunteers to fill those roles.  For potential volunteers, an application and interview can mean a long time (weeks?) before they get to do anything hands-on.  It also carries the risk that we&#039;d have to turn a qualified volunteer away due to lack of suitable positions.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;So what to do?&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;We need a more fluid way of interacting with potential contributors.  Since our bug database is public, we can begin by simply tagging a few bugs that are appropriate for newcomers -- things that don&#039;t require sensitive access and are well-encapsulated so they can be completed without extensive knowledge of Mozilla&#039;s infrastructure.&lt;/p&gt;

&lt;p&gt;&lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/bit.ly/tTsnix&#039;]);&quot;  href=&quot;http://bit.ly/tTsnix&quot;&gt;Here&#039;s the list.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It&#039;s a bit short right now.  There are a few things that may help:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We can get better about identifying appropriate tasks and projects and making bugs out of them.
&lt;li&gt;We can identify a means of giving limited or sandboxed access to a new volunteer.
&lt;li&gt;Consumers of Mozilla&#039;s IT resources can begin tagging bugs, where Mozilla can provide the resources and volunteers can do the heavy lifting - got any ideas?
&lt;/ul&gt; 
 
    </content:encoded>

    <pubDate>Wed, 16 Nov 2011 23:05:24 -0600</pubDate>
    <guid isPermaLink="false">http://code.v.igoro.us/archives/70-guid.html</guid>
    
</item>
<item>
    <title>Subscribe to a google group with a different address?</title>
    <link>http://code.v.igoro.us/archives/67-Subscribe-to-a-google-group-with-a-different-address.html</link>
            <category>Sysadmin</category>
    
    <comments>http://code.v.igoro.us/archives/67-Subscribe-to-a-google-group-with-a-different-address.html#comments</comments>
    <wfw:comment>http://code.v.igoro.us/wfwcomment.php?cid=67</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://code.v.igoro.us/rss.php?version=2.0&amp;type=comments&amp;cid=67</wfw:commentRss>
    

    <author>nospam@example.com (Dustin J. Mitchell)</author>
    <content:encoded>
    &lt;p&gt;Google Groups is one place where, IMHO, Google pushes its hegemony too far, making it difficult to use.  I wanted to subscribe to puppet-users with my Mozilla address, but since I have a Google account, Groups assumes I want to subscribe with that address.  No!&lt;/p&gt;

&lt;p&gt;I found the fix with a bit of Googling (some irony there).  It involves editing a URL:&lt;/p&gt;

&lt;blockquote&gt;http://groups.google.com/group/puppet-users/boxsubscribe?email=email@domain.com&lt;/blockquote&gt;

&lt;p&gt;where you&#039;d substitute the name of the group you want for &lt;i&gt;puppet-users&lt;/i&gt; and add your email at the end. &lt;/p&gt;
 
    </content:encoded>

    <pubDate>Fri, 02 Sep 2011 15:04:00 -0500</pubDate>
    <guid isPermaLink="false">http://code.v.igoro.us/archives/67-guid.html</guid>
    
</item>
<item>
    <title>Nagios NSCA from Python</title>
    <link>http://code.v.igoro.us/archives/69-Nagios-NSCA-from-Python.html</link>
            <category>Code</category>
            <category>mozilla</category>
            <category>Sysadmin</category>
    
    <comments>http://code.v.igoro.us/archives/69-Nagios-NSCA-from-Python.html#comments</comments>
    <wfw:comment>http://code.v.igoro.us/wfwcomment.php?cid=69</wfw:comment>

    <slash:comments>2</slash:comments>
    <wfw:commentRss>http://code.v.igoro.us/rss.php?version=2.0&amp;type=comments&amp;cid=69</wfw:commentRss>
    

    <author>nospam@example.com (Dustin J. Mitchell)</author>
    <content:encoded>
    &lt;p&gt;I&#039;ve been working on improving the monitoring of the build slaves at Mozilla.  As part of this project, I needed to be able to submit passive check results to the Nagios servers via &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/community.nagios.org/2009/06/11/nagios-setting-up-the-nsca-addon-for-passive-checks/&#039;]);&quot;  href=&quot;http://community.nagios.org/2009/06/11/nagios-setting-up-the-nsca-addon-for-passive-checks/&quot;&gt;NSCA&lt;/a&gt; during system startup.  I&#039;m doing this from a Python script that needs to run on a wide array of systems using whatever random Python is available.  We run some oddball stuff, so the common denominator is Python 2.4.&lt;/p&gt;

&lt;p&gt;It turns out that there&#039;s no Python NSCA library, although there is &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/search.cpan.org/dist/Net-Nsca/lib/Net/Nsca.pm&#039;]);&quot;  href=&quot;http://search.cpan.org/dist/Net-Nsca/lib/Net/Nsca.pm&quot;&gt;Net::Nsca&lt;/a&gt; in Perl.  So, I wrote one, and put it on github: &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/github.com/djmitche/pynsca&#039;]);&quot;  href=&quot;https://github.com/djmitche/pynsca&quot;&gt;https://github.com/djmitche/pynsca&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;At the moment, this only knows XOR, and only does service checks.  That&#039;s all I need, but hopefully it can be easily expanded to cover other purposes.  The one thing I want to avoid is adding mandatory requirements -- this should work, at least in plain-text and XOR modes, on a plain-vanilla Python installation.&lt;/p&gt;

&lt;p&gt;By the way, the startup script I&#039;m working on is &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/hg.mozilla.org/build/puppet-manifests/file/tip/modules/buildslave/files/runslave.py&#039;]);&quot;  href=&quot;http://hg.mozilla.org/build/puppet-manifests/file/tip/modules/buildslave/files/runslave.py&quot;&gt;runslave.py&lt;/a&gt;, which includes a modified copy of &lt;i&gt;pynsca&lt;/i&gt; and does a number of other housekeeping jobs as well.  More on that in a subsequent post. &lt;/p&gt;
 
    </content:encoded>

    <pubDate>Fri, 20 May 2011 16:55:11 -0500</pubDate>
    <guid isPermaLink="false">http://code.v.igoro.us/archives/69-guid.html</guid>
    
</item>
<item>
    <title>Amanda's Transfer Mechanisms</title>
    <link>http://code.v.igoro.us/archives/68-Amandas-Transfer-Mechanisms.html</link>
            <category>amanda</category>
    
    <comments>http://code.v.igoro.us/archives/68-Amandas-Transfer-Mechanisms.html#comments</comments>
    <wfw:comment>http://code.v.igoro.us/wfwcomment.php?cid=68</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://code.v.igoro.us/rss.php?version=2.0&amp;type=comments&amp;cid=68</wfw:commentRss>
    

    <author>nospam@example.com (Dustin J. Mitchell)</author>
    <content:encoded>
    &lt;p&gt;There&#039;s been a bit of confusion on the mailing list and IRC about how Amanda assembles transfers out of transfer elements, and how transfer mechanisms influence that.  &lt;/p&gt;

&lt;p&gt;In the final form of a transfer, any two adjacent elements must have
the &lt;em&gt;same&lt;/em&gt; mechanism.  For example is, an upstream element speaking
XFER_MECH_PUSH_BUFFER cannot talk to a downstream element using
XFER_MECH_READ_FD (nor, more confusingly, XFER_MECH_PULL_BUFFER).  So each mechanism is an
isolated definition of &quot;here&#039;s how upstream and downstream should
talk&quot;.  They come in pairs because generally anything upstream can do
to downstream (e.g., upstream can write to downstream&#039;s fd) can occur
in reverse (e.g., downstream can read from upstream&#039;s fd).&lt;/p&gt;

&lt;p&gt;What makes this confusing is that if you specify a set of elements which can&#039;t talk directly to one another, then xfer.c will add &quot;glue&quot; elements &lt;em&gt;between&lt;/em&gt; the specified elements.  To make that concrete, imagine you specify a transfer as&lt;/p&gt;

&lt;pre&gt;source-holding --&gt; filter-xor --&gt; dest-fd&lt;/pre&gt;

(if you like practical examples, then imagine filter-xor is a buffer-based decompression filter, and you&#039;re pulling data from holding disk, decompressing, and sending to a pipe -- something amfetchdump would do).  Here are the mechanisms supported by each element:

&lt;pre&gt;
source-holding:
 XFER_MECH_PULL_BUFFER
&lt;/pre&gt;

&lt;pre&gt;
filter-xor
 XFER_MECH_PULL_BUFFER (input) and
 XFER_MECH_PULL_BUFFER (output)
or
 XFER_MECH_PUSH_BUFFER (input) and
 XFER_MECH_PUSH_BUFFER (output)
&lt;/pre&gt;

&lt;pre&gt;
dest-fd
 XFER_MECH_WRITEFD (input)
&lt;/pre&gt;

&lt;p&gt;In putting these together, source-holding and filter-xor can use the same mechanism (PULL_BUFFER).  This leaves filter-xor using PULL_BUFFER for output, but dest-fd does not support this.  So xfer.c adds a glue element that can speak PULL_BUFFER on input and WRITEFD on output.  This element basically loops in a thread, calling upstream-&gt;pull_buffer and write(downstream-&gt;input_fd, buffer).  So the final xfer looks like&lt;/p&gt;

&lt;pre&gt;
 source-holding --(PULL_BUFFER)--&gt; filter-xor --(PULL_BUFFER)--&gt; glue --(WRITEFD)--&gt; dest-fd
&lt;/pre&gt;

&lt;p&gt;Hopefully that helps to explain how the glue works.&lt;/p&gt;

&lt;p&gt;Note that one of the cool things about this arrangement is that in most cases the complexity is in the glue, not the elements.  In fact, in this case the glue provides the only thread that&#039;s required to run this transfer, so the other three element implementations don&#039;t need to manage threads at all. &lt;/p&gt;
 
    </content:encoded>

    <pubDate>Sat, 22 Jan 2011 14:47:13 -0600</pubDate>
    <guid isPermaLink="false">http://code.v.igoro.us/archives/68-guid.html</guid>
    
</item>
<item>
    <title>virtualenv for Perl</title>
    <link>http://code.v.igoro.us/archives/66-virtualenv-for-Perl.html</link>
            <category>Code</category>
    
    <comments>http://code.v.igoro.us/archives/66-virtualenv-for-Perl.html#comments</comments>
    <wfw:comment>http://code.v.igoro.us/wfwcomment.php?cid=66</wfw:comment>

    <slash:comments>2</slash:comments>
    <wfw:commentRss>http://code.v.igoro.us/rss.php?version=2.0&amp;type=comments&amp;cid=66</wfw:commentRss>
    

    <author>nospam@example.com (Dustin J. Mitchell)</author>
    <content:encoded>
    &lt;p&gt;I absolutely love &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/pypi.python.org/pypi/virtualenv&#039;]);&quot;  href=&quot;http://pypi.python.org/pypi/virtualenv&quot;&gt;virtualenv&lt;/a&gt; for Python development.  It allows me to develop &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/buildbot.net&#039;]);&quot;  href=&quot;http://buildbot.net&quot;&gt;Buildbot&lt;/a&gt; against several versions of Python and several versions of its dependencies, without modifying my system&#039;s Python installation at all!&lt;/p&gt;

&lt;p&gt;Now, I need to do the same thing in Perl.  So I thought I&#039;d compare the two side-by-side.&lt;/p&gt;

&lt;p&gt;&lt;h2&gt;virtualenv&lt;/h2&gt;&lt;/p&gt;

&lt;pre&gt;
# install virtualenv locally
wget http://bitbucket.org/ianb/virtualenv/raw/tip/virtualenv.py
# set up a sandbox
python virtualenv.py sandbox
# activate it
source sandbox/bin/activate
# start installing stuff
easy_install buildbot
&lt;/pre&gt;

&lt;h2&gt;local::lib&lt;/h2&gt;

&lt;p&gt;There is no local::lib gentoo ebuild!  I&#039;m sure there&#039;s a good reason, but that&#039;s odd all the same!&lt;/p&gt;

&lt;pre&gt;
# install local::lib locally
wget http://search.cpan.org/CPAN/authors/id/G/GE/GETTY/local-lib-1.006007.tar.gz
tar -zxf local-lib-1.006007.tar.gz
cd local-lib-1.006007
perl Makefile.PL --bootstrap # (accept lots of defaults)
make test &amp;&amp;amp; make install
# activate it (permanently)
echo &#039;eval $(perl -I$HOME/perl5/lib/perl5 -Mlocal::lib)&#039; &gt;&gt;~/.bashrc
eval $(perl -I$HOME/perl5/lib/perl5 -Mlocal::lib)
# start installing stuff
perl -MCPAN -e install Config::General # (I have to accept the same defaults again??)
&lt;/pre&gt;

&lt;p&gt;I think virtualenv is the clear winner here!&lt;/p&gt;
 
    </content:encoded>

    <pubDate>Thu, 11 Nov 2010 10:48:43 -0600</pubDate>
    <guid isPermaLink="false">http://code.v.igoro.us/archives/66-guid.html</guid>
    
</item>
<item>
    <title>Firefox 4.0b7 - a few tweaks</title>
    <link>http://code.v.igoro.us/archives/65-Firefox-4.0b7-a-few-tweaks.html</link>
            <category>mozilla</category>
    
    <comments>http://code.v.igoro.us/archives/65-Firefox-4.0b7-a-few-tweaks.html#comments</comments>
    <wfw:comment>http://code.v.igoro.us/wfwcomment.php?cid=65</wfw:comment>

    <slash:comments>4</slash:comments>
    <wfw:commentRss>http://code.v.igoro.us/rss.php?version=2.0&amp;type=comments&amp;cid=65</wfw:commentRss>
    

    <author>nospam@example.com (Dustin J. Mitchell)</author>
    <content:encoded>
    &lt;p&gt;The new beta of Firefox 4.0 was released today.  I&#039;m not quite willing to run Minefield (nightlies), so I&#039;ve been eagerly awaiting this beta to fix some nagging but not show-stopper bugs in 4.0b6.  One of those involved bad interactions of App Tabs with Panorama.  Now the app tabs nicely decorate the side of each tab set in the panorama view.&lt;/p&gt;

&lt;p&gt;Another nice thing is that the Option-Space key combination, which opened panorama in 4.0b6, no longer does so.  That&#039;s OK - I found that to be too easy to press anyway.  It&#039;s now bound to Command-E (right there at the top of the &quot;View&quot; menu).&lt;/p&gt;

&lt;p&gt;Panorama has also been re-bound to swipe-up and swipe-down, which makes me less happy.  In most apps on the Mac, those swipes are equivalent to the &quot;Home&quot; and &quot;End&quot; keystrokes -- they scroll to the top or bottom of the current page.  So with a little help from my new co-workers, I discovered the settings to fix that.&lt;/p&gt;

&lt;p&gt;The full list of gesture bindings is &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/t.tal.by/post/95428783/changing-firefox-gestures&#039;]);&quot;  href=&quot;http://t.tal.by/post/95428783/changing-firefox-gestures&quot;&gt;written up here&lt;/a&gt;, but the two I needed to change are &lt;tt&gt;browser.gesture.swipe.up&lt;/tt&gt; and &lt;tt&gt;.down&lt;/tt&gt;.  The scrolling commands to bind to them are &lt;tt&gt;cmd_scrollTop&lt;/tt&gt; and &lt;tt&gt;cmd_scrollBottom&lt;/tt&gt;.&lt;/p&gt;

&lt;p&gt;4.0 has a number of other great UI enhancements, too.  I&#039;m excited to see 4.0 finally released!&lt;/p&gt;

&lt;p&gt;[edit: fixed formatting] &lt;/p&gt;
 
    </content:encoded>

    <pubDate>Wed, 10 Nov 2010 15:44:46 -0600</pubDate>
    <guid isPermaLink="false">http://code.v.igoro.us/archives/65-guid.html</guid>
    
</item>
<item>
    <title>irssi settings for status-in-nick</title>
    <link>http://code.v.igoro.us/archives/63-irssi-settings-for-status-in-nick.html</link>
            <category>mozilla</category>
    
    <comments>http://code.v.igoro.us/archives/63-irssi-settings-for-status-in-nick.html#comments</comments>
    <wfw:comment>http://code.v.igoro.us/wfwcomment.php?cid=63</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://code.v.igoro.us/rss.php?version=2.0&amp;type=comments&amp;cid=63</wfw:commentRss>
    

    <author>nospam@example.com (Dustin J. Mitchell)</author>
    <content:encoded>
    &lt;p&gt;I am getting started in releng at Mozilla, and IRC provides a central meeting-place for the group.  As such, indicating your status to this group is an important, so others can know whether you&#039;re nearby to answer a question or take care of a problem.  This is generally done by adding suffixes to the IRC nickname, e.g., &quot;dustin|afk&quot; or &quot;dustin|lunch&quot;.&lt;/p&gt;

&lt;p&gt;Before I go further, I know that this is frown on, and even results in autoignores, in some corners of IRC.  If that&#039;s the case for you, read no further. &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/irssi.org/&#039;]);&quot;  href=&quot;http://irssi.org/&quot;&gt;Irssi&lt;/a&gt;&#039;s documentation is utterly incomplete.  So the only way to figure out how to configure something or write a script is to find and adapt examples.  So hopefully this entry will feed back into that pool.&lt;/p&gt;

&lt;p&gt;What I want is an easy way to bind some keystrokes to commands like &lt;tt&gt;/NICK dustin|afk&lt;/tt&gt;.  However, I want to be very careful &lt;i&gt;not&lt;/i&gt; to set this nick on other chatnets, particularly since I&#039;m generally known as djmitche there, not dustin.  So I began by writing a script that can double-check this:&lt;/p&gt;

&lt;pre&gt;
use strict;

use vars qw ($VERSION %IRSSI);

$VERSION = &#039;v1.0&#039;;
%IRSSI = (
          name        =&gt; &#039;moznick&#039;,
          authors     =&gt; &#039;dustin&#039;,
          contact     =&gt; &#039;dustin@mozilla.com&#039;,
          url         =&gt; &#039;http://code.v.igoro.us/&#039;,
          license     =&gt; &#039;GPLv2&#039;,
          description =&gt; &#039;Sets my nick status for Mozilla co-workers&#039;,
         );

use Irssi;

my $last_nick = &#039;&#039;;

sub is_mozilla {
    my ($server) = @_;
    if (!$server || $server-&gt;{&#039;chatnet&#039;} eq &#039;mozilla&#039;) {
        return 1;
    }

    Irssi::print(&quot;This isn&#039;t a mozilla channel!&quot;);
    return 0;
}

sub cmd_moznick {
    my ($data, $server, $channel) = @_;

    if (is_mozilla($server)) {
        my $new_nick = $data? &quot;dustin|$data&quot; : &quot;dustin&quot;;
        return if ($new_nick eq $last_nick);

        $server-&gt;command(&quot;NICK $new_nick&quot;);
        Irssi::print(&quot;nick set to $new_nick&quot;);
        $last_nick = $new_nick;
    }
}

Irssi::command_bind(&quot;moznick&quot;, &quot;cmd_moznick&quot;);
&lt;/pre&gt;

&lt;p&gt;This just adds a &lt;tt&gt;/MOZNICK&lt;/tt&gt; command that will set my nick, but only on a Mozilla chatnet.  Then I added an alias and some bindings.  I don&#039;t like irssi&#039;s configuration-writing stuff, as it&#039;s several times blown away my configuration.  Instead, I edit the config file directly.  So I have:&lt;/p&gt;

&lt;pre&gt;
aliases = { 
    moznick_moz = &quot;window goto #build; moznick $*&quot;;
};

keyboard = ( 
    { key = &quot;meta-space&quot;; id = &quot;multi&quot;; data = &quot;command moznick_build&quot;; },
    { key = &quot;meta-z&quot;; id = &quot;multi&quot;; data = &quot;command moznick_build brb&quot;; },
    { key = &quot;meta-x&quot;; id = &quot;multi&quot;; data = &quot;command moznick_build away; command away&quot;; }
);
&lt;/pre&gt;

&lt;p&gt;The advantage of the &lt;tt&gt;window goto&lt;/tt&gt; in the alias is that it will switch to a channel on the mozilla chatnet.  I&#039;d love to have a way to just switch to that chatnet without changing windows, but this isn&#039;t bad.&lt;/p&gt;
 
    </content:encoded>

    <pubDate>Fri, 22 Oct 2010 12:06:04 -0500</pubDate>
    <guid isPermaLink="false">http://code.v.igoro.us/archives/63-guid.html</guid>
    
</item>
<item>
    <title>IPv6 and Amanda</title>
    <link>http://code.v.igoro.us/archives/61-IPv6-and-Amanda.html</link>
            <category>amanda</category>
            <category>Sysadmin</category>
    
    <comments>http://code.v.igoro.us/archives/61-IPv6-and-Amanda.html#comments</comments>
    <wfw:comment>http://code.v.igoro.us/wfwcomment.php?cid=61</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://code.v.igoro.us/rss.php?version=2.0&amp;type=comments&amp;cid=61</wfw:commentRss>
    

    <author>nospam@example.com (Dustin J. Mitchell)</author>
    <content:encoded>
    &lt;p&gt;Amanda joined the IPv6 revolution in November 2006 - all of the BSD-style authentication mechanisms can support IPv6 endpoints.  However, it&#039;s generally agreed that this was a mistake, and in this post I will talk about why that&#039;s the case. First, a bit of background on how Amanda&#039;s networking code works, and what had to change to support IPv6.  Amanda supports security mechanisms called BSD (the oldest), BSDUDP, and BSDTCP.  These all authenticate (if you can call it that) using the same sorts of checks that rsh uses.  The incoming connection is accepted if:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;it is from a &quot;reserved&quot; port (less than 1024);&lt;/ii&gt;
&lt;li&gt;the address of the initiator has complementary forward and reverse DNS records in place; and&lt;/li&gt;
&lt;li&gt;the initiator&#039;s hostname is in &lt;tt&gt;.amandahosts&lt;/tt&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;During a backup operation, the Amanda server contacts each client host.  When using the BSD authentications, this triggers &lt;tt&gt;amandad&lt;/tt&gt;, which checks the above restrictions before beginning communication with the server.  This initial connection is packet-based, and can be carried out over UDP (for BSD and BSDUDP) or TCP (BSDTCP).  When a dump begins, several &quot;streams&quot; are opened to transmit the data, index, and metadata.  For BSD and BSDUDP, each stream is implemented as a distinct TCP connection, where the client sends a port number to the server and the server connects to that port.  BSDTCP multiplexes all streams over a single TCP connection using a basic type/length packet encapsulation.&lt;/p&gt;

&lt;p&gt;The first challenge in adding IPv6 support was to deal properly with IPv6 addresses when querying the DNS.  That meant switching to getaddrinfo and getnameinfo, as suggested by &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/www.kame.net/newsletter/19980604/&#039;]);&quot;  href=&quot;http://www.kame.net/newsletter/19980604/&quot;&gt;Jun-ichiro itojun Itoh&lt;/a&gt;. These functions bring their own compatibility problems, but Amanda uses &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/www.gnu.org/software/gnulib/&#039;]);&quot;  href=&quot;http://www.gnu.org/software/gnulib/&quot;&gt;gnulib&lt;/a&gt;, which provides compatibile implementations on systems where they are not available, minimizing the difficulty.&lt;/p&gt;

&lt;p&gt;We had a lot of trouble from systems such as RHEL3 possessing IPv6 support in the compiler environment but not in the kernel.  On such systems, code using constants like AF_INET6 or AI_V4MAPPED would compile without problems, but fail at runtime.  We added a WORKING_IPV6 preprocessor conditional, without which all references to IPv6-related symbols were removed.  At configure time, Amanda tries to create an IPv6 socket, and sets this conditional to true if it succeeds.  The &lt;tt&gt;--without-ipv6&lt;/tt&gt; configure option forcibly disables IPv6 support.&lt;/p&gt;

&lt;p&gt;The sockaddr structures and API for IPv6 are fairly difficult to use, particularly if it&#039;s not known in advance what sort of address they will contain.  We added a set of macros and utility functions in &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/github.com/zmanda/amanda/blob/master/common-src/sockaddr-util.c&#039;]);&quot;  href=&quot;http://github.com/zmanda/amanda/blob/master/common-src/sockaddr-util.c&quot;&gt;sockaddr-util.c&lt;/a&gt; and &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/github.com/zmanda/amanda/blob/master/common-src/sockaddr-util.h&#039;]);&quot;  href=&quot;http://github.com/zmanda/amanda/blob/master/common-src/sockaddr-util.h&quot;&gt;sockaddr-util.h&lt;/a&gt;.  Using these macros throughout Amanda removed a significant amount of code that was conditionalized on both compile-time support and runtime address family, and centralized that logic in one easily-maintained place.&lt;/p&gt;

&lt;p&gt;On our build systems, we had to deal with different levels of support in the compile environment and the kernel.  This is fine: most Amanda users install binary packages that are produced on roughly the same OS distribution and version as was used for the build, so the kernel support is generally the same.  However, a third variable has tripped up lots of Amanda users: system configuration.  In particular, several newer Linux distributions have shipped with &lt;tt&gt;localhost&lt;/tt&gt; resolving to ::1 vi &lt;tt&gt;/etc/hosts&lt;/tt&gt;, but without enough interface configuration to actually utilize a socket bound to that address.  Amanda uses localhost sockets for inter-process communication, so this misconfiguration causes backup operations to fail.  The solution is to either finish configuring IPv6 on the host, remove the reference to ::1 in &lt;tt&gt;/etc/hosts&lt;/tt&gt;, or build Amanda with &lt;tt&gt;--without-ipv6&lt;/tt&gt;.&lt;/p&gt;

&lt;p&gt;I have not yet heard of an Amanda installation where IPv6 communication is in use.  But I have heard from countless IPv4 users whose Amanda installations have failed due to bad IPv6 support.  At the moment, then, I feel that adding IPv6 support to Amanda has been a net negative for the project.  Although there is doubtless room for improvement, I will not entertain patches for better IPv6 support, for fear they will introduce new bugs for our exclusively IPv4 userbase.&lt;/p&gt;

&lt;p&gt;Of course, all of this may change as dual-stack networks grow more prevalent and are replaced by pure IPv6 networks!&lt;/p&gt;
 
    </content:encoded>

    <pubDate>Fri, 16 Jul 2010 22:04:00 -0500</pubDate>
    <guid isPermaLink="false">http://code.v.igoro.us/archives/61-guid.html</guid>
    
</item>
<item>
    <title>SSH With Snow Leopard</title>
    <link>http://code.v.igoro.us/archives/60-SSH-With-Snow-Leopard.html</link>
            <category>Sysadmin</category>
    
    <comments>http://code.v.igoro.us/archives/60-SSH-With-Snow-Leopard.html#comments</comments>
    <wfw:comment>http://code.v.igoro.us/wfwcomment.php?cid=60</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://code.v.igoro.us/rss.php?version=2.0&amp;type=comments&amp;cid=60</wfw:commentRss>
    

    <author>nospam@example.com (Dustin J. Mitchell)</author>
    <content:encoded>
    &lt;p&gt;I just upgraded my Macbook to Snow Leopard, and the upgrade has changed the way SSH authentication works.  I have set up a system I like quite a bit, now, and thought I would share. My usage pattern is that I do most of my work via &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/www.gnu.org/software/screen/&#039;]);&quot;  href=&quot;http://www.gnu.org/software/screen/&quot;&gt;GNU screen&lt;/a&gt; running on my login server, &lt;tt&gt;euclid&lt;/tt&gt;.  So I want a simple procedure that will connect me to that screen session, with a proper SSH agent set up.&lt;/p&gt;

&lt;p&gt;Snow Leopard automatically starts an &lt;tt&gt;ssh-agent&lt;/tt&gt; process at login.  This is great, but does not interoperate with &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/sshkeychain.sourceforge.net/&#039;]);&quot;  href=&quot;http://sshkeychain.sourceforge.net/&quot;&gt;SSHKeychain&lt;/a&gt;.  Dropping SSHKeychain is OK with me - I don&#039;t use SSH tunnels, so it really only acted as a GUI for passphrase entry.  It also ate CPU occasionally, which of course causes the macbook to become more painfully hot than usual.&lt;/p&gt;

&lt;p&gt;So I have three problems to solve: 1. automatically add my key to ssh-agent; 2. automatically expire the key at appropriate times (at my paranoia level, that&#039;s at system sleep); and 3. make multiple agent instances usable from the same shell session on the server.&lt;/p&gt;

&lt;h1&gt;Adding the Key at Connection Time&lt;/h1&gt;

&lt;p&gt;Adding the key is relatively straightforward.  I wrote a short script that Terminal runs when I hit ⌘-N or ⌘-T:&lt;/p&gt;

&lt;pre&gt;
#! /bin/bash

# does ssh-agent not have a key?
if ! ssh-add -l; then
    ssh-add ~/.ssh/dustin || exit 1
fi

exec ssh -x -t euclid.r.igoro.us bin/startscreen
&lt;/pre&gt;

&lt;p&gt;This will prompt me for the passphrase when there is not already a key active, but proceed directly to the ssh invocation if the key situation is OK.  The &lt;tt&gt;-x&lt;/tt&gt; option to &lt;tt&gt;ssh&lt;/tt&gt; is there to turn off X11 forwarding; without this option, SSH will helpfully start the X11 app.  I think this is a great feature, but I don&#039;t use X11 apps very often, so I&#039;ve disabled it.&lt;/p&gt;

&lt;h1&gt;Expiring the Key Automatically&lt;/h1&gt;

&lt;p&gt;Mac OS has a nicely designed system in place to allow applications to get notified when the system is changing power states.  However, I wasn&#039;t interested in writing a full OS X app for this particular project.  Enter &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/www.bernhard-baehr.de/&#039;]);&quot;  href=&quot;http://www.bernhard-baehr.de/&quot;&gt;sleepwatcher&lt;/a&gt;.  This is a beautifully simple program that just executes scripts on particular power events.  I set this up to run via launchd, as directed in the README, and to run &lt;tt&gt;~/.ssh/sleep&lt;/tt&gt; on sleep.  That script contains:&lt;/p&gt;

&lt;pre&gt;
#! /bin/bash

# first, don&#039;t inherit a socket (sleepwatcher doesn&#039;t get the user&#039;s env)
SSH_AUTH_SOCK=

# find some sockets
echo &quot;.ssh/sleep:&quot; `id`
for sock in /tmp/launch-*/Listeners; do
    if [ -w $sock ]; then
        echo &quot;Trying to remove .ssh/dustin from socket $sock&quot;
        SSH_AUTH_SOCK=$sock /opt/local/bin/ssh-add -d ~/.ssh/dustin
    else
        echo &quot;Skipping unwritable socket $sock&quot;
    fi  
done
&lt;/pre&gt;

&lt;p&gt;The for loop is required because a script run from sleepwatcher doesn&#039;t inherit the &lt;tt&gt;SSH_AUTH_SOCK&lt;/tt&gt; variable that points to the running SSH agent.  The loop simply searches for a writable SSH socket of the pattern used by the system&#039;s agent.&lt;/p&gt;

&lt;h1&gt;SSH Agent and Screen&lt;/h1&gt;

&lt;p&gt;If you naïvely set up an SSH agent, connect to a remote system, and start screen there, things will work great - until you disconnect from the screen session.  When you connect to the remote system, SSH forwards the agent connection for you, and sets &lt;tt&gt;SSH_AUTH_SOCK&lt;/tt&gt; on the remote system to point to this forwarded socket.  Screen passes this variable along blindly, so it appears in all of the shells opened in screen windows, and things work as you&#039;d expect.  When that SSH connection is removed, and a new one established, the forwarded agent appears at a new socket.  But those shells running in screen windows are still pointing to the old name, and will no longer be able to connect.&lt;/p&gt;

&lt;p&gt;The fix is to create a socket with a well-known name that will not change from connection to connection.  The following script takes care of it.  WARNING: this script is vulnerable to /tmp race conditions.  I am the only user on my servers, so this doesn&#039;t bother me, but fixing it should be relatively straightforward.&lt;/p&gt;

&lt;pre&gt;
#! /bin/bash
# hard-link the SSH socket to one with a fixed name on the local
# machine, and set SSH_AUTH_SOCK to point to that fixed name.  Later
# invocations of this script will change the link, but the name will
# remain valid, allowing existing shells to continue to function.
setup_fixed_socket() {
  local old_socket=&quot;$SSH_AUTH_SOCK&quot;
  local socket_dir=&quot;/tmp/$(uname -n)-$(id -u)&quot;
  local socket_file=$socket_dir/agent

  # set up the directory and permissions
  [ -e $socket_dir ] || mkdir -p $socket_dir
  chmod 700 $socket_dir

  # remove an existing link
  [ -e $socket_file ] &amp;&amp;amp; rm $socket_file

  # hard-link in the new one
  ln $old_socket $socket_file

  # return the new socket
  echo $socket_file
}

# this variable will be exported to every shell opened by this
# invocation of screen -- even subsequent connections to it.  This
# variable may live for days or weeks.
export SSH_AUTH_SOCK=$(setup_fixed_socket)

# finally, fire up screen.  Try reattaching to a running
# session; otherwise start up a new one
screen -R -DD ${@} || screen
&lt;/pre&gt;
 
    </content:encoded>

    <pubDate>Sat, 10 Jul 2010 14:27:00 -0500</pubDate>
    <guid isPermaLink="false">http://code.v.igoro.us/archives/60-guid.html</guid>
    
</item>
<item>
    <title>What's New in Amanda: The End of Fragmentation</title>
    <link>http://code.v.igoro.us/archives/59-Whats-New-in-Amanda-The-End-of-Fragmentation.html</link>
            <category>amanda</category>
    
    <comments>http://code.v.igoro.us/archives/59-Whats-New-in-Amanda-The-End-of-Fragmentation.html#comments</comments>
    <wfw:comment>http://code.v.igoro.us/wfwcomment.php?cid=59</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://code.v.igoro.us/rss.php?version=2.0&amp;type=comments&amp;cid=59</wfw:commentRss>
    

    <author>nospam@example.com (Dustin J. Mitchell)</author>
    <content:encoded>
    &lt;p&gt;Most of my posts in this series have been about features that are available in a released version of Amanda.  This time, I want to share a project I&#039;m working on right now - one that will be available in Amanda-3.2.  I&#039;m reworking the way Amanda writes its data to tape (or any other kind of storage) to make it more efficient, more reliable, and simpler to configure.&lt;/p&gt;

&lt;p&gt;Historically, Amanda&#039;s conservative approach to finicky tape hardware has meant that it wasted some space at the end of each tape.  With the changes I&#039;m working on, Amanda will no longer waste this space, and can also avoid some needless copying of data in most cases, with a minimum of additional risk. &lt;h1&gt;Amanda&#039;s Storage Format&lt;/h1&gt;&lt;/p&gt;

&lt;p&gt;Before examining the new functionality, let&#039;s look at Amanda&#039;s storage format.  Amanda treats all storage devices like tapes&lt;sup&gt;1&lt;/sup&gt; - a set of sequentially numbered data files of arbitrary size, each composed of a sequence of fixed-size blocks.  Each file begins with a one-block header that identifies the dump and gives information about its contents.  The header is followed by blocks of raw data.&lt;/p&gt;

&lt;p&gt;Amanda supports writing a dump across multiple tapes - spanning.&lt;sup&gt;2&lt;/sup&gt;  The technique is this: a dump is split into a sequence of parts, and each part is written a a single file on a volume.  During recovery, Amanda reads the parts in sequence, and concatenates their data to reproduce the original dumpfile.  Usually all parts are the same size, and this size is generally 1-5% of the tape capacity.&lt;/p&gt;

&lt;h1&gt;Better Safe than Sorry - At a Cost&lt;/h1&gt;

&lt;p&gt;Amanda was originally designed around tape drives - in fact, if you look at the history of Linux kernel support for tape drives, it is closely intertwined with Amanda development.  Tape drives are finicky beasts, and in many cases cannot distinguish the end of the tape (called EOM) from any other fatal error.  Worse, tape drives employ large caches to ensure they can write continuously, and when an error occurs all of the data in that cache is lost, and there is no way for Amanda to determine how much actually made it onto the tape.  Beginning a new on-tape file (writing a filemark) flushes the cache and signals any errors immediately.&lt;/p&gt;

&lt;p&gt;Since time immemorial, then, Amanda has treated any error from the tape drive as EOM, and assumed that all data written since the last filemark is potentially corrupt.  That means that the part in progress when the error occurred is logged as PARTIAL, and Amanda will start at the beginning of that part on the next tape.&lt;/p&gt;

&lt;p&gt;The PARTIAL part is recorded in the catalog, but will not be used for recovery, so it is effectively wasted space.  A little arithmetic will tell you that, on average, each tape will waste half of the part size.  This is at least excusable with real tape drives; with vtapes (disk), this wasted space is completely unnecessary.  Worse, vtapes are most flexible when they are kept small and dumps are spanned over many vtapes per night; but the wasted space increases linearly with the number of vtapes used.&lt;/p&gt;

&lt;p&gt;In order to rewind a part and write it again on a new tape, Amanda also needs to keep its data somewhere, called the part cache.  When the dump is on the holding disk, the holding disk acts as a part cache.  Otherwise, Amanda can cache parts in memory or on disk.  Caching in memory is faster, but requires a lot of RAM for a reasonable part size.  Caching on disk allows larger parts, but is considerably slower.&lt;/p&gt;

&lt;h1&gt;Logical EOM&lt;/h1&gt;

&lt;p&gt;More recent tape drives (those made in the last decade or so) have a feature called &quot;early warning&quot;.  With this feature enabled, the drive alerts the host system when it is &quot;near&quot; EOM, and flushes the cache to tape.  Exactly what &quot;near&quot; means is not specified in the SCSI standard, but in general there&#039;s room to flush the cache and write a filemark, at least.  This is sometimes called a logical EOM - LEOM.&lt;/p&gt;

&lt;p&gt;Amanda can take advantage of this functionality to cleanly finish a part before running headlong into a physical EOM.  This eliminates the wasted space for a PARTIAL part, and also eliminates the need to cache parts, since rewinding is not required.  In one small change (well, OK, it&#039;s &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/github.com/zmanda/amanda/compare/1bc521c5ce1be2d144fefc8ce37917c55ab690e8...6a087798ea0c9945093226150da37d5af49d1810&#039;]);&quot;  href=&quot;http://github.com/zmanda/amanda/compare/1bc521c5ce1be2d144fefc8ce37917c55ab690e8...6a087798ea0c9945093226150da37d5af49d1810&quot;&gt;about 4,300 lines&lt;/a&gt;), Amanda gets faster and uses storage space more efficiently.  What&#039;s not to love?&lt;/p&gt;

&lt;p&gt;Better yet, all of the non-tape devices (vtapes, S3 devices, DVD-ROMs, etc.) can easily emulate LEOM, so backups to these devices will automatically benefit from this improvement.&lt;/p&gt;

&lt;h1&gt;In the Code&lt;/h1&gt;

&lt;p&gt;&lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/github.com/zmanda/amanda/compare/1bc521c5ce1be2d144fefc8ce37917c55ab690e8...6a087798ea0c9945093226150da37d5af49d1810&#039;]);&quot;  href=&quot;http://github.com/zmanda/amanda/compare/1bc521c5ce1be2d144fefc8ce37917c55ab690e8...6a087798ea0c9945093226150da37d5af49d1810&quot;&gt;Three important patches&lt;/a&gt; toward this functionality were just committed.  What remains is to set up real LEOM support for the VFS device (vtapes) and for the tape device.&lt;/p&gt;

&lt;p&gt;The VFS device can, of course, trivially emulate LEOM when it is enforcing the MAX_VOLUME_USAGE property - the vtape length.  However, predicting when a filesystem will run out of space is much more difficult.  We are still discussing options, and I would love to hear suggestions here or on the mailing list.&lt;/p&gt;

&lt;p&gt;As for the tape device, it will assume that LEOM is not supported unless the user configures it explicitly (with the &quot;LEOM&quot; device property) or we can determine support for LEOM from the operating system at runtime.  Unfortunately, this is one of those areas so technical that only a half-dozen people know how it works, so it may take me some time to track down this information for non-Linux operating systems.  Again, advice and assistance is welcome!&lt;/p&gt;

&lt;hr /&gt;

&lt;ul&gt;
&lt;li&gt;&lt;sup&gt;1&lt;/sup&gt;This is an ages-old design decision, but one that artificially constrains Amanda&#039;s flexibility, especially with vtapes.
&lt;li&gt;&lt;sup&gt;2&lt;/sup&gt;In fact, Amanda has supported spanning for something like 7 years now.  Yet I occasionally see users in #amanda complaining about this serious limitation and wondering when we&#039;re going to do anything about it.  Will 2003 be soon enough?
&lt;/ul&gt;
 
    </content:encoded>

    <pubDate>Thu, 08 Jul 2010 18:07:00 -0500</pubDate>
    <guid isPermaLink="false">http://code.v.igoro.us/archives/59-guid.html</guid>
    
</item>
<item>
    <title>What's New in Amanda: Hackability</title>
    <link>http://code.v.igoro.us/archives/45-Whats-New-in-Amanda-Hackability.html</link>
            <category>amanda</category>
    
    <comments>http://code.v.igoro.us/archives/45-Whats-New-in-Amanda-Hackability.html#comments</comments>
    <wfw:comment>http://code.v.igoro.us/wfwcomment.php?cid=45</wfw:comment>

    <slash:comments>3</slash:comments>
    <wfw:commentRss>http://code.v.igoro.us/rss.php?version=2.0&amp;type=comments&amp;cid=45</wfw:commentRss>
    

    <author>nospam@example.com (Dustin J. Mitchell)</author>
    <content:encoded>
    &lt;p&gt;It&#039;s been a while since I&#039;ve posted about recent development in &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/amanda.org&#039;]);&quot;  href=&quot;http://amanda.org&quot;&gt;Amanda&lt;/a&gt;, but it&#039;s not for lack of interesting topics!&lt;/p&gt;

&lt;p&gt;Today I want to talk a little bit about Amanda&#039;s development.  Historically, Amanda has always had a small, core group of developers who do the lion&#039;s share of the development work.  There are probably lots of reasons for this, not least of which is that a backup application isn&#039;t the sexiest project on which to spend your spare time.  But I think there&#039;s a deeper reason, and it has to do with hackability.
 Amanda was originally written in C, which means any changes require the full set of developer tools.  For example, just to fix a typo in an error message, you would need to find the source, configure and compile it, find and fix the error message, and recompile to test.  Fixing something more substantial in the highly interdependent Amanda codebase also requires a deep understanding of many parts of Amanda - from the obscure configuration interface to the oddly interlinked disklist structure.  This level of programming skill is not common among Amanda&#039;s user base (systems administrators), and I can count the people who understand the disklist structure on one hand.&lt;/p&gt;

&lt;p&gt;The result has been a paltry flow of patches from anyone but the core hackers.  Furthermore, no entry path has been available by which newcomers could work their way up to being core developers.  While I don&#039;t want to disparage the work of any of the great programmers who have written Amanda over the years, it&#039;s a shame that there have been so few at any time, and I worry about what would happen if the number were to reach zero.  So what to do?&lt;/p&gt;

&lt;h1&gt;$hackability++&lt;/h1&gt;

&lt;p&gt;We&#039;ve done a few things to try to make Amanda more hackable.  Probably the biggest change is to rewrite parts of Amanda in Perl.  I&#039;m asked &quot;why&quot; quite often, and while we had a lot of reasons, two relate directly to hackability.  First, more sysadmins know Perl than C, because Perl is quite often used to build the &quot;glue&quot; that links systems together.  Interestingly, based on many conversations, it seems that Python may also have been a good choice, as I &lt;a href=&quot;http://code.v.igoro.us/archives/12-Perl-vs.-Python.html&quot;&gt;suspected when I first proposed the rewrite&lt;/a&gt;.  But it&#039;s too late now!&lt;/p&gt;

&lt;p&gt;Second, and more importantly, Perl code can be hacked in place.  If &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/wiki.zmanda.com/man/amvault.8.html&#039;]);&quot;  href=&quot;http://wiki.zmanda.com/man/amvault.8.html&quot;&gt;amvault&lt;/a&gt; isn&#039;t acting the way you want it to, just open up &lt;tt&gt;/usr/sbin/amvault&lt;/tt&gt; and tweak away.  No need to download the source, no need to compile, no segmentation faults, just hacking.  When you&#039;re done, run a quick &lt;tt&gt;diff&lt;/tt&gt; and send the results to amanda-hackers.&lt;/p&gt;

&lt;p&gt;Even users who do not know Perl can take advantage of this &lt;i&gt;in-situ&lt;/i&gt; hackability.  Within Amanda&#039;s C code, if I want a user to try a patch, that user must figure out how to download Amanda&#039;s source, apply the patch, configure, compile, and install.  None of those steps are trivial.  With Perl code, I can often provide a patch that is simple enough to be applied directly to the installed executables by hand, or with a simple application of &lt;tt&gt;patch&lt;/tt&gt;.  Everyone stays focused on the bug under investigation, and the user&#039;s backups are up and running that much more quickly.&lt;/p&gt;

&lt;h1&gt;New APIs&lt;/h1&gt;

&lt;p&gt;As I mentioned before, historically Amanda&#039;s code has been highly interdependent.  Details of the implementation of the holding disk were spread over most of the files in the server implementation.  The dumplevel -987 has a special meaning that is documented nowhere, but referenced in several source files.  All of this makes new development difficult, because it&#039;s impossible to &quot;slice off&quot; and study a portion of Amanda in isolation.&lt;/p&gt;

&lt;p&gt;The solution here is to create abstract interfaces, where new functionality can be &quot;plugged in&quot; and Amanda can use it without changes.  The Amanda developers have abused the term &quot;API&quot; for these interfaces, and we now have quite a few:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/wiki.zmanda.com/index.php/Application_API&#039;]);&quot;  href=&quot;http://wiki.zmanda.com/index.php/Application_API&quot;&gt;Application API&lt;/a&gt; - an abstraction of backup clients, e.g., &lt;a href=&quot;http://code.v.igoro.us/archives/50-Whats-New-in-Amanda-Postgres-Backups.html&quot;&gt;ampgsql&lt;/a&gt; for Postgres;
&lt;li&gt;&lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/wiki.zmanda.com/index.php/Device_API&#039;]);&quot;  href=&quot;http://wiki.zmanda.com/index.php/Device_API&quot;&gt;Device API&lt;/a&gt; - an abstraction of backend storage devices, such as tape, disk, cloud, or DVD-RW;
&lt;li&gt;&lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/wiki.zmanda.com/index.php/Changer_API&#039;]);&quot;  href=&quot;http://wiki.zmanda.com/index.php/Changer_API&quot;&gt;Changer API&lt;/a&gt; - an abstraction of tape changers and other mechanisms for selecting from a set of volumes; and
&lt;li&gt;&lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/wiki.zmanda.com/index.php/Script_API&#039;]);&quot;  href=&quot;http://wiki.zmanda.com/index.php/Script_API&quot;&gt;Script API&lt;/a&gt; - a means of invoking scripts before or after certain events during a backup.
&lt;/ul&gt;

&lt;p&gt;This strategy has already paid off: we have seen several new scripts and applications contributed, and the DVD-RW device arrived out of the blue as a contribution from someone who found it useful.&lt;/p&gt;

&lt;h1&gt;Other Changes&lt;/h1&gt;

&lt;p&gt;In the interest of greater accessibility to new hackers, we have also put Amanda on &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/github.com/zmanda/amanda&#039;]);&quot;  href=&quot;http://github.com/zmanda/amanda&quot;&gt;github&lt;/a&gt; and created a set of good &quot;beginner&quot; projects.  Zmanda has even offered to &lt;a href=&quot;http://code.v.igoro.us/archives/53-Want-to-work-on-Amanda.html&quot;&gt;pay people to hack on Amanda&lt;/a&gt;, as a way of easing the cost of entry.  I also try to point out interesting projects on the Amanda mailing list, particularly projects that Jean-Louis and I probably will not find time to work on.&lt;/p&gt;

&lt;p&gt;The idea here is to encourage new hackers to pick up a well-scoped project to become familiar with Amanda.  The hackers can then move on to more sophisticated projects that meet their particular backup needs or address a particular interest.&lt;/p&gt;

&lt;h1&gt;Will You Join Me?&lt;/h1&gt;

&lt;p&gt;So Amanda is ready for you.  When can you start?&lt;/p&gt;
 
    </content:encoded>

    <pubDate>Thu, 01 Jul 2010 22:29:00 -0500</pubDate>
    <guid isPermaLink="false">http://code.v.igoro.us/archives/45-guid.html</guid>
    
</item>
<item>
    <title>IPv6 Configuration</title>
    <link>http://code.v.igoro.us/archives/57-IPv6-Configuration.html</link>
            <category>Sysadmin</category>
    
    <comments>http://code.v.igoro.us/archives/57-IPv6-Configuration.html#comments</comments>
    <wfw:comment>http://code.v.igoro.us/wfwcomment.php?cid=57</wfw:comment>

    <slash:comments>1</slash:comments>
    <wfw:commentRss>http://code.v.igoro.us/rss.php?version=2.0&amp;type=comments&amp;cid=57</wfw:commentRss>
    

    <author>nospam@example.com (Dustin J. Mitchell)</author>
    <content:encoded>
    &lt;p&gt;&lt;div style=&quot;float:right&quot;&gt;&lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/ipv6.he.net/certification/scoresheet.php?pass_name=djmitche&#039;]);&quot;  href=&quot;http://ipv6.he.net/certification/scoresheet.php?pass_name=djmitche&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://ipv6.he.net/certification/create_badge.php?pass_name=djmitche&amp;amp;badge=3&quot; width=229 height=137 border=0 alt=&quot;IPv6 Certification Badge for djmitche&quot;&gt;&lt;/img&gt;&lt;/a&gt;&lt;/div&gt;I&#039;ve been meaning to get IPv6 set up on my local network for some time.  My only practical reason is that &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/amanda.org&#039;]);&quot;  href=&quot;http://amanda.org&quot;&gt;Amanda&lt;/a&gt; supports IPv6 and I should test that support.  It was also a good chance to re-immerse myself in network configuration, and Hurricane Electric has a neat &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/ipv6.he.net/certification&#039;]);&quot;  href=&quot;http://ipv6.he.net/certification&quot;&gt;certification process&lt;/a&gt; to add some motivation. I began by getting local IPv6 connectivity set up over the HE tunnel, using my Gentoo systems.  This was fairly straightforward, as the Gentoo net scripts natively support IPv6.  The firewall system I use (&lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/www.shorewall.net/&#039;]);&quot;  href=&quot;http://www.shorewall.net/&quot;&gt;Shorewall&lt;/a&gt;) does not support IPv6 directly.  Instead, there&#039;s a parallel &lt;tt&gt;shorewall6&lt;/tt&gt; package to install.  Aside from the annoyance of setting up two separate firewalls, this did not cause appreciable difficulties.  With all of this in place, I was at the &quot;Explorer&quot; level.&lt;/p&gt;

&lt;p&gt;The next task was to set up a working IPv6 desktop.  My home network uses 802.1q VLAN tagging to layer both an external, publicly routable IPv4 network (99.89.149.16/29 on VLAN 20) and an internal, NAT&#039;d IPv4 network (172.16.1/24 on VLAN 10).  I wanted to make VLAN 10 a dual-stack network, rather than invent a new VLAN for my IPv6 network.  Initially, I didn&#039;t realize that HE uses, in my case, 2001:470:1f10:826::0/64 just for the tunnel (yes, two addresses out of 2&lt;sup&gt;64&lt;/sup&gt; used -- maybe we&#039;ll need IPv8 sooner than we think!).  I assumed that the /64 I was allocated was to be used for all of my nodes, and tried to subnet it locally, using 2001:470:1f10:826::0/112 for the tunnel and 2001:470:1f10::1/112 for the internal network.  This worked with manual configuration, but &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/www.litech.org/radvd/&#039;]);&quot;  href=&quot;http://www.litech.org/radvd/&quot;&gt;radvd&lt;/a&gt; seemed to always want to advertise a /64.  A little reading about the RA protocol showed this to be correct: RA provides the high 64 bits (the network portion), and the clients provide the low 64 bits using EUI-64.  I was stymied until I looked at the tunnel details again and noticed that the &quot;Routed IPv6 Prefixes&quot; section listed a different prefix (2001:470:1f11:826/64).&lt;/p&gt;

&lt;p&gt;With this in place, the subnet and firewall setup was a breeze.  Using a manual configuration on my MacBook, I was able to communicate via IPv6.  However, the stateless autoconfiguration didn&#039;t work.  I briefly tried DHCPv6, but Macs do not support it.  The RA client correctly combines the network and EUI-64 components to create a full address, and it correctly copies the link-local address of the router, but it does not set up a default route using that router, making the whole thing fairly useless.  A trip to #ipv6 confirmed that Macs are, indeed, broken this way, so I stopped worrying about it.&lt;/p&gt;

&lt;p&gt;The remainder of the certification process involved getting Apache, Postfix, and Bind speaking IPv6, none of which was very difficult.  I did discover that BIND&#039;s $ORIGIN didn&#039;t work correctly.  A zonefile with&lt;/p&gt;

&lt;pre&gt;
$ORIGIN 6.2.8.0.1.1.f.1.0.7.4.0.1.0.0.2.ip6.arpa.
8.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0 IN PTR knuth.r.igoro.us.
&lt;/pre&gt;

&lt;p&gt;didn&#039;t work, but spelling out the entire reversed address did.  I&#039;m sure this was due to a typo, but several checks didn&#039;t reveal anything.&lt;/p&gt;

&lt;p&gt;However, I&#039;m now stuck at the Guru level until GoDaddy starts supporting IPv6 glue for the &lt;tt&gt;.us&lt;/tt&gt; TLD.  I feel cheated, somehow!&lt;/p&gt;
 
    </content:encoded>

    <pubDate>Sun, 27 Jun 2010 16:27:12 -0500</pubDate>
    <guid isPermaLink="false">http://code.v.igoro.us/archives/57-guid.html</guid>
    
</item>

</channel>
</rss>
