macintosh
Sep 25, 2008
lxml on Mac OS X
Now with even less seg-faulting!
For a current project I needed to include (the most excellent Python XML library) lxml. Getting the right version to run on Mac OS X has been notoriously difficult, though. Easy-installing it was broken (and currently is, for me, as well) and while I have found multiple how-tos, they all dealt with the problem by installing it manually from sources and patching the configure process etc. pp. That would, of course, defeat the whole purpose of using buildout in the first place.
Cheeseshop to the rescue: there is a recipe for installing lxml along with the proper versions of libxml and libxslt, however, its default values didn't work for me. So for the record: the following buildout snippet will get you non-segfaulting lxml on (at least) Mac OS X 10.5.x and Ubuntu linux. YMMV.
parts =
[...]
lxml
eggs =
[...]
lxml==2.1.2
[lxml]
recipe=plone.recipe.lxml
egg =
lxml==2.1.2
libxml2_url =
http://xmlsoft.org/sources/libxml2-2.7.1.tar.gz
libxslt_url =
http://xmlsoft.org/sources/libxslt-1.1.24.tar.gz
p.s. this should be good news for all folks working with Deliverance. Perhaps now I could revisit that...
Apr 18, 2008
Connecting Plone to Mac OS X Server with LDAP
A step-by-step how-to for connecting a Plone 3.x instance with a Mac OS X 10.5.x Server's OpenDirectory service
The idea is, of course, that all (or just some) of your OS X Server users can authenticate against a Plone instance using the same credentials that they use to access all the other services (usually filesharing).
Requirements
I'm assuming a buildout based setup, so you will need to add the following bits to your buildout.cfg:
[buildout]
parts =
...
productdistros
openldap
...
[openldap]
recipe = zc.recipe.cmmi
url = http://www.openldap.org/software/download/OpenLDAP/openldap-release/openldap-2.3.27.tgz
extra_options= --disable-slapd --disable-backends
...
[productdistros]
recipe = plone.recipe.distros
urls =
...
http://plone.org/products/ploneldap/releases/1.0/PloneLDAP-bundle-1.0.tar.gz
nested-packages =
...
PloneLDAP-bundle-1.0.tar.gz
You will also need python-ldap, for which even some eggs exist, however, I found that they didn't work on my test server (Ubuntu, 64bit) as they seem to have some .so files that assume a 32bit architecture (just a wild guess on my part), so instead I just installed it via apt-get (Ubuntu really has good support for Python2.4 based packages btw, no wonder it's so popular among Zopistas and Plonistas!)
sudo apt-get install python2.4-ldap
Now you can run ./bin/buildout and restart your instance.
Adding the plug-in
In the ZMI, navigate to your Plone instance's acl_users and add a Plone LDAP Plugin from the upper right hand select box. Obviously, filling out the following form with exactly the right values is the trickiest bit of the entire operation, so I've tried to make the example values as self-evident as possible. They all assume that the FQDN of your Mac OS X server is my.ldap.server.tld, so it should be a no-brainer to substitute all values according to your own setup.
-
Set all three mappings (for Login Name Attribute, User ID Attribute and RDN Attribute) to
UID (uid). -
Users Base DNtocn=users,dc=my,dc=ldap,dc=server,dc=tld -
Groups Base DNtocn=groups,dc=my,dc=ldap,dc=server,dc=tld -
Manager DNtouid=diradmin,cn=users,dc=my,dc=ldap,dc=server,dc=tld. You will obviously need to substitutediradminfor the id you chose when setting up the OpenDirectory server. Hint: it's the same id you use to log into the Workgroup Manager ;-) - I have switched off encryption and SSL in my tests, so no guarantees that it will work with encryption (my Plone instance is running inside a VMware Fusion instance on the OS X Server itself, so I didn't see any need to bother with encryption, for a change)
Configuring the plug-in
Now you need to click on the newly created plugin at /plone/acl_users/ldap and activate all functionalities.
Still at /plone/acl_users/ldap click on Properties and User_Management and move the ldap plug-in to the top in both forms.
Finally, navigate to /plone/acl_users/ldap/acl_users and change the value for User object classes to posixAccount.
You now should be able to log into the Plone site using the credentials of a OS X Server user.
Apr 04, 2008
Using the OKI C9800 on a Mac
From the WTF-Department
Earlier this week I bought a printer for the new project I'm working on. A big, bad-ass OKI 9800 A3 color printer for the price of a small car -- not my money -- the client's money ;-).
Since we're a Mac-only shop here, I made sure it's got postscript3 and ethernet, so that connectivity wouldn't be a problem. Well, it was. Of course. Long story short: if we used the offical, OKI supplied PPD, the printer wouldn't print. It only could be coaxed into printing when using the generic postscript PPD -- which of course knew nothing about the A3 paper size or any of the other nifty features.
After spending three days(!) with the OKI hotline (spent mainly with re-stating our problem and configuration to various operators) I finally hit gold. In the form of a friendly, competent and female(!) operator (Hallo, Frau Walther!) who didn't just resort to OKI's ticket database but (gasp!) to her memory. She actually remembered a similar case a while back, told me to hold, came back 30 seconds later and ever since we're able to print here!
Turns out, that OKI has been delivering a faulty PPD - ever since march 2005! In the end it's just a single % character that's missing. I have to ask myself: WTF did they not update that file? Anyway, I'm posting this so that any other fellow OKI users can find this (because until now googling for the error Missing filter "application/vnd.cups-postscript 0 fierycupsfilter" didn't deliver any results. Hopefully, this will have changed).
Below you can find a diff of the the PPD or, for your convenience, you can download a patched version right here from tomster.org.
@@ -2947,5 +2947,5 @@
*% PPD Last Modified 2005.03.10
*% OS 10.2 PPD DB version 4/10/03 JDF
-*cupsFilter: "application/vnd.cups-postscript 0 fierycupsfilter"
+*% cupsFilter: "application/vnd.cups-postscript 0 fierycupsfilter"
*% End of PPD file
Mar 16, 2008
nginx and varnish on Mac OS X
Notes on how to create a local deployment setup for Zope on Mac OS X for debugging purposes.
Any non-trivial deployment of Plone usually consists of at least a web server 'sitting in front of' it, often enough accompanied by some sort of caching service. For my own purposes I have settled on nginx for the former and varnish for the latter[1].
They have proven to be a reasonably good team for me, especially in combination with recent versions of CacheFu, Plone's de facto default caching product. By 'reasonably good' I mean, that varnish and CacheFu in their 'normal' setup (i.e. with the 'official' Plone .vcl config) offer a reasonable trade-off between performance and potentially stale content.
I noticed this behaviour particularly when looking at Zope's access log (i.e. var/log/primary-Z2.log) while accessing my latest Plone installation at wahlcomputer.ccc.de. There was much too much going on, as theoretically there shouldn't be any requests reaching the backend until some content had changed. In essence, the site behaved much slower than it would need to by answering unnecessarily to requests that varnish should be able to satisfy.
However, in order to debug the caching and purging of content in detail I needed a local Mac OS X based setup that mirrored that on the FreeBSD box serving the site as closely, as possible. I habitually took notes while setting it up on my desktop machine and am now retracing my steps as I attempt to duplicate it on my Macbook (Just like a bug isn't fixable until it's reproducible, I never consider my admin work done until I have been able to do it at least twice). I'm confident that somebody out there will find the following notes useful, too (even if it's just myself six months^wweeks down the road)...
Since I'm a happy user of the macports collection already anyway, I let it do the 'heavy lifting' of actually installing nginx and varnish. In addition I provided a launchd startup item for varnish and also added a host entry for wahlcomputer to enable virtual hosting for nginx and varnish. Here it goes:
sudo port install nginx
sudo port install varnish
DNS
Before continuing the setup I first wanted to make sure that I could use the domain name wahlcomputer to access my machine. Instead of doing it 'properly' by adding a new record to OpenLDAP and thus possibly opening up what could amount to yet another can of worms I simply tried to edit ye' good ol' /etc/hosts file and added the following line:
127.0.0.1 wahlcomputer
And sure enough, even in the days of 'OpenLDAP FTW!!' Mac OS X still honours entries made to the hosts file so I could move on.
nginx
Next, I configured the freshly installed nginx. As the port already comes with a launchd start up item, I just needed to load it:
sudo launchctl load /opt/local/etc/LaunchDaemons/org.macports.nginx/org.macports.nginx.plist
It's my practice to leave the default files as untouched as possible and put all my configurations into separate files, that I simply include:
sudo mv /opt/local/etc/nginx/nginx.conf.default /opt/local/etc/nginx/nginx.conf
sudo mkdir /opt/local/etc/nginx/includes
sudo touch /opt/local/etc/nginx/includes/wahlcomputer.conf
sudo mkdir /opt/local/var/log/nginx/
To make nginx aware of those files I added the following line just before the final closing }:
include etc/nginx/includes/*.conf;
Here's its contents in its full, unabridged glory (and VHM gore):
server {
server_name wahlcomputer.ccc.de wahlcomputer;
location / {
proxy_pass http://127.0.0.1:8071/VirtualHostBase/http/wahlcomputer:80/foo/VirtualHostRoot/;
}
}
For the changes to take effect, I needed to restart nginx like so (why, oh why, does launchctl with all its bells and whistles not have a simple reload or restart command?!):
sudo launchctl stop org.macports.nginx
sudo launchctl start org.macports.nginx
Now visiting http://wahlcomputer/ showed the front page of the Plone site and I could move on to varnish:
varnish
Unlike nginx, the varnish port (currently) does not come with a startup item, so I made my very own (by blatantly copying from the nginx setup):
sudo mkdir /opt/local/etc/varnish
sudo touch /opt/local/etc/varnish/default.vcl
sudo mkdir /opt/local/etc/LaunchDaemons/org.macports.varnish
sudo touch /opt/local/etc/LaunchDaemons/org.macports.varnish/org.macports.varnishd.plist
sudo chown root:wheel /opt/local/etc/LaunchDaemons/org.macports.varnish/org.macports.varnishd.plist
sudo chmod 644 /opt/local/etc/LaunchDaemons/org.macports.varnish/org.macports.varnishd.plist
sudo ln -s /opt/local/etc/LaunchDaemons/org.macports.varnish/org.macports.varnishd.plist /Library/LaunchDaemons/
sudo mkdir /opt/local/var/varnish
sudo chown -R _www /opt/local/var/varnish
Looking at varnishd's man page - HTTP accelerator daemon - Linux Manual - Digipedia") I saw that there are some options that must be passed in upon start up. I did this by adding them to the ProgramArguments array in the /opt/local/etc/LaunchDaemons/org.macports.varnish/org.macports.varnishd.plist file:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Disabled</key>
<false/>
<key>KeepAlive</key>
<false/>
<key>Debug</key>
<false/>
<key>Label</key>
<string>varnishd</string>
<key>OnDemand</key>
<false/>
<key>GroupName</key>
<string>staff</string>
<key>UserName</key>
<string>_www</string>
<key>ProgramArguments</key>
<array>
<string>/opt/local/sbin/varnishd</string>
<string>-a</string>
<string>localhost:6081</string>
<string>-T</string>
<string>localhost:6082</string>
<string>-f</string>
<string>/opt/local/etc/varnish/default.vcl</string>
</array>
<key>RunAtLoad</key>
<false/>
</dict>
</plist>
Now all that was missing was to add some directives to the currently still empty file /opt/local/etc/varnish/default.vcl. It ended up being too long to quote here in its entirety, instead I will simply point you to a nice variation of the 'official zope-plone.vcl that I found that sports some neat enhancements.
Finally I could start up varnish:
sudo launchctl load /opt/local/etc/LaunchDaemons/org.macports.varnish/org.macports.varnishd.plist
In the nginx wahlcomputer.conf file all I needed to change was the port number from 8071 (the Zope instance) to 6081 (varnish).
By keeping a tail on the access logs of nginx and my Zope instance and looking at the response headers with firebug I can now start to tweak my setup to my heart's content. Stay tuned.
[1] A bit of an explanation is perhaps necessary as to why even bother with two types of machinery in front of Plone. The short answer is 'separation of concerns'. While varnish could theoretically take over most of the features that I use nginx for (namely, URL-rewriting, logging and static content delivery) I still would need it for SSL/HTTPS. Also, the logging feature of varnish requires an extra varnishlog process anyway.
Feb 27, 2008
Launchd in a nutshell
Apple's solution for startup items works well but seems over-engineered.
Today I needed to make a fetchmail process automatically start on a Mac OS X Server instance.
Now, ever since Version 10.4 this is the domain of launchd. But compared to what I'm used to in FreeBSD, Apple's own introduction to launchd seemed rather daunting.
My reasong was something along the lines of "If I can't use something as straightforward as rc I might as well get out the big guns and use daemontools" (which already e.g. takes care of my IMAP Server and, of course, my name servers.)
Well, to make a long story short, once I got over the fact, that I need to write XML to configure startup items everything else went rather smoothly. In the end, to have fetchmail launched automatically at startup I needed the following markup in /Library/LaunchDaemons/fetchmail.plist:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Disabled</key>
<false/>
<key>GroupName</key>
<string>staff</string>
<key>KeepAlive</key>
<true/>
<key>Label</key>
<string>fetchmail</string>
<key>Program</key>
<string>/usr/bin/fetchmail</string>
<key>ProgramArguments</key>
<array>
<string>--fetchmailrc=/Users/diradmin/.fetchmailrc</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>Umask</key>
<integer>7</integer>
<key>UserName</key>
<string>diradmin</string>
<key>WorkingDirectory</key>
<string>/Users/diradmin/</string>
</dict>
</plist>
(Since the fetchmail process won't be launched via a logged in user, I needed to point it explicitly to the config file I developed for it using the ProgramArguments key.)
Next, I needed to make sure that the abovementioned file had the right ownership and permissions:
sudo chown root:wheel /Library/LaunchDaemons/fetchmail.plist
sudo chmod 644 /Library/LaunchDaemons/fetchmail.plist
Unlike with rc or daemontools, however, just because I now had a perfectly fine config file sitting in its proper place didn't mean anything would happen next time the machine booted. No, I still needed to explicitly tell launchd to use this item using its companion launchctl command:
sudo launchctl load fetchmail.plist
To test the item I then proceeded to manually start it:
sudo launchctl start fetchmail
Note, that this time I didn't state fetchmail.plist as above but rather fetchmail, which refers to the Label key in the XML.
And sure enough, fetchmail was now up and running and was doing its thing. Since I had set KeepAlive to <true/> I could kill it and not even a second later, it was back up and running (with a new PID, of course). Nice. Just like daemontools.
While I'm glad that this all went rather smoothly for me I must say that I much prefer rc and daemontools, though. launchd seems over-engineered. I find that snippet above positively ugly. Even for XML. I mean, come on, what's this supposed to be: <key>RunAtLoad</key><true/>?
But to be fair, Apple specifically designed launchd to handle more than just start up items but to replace "init, rc, the init.d and rc.d scripts, SystemStarter (Mac OS X), inetd and xinetd, atd, crond and watchdogd", to quote its Wikipedia entry.
Anyway, from now on I'm probably just going to use the snippet above as boilerplate and get over with it ;-)
Oh, and Tim? Sorry about the XML bashing. I got nothing against XML per se. In fact I wouldn't know what to do without it. I just don't think it's a good choice for configuration files that are created and read by humans. (And perhaps, neither do you.) Even Zope is moving away from ZCML ;-)
