Google Web Store

Google web store is out, it’s just a bunch of links to websites. Really it does just about nothing. I love it! Why? Despite doing nothing at all, companies like the New York Times and NPR are making nice HTML 5, CSS3 websites. By targeting the “web store” they can ignore non standards compliant browsers. The sites are often much better and because they are just web links many of them run in Firefox and Opera. I did have some trouble loading the NPR app in Firefox though. Hopefully Firefox 4 and their web store will solve this. Anything that pushed companies to make nicer standards compliant websites is good in my opinion.

The web store does have one feature,  users can rate “apps” and the better apps can get featured.

Better report writing with the Appy framework

Awhile ago I mentioned using openoffice’s pyuno to create reports. I wanted to insert some variables right in a word file so that end users could customize reports themselves. Well it seems Appy POD does just this. While it doesn’t support ods as my little project does it’s far better in every other way. For one it doesn’t require unless you want to convert the document, making it way faster. It also pushes a lot of report writing work to openoffice (or any office program that can do track changes). This makes for more end user flexibility, at the expense of ease of use. I can easily pass pod Django model instances and pod will render them. In my word document I can just add


to render some student instance’s name. You can even put python code in the document for loops and such (do row for x in many_xs can make a new row for each of your objects). Of course with such flexibility comes a sharper learning curve. You have to put python code in track changes, comments, or fields. While it looks nice to view, making the report can be frustrating. I made an openoffice extension to make it easier to add fields, just install then click tools, addons, insert field. One could also place this in a toolbar or keyboard shortcut for even easier access.

Insert Field Openoffice Extension

Appy POD is certainly worth looking into for anyone looking to do customizable report writing. It’s like Django’s templating system but for the word processor.

What’s missing in Linux today

Seems like there’s always a new article about Linux rising to the top or failing. Year of the Linux Desktop, Linux has no market share and never will, etc, etc. Its seems that Linux both has solved every possible problem and has 110% market share while also having 0% market share and useless. Here are my thoughts on Linux being used to replace Windows in the enterprise based on my experience with it.

Wifi, still trouble (try using certain Ralink cards) but manageable and rarely a problem.

Office productivity is fine. OpenOffice LibreOffice (this name sucks but so does oracle so I’m divided) works. MS Office runs in wine but expect to pay for a commercial wine if you want multi user support. No serious issues here.

Printing, some just don’t work. But I’ve rarely encountered this. Many take some effort to work, but nothing beyond an entry level sys admin. Good enough for me.

LDAP support. If you’ve read this blog before you know there’s major issues here. It can be done. But with limitations. For example Windows lets you select your domain. You try and log in to a domain it waits for the domain to come up then you log in. You select local machine and it just does it without the need to wait. Linux….well nothing similar. I use Centrify Express but I have to choose between waiting (a long time at boot) for the domain connection to be made or just ignoring it and getting authentication errors (if credentials aren’t cached) when the computer is still connecting to the network and the domain. People expect this stuff to just work, since 2000 at least. A decade later and Linux can’t do it seamlessly.

File shares. Simple smb or nfs is easy yes. Want to put your home on nfs? Fine. WHO DOES THAT? It’s 2010 everyone uses laptops. People take the laptop outside and the home folder drops? This is not acceptable. I’m writing off NFS as useless on desktop computing. Windows deals with this with folder redirection. Your share folders act like mounted network drives until they are synced locally. When back online files get synced to the network. It just works as they say. I am looking into an old program called unison which seems to be able to sync folders. Also there is a program called sparkleshare that’s still in development that looks promising.  Both of these would give you Dropbox-esk sync functionality. That’s nice but still Windows does it better.

Application compatibility. This one probably puts off a lot of people. I actually think Linux is good here, of course I speak only from my own experience. My thinking today is where is not IS there a Linux version. There are notable exceptions that I simply don’t use. My biggest complaint here is that people need to make deb and rpm packages for their stuff. Seriously if you can afford to make some stupid custom install you can afford to make a package instead. Games are an exception but I’m talking about using Linux for enterprise desktops not personal.

