Archives / Search ›

Most incompatible blog ever

So I saw a link to this weblog on Planet Python, and thought it would be interesting to subscribe. But…

  • Even simple display of blog entries requires JavaScript, so they don’t render in NetNewsWire (where I have JavaScript disabled).
  • Even with JavaScript enabled, entries don’t render in released versions of Safari, and links to old posts are broken in Opera. Everything appears to work fine in Mozilla and WebKit trunk.
  • With browsers that actually load the pages, there’s often an annoying lag between when an empty page shell loads, apparently completely, and when the content deigns to appear. If you try to expand a post, the page inexplicably scrolls to the top for a second, before giving you what you asked for.
  • The RSS feed is titles-only, so I can’t read it that way either.
  • There are no visible permalinks on the site itself: every link just calls some JavaScript function or other.

So in order to find the first entry (which, conveniently, is #15) I had grab it from the RSS feed, or guess. The author is aware of the problems, as shown by a comment on that post. His name and email address, of course, appear nowhere apparent on the blog, but can be obtained through whois or his PyWeek entry (the latter seems to be a reasonably normal Web page).

After all that, the content is actually pretty decent, so I’ll remain subscribed; I’ll just curse loudly every time I have to switch browsers to view an entry. I look forward to version 2.0 implemented entirely in Flash.

1001Screenshot 1.0.2 released

Just a minor fix because 1001 1.0b44 gained a hyphen in its bundle identifier; it is now tv.kung-foo.1001 instead of tv.kungfoo.1001. Download here; requires Mac OS X 10.3 or later and, obviously, 1001 and a Flickr account.

And since I posted the original message about this, 1.0b45 came out. 1001 continues getting nicer; maybe I should actually use my real camera a bit more, instead of just posting screenshots and poor-quality phonecam pictures :-)

Now, off to install my new bike tires before I go to school.

(Doh, the link was broken; fixed. The new tire I installed survived the trip to school; so far, so good.)

Overriding DNS for domains in OS X Tiger

ACM@UIUC has a bunch of machines behind NAT, which are all in the non-publicly-served domain internal.acm.uiuc.edu, and as I started to need these machines more for my research, I got annoyed at having to do a nested ssh every time I wanted to access them.

The obvious solution was a VPN. I set up OpenVPN on our OpenBSD router box. I’ve done enough OpenVPN evangelism here, so I won’t do more than say it’s worth checking out.

Next came the client side. OpenVPN, at least on Unix platforms, doesn’t automatically modify your nameserver configuration (it used to not modify your routing table either), so I wrote a Python script which automatically edits resolv.conf to add the appropriate nameserver address for internal.acm when you connect, and remove it when you disconnect.

This worked wonderfully until I upgraded to Tiger. OS X 10.4, except for a few tools like host, no longer directly reads /etc/resolv.conf to determine nameservers and search domains. Instead, Tiger has a much more flexible (but rather poorly documented) DNS interface as part of the System Configuration framework. Not to worry, it does keep resolv.conf up to date with the current state of things, but if you change that file, don’t expect Safari, Mail, or even ssh or ping to recognize your changes.

After some poking around and help from a mailing list, I developed a solution. Try running scutil --dns, where you’ll see multiple resolvers, each resolver with its own set of (search) domains and nameservers—it’s like a routing table for DNS. This architecture solves my problem much more elegantly than editing resolv.conf. You can even be connected to multiple VPNs simultaneously, with a private nameserver and associated domains for each VPN, and everything just works™.

I rewrote the script to use this new mechanism, and had been using it a month or so without problems, when I found this article posted at macosxhints.com, which proposes a much more primitive method of altering the nameserver configuration. So I posted a comment saying anyone could email me and I’d send them my script—a sure-fire procrastination tactic, since I was sure nobody would email me immediately, and I planned on cleaning the script up for more general use, just not then because I had several deadlines.

I’ve now had a chance to clean up the script so it is more generically useful. Here is the script with its associated OpenVPN config file.

In order to get the script to work, you’ll need to install PyObjC (has an installer), then the SystemConfiguration wrapper.

