Java 2 Ada

Integrating the project subversion revision in an Ada application log

By stephane.carrez

In software development it is often necessary to know the revision number that was used to build an application or a library. This is specially useful when a problem occurred to get and look at the good sources. Integrating this information automatically in the build process is a common practice. This article explains how an Ada application can report the subversion repository and revision in an application log.

Subversion keyword substitution

Subversion provides a substitution feature which allows to replace some pre-defined keywords by the file revision, the last modified date or the last author. In an Ada source, we could declare the following string variables:

package Version is
   Revision : constant String := "$Rev$";
   Head_URL : constant String := "$HeadURL$";
end Version;

To activate the keyword substitution you have to set some subversion property on the file:

$ svn propset svn:keywords "Revision HeadURL" version.ads

Each time the file is committed, the keywords will be replaced to integrate the new value. The expanded string will look like:

$Rev: 318 $
$HeadURL: https://ada-util.googlecode.com/svn/trunk $

The issue with subversion keyword substitution is that the information reported only concerns the file changed not the revision of the project (as returned by svnversion for example). In other words, it is necessary to change the version.ads file to get an updated revision number.

Keyword substitution with gnatprep

The gnatprep tool is a pre-processor provided by the GNAT Ada compiler. It reads an input file, evaluates some conditions and expressions (similar to cpp but slightly different) and produces an output file with substituted values. The file to pre-process is an Ada file that will have the .gpb extension to differentiate it from regular Ada files. For our concern we will use gnatprep to substitute some variables, a String and a number. The declaration could be the following:

package Version is
   Head_URL : constant String := $URL;
   Revision : constant Positive := $REVISION;
end Version;

To produce the expanded .ads file, we will invoke gnatprep and give it the URL and REVISION variables. The manual command would look like:

$ gnatprep -DREVISION=23 -DURL="https://..." \
    src/version.gpb src/version.ads

Running such command by hand can be cumbersome. It is easy to use a Makefile with a make target that will do the full job of extracting the latest revision and invoke gnatprep. The make target is the following (make sure to have a tab as first character in the gnatprep command):

version:
        gnatprep `svn info | grep '^[UR][eR][Lv]' | sed -e 's,URL: \(.*\),-DURL="\1",' -e 's,Revision: ,-DREVISION=,'` \
                  src/version.gpb src/version.ads

This make target could be run manually or be integrated as part of the build process so that it is executed each time a release build is performed.

Writing the log

The easy part is to report the application revision number either in a log or on the standard output.

with Ada.Text_IO;
...
   Ada.Text_IO.Put_Line ("Revision " & Positive'Image (Revision));

References

Subversion Keyword Substitution

Preprocessing Using gnatprep

To add a comment, you must be connected. Login to add a comment

Server configuration management: track changes with subversion and be notified

By stephane.carrez 1 comment

The overall idea is to put the server configuration files stored in /etc directory under a version control system: subversion. The VCS is configured to send an email to the system administrators. The email contains the differences with a previous version. A cron script is executed every day to automatically commit the changes, thus triggering the email.

The best practice is of course that each system administrator commits their changes after they validated the new running configuration. If they do so, they are able to specify a comment which is helpful to understand what was done.

Install subversion

First, you should install subversion with its tools.

 sudo apt-get install -y subversion subversion-tools

Mail notification

For the mail notification, you may use postfix, exim or sendmail. But to avoid to setup a complete mail system, you may just use a simple mail client. For this, you can use the combination of esmtp and procmail.

 sudo apt-get install -y procmail esmtp

Create the subversion repository

The subversion repository will contain all the version and history of your /etc. It must be protected carefully because it contains sensitive information.

 sudo mkdir /home/svn
 sudo svnadmin create /home/svn/repos
 sudo chmod 700 /home/svn
 sudo chmod 700 /home/svn/repos

Now, setup the subversion repository to send an email for each commit. For this, copy or rename the post-commit.tmpl file and edit it to specify to whom you want the email to be sent:

 sudo cp /home/svn/repos/hooks/post-commit.tmpl  \
           /home/svn/repos/hooks/post-commit

and change the last line to something like (with your email address)

 /usr/share/subversion/hook-scripts/commit-email.pl \
  --from yoda+mercure@alliance.com \
  "$REPOS" "$REV" yoda@alliance.com

Initial import

To initialize the repository, we can use the svn import command:

 sudo svn import -m 'Initial import of /etc' \
               /etc file:///home/svn/repos/etc

Subversion repository setup in /etc

Now the hard stuff is to turn /etc into a subversion environment without breaking the server. For this, we extract the subversion /etc repository somewhere and copy only the subversion files in /etc.

 sudo mkdir /home/svn/last
 sudo sh -c "cd /home/svn/last && svn co file:///home/svn/repos/etc"
 sudo sh -c "cd /home/svn/last/etc && tar cf - `find . -name .svn` | (cd /etc && tar xvf -)"

At this step, everything is ready. You can go in /etc directory and use all the subversion commands. Example:

 sudo svn log /etc/hosts

to see the changes in the hosts file.

Auto-commit and detection of changes

The goal now is to detect every day the changes that were made and send a mail with the changes to the supervisor. For this, you create a cron script that you put in /etc/cron.daily. The script will be executed every day at 6:25am. It will commit the changes that were made and send an email for the new files.

 #!/bin/sh
 SVN_ETC=/etc
 HOST=`hostname`
 # Commit those changes
 cd $SVN_ETC && svn commit -m "Saving changes in /etc on $HOST"
 # Email address to which changes are sent
 EMAIL_TO="TO_EMAIL"
 STATUS=`cd $SVN_ETC && svn status`
 if test "T$STATUS" != "T"; then
   (echo "Subject: New files in /etc on $HOST";
    echo "To: $EMAIL_TO";
    echo "The following files are new and should be checked in:";
    echo "$STATUS") | sendmail -f'FROM_EMAIL' $EMAIL_TO
 fi

In this script you will replace TO_EMAIL and FROM_EMAIL by real email addresses.

Complete setup script

To help setup and configure all this easily, I'm now using a script that configures everything. You can download it: mk-etc-repository. The usage of the script is really simple, you just need to specify the email address for the notification:

 sudo sh mk-etc-repository sysadmin@mycompany.com
1 comment
To add a comment, you must be connected. Login to add a comment