More uno reports

I’ve been playing around more with’s uno api for making reports. Since I’ll be making more updates I’ll just post a link to the Google Code site

My latest improvement is supporting tables. It’s probably best to just show what it does.

Now a user could just download the report, change fonts, layout, etc, and reupload it. It does have it’s limitations and is a work in progress but it’s already pretty cool. As a developer I can just define what variables can be used and let someone else make the report (and change it around later). To use it you just have to make the proper data structures, so really this could be ported to any data driven application, not just Django.

LED lighting

I’ve recently purchased some LED lighting to see how it is. LED lights are more energy efficient and last much longer than CLF lights. That also don’t contain mercury and are very durable. I went with four of these

I have them installed in overhead recessed light fixtures. They seem to be ideal for this type of use because they are highly directional. The light seems to be on par with CLF but not as “warm” as incandescent. They work with a dimmer switch, though at certain levels they do flicker. It’s not a problem it happens at a predictable level that I just avoid. Pricewise they are very expensive. But I do expect them to pay for themselves in the long term in terms of energy savings and that they should last a very long time. Also I dropped one once and it didn’t break. I can’t figure out where they are made, they actually don’t say. The price should keep going down as more people buy them, but I’m ok with being an early adopter. Yeah energy efficiency!

Django and uno reports’s python uno library is great for report writing in a web application. I wanted to create a report template system where users can create templates with a word processor of their choice. I created a simple template model which consists of a CharField and FileField. Users can upload templates here in .doc, .odt, or any format supports.

Next I created some generic template report functions.

from django.http import HttpResponse
from django.core.servers.basehttp import FileWrapper

import uno
import os
import string
import tempfile

def findandreplace(document, search, find, replace):
"""This function searches and replaces. Create search, call function findFirst, and finally replace what we found."""
#What to search for
search.SearchString = unicode(find)
#search.SearchCaseSensitive = True
#search.SearchWords = True
found = document.findFirst( search )
if found:
print 'Found %s' % find
while found:
found.String = string.replace( found.String, unicode(find),unicode(replace))
found = document.findNext( found.End, search)

def replace_report(infile, outfile, data):
"""Replace words in a file use like this
data['$TEST']='worked yay'
returns a django HttpResponse of the file"""
# Boring uno stuff
local = uno.getComponentContext()
resolver = local.ServiceManager.createInstanceWithContext("", local)
context = resolver.resolve("uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext")
desktop = context.ServiceManager.createInstanceWithContext("", context)

# open document
document = desktop.loadComponentFromURL("file://" + str(infile) ,"_blank", 0, ())
cursor = document.Text.createTextCursor()

search = document.createSearchDescriptor()
#Do a loop of the data and replace the content.
for find,replace in data.items():
print find,replace

