<?xml version="1.0" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <atom:link href="http://www.mivok.net/rss.xml" rel="self"
            type="application/rss+xml" />
        <description>mivok.net blog</description>
        <generator>swpg</generator>
        <title>Mivok.net</title>
        <language>en-US</language>
        <link>http://www.mivok.net</link>
        <ttl>60</ttl>
        
        <item>
            <guid>http://www.mivok.net/2010/03/31/solaris-freebsd.html</guid>
            <link>http://www.mivok.net/2010/03/31/solaris-freebsd.html</link>
            <title>From Solaris to FreeBSD</title>
            <description>&lt;p&gt;Less than one week after I switched my hosting over to Solaris 10, with all
its ZFS/dtrace goodness, Oracle quietly makes a &lt;a class=&#34;reference external&#34; href=&#34;http://arstechnica.com/open-source/news/2010/03/solaris-10-no-longer-free-as-in-beer-now-a-90-day-trial.ars&#34;&gt;license change&lt;/a&gt; that
everybody dealing with Solaris is likely now familiar with, and Solaris 10 is
no longer free to use. Emails to Sun/Oracle&#39;s licensing department result only
in form letters repeating instructions on the website, and then nothing.&lt;/p&gt;
&lt;p&gt;I can&#39;t really blame Oracle for this, Sun didn&#39;t make enough money to survive,
and Oracle has this radical idea that you need to actually charge people in
order to make money. I can blame them for not providing more clarity regarding
the issue (so far they haven&#39;t announced anything), and for leaving customers
unsure about what&#39;s going to happen next. However, this is mostly besides the
point. I now needed to look into a good alternative.&lt;/p&gt;
&lt;p&gt;OpenSolaris is the obvious candidate, and I&#39;ve played around with it a little
previously, but I can&#39;t make myself like some of the changes made to it. The
biggest annoyances being related to the new packaging system and some of the
poor choices made in its design (e.g. no --nodeps option). That is an entire
post (or rather, rant) in itself however. In addition to this, I can&#39;t help
but believe that Oracle is going to make some change to OpenSolaris that makes
it not a realistic option.&lt;/p&gt;
&lt;p&gt;This is where FreeBSD comes in. With release 8.0, ZFS has become a fully
supported filesystem. It has dtrace support, jails (just like zones), even
&lt;a class=&#34;reference external&#34; href=&#34;http://bsdbased.com/2009/11/27/vimage-better-virtualization-in-freebsd-8&#34;&gt;virtual networking&lt;/a&gt; so you can have a full network stack inside the jail.&lt;/p&gt;
&lt;p&gt;For my personal server, the main feature I was interested in was ZFS,
specifically ZFS root/boot. With ZFS it is trivial to set up mirrored drives,
and I wanted to avoid doing software raid with UFS as well as ZFS. Thankfully
there is &lt;a class=&#34;reference external&#34; href=&#34;http://wiki.freebsd.org/RootOnZFS&#34;&gt;extensive documentation&lt;/a&gt; on how to do this. It isn&#39;t in the
standard install, but if you need a repeatable procedure for many servers, it&#39;s
a (relatively) simple matter to script the installation, and you would
probably want to do this anyway for an automated install.&lt;/p&gt;
&lt;p&gt;There were a few gotchas, as with any new system you&#39;re not familiar with, but
so far it looks quite nice. I&#39;ll be looking further into jails (especially the
vimage jails) and other nice features. Hopefully, FreeBSD will turn out to be
a good replacement for Solaris.&lt;/p&gt;
</description>
            <pubDate>Wed, 31 Mar 2010 00:00:00 </pubDate>
        </item>
        
        <item>
            <guid>http://www.mivok.net/2010/03/06/pytemplate.html</guid>
            <link>http://www.mivok.net/2010/03/06/pytemplate.html</link>
            <title>A skeleton template for new python projects</title>
            <description>&lt;p&gt;Whenever I start a new programming project, I find myself implementing the
