I'm currently working on a project that consists of multiple subsystems. Integrating those subsystems is normally a matter of getting the installer for each and then running them on a machine that has been prepared to have all prerequisites. It's not really a lot of work, although it can be a bit cumbersome at times.
But since we build installers only once per week, we also only get one such integration build per week. And for some of the stuff I'm working with that just isn't good enough.
So I decided to do something about it and see if I could create a nightly integration build. Luckily we already run quite some unit tests every night and -as it happens- one of the teams is using VMWare as the basis of their unit tests in a way I hadn't seen before.
The team has a VMWare image with a snapshot just after they installed all the prerequisites on it. Every night, they revert the VMWare image to that snapshot and then install the software on it through a combination of NAnt files, batch files and custom made executables.
The key to installing the software without security issues is to have it run on the VMWare image itself, which is accomplished by using the wonderful psexec tool. Using psexec allows you to start a process on remote machine. Or a remote virtual machine in our case.
So the main NAnt file conists of this first instruction:
<exec program="vmrun" append="true" commandline="reverttosnapshot "${vmware.image.file}"" />
Which reverts the VMWare image to its snapshot.
And then many of these instructions:
<exec program="psexec.exe" basedir="${pstools.dir}" commandline="\\${target.name} -u ${runas.username} -p ${runas.password} -i nant -logger:NAnt.Core.XmlLogger -f:"${host.name}\install_module_a.build" -D:database.type=mssql -D:database.cm.server=amssql2005 -D:database.cm.database=nightly_53_${target.name} -D:database.cm.username=dbuser53 -D:database.cm.password=dbuser53" />
I think you'll agree that this isn't the most readable NAnt instruction ever seen. But it basically starts NAnt on the remote (virtual) machine with a .build file that is on the (physical) host machine. All the -D arguments just tell the .build file what to do on which machine.
After a bunch of these psexec commands, we tell the virtual machine to reboot:
<exec program="psshutdown.exe" basedir="${pstools.dir}" commandline="-r -t 10 -f \\${target.name}" />
And voila, we have a fresh nightly build ready for testing.
I'm pretty sure we could also have accomplished that last step through some of VMWare's tools, but -like pretty much all
sysinternals tools- psshutdown just happens to be part of our standard tool belt.
Now all that is left to do is run an automatic sysprep on the fresh build, so that multiple people can start it without getting into each others way.