In this blog I want to explain how the Software Updater module works in GCF. Towards this I have written a example program – “A simple browser”. The simple browser program provides a main-window with a address-bar (QLineEdit), where you can type a URL and the QWebView below shows the corresponding page. When the simple browser is launched, it shows up like this.
Suppose that I have deployed this application and have a whole lot of people using it. I then want to release updates for this application that should automatically download and install. What do I do?
The Software Updater module in GCF is meant to solve this very problem. The main() function of the browser code has the following code snippet.
GCF has a new built-in component called UpdaterComponent. Before initializing the component we
- Specify the primary server site from where updates can be downloaded. In this case it is the serversite directory within the local file system. It can be a HTTP or FTP location
- Enable/Disable third party update sites. This means you can have applications that can look for updates from other sites also
- Set the frequency of update-finding. Here it is ‘ApplicationStartup’. It can be ‘ApplicationStartupButOnceADay’, ‘UponUserRequest’, ‘OnceInAnHour’ etc…
- Once GCF figures out updates hosted in different sites, it creates a unified (dependency resolved) list of updates. You can configure GCF to automatically download all updates in the list, or just critical updates or even present a dialog box to the user for selecting updates to install. In this example we set the update strategy as ‘SelectAllUpdates’.
Server sites have to host a special file called Updates.xml and list out all the updates served from it. For the ‘simple browser’ example, the Updates.xml looks like this.
Since GCF is based on Qt, which is a cross-platform thing; you can have compressed update files (GVZ files) for each architecture/os-platform combination. Updates.xml should also specify the baseline version against which updates in that server can be installed. GCF provides a tool called ‘CreateGVZ’ to compress a directory into a GVZ file and a tool called ‘ExtractGVZ’ to extract contents of a GVZ file. Each compressed GVZ file contains
- Shared objects, libraries, XML files, config files etc pertaining to the update
- An Install.js script that describes how the update should be installed.
Shown below is a sample Install.js script for the ‘BookmarkComponent’.
The script basically contains a DoInstall() method that performs the update installation. ‘System’ and ‘FileSystem’ objects are provided by environment within which the script is executed. The environment is called ‘UpdateInstaller’ which is explained later in this blog
Now coming back to the code, when GCF::UpdaterComponent::initialize() is called, GCF
- Checks if there are updates in the download queue from the last session. If yes, the downloading of updates is resumed. This means that the user need not have to keep a session active until all updates have been downloaded. Updates can be downloaded over several sessions.
- Depending on frequency of update-finding, GCF spawns a thread and starts looking for updates
- After making a a unified (dependency resolved) list of updates, it then spawns yet another thread and begins downloading selected updates from their respective server sites. Ofcourse the update-strategy is taken into consideration
For communication between threads and between sessions of the same application, GCF::UpdaterComponent creates a special directory called Update within which it dumps all logs, temporary files, downloaded compressed updates and so on. Downloaded updates are dumped into this directory.
Next time when the GCF app is restarted, it checks whether there are any updates that were downloaded in the previous session. If yes, then the user is asked whether he wants to install the updates. If the user responds yes; then a separate process called ‘UpdateInstaller’ is launched and the GCF all quits. UpdateInstaller then installs the updates and restarts the application.
Let me show how this works with the ‘Simple Browser’ example. When I launch the program for the first time, it looks for updates in the primary server site and downloads updates into a special internal directory. Now when I select “Updates” -> “Preferences” you can see that GCF reports 2 available updates.
When the program is restarted, the user is asked…
If the user responds yes, the the ‘simple browser’ application quits and launches the ‘UpdateInstaller’ program, which installs the downloaded updates.
Upon clicking ‘Ok’, the ‘simple browser’ application is restarted.
Now when you look into go to Updates -> Preferences -> Installed Updates, you will notice this
The software updater module dumps sufficient information about its runtime into a log file, which is basically a HTML file.
Even the ‘UpdateInstaller’ dumps information about its runtime into another log file. These log files can be studied to figure out if there were any issues while finding, downloading and installing updates.
Cool module isnt it? If you like it, drop us an email. Checkout a copy of GCF from this SVN location to see all thisfor your self. SideNote: the module is not fully tested yet, so dont bet on it to work perfectly right now
SVN location: https://svn2.hosted-projects.com/vcreatelogic/GCF2/trunk/GCF