After a discussion on #sugar, I noticed that setting up a custom update-mechanism for Activities/XO bundles on XO’s is a bit of a lost art. I had to dig through the Sugar code a bit to get a clear understanding. I’ve updated the laptop.org wiki (see http://wiki.laptop.org/go/Software_updater), but it might be useful to give other deployments a heads-up on what’s involved through this syndicated post.
So the XO has a nice gui activity-updater, accessable by opening the control-panel, and then choosing the activity updater. Figures. The updater gives you two valuable functions: Updating existing activities, and installing new ones. At the moment the updater can’t be instructed to delete certain activities though, which is to bad, because otherwise deployments could contain just about all the administration of activities within one central place.
Out of the box an XO will check a default wiki-page on the laptop.org wiki. The XO expects a list of links to relevant builds of activities, together with some metadata embedded in the span/div that surrounds it. The XO will loop through all the activities in your Activities dir, it checks if it’s got a custom update url defined in its activities.info file. If so it’ll try to update from that url. Either way, it will also check the version on the page and will use the highest one. If it finds a newer build, it will include it in the list of suggested updates. If the XO finds an activity that’s not yet installed it will also be included in the list, but new activities will not be checked for updates from the url defined in its activity.info file.
As a local deployment you would want to control yourself to which version you want to update. You want to make sure the new version works for your build, and for your objectives, and not the ones of some random guy that happens to updates the according wiki-page. So what you do is point the XO to an update page under your control, which points the XO to the activities you want to put on it. To override the default update page, put a file with either /etc/olpc-update/activity-groups or /home/olpc/Activities/.groups on your system, with the relevant update urls on different lines (yes, you can have multiple).
At OLE Nepal we manage the activities on the schoolserver. So we’ve got a canonical set of activities in a folder reachable through http. In the same folder we put a dynamically generated page in the right format. A cron job checks the folder every hour, grovels the activity/info file of every one of them, and writes out a page with the correct metadata. In this way managing the right set of activities becomes a drag-and-drop affair.
def makeItemString(actId, actVer, actUrl, actName): return """ <br/> <span class="olpc-activity-info"> <span class="olpc-activity-id" style="display:none;">%s</span> <span class="olpc-activity-version" style="display:none;">%s</span> <span class="olpc-activity-url"><a href='%s'>%s</a></span> </span> """ % (actId, actVer, actUrl, actName)
So the updater will search for nodes with have olpc-activity-info as class name. Then it also wants to know the activity-id, the activity-version, and the activity-url, all extracted from the activity info file in the XO bundle.
As written above, if an installed activity has an update-url defined in its activity.info file by the activity creator, the XO will check the url for a version greater than the one in the groups file url. The latest version will be installed. This is seen as a feature, but I disagree. The url of some random page should NOT be checked. Again, we want to have control over what gets installed, and we can’t leave the risk of broken activities to chance or evil activity-developers. So I hacked the Sugar updater code ever so slightly and put it in our pilgrim local build:
The simplest way to not check the activity.info url is to open /usr/share/sugar/shell/controlpanel/model/updater.py and edit refresh_existing to not call _retrieve_update_version, but assign the values it would return if no update-url was found; so a tuple containing:
(0 if _DEBUG_MAKE_ALL_OLD else act.get_activity_version()), None, None, 0
And since the updater doesn’t check for new versions of new activities, we don’t need to make provisions for them.
And that’s about it. This gives us control enough over which activity is installed on our deployment XO’s. Cases not covered though by this mechanism are new bundles installed by the children themselves, and children installing versions newer than the ones we put in the schoolserver (which can be remedied easily enough by making sure the first tuple value above is always 0). But I’m not sure not addressing them should be regarded as missing features, or wanted behaviour.
[update] I sent a mail with some of my thoughts to the sugar-devel list and C. Scott Ananian layed out some excellent ideas for enhancing the updater to resolve to deficiencies mentioned above.