If you’re not familiar with using Python’s distutils, to install the wrapper, cd into the SystemConfiguration-0.3 directory, then run python setup.py install. If you get permissions errors (which you shouldn’t on a default OS X install, but…) you might need to sudo python setup.py install instead.

When the VPN is up, OS X Tiger will use the OpenVPN DHCP option-provided nameserver(s) for the corresponding search domains, but will use your existing nameserver(s) for everything else. Use scutil --dns to see one or more resolvers appear after you’re connected, and disappear when you disconnect.

Version 3.0a2 of Tunnelblick, an OS X OpenVPN GUI, now seems to work with this script, as long as you change the cd command in the OpenVPN config file to use an absolute path. It’d be great if it or similar software could adopt this approach automatically, so I didn’t have to write a script at all.

Configuring Trac with FastCGI and lighttpd

I initially tried getting tracd to work, but couldn’t get it to generate URLs that made sense. So, I decided to investigate all the fuss about using lighttpd and FastCGI. It works, better than tracd likely, and is certainly more flexible.

Here’s my lighttpd.conf for dev.sabi.net. It essentially implements the “Global authentication” example from the TracMultipleProjects page on the Trac wiki. You need a trunk version of Trac for this to work; 0.8.x don’t have FastCGI support.

server.port         = 9013
server.document-root= "/home/nriley/web/public/"
server.indexfiles   = ( "index.html" )
server.pid-file     = "/home/nriley/var/run/lighttpd.pid"
server.errorlog     = "/home/nriley/logs/lighttpd.error.log"
accesslog.filename  = "/home/nriley/logs/lighttpd.access.log"
url.access-deny     = ( "~", ".inc" )
compress.cache-dir  = "/home/nriley/var/cache/lighttpd/compress/"
compress.filetype   = ( "text/plain", "text/html" )
fastcgi.server      = ( "/trac" =>
                       ( "trac" =>
                        ( "socket" => "/home/nriley/var/run/trac-fastcgi.sock",
                          "bin-path" => "/home/nriley/cgi-bin/trac.fcgi",
                          "bin-environment" =>
                           ( "TRAC_ENV_PARENT_DIR" => "/home/nriley/trac" )
                        )
                       )
                      )
alias.url           = ( "/media/" => "/home/nriley/share/trac/htdocs/" )
auth.backend        = "htdigest"
auth.backend.htdigest.userfile= "/home/nriley/etc/trac.digest.passwd"
$HTTP["url"] =~ "^/trac/[^/]+/login" {
    auth.require    = ( "/" =>
                       ( "method" => "digest",
                         "realm" => "sabi.net Subversion repository",
                         "require" => "user=nicholas"
                       )
                      )
}

In order for the above FastCGI association to work, I must create a file named trac in the server’s document root, so lighttpd has something to pass along to the FastCGI script. (I got this tidbit from this article on using Django with lighttpd).

I needed to use /media instead of /trac or something like /trac-common or /trac/common because I couldn’t get lighttpd to give up the FastCGI assocation with /trac.

It appears there’s nothing equivalent to “Require valid-user” in lighttpd, and the “require” statement isn’t parsed until a request is received, so you’ll need to add a bunch of users to a group and require a group, likely. The parsing error is very poorly identified, too: (http_auth.c.345) = is missing. I had to dig through the lighttpd source to see what it was referring to.

So, everything seemingly works; the only problem I’m having is my log file getting polluted with these messages:

2005-08-01 03:08:38: (mod_fastcgi.c.2110) FastCGI-stderr:  

which I’ve filed as a bug in Trac.

I also had to do some digging to figure out how to enable anonymous access to Subversion via WebDAV. The Subversion repository’s DAV interface was created as private to begin with, a sensible precaution. However, I couldn’t use <LimitExcept> to apply permissions, so instead I have a AuthzSVNAccessFile svn-access.conf that looks like this:

[dev:/]
nicholas = rw
* = r

Then I open up Apache access with Satisfy Any. Some more discussion of this technique is here.