# create temporariy file to store document in
tmp = tempfile.NamedTemporaryFile()
document.storeToURL("file://" + str(, ())

# create http response out of temporariy file.
wrapper = FileWrapper(file(
response = HttpResponse(wrapper, content_type='application/odt')
response['Content-Length'] = os.path.getsize(
response['Content-Disposition'] = 'attachment; filename=' + outfile

return response

In this example I’m replacing text in a file. The result is returned as a http response. I can use it like this

template = Template.objects.get_or_create(name="My Selected Template")[0]
data['$date'] = str(
return replace_report(template.file.path, "file.odt", data)

In this case I am taking out my template and replacing all instances of the word “$date” with the current date. I choose to use $ to mark it as a variable but it could really be anything. Now when a user wants to change a font they can do it themselves.

Linux and Active Directory round 2

* edit Jan 12 2010. Better more reliable scripts.

* edit Oct 27th The netbook deployment went well this time. Feedback is generally that they have less problems than our Windows machines. Using Impress instead of MS powerpoint seems to be the biggest issue as Impress has trouble importing some powerpoint files in the office open XML format. Next on my todo list is play around with Unison file sync, NFS, and update this guide to reflect some improvements a colleague made.

The goal here is to create typical Windows Active Directory connect like Linux workstation. This includes being able to log in using Active Directory and mount various shared folders. It also must be idiot proof. We don’t want users saving on the desktop not realizing the desktop is not part of their smb share. It also must be cloneable. There should be absolutely no required interaction with the the computer after putting on this image.

Active Directory Integration

I choose to use Centrify for this. Likewise open is another option, but it seemed more buggy and I hate the way you have to configure it.

Ok make sure partner repositories are enabled and install centrifydc. If you want to make a clone-able image set your host name as something generic like “stockimage”. Add this script to crontab’s @restart

if [ "$hostCurrent" == "$hostOld" ]
    set -x
    host1=$(/usr/sbin/dmidecode | grep 'Serial Number: ' | sed 's/.*: (.*)/1/;q')
    host=$(echo $host | sed 's/[ ]*//g')
    hostname $host
    echo $host > /etc/hostname
    # TODO: axe this ugly hack and have upstart call us when we're connected
    while [ $counter -lt 60 ] && [ ! `/sbin/route -n | sed -rn 's/^[ ]+([0-9.]+)[ ]+*/1/p'` ]
        sleep 1
        counter=`expr $counter + 1`
    # Do NOT put regular administrator password here!
    # Use a special account and keep it DISABLED.
    /usr/sbin/adleave -u 'j' -p 'secret'
    /usr/share/centrifydc/bin/centrifydc stop
    /usr/sbin/adjoin -f -u 'j' -p 'secret' -w --name $host
set +x
    ) >& /opt/ad.log
elif [ "`sed 1q $commonauth | grep '^# lines inserted by Centrify'`" ]
    # Prevent double password prompt
    pammount=`sed -rn '/^auth[ ]+optional[ ]$/p' $commonauth`
    sed -ri '/^auth[ ]+optional[ ]$/d' $commonauth
    sed -ri 's/^(auth[ ]+sufficient[ ]$/1 try_first_pass/' $commonauth
    sed -i  "1i\$pammount" $commonauth

That script will rename the hostname to something unique and join your domain. Because it’s on @reboot it runs every time the computer is turned on thus when you image it, it runs! Maybe put this in crontab last because you don’t want it running on your image. If you’re only joining one machine to AD then just run the adjoin command.

Ok bug work around time! I said Centrify is less buggy remember. This is only important for multi user machines, if there will only be one user you may skip this section. Ubuntu will boot well before you are online and thus a new user will get Authentication Error when trying to log in right away. To fix this first of all make sure if you use wireless that “enabled for all users” is checked in NetworkManager.

Next we need GDM to wait for centrify to connect before starting. We can do this with upstart.

Edit /etc/init/gdm.conf and look for the start on section. This basically tells GDM to only start once certain things have happened. Add centrify-connected to the bottom as seen here.

start on (filesystem
and started dbus
and (graphics-device-added fb0 PRIMARY_DEVICE_FOR_DISPLAY=1
or drm-device-added card0 PRIMARY_DEVICE_FOR_DISPLAY=1
or stopped udevtrigger)
and centrify-connected)

Now it we need to make the centrify-connected signal. Edit /etc/init.d/centrifydc and look for case “$CMD” in start). Add “initctl emit centify-connected” under wait_adclient  Like this.

echo -n "Starting $NAME: "
start-stop-daemon --start --quiet --exec $DAEMON --pidfile $PIDFILE 
if [ $RETVAL -eq 0 ]; then
echo "OK"
# upstart won't start gdm until we say we're connected
initctl emit centrify-connected  # added
echo "FAIL

That emits the signal telling GDM that Centrify is connected. The script is part of Centrify, it just didn’t emit the signal. It’s like they thought of this problem but didn’t actually fix it.You could reboot now if you wanted and it should work, but there’s much more we can do.

If your splash no longer shows up (happens to me 100% of the time on 10.04). You can try this command to fix it. I add this note because it can take a while for wifi to connect, then centrify to find AD, then GDM to start. If the users stares at the black screen for 1 minute they will probably assume the computer is just broken.

sudo -i
echo FRAMEBUFFER=y > /etc/initramfs-tools/conf.d/splash Code:
update-initramfs -u

Mount Windows Shares

Now your users will fire up nautilus and start browsing windows shares. smb://$/myuser/documents is so easy to remember right? 😛

Lets face it users don’t know what a file share is usually. Lets mount them automatically for them like Windows does.

sudo apt-get install libpam-mount smbfs

Now edit /etc/security/pam_mount.conf.xml

make it looks something like this in the section <pam_mount> Make sure to change it for your own purposes. In this example I’m mounting a user’s documents folder.


<!-- Volume definitions -->

<volume user="*" fstype="cifs" server="server" path="users/%(DOMAIN_USER)" mountpoint="~/Documents" />

Don’t try mounting anything as Desktop because gnome won’t like it. There is a workaround here if you really need Desktop to be part of the share. First turn off the auto-creation of these folders (this puts you in charge of making them! Nautilus will not start if it doesn’t have these folders! Yes Nautilus sucks.) Edit /etc/xdg/user-dirs.conf and set enabled to False. Now edit /etc/skel/.profile and add the lines

mkdir "$HOME/Documents/Desktop" 2> /dev/null
ln -s "$HOME/Documents/Desktop" "$HOME/Desktop" 2> /dev/null
mkdir "$HOME/Documents/Downloads" 2> /dev/null
ln -s "$HOME/Documents/Downloads" "$HOME/Downloads" 2> /dev/null

This would symlink the Desktop and Downloads folder to be inside of Documents. Documents in actually a smb share. This should keep users saving files in places that are in smb.

There are two Ubuntu bugs related to smbfs. If your system hangs at logout look here

If it hangs at shutdown look here

Ok another Centrify bug work around is explained here Centrify goofs up pam_mount. I mean who would really want to connect to shares AND use active directory  😉  If you can’t handle clicking

1) Open /etc/pam.d/common-auth file

2) Check if “auth optional” is the first line and “auth sufficient” second line. If “yes” then change the second line to:

auth       sufficient try_first_pass

I also found that adding try_first_pass to the line will allow non AD users to log in without entering the password twice.

Odds and ends

If you want to give some users sudo edit /etc/sudoers and add

%ADMIN\UnixAdmins ALL = (ALL) ALL

That command would give the UnixAdmins group in the domain ADMIN sudo access.

If you want to edit the default desktop install a program called sabayon. It crashes sometimes but when not crashing it works pretty well. For some reason rebooting fixes it’s crashing…weird.

Another problem is that non admin users can disable network manager for the entire system even after a reboot! I’m not sure what to do about this, it’s a major headache because users won’t be able to log in at all without networking. I can’t think of any fix other than disabling network manager, but this is not ideal as sometimes there are legitimate uses for network manager.

As Mike pointed one could use the adjoin –selfserve command if AD knows the hostnames in advance. I choose to use an account that is usually disabled so if users see the password, they won’t be able to do much.

Compared to Windows this is a huge pain the first time to get right but cloning is way easier. I love running one image on many different models of computers. I moved the image around to several computers fine tuning it for each one. That included installing specific drivers. In the end I have one image that can be deployed anywhere.

I’m still missing a few must have features such as syncing the entire home folder to a share. NFS home folder is not enough, try leaving the building with your NFS home folder laptop. iFolder is an option I want to look into more. My initial experience is that it’s difficult to configure. It also doesn’t give you a CIFS interface which is often nice to have. There are any number of hosted solutions (Dropbox, JungleDisk, Ubuntu one, etc) that might work for you. It’s a shame Canonical won’t offer this as an on site solution like they do Landscape. Sparkle Share is an upcoming project that aims to meet this need but it’s not ready yet. You could also look into CMS software such as Alfresco.