same initial functionality over and over: config files, command line options,
some form of debug/logging output and so on. I hesitate to call this
&#39;boilerplate&#39; code, but I can&#39;t really think of a better word to describe it.
Faced with this, I&#39;ve come up with a template that I can build on that gives
me some skeleton code to implement features I nearly always require. It&#39;s not
very big, but saves time when starting a new project.&lt;/p&gt;
&lt;p&gt;Most of my projects start with some wacky idea that just pops into my head
(usually with the assistance of a higher than normal level of caffeine), then
out through my fingers as quickly as possible to get something that kinda
sorta works before I forget, or worse - get pulled off on some other task (my
free time is very limited). Before starting the skeleton code, I would be half
way through, suddenly realizing that it would be really useful to have
somewhere to store configuration options right now, and waste time
implementing that code instead of what I&#39;m really doing. Using python with its
large amount of built-in libraries reduces, but doesn&#39;t eliminate the problem.&lt;/p&gt;
&lt;p&gt;I suspect a template of this sort is a somewhat personal thing, but if anybody
would find such a thing useful, the git repository is
git://git.mivok.net/pytemplate.git/ (&lt;a class=&#34;reference external&#34; href=&#34;http://git.mivok.net/gitweb/?p=pytemplate.git&#34;&gt;browse&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;These are the things I implemented/included in the template:&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul class=&#34;simple&#34;&gt;
&lt;li&gt;Setting up of logging (used for debuggin and informational output) using
the logging module. This does some basic setup with timestamps, outputting
to stdout, and then I can just do &lt;tt class=&#34;docutils literal&#34;&gt;&lt;span class=&#34;pre&#34;&gt;logging.info(&amp;quot;something&amp;quot;)&lt;/span&gt;&lt;/tt&gt; or
&lt;tt class=&#34;docutils literal&#34;&gt;&lt;span class=&#34;pre&#34;&gt;logging.debug(&amp;quot;debug&lt;/span&gt; only output&amp;quot;)&lt;/tt&gt; and things work out how I expect.&lt;/li&gt;
&lt;li&gt;Configuration file parsing using ConfigParser. There is code to search for
several common config file locations (&lt;tt class=&#34;docutils literal&#34;&gt;&lt;span class=&#34;pre&#34;&gt;~/.prognamerc&lt;/span&gt;&lt;/tt&gt;,
&lt;tt class=&#34;docutils literal&#34;&gt;/etc/prognamerc&lt;/tt&gt;), and to load a default configuration from
&lt;tt class=&#34;docutils literal&#34;&gt;data/defaults&lt;/tt&gt;.&lt;/li&gt;
&lt;li&gt;ConfigParser isn&#39;t used directly. There is a separate config.py module that
adds default variants of the various get methods. For example,
getintdefault, which will fetch an integer from the config file, falling
back to a default value if the option doesn&#39;t exist rather than raising an
exception.&lt;/li&gt;
&lt;li&gt;Command line option processing with some default options specifying whether
to turn debugging output on and to specify an alternative config file
location. New options can be quickly added, and the two options I add in
every project are already in place.&lt;/li&gt;
&lt;li&gt;A project layout based on that mentioned at
&lt;a class=&#34;reference external&#34; href=&#34;http://sayspy.blogspot.com/2010/03/various-ways-of-distributing-python.html&#34;&gt;http://sayspy.blogspot.com/2010/03/various-ways-of-distributing-python.html&lt;/a&gt;
and a predone setup.py script, allowing simple distribution of the app.&lt;/li&gt;
&lt;li&gt;A &lt;tt class=&#34;docutils literal&#34;&gt;use_template.sh&lt;/tt&gt; script that goes through and replaces &#39;progname&#39; with
the actual name of the project. Edit this script, fill in the values, and
run it once. Then it can be deleted, with the template code already filled
in.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is being updated as I change how I do things. For instance the repository
layout was changed very recently. If you find yourself starting multiple
projects and implementing similar features each time, try building your own
template. Even if it only contains a license file, skeleton readme file, and
something to process command line arguments, it is work that you don&#39;t have to
do each time.&lt;/p&gt;
</description>
            <pubDate>Sat, 06 Mar 2010 00:00:00 </pubDate>
        </item>
        
        <item>
            <guid>http://www.mivok.net/2010/03/05/gitosis.html</guid>
            <link>http://www.mivok.net/2010/03/05/gitosis.html</link>
            <title>Gitosis - manage git repositories sanely</title>
            <description>&lt;p&gt;I&#39;ve finally made all my projects available publicly via git at
&lt;a class=&#34;reference external&#34; href=&#34;http://git.mivok.net/&#34;&gt;http://git.mivok.net/&lt;/a&gt; thanks to &lt;a class=&#34;reference external&#34; href=&#34;http://eagain.net/gitweb/?p=gitosis.git&#34;&gt;gitosis&lt;/a&gt;. Before that, I kind of just thrown
everything in a git directory under my home directory and accessed it over
ssh, which worked fine for private repositories, but fell flat whenever I
wanted to make something available to somebody else.&lt;/p&gt;
&lt;p&gt;Gitosis promised to make it easy to add new repositories and set up access for
new people as needed, and once everything is set up, it is really easy -
everything is contained in a config file inside a git repository, so you can
make changes locally and push. You also have the benefit that your changes
themselves are under version control. However, there were a few hiccups along
the way, so I&#39;m going to describe what I did in case others try and hit the
same problems I did.&lt;/p&gt;
&lt;p&gt;Gitosis uses python and setuptools, which I already had available. I&#39;m running
Ubuntu, so installing any requirements is as simple as running:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;aptitude install python python-setuptools
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Of course, git itself is a requirement. For now we&#39;ll use the Ubuntu package,
but it&#39;s a good idea to build from source if you want the latest version:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;aptitude install git-core
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Next, get the gitosis source:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;git clone git://eagain.net/gitosis.git
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;and install:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span class=&#34;nb&#34;&gt;cd &lt;/span&gt;gitosis
sudo python ./setup.py install
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;So far, everything is pretty straightforward. Next we need to add a user that
everyone will connect as in order to access repositories. The main method
gitosis uses for accessing repositories, is to have a single user that
everyone connects to over ssh. Logins are only allowed via ssh keys, and
anyone who connects is restricted to running gitosis commands, preventing them
from accessing anything they shouldn&#39;t.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;sudo adduser --system --shell /bin/sh --gecos &lt;span class=&#34;s1&#34;&gt;&amp;#39;git user&amp;#39;&lt;/span&gt; &lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
    --group --disabled-password --home /srv/git git
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Here I&#39;ve set the home directory to &lt;tt class=&#34;docutils literal&#34;&gt;/srv/git&lt;/tt&gt;. This directory will hold all
repositories and gitosis files. Next we need to initialize this directory with
all of the gitosis configuration files:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;sudo -H -u git gitosis-init &amp;lt; your-ssh-key.pub
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;(the -H option to sudo sets the HOME variable to the user you are running
commands as. In this case - /srv/git).&lt;/p&gt;
&lt;p&gt;The &lt;tt class=&#34;docutils literal&#34;&gt;&lt;span class=&#34;pre&#34;&gt;your-ssh-key.pub&lt;/span&gt;&lt;/tt&gt; file should be your ssh public key for the computer you
are working on now. You will use this to access the administration repository
and any other repositories you create later. If you don&#39;t have an ssh key set
up already, make one now and copy the &lt;tt class=&#34;docutils literal&#34;&gt;id_rsa.pub&lt;/tt&gt; file to the server before
running the above command:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;ssh-keygen -t rsa -b 4096
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;For more information on ssh-keys, see the ssh-keygen man page.&lt;/p&gt;
&lt;p&gt;Note: by default, gitosis takes the comment field of your ssh key to be your
username. In my case, it was &lt;a class=&#34;reference external&#34; href=&#34;mailto:mark&amp;#64;laptop&#34;&gt;mark&amp;#64;laptop&lt;/a&gt;, and I would have had to use
&lt;a class=&#34;reference external&#34; href=&#34;mailto:mark&amp;#64;laptop&#34;&gt;mark&amp;#64;laptop&lt;/a&gt; as my username whenever editing permissions. If you want something
nicer, edit the copy of your public key before running the &lt;tt class=&#34;docutils literal&#34;&gt;&lt;span class=&#34;pre&#34;&gt;gitosis-init&lt;/span&gt;&lt;/tt&gt;
command and change the comment field to something a little nicer.&lt;/p&gt;
&lt;p&gt;Now you have the basic server set up. To edit the configuration, clone the
administration repository:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;git clone git@your-server.example.com:gitosis-admin.git
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then you can edit the gitosis.conf file, commit it, and push back to the
server.&lt;/p&gt;
&lt;p&gt;At this point I hit my first snag. Any changes pushed back to the server
didn&#39;t take effect. The magic updating of settings wasn&#39;t working. After some
hunting around (read: typing stuff into Google and clicking frantically), I
found that all of the magic is done via a hook on the gitosis-admin
repository. For some reason, the hook script wasn&#39;t executable, and so never
ran. Before committing any configuration changes, make sure to fix the
permissions on the repository hook:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;sudo chmod +x /srv/git/repositories/gitosis-admin.git/hooks/post-update
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The basic gitosis setup at this point is complete. Aside from adding
repositories and new users, the other steps are optional. However, we are
talking about making repositories publicly accessible, and the other two steps
- setting up &lt;tt class=&#34;docutils literal&#34;&gt;&lt;span class=&#34;pre&#34;&gt;git://&lt;/span&gt;&lt;/tt&gt; access via &lt;tt class=&#34;docutils literal&#34;&gt;&lt;span class=&#34;pre&#34;&gt;git-daemon&lt;/span&gt;&lt;/tt&gt; and setting up gitweb will do
this.&lt;/p&gt;
&lt;p&gt;First though, here&#39;s a quick overview on adding users/repositories.&lt;/p&gt;
&lt;p&gt;To add a new user, get a copy of their ssh public key (ssh keys are what makes
the whole thing work), and copy it to your gitosis-admin checkout inside the
&lt;tt class=&#34;docutils literal&#34;&gt;keydir&lt;/tt&gt; directory. Name the file &lt;tt class=&#34;docutils literal&#34;&gt;USERNAME.pub&lt;/tt&gt;, replacing the username with
the name of the user you wish to add - this is the username you will use when
setting permissions. For example, if you add &lt;tt class=&#34;docutils literal&#34;&gt;joe.pub&lt;/tt&gt;, then you will use joe
as the username in the configuration below.&lt;/p&gt;
&lt;p&gt;To add a repository, you just give somebody permission to access it and then
push. This involves editing the gitosis.conf and adding a few lines:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span class=&#34;k&#34;&gt;[group foo]&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;writable&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;myrepository&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;members&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;joe&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This allows user joe to write to myrepository.git. You then add this as a
remote in your local repository and push to create the repository on the
server:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span class=&#34;nb&#34;&gt;cd &lt;/span&gt;path/to/my-repository
git remote add origin git@your-server.example.com:myrepository.git
git push
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This assumes you actually have something to push. In practice this isn&#39;t an
issue - you start with a blank local repository (using &lt;tt class=&#34;docutils literal&#34;&gt;git init&lt;/tt&gt;), commit
your first changes, and push. The first person to push actually creates the
repository.&lt;/p&gt;
&lt;div class=&#34;section&#34; id=&#34;setting-up-git-access&#34;&gt;
&lt;h2&gt;Setting up git:// access&lt;/h2&gt;
&lt;p&gt;This part allows people to clone a repository without needing to authenticate,
and without having to generate ssh keys. You can&#39;t push to repositories in
this way however - you have to use ssh if you want to push back to a
repository. Chances are, you don&#39;t want all repositories to be public, and
gitosis allows you to pick and choose which you make public and which you make
private using (wait for it...) the gitosis.conf file.&lt;/p&gt;
&lt;p&gt;Setting up git:// access is as simple as running the git-daemon command:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;sudo -u git git-daemon --base-path&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;/srv/git/repositories/
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If you&#39;re running Ubuntu however, gitosis comes with a nice script that you
just drop in to /etc/event.d, edit to change the path, and it will start the git-daemon
automatically on boot:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;sudo cp gitosis/etc-event.d-local-git-daemon /etc/event.d/local-git-daemon
sudo sed -i s+/srv/example.com/git+/srv/git+ /etc/event.d/local-git-daemon
sudo initctl start &lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;-git-daemon
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The initctl script starts the daemon without rebooting, which is usually a
good thing.&lt;/p&gt;
&lt;p&gt;By default, no repositories are made public. To make them public, you need to
add a &lt;tt class=&#34;docutils literal&#34;&gt;daemon = yes&lt;/tt&gt; option to your gitosis.conf:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span class=&#34;k&#34;&gt;[repo myrepository]&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;daemon&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;yes&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Here we have made a new &lt;tt class=&#34;docutils literal&#34;&gt;repo&lt;/tt&gt; section for myrepository. Save the gitosis.conf
file, commit, push, and you should be able to clone myrepository using
&lt;tt class=&#34;docutils literal&#34;&gt;&lt;span class=&#34;pre&#34;&gt;git://your-server.example.com/myrepository.git&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;section&#34; id=&#34;gitweb-making-everything-look-pretty&#34;&gt;
&lt;h2&gt;Gitweb - making everything look pretty&lt;/h2&gt;
&lt;p&gt;The final step is getting gitweb working. For this you need a copy of
gitweb.cgi and associated files. I built git from source, and gitweb.cgi was
built as part of this, but if you didn&#39;t do this, there is an Ubuntu package
available called &lt;tt class=&#34;docutils literal&#34;&gt;gitweb&lt;/tt&gt;. I also use lighttpd on my server, with pages stored
under &lt;tt class=&#34;docutils literal&#34;&gt;/srv/www/domain.example.com/pages/&lt;/tt&gt; so I&#39;ll be describing a
configuration for that server and layout.&lt;/p&gt;
&lt;p&gt;First, copy &lt;tt class=&#34;docutils literal&#34;&gt;gitweb.cgi&lt;/tt&gt;, &lt;tt class=&#34;docutils literal&#34;&gt;gitweb.css&lt;/tt&gt;, and all of the images to
&lt;tt class=&#34;docutils literal&#34;&gt;/srv/www/domain.example.com/&lt;/tt&gt;. I put the css files and images inside a
&lt;tt class=&#34;docutils literal&#34;&gt;pages&lt;/tt&gt; subdirectory (the document root), and put &lt;tt class=&#34;docutils literal&#34;&gt;gitweb.cgi&lt;/tt&gt; inside a
separate &lt;tt class=&#34;docutils literal&#34;&gt;&lt;span class=&#34;pre&#34;&gt;cgi-bin&lt;/span&gt;&lt;/tt&gt; directory outside of the document root.&lt;/p&gt;
&lt;p&gt;Next, configure lighttpd. I have simple-vhost set up which sets the document
root based on the domain name requested, so we only need to do special set up
for the git/cgi parts:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span class=&#34;nv&#34;&gt;$HTTP&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;quot;host&amp;quot;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;~ &lt;span class=&#34;s2&#34;&gt;&amp;quot;^git\.your-server\.example\.com$&amp;quot;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
     url.redirect &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;
         &lt;span class=&#34;s2&#34;&gt;&amp;quot;^/$&amp;quot;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&amp;gt; &lt;span class=&#34;s2&#34;&gt;&amp;quot;/gitweb/&amp;quot;&lt;/span&gt;,
         &lt;span class=&#34;s2&#34;&gt;&amp;quot;^/gitweb$&amp;quot;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&amp;gt; &lt;span class=&#34;s2&#34;&gt;&amp;quot;/gitweb/&amp;quot;&lt;/span&gt;
     &lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
     alias.url &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;
         &lt;span class=&#34;s2&#34;&gt;&amp;quot;/gitweb/&amp;quot;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&amp;gt; &lt;span class=&#34;s2&#34;&gt;&amp;quot;/srv/www/git.your-server.example.com/cgi-bin/gitweb.cgi&amp;quot;&lt;/span&gt;,
     &lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
     setenv.add-environment &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;
         &lt;span class=&#34;s2&#34;&gt;&amp;quot;GITWEB_CONFIG&amp;quot;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&amp;gt; &lt;span class=&#34;s2&#34;&gt;&amp;quot;/srv/www/git.your-server.example.com/gitweb.conf&amp;quot;&lt;/span&gt;,
     &lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
     &lt;span class=&#34;nv&#34;&gt;$HTTP&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;quot;url&amp;quot;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;~ &lt;span class=&#34;s2&#34;&gt;&amp;quot;^/gitweb/&amp;quot;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt; cgi.assign &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;quot;&amp;quot;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&amp;gt; &lt;span class=&#34;s2&#34;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
 &lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Gitosis does provide a config file for lighttpd, but it wasn&#39;t appropriate for
my setup. Note that the above needs the following modules loaded: &lt;tt class=&#34;docutils literal&#34;&gt;mod_alias&lt;/tt&gt;,
&lt;tt class=&#34;docutils literal&#34;&gt;mod_cgi&lt;/tt&gt;, &lt;tt class=&#34;docutils literal&#34;&gt;mod_redirect&lt;/tt&gt;, &lt;tt class=&#34;docutils literal&#34;&gt;mod_setenv&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;Gitweb.cgi needs editing slightly in the above configuration, by default it
looks for the css file in the same location as the gitweb.cgi file (i.e. in a
/gitweb/ dir), but they are stored at the root of the site. Open up gitweb.cgi
and search for gitweb.css. Add a slash before the filename and save the file.&lt;/p&gt;
&lt;p&gt;Next is creating a gitweb.conf file. Again, gitosis helps out here, providing
a &lt;tt class=&#34;docutils literal&#34;&gt;gitweb.conf&lt;/tt&gt; file that just needs some tweaking with the right paths.
Copy the &lt;tt class=&#34;docutils literal&#34;&gt;gitweb.conf&lt;/tt&gt; file from the gitosis source distribution to
&lt;tt class=&#34;docutils literal&#34;&gt;&lt;span class=&#34;pre&#34;&gt;/srv/www/git.your-server.example.com/&lt;/span&gt;&lt;/tt&gt;, and open it up for editing.&lt;/p&gt;
&lt;p&gt;Edit the &lt;tt class=&#34;docutils literal&#34;&gt;$projects_list&lt;/tt&gt;, &lt;tt class=&#34;docutils literal&#34;&gt;$projectroot&lt;/tt&gt;, and the &lt;tt class=&#34;docutils literal&#34;&gt;&amp;#64;git_base_url_list&lt;/tt&gt;
lines and save:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span class=&#34;nv&#34;&gt;$projects_list&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#39;/srv/git/gitosis/projects.list&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;$projectroot&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;quot;/srv/git/repositories&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;@git_base_url_list&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#39;git://your-server.example.com&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;By default, gitosis creates repositories that are only accessible by the git
user and users in the git group, so we need to give the web server permissions
to access repositories. If this isn&#39;t done, gitweb will say that there are no
repositories available even when you configure web access in gitosis for the
repository.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;usermod -G git www-data
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You will need to restart the web server after this in order for the group
change to take effect. If your web server is running as someone else other
than &lt;tt class=&#34;docutils literal&#34;&gt;&lt;span class=&#34;pre&#34;&gt;www-data&lt;/span&gt;&lt;/tt&gt;, change the above command appropriately.&lt;/p&gt;
&lt;p&gt;Finally, to give access to a repository via gitweb, the process is similar to
setting up git:// access. Edit gitosis.conf, and add a &lt;tt class=&#34;docutils literal&#34;&gt;gitweb = yes&lt;/tt&gt; line
next to the &lt;tt class=&#34;docutils literal&#34;&gt;daemon = yes&lt;/tt&gt; line for the repository. Commit, push, and the
repository should now show up in gitweb. In the default configuration, you need
to have both &lt;tt class=&#34;docutils literal&#34;&gt;daemon = yes&lt;/tt&gt; and &lt;tt class=&#34;docutils literal&#34;&gt;gitweb = yes&lt;/tt&gt; for a repository to be made
available via gitweb. See the &lt;tt class=&#34;docutils literal&#34;&gt;gitweb.conf&lt;/tt&gt; file if you want to change this.&lt;/p&gt;
&lt;/div&gt;
</description>
            <pubDate>Fri, 05 Mar 2010 00:00:00 </pubDate>
        </item>
        
        <item>
            <guid>http://www.mivok.net/2009/09/20/bashfunctionoverride.html</guid>
            <link>http://www.mivok.net/2009/09/20/bashfunctionoverride.html</link>
            <title>Bash function renaming and overriding</title>
            <description>&lt;p&gt;One annoyance I found when writing bash scripts is the lack of function
references. This became apparent when overriding a function, but when I wanted
to change the behavior only slightly. I had a library of functions, and wanted
to add some commands before the start of the function, and some cleanup code
immediately after it finished.&lt;/p&gt;
&lt;p&gt;This being a library function that was called
elsewhere, I couldn&#39;t edit the function in the library itself. Nor could I
edit the calling code and add the steps before and after - the calling code
was itself another library function. This left the option of copying and
pasting the entire function, and adding my extra code to the beginning and
end.&lt;/p&gt;
&lt;p&gt;In python (and many other languages), I would have done something like the
following:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span class=&#34;n&#34;&gt;old_foo&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;foo&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;foo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;initialization_code&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;old_foo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;cleanup_code&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;but bash doesn&#39;t seem to support function references in that manner. After
much searching however, I finally found a way to save a function under a new
name, which gives the same kind of functionality using bash&#39;s &lt;tt class=&#34;docutils literal&#34;&gt;declare&lt;/tt&gt;
builtin.&lt;/p&gt;
&lt;p&gt;The &lt;tt class=&#34;docutils literal&#34;&gt;declare&lt;/tt&gt; command prints out the values of declared variables, and more
importantly, declared functions - &lt;tt class=&#34;docutils literal&#34;&gt;declare &lt;span class=&#34;pre&#34;&gt;-f&lt;/span&gt; foo&lt;/tt&gt; will print out the code
for function &lt;tt class=&#34;docutils literal&#34;&gt;foo&lt;/tt&gt;. So all you need to do is execute the output of the
&lt;tt class=&#34;docutils literal&#34;&gt;declare &lt;span class=&#34;pre&#34;&gt;-f&lt;/span&gt;&lt;/tt&gt; command, after substituting the name of the function. The
following bash function does just this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;save_function&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;nb&#34;&gt;local &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;ORIG_FUNC&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;declare&lt;/span&gt; -f &lt;span class=&#34;nv&#34;&gt;$1&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;nb&#34;&gt;local &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;NEWNAME_FUNC&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;quot;$2${ORIG_FUNC#$1}&amp;quot;&lt;/span&gt;
    &lt;span class=&#34;nb&#34;&gt;eval&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;quot;$NEWNAME_FUNC&amp;quot;&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Add that to your scripts, and you have a simple way to copy/rename a function,
and a simple way to add a step before/after an existing function. To copy the
python example above:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;save_function foo old_foo
foo&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
    initialization_code&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt;
    old_foo&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt;
    cleanup_code&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now any code calling foo in the script will get the new behavior.&lt;/p&gt;
</description>
            <pubDate>Sun, 20 Sep 2009 00:00:00 </pubDate>
        </item>
        
        <item>
            <guid>http://www.mivok.net/2009/04/18/bashquoting.html</guid>
            <link>http://www.mivok.net/2009/04/18/bashquoting.html</link>
            <title>Bash quoting and whitespace</title>
            <description>&lt;p&gt;A common thing when writing shell scripts is to allow the user to specify
options to commands in a variable. Something like the following:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span class=&#34;gp&#34;&gt;$&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;OPTS&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;quot;--some-option --some-other-option&amp;quot;&lt;/span&gt;
&lt;span class=&#34;gp&#34;&gt;$&lt;/span&gt; my_command &lt;span class=&#34;nv&#34;&gt;$OPTS&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We can set my_command to the following script to see exactly what gets
passed:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span class=&#34;c&#34;&gt;#!/bin/bash&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;for &lt;/span&gt;t; &lt;span class=&#34;k&#34;&gt;do&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;quot;&amp;#39;$t&amp;#39;&amp;quot;&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Running the above prints the following output:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span class=&#34;go&#34;&gt;&amp;#39;--some-option&amp;#39;&lt;/span&gt;
&lt;span class=&#34;go&#34;&gt;&amp;#39;--some-other-option&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This works fine, until you want to include options with whitespace in them:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span class=&#34;gp&#34;&gt;$&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;OPTS&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;quot;--libs=&amp;#39;-L/usr/lib -L/usr/local/lib&amp;#39;&amp;quot;&lt;/span&gt;
&lt;span class=&#34;gp&#34;&gt;$&lt;/span&gt; my_command &lt;span class=&#34;nv&#34;&gt;$OPTS&lt;/span&gt;
&lt;span class=&#34;go&#34;&gt;&amp;#39;--libs=&amp;#39;-L/usr/lib&amp;#39;&lt;/span&gt;
&lt;span class=&#34;go&#34;&gt;&amp;#39;-L/usr/local/lib&amp;#39;&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This output clearly isn&#39;t what we want. We want a single parameter passed with
the entire content of $OPTS.  The culprit here is &lt;a class=&#34;reference external&#34; href=&#34;http://wooledge.org:8000/WordSplitting&#34;&gt;Word Splitting&lt;/a&gt;. Bash will
split the value of $OPTS into individual parameters based on whitespace. One
way to get around this is to put &lt;cite&gt;$OPTS&lt;/cite&gt; in double quotes:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span class=&#34;gp&#34;&gt;$&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;OPTS&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;quot;--libs=&amp;#39;-L/usr/lib -L/usr/local/lib&amp;#39;&amp;quot;&lt;/span&gt;
&lt;span class=&#34;gp&#34;&gt;$&lt;/span&gt; my_command &lt;span class=&#34;s2&#34;&gt;&amp;quot;$OPTS&amp;quot;&lt;/span&gt;
&lt;span class=&#34;go&#34;&gt;&amp;#39;--libs=&amp;#39;-L/usr/lib -L/usr/local/lib&amp;#39;&amp;#39;&lt;/span&gt;

&lt;span class=&#34;gp&#34;&gt;$&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;OPTS&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;quot;--libs=-L/usr/lib -L/usr/local/lib&amp;quot;&lt;/span&gt;
&lt;span class=&#34;gp&#34;&gt;$&lt;/span&gt; my_command &lt;span class=&#34;s2&#34;&gt;&amp;quot;$OPTS&amp;quot;&lt;/span&gt;
&lt;span class=&#34;go&#34;&gt;&amp;#39;--libs=-L/usr/lib -L/usr/local/lib&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Putting &lt;tt class=&#34;docutils literal&#34;&gt;$OPTS&lt;/tt&gt; in double quotes suppresses word expansion. In the above
example, that works as expected. The second command has the single quotes
removed as they were passed directly to the command, which isn&#39;t what we
wanted. So far, so good. The problem, as you may have spotted by the removal
of the single quotes, comes when we want to pass more than one parameter in
&lt;tt class=&#34;docutils literal&#34;&gt;$OPTS&lt;/tt&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span class=&#34;gp&#34;&gt;$&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;OPTS&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;quot;--cflags=O3 --libs=-L/usr/lib -L/usr/local/lib&amp;quot;&lt;/span&gt;
&lt;span class=&#34;gp&#34;&gt;$&lt;/span&gt; my_command &lt;span class=&#34;s2&#34;&gt;&amp;quot;$OPTS&amp;quot;&lt;/span&gt;
&lt;span class=&#34;go&#34;&gt;&amp;#39;--cflags=O3 --libs=-L/usr/lib -L/usr/local/lib&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Here, the entire &lt;tt class=&#34;docutils literal&#34;&gt;$OPTS&lt;/tt&gt; variable gets passed as a single parameter, which
isn&#39;t what we want. We want &lt;tt class=&#34;docutils literal&#34;&gt;&lt;span class=&#34;pre&#34;&gt;--cflags&lt;/span&gt;&lt;/tt&gt; to be passed as one parameter, and
&lt;tt class=&#34;docutils literal&#34;&gt;&lt;span class=&#34;pre&#34;&gt;--libs&lt;/span&gt;&lt;/tt&gt; (and everything that comes with it) to be passed as another
parameter. Adding more quotes, backslash escaped or not, does nothing to help.&lt;/p&gt;
&lt;p&gt;The solution? Use bash arrays:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span class=&#34;gp&#34;&gt;$&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;OPTS&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;quot;--cflags=O3&amp;quot;&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;quot;--LIBS=-L/usr/lib -L/usr/local/lib&amp;quot;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;gp&#34;&gt;$&lt;/span&gt; my_command &lt;span class=&#34;s2&#34;&gt;&amp;quot;${OPTS[@]}&amp;quot;&lt;/span&gt;
&lt;span class=&#34;go&#34;&gt;&amp;#39;--cflags=O3&amp;#39;&lt;/span&gt;
&lt;span class=&#34;go&#34;&gt;&amp;#39;--LIBS=-L/usr/lib -L/usr/local/lib&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Perfect. But what about backward compatibility? If you have hundreds of
scripts that use a string for &lt;tt class=&#34;docutils literal&#34;&gt;$OPTS&lt;/tt&gt;, how does it work if you change to
using arrays? Let&#39;s try it out:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span class=&#34;gp&#34;&gt;$&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;OPTS&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;quot;--some-option --some-other-option&amp;quot;&lt;/span&gt;
&lt;span class=&#34;gp&#34;&gt;$&lt;/span&gt; my_command &lt;span class=&#34;s2&#34;&gt;&amp;quot;${OPTS[@]}&amp;quot;&lt;/span&gt;
&lt;span class=&#34;go&#34;&gt;&amp;#39;--some-option --some-other-option&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;So it works if your old scripts only have single options, but if multiple
scripts are needed, then they will need to be changed to use arrays instead.
This however seems to be the best option for passing multiple arguments with
whitespace.&lt;/p&gt;
</description>
            <pubDate>Sat, 18 Apr 2009 00:00:00 </pubDate>
        </item>
        
    </channel>
</rss>