2010
Sub-archives
Nov 19, 2010
IOError: decoder jpeg not available
Moving a Zope instance made Plone sites lose image thumbnail generation. Seemingly odd PIL behaviour.
As often happens in hosting we recently moved some sites from one server to another. In this case a server had gone bang and so we rebuilt everything on a new server running the latest Ubuntu LTS.
Of course, one issue in moving the hosting was that the new server installation didn't come with the same versions of software installed as the old one did. In this case our Zope instance needs Python 2.3 - a fine vintage - but our new Ubuntu installation has Python 2.5 as the lowest available version for install by the package manager.
Thankfully, in the open source world it's easy to build older versions to run pretty much anywhere you want; so in a very short time we had the Zope instance up and running on our homemade Python 2.3 complete with Python Imaging Library (PIL).
Or so we thought.
After a short while we noticed an issue that thumbnails were not being generated when new images were uploaded. In the log was found:
File ".../lib/python2.3/site-packages/PIL/ImageFile.py", line 189, in load
d = Image._getdecoder(self.mode, d, a, self.decoderconfig)
File "...lib/python2.3/site-packages/PIL/Image.py", line 385, in _getdecoder
raise IOError("decoder %s not available" % decoder_name)
IOError: decoder jpeg not available
This error suggests that PIL had not been built with libjpeg support, however when building PIL it had output the following:
*** PIL CORE support not installed *** TKINTER support not installed --- JPEG support ok --- ZLIB (PNG/ZIP) support ok *** FREETYPE2 support not installed *** LITTLECMS support not installed
which indicates that libjpeg and zlib were both found during the build.
After a bit of rebuilding and head scratching the Plone community came to the rescue here:
http://plone.org/documentation/error/ioerror-decoder-jpeg-not-available
In our case we had simply omitted to specify the root of the libjpeg install (for us this is simply /usr because it was installed by the package manager).
So the crucial thing for us was to replace in PIL's setup.py :
JPEG_ROOT = None ZLIB_ROOT = None
JPEG_ROOT = libinclude("/usr/")
ZLIB_ROOT = libinclude("/usr/")It's a bit odd that it goes on and builds anyway with this missing but now we know about it we'll be looking out for it next time.
Sep 07, 2010
Google Wave is dead, long live Wave
Is the end of Google Wave the end of a new kind of communication, or just the end of the beginning?
A little over a year ago I blogged on the new phenomenon that was Google Wave. During that year we saw it gain popularity and all manner of extensions, plugins and desktop applications like Waveboard. As a company we used (and still use) it to write collaborative documents. Sadly, though, Wave would never reach its potential before Google decided to pull the plug on it.
On the face of it Wave was an obvious development - we all send messages around the world by various means, email, IM, forum, wiki, blog - so what we needed was a way to tie it all together - wasn't it? Well maybe, but the crucial thing that needed to happen didn't - at least not in time. Wave never saw its tentacles extend fully into the systems that we all know and already use, meaning that you had to convert yourself over to Wave in order to use it.
Another drawback was that there was no way yet (although it was promised for the future) to really use your own Wave server and have it hook into a larger Wave "cloud". That and the overall complexity of the Google interface seems to have resulted in Wave's premature death.
The odd thing now is that out of the ashes of Wave comes, yes, Wave. Google recently announced "Wave-in-a-box" which is ostensibly giving wave to the Open Source community so that in time everyone could host their own Wave server. This could be the best thing that happened to it. The Open Source community already manages development of the world's most popular web server - Apache, the most often recommended browser - Firefox, and provides free alternatives to commercial software in just about every sector.
The Google implementation of Wave was arguably too different and radical, too ahead of its time, but if the Open Source community can build on this basis in a modular way then, in time, Wave could still become the foundation of a new way of sending messages, an all-encompassing, open, distributed system that represents as much of a step forward as email has been over the last 20 or more years.
Aug 17, 2010
Intermediate Certificates
The future of the Certificate Industry is one of increasing fragmentation, and we can no longer rely purely on the browsers to do all the hard work for us. What this means in practice is an extra step, and something called an Intermediate Certificate.
We were advised by our Certificate Authority of choice (GeoTrust) some while back that they would be switching to new 2048-bit signing. Great, we thought. Now instead of it taking merely the lifetime of the universe to hack a certificate by brute force, it will take the lifetime of the universe squared. Big deal.
What we didn't realised was that in practice that would mean that the next time we renewed a certificate and installed it, the browser (in this case Firefox) wouldn't recognise it, and reports:
This Connection is Untrusted
www.site.com uses an invalid security certificate.
The certificate is not trusted because the issuer certificate is unknown.
(Error code: sec_error_unknown_issuer)
It worked with every other browser, but what's the point of shelling out for a bona-fide certificate if one of the world's most popular browsers doesn't recognise it? Good question.
We quickly searched for a solution, and discovered that we aren't the first people to whom this has happened. We also discovered, like them, that information from GeoTrust themselves is thin on the ground. We certainly didn't get any warning that something called an Intermediate Certificate might be required. Oh no, we had to work that out for ourselves.
The good news for anyone reading this is that we have discovered a useful page where you can download any Intermediate Certificate you might need. We're quite happy to advertise ssl247.com on this page because they really helped us out. Thanks guys!
Once you have your Intermediate Certificate, put it into a text file on your Apache server (we put it into /etc/apache2/certs and give it the suffix .crt) then add/modify the following directives in the relevant ssl VirtualHost:
SSLEngine on SSLCertificateFile /etc/apache2/certs/site.pem SSLCertificateKeyFile /etc/apache2/certs/site.key SSLCACertificateFile /etc/apache2/certs/intermediate.crt
Restart Apache and your site's new cert should now be trusted. Problem solved.
Feb 24, 2010
Recovering a Zope or Plone site that you can't access
Editing the ZODB via a python shell
Recently we had a case where someone changed the encoding on their Plone site using the portal_properties tool. This resulted in the site being unaccessible, even via the ZMI.
So, for posterity, here's how to recover from a fatal property setting:
1) Stop the instance (bin/instance stop or whatever)
2) Attach a python shell to the instance. There are a number of ways but in recent Zopes that ship with Plone (in this case Plone 3.3.1) the easiest is this:
bin/instance debug
This should run up a few lines and then settle down to a >>> prompt where you can type some python. You're now in a python shell and the ZODB is directly accessible via the "app" object.
3) Start a transaction. The right syntax had me foxed for a while, as it seems to have changed along the way, but the way to do it in recent zopes is like this:
>>> import transaction
It's important to do this before you start fiddling.
4) Make any changes you want. There are a few pages on things you might like to do to delete rogue objects etc, such as these:
http://www.zopelabs.com/cookbook/1054240694
http://wiki.zope.org/zope2/DebuggingWithIPythonAndOtherTips
However these are a bit old and don't help so much in this case as we need to change a property. So we do this:
>>> obj= app.unrestrictedTraverse("/Plone/portal_properties")
We can then look at a property like so:
>>> print obj.site_properties.default_charset ASCII
Aha, so this is wrong. Let's change it:
>>> obj.site_properties.default_charset="utf-8"
And see if it's changed:
>>> print obj.site_properties.default_charset utf-8
5) Very important step - if all went well don't quit the shell at this point, we need to commit like so:
>>> transaction.commit()
[If all didn't go well, then best to quit and not commit. That should leave things as they were before you started.]
6) You can then detach from the python shell with ctrl-d and see if your Plone site now works again.



