Ant is a popular build tool, especially for Java development. What most people don't realize is it can be used to automate other tasks. Lately I started using it for system administration purposes. Don't get me wrong, I'm not saying it should replace good old fashioned scripts. On the contrary, I estimate that I use simple bash scripts for 90% of the tasks, real languages like Python or PHP for 9%, remaining 1% is everything else, including Ant. And even this jobs I could do with other tool. But if a 10-line buildfile does the job of 100-line Python script, I'll go with the simpler solution.
What sysadmin tasks can you do with Ant?
Ant has support for:
-
File operations, like copy, delete, move, mkdir, chown, chmod. Useful as a part of a more complicated task. If you only need file operations, shell script is way easier to write.
-
Archives: usual like tar, gzip, bzip2, zip and few others, including rpm.
-
Network-related: sending email, remote execution with SSH and telnet, FTP and SCP client, HTTP client (with ant-contrib)
-
Revision control systems: CVS built-in, many (if not all) others with a plugin
When I use Ant?
I found two tasks for which Ant excels. Both are often needed in modern environments - with virtualization and cloud platforms in place, one administrator often controls hundreds of systems.
Uploading files to remote systems
Ant supports FTP and SCP. Nothing special, except it's easy to send only modifled files. Obviously with ordinary script you can read the timestamps, store them somewhere and compare them yourself, but it's more tedious. Here's an FTP example:
<?xml version="1.0" encoding="UTF-8"?>
<project name="whatever" default="ftpexample">
<target name="ftpexample">
<ftp server="www.example.com"
userid="admin"
password="YourVerySecretPassword"
passive="yes"
depends="yes"
verbose="yes"
remotedir="/wherever/I/want "
binary="yes">
<fileset dir="/source/directory" defaultexcludes="yes">
</fileset>
</ftp>
</target>
</project>
Let's go through the example, skipping obvious lines.
-
depends="yes" - only send modifiles files. Yes, it's that simple.
-
verbose="yes" - print names of the transfered files.
-
defaultexcludes="yes" - exclude backups (filenames ending with ~), CVS and SVN directories and the like.
Running remote commands on multiple systems
Ant can run tasks in parallel and track dependencies between tasks (i.e. before running task2, make sure task1 was finished). Ant can run commands remotely with SSH or telnet. Combine the two and you get a simple way of writing a distributed glue code. As an example, we'll check numbers of messages in Postfix queue on several servers.
<?xml version="1.0" encoding="UTF-8"?>
<project name="remoteexample" default="all">
<target name="checkservers">
<parallel>
<sshexec host="server1.example.com"
username="exampleuser"
trust="yes"
keyfile="${user.home}/.ssh/id_rsa"
outputproperty="out1"
command="find /var/spool/postfix/deferred -type f -print | wc -l" />
<sshexec host="server2.example.com"
username="exampleuser"
trust="yes"
keyfile="${user.home}/.ssh/id_rsa"
outputproperty="out2"
command="find /var/spool/postfix/deferred -type f -print | wc -l" />
</parallel>
</target>
<target name="all" depends="checkservers">
<echo message="${out1}" />
<echo message="${out2}" />
</target>
</project>
Two caveats:
- Ant has built-in support for SSH. If you run it on Linux, it will not follow your usual configuration in ~/.ssh. You need to provide all required parameters in the buildfile, like the path to keyfile in the example above.
- If you run the above example, you'll notice the output looks like this:
all:
[echo] find /var/spool/postfix/deferred -type f -print | wc -l : 2
[echo] find /var/spool/postfix/deferred -type f -print | wc -l : 0
The command you ran is a part of the outputproperty. It's a known bug of Ant, local exec doesn't behave that way. It was fixed lately, but the new build is not available yet. If you want to process the return value (e.g. sum the outputs), you either have to filter the command out or compile Ant from subversion. Tried both ways and filtering in the shell script is the easier one.
The downsides of Ant
- Ant requires Java. Not a problem if you need it anyway, but JRE is a little too big to install just for one or two scripts.
- Ant buildfile.xml has a completely different syntax than a script. You don't write a sequence of commands. Instead, you declare what you want to achieve and what it requires using simple XML syntax. Still, it only takes an hour or two to grasp the concept and start writing buildfiles.