At times you need to gather information from a client machine before you can generate its configuration. For example, if some of your machines have both a local scratch disk and a system disk while others only have the system disk, you would want to know this information to correctly generate an /etc/auto.master autofs config file for each type. Here we will look at how to do this.

For the purposes of this example, you will need to set up the TCheetah plugin, as described on the TCheetah page.


This does not mean that TCheetah is required in order for Probes to operate properly.

Next, we need to create a Probes directory in our toplevel repository location:

mkdir /var/lib/bcfg2/Probes

This directory will hold any small scripts we want to use to grab information from client machines. These scripts can be in any scripting language; the shebang line (the #!/usr/bin/env some_interpreter_binary line at the very top of the script) is used to determine the script’s interpreter.


Bcfg2 uses python mkstemp to create the Probe scripts on the client. If your /tmp directory is mounted noexec, you will likely need to modify the TMPDIR environment variable so that the bcfg2 client creates the temporary files in a directory from which it can execute.

Now we need to figure out what exactly we want to do. In this case, we want to hand out an /etc/auto.master file that looks like:

/software  /etc/ --timeout 3600
/home      /etc/auto.home --timeout 3600
/hometest  /etc/auto.hometest --timeout 3600
/nfs       /etc/auto.nfs --timeout 3600
/scratch   /etc/auto.scratch --timeout 3600

for machines that have a scratch disk. For machines without an extra disk, we want to get rid of that last line:

/software  /etc/ --timeout 3600
/home      /etc/auto.home --timeout 3600
/hometest  /etc/auto.hometest --timeout 3600
/nfs       /etc/auto.nfs --timeout 3600

So, from the Probes standpoint we want to create a script that counts the number of SCSI disks in a client machine. To do this, we create a very simple Probes/scratchlocal script:

cat /proc/scsi/scsi | grep Vendor | wc -l

Running this on a node with n disks will return the number n+1, as it also counts the controller as a device. To differentiate between the two classes of machines we care about, we just need to check the output of this script for numbers greater than 2. We do this in the template.

The TCheetah/ directory is laid out much like the Cfg/ directory. For this example we will want to create a TCheetah/etc/auto.master directory to hold the template of the file in question. Inside of this template we will need to check the result of the Probe script that got run and act accordingly. The TCheetah/etc/auto.master/template file looks like:

/software  /etc/ --timeout 3600
/home      /etc/auto.home --timeout 3600
/hometest  /etc/auto.hometest --timeout 3600
/nfs       /etc/auto.nfs --timeout 3600
#if int($self.metadata.Probes["scratchlocal"]) > 2
/scratch   /etc/auto.scratch --timeout 3600
#end if

Any Probe script you run will store its output in $self.metadata.Probes["scriptname"], so we get to our scratchlocal script’s output as seen above. (See Handling Probe Output, below, for more information on how this is done.) Note that we had to wrap the output in an int() call; the script output is treated as a string, so it needs to be converted before it can be tested numerically.

With all of these pieces in place, the following series of events will happen when the client is run:

  1. Client runs
  2. Server hands down our scratchlocal probe script
  3. Client runs the scratchlocal probe script and hands its output back up to the server
  4. Server generates /etc/auto.master from its template, performing any templating substitutions/actions needed in the process.
  5. Server hands /etc/auto.master down to the client
  6. Client puts file contents in place.

Now we have a nicely dynamic /etc/auto.master that can gracefully handle machines with different numbers of disks. All that’s left to do is to add the /etc/auto.master to a Bundle:

<Path name='/etc/auto.master'/>

Handling Probe Output

Bcfg2 stores output from probes in the Probes property of a client’s metadata object. To access this data in TGenshi, for instance, you could do:


This is not the full output of the probe; any lines that start with “group:” have been stripped from the output. The data is a string-like object that has some interesting and salient features:

  • If the data is a valid XML document, then metadata.Probes['script-name'].xdata will be an lxml.etree._Element object representing the XML data.
  • If the data is a valid JSON document, and either the Python json or simplejson module is installed, then metadata.Probes['script-name'].json will be a data structure representing the JSON data.
  • If the data is a valid YAML document, and either the Python yaml or syck module is installed, then metadata.Probes['script-name'].yaml will be a data structure representing the YAML data.

If these conditions are not met, then the named properties will be None. In all other fashions, the probe data objects should act like strings.

Host- and Group-Specific probes

Bcfg2 has the ability to alter probes based on client hostname and group membership. These files work similarly to files in Cfg.

If multiple files with the same basename apply to a client, the most specific one is used. Only one instance of a probe is served to a given client, so if a host-specific version and generic version apply, only the client-specific one will be used.

If you want to to detect information about the client operating system, the Ohai plugin can help.


The FileProbes plugin allows you to probe a client for a file, which is then added to the Cfg specification. If the file changes on the client, FileProbes can either update it in the specification or allow Cfg to replace it.

FileProbes will not probe a file if there’s already a file in Cfg that will apply to the client. So if, for instance, you have a generic file in Cfg/etc/foo.conf/foo.conf that applies to all hosts, FileProbes will not retrieve /etc/foo.conf from the client (unless update is enabled; see Configuration below).

When a new config file is first probed, an info.xml file is also written to enforce the permissions from that client. Subsequent probes from other clients will not modify or overwrite the data in info.xml. (This ensures that any manual changes you make to info.xml for that file are not circumvented.)


FileProbes is configured in FileProbes/config.xml, which might look something like:

  <FileProbe name="/etc/foo.conf"/>
  <Group name="blah-servers">
    <FileProbe name="/etc/blah.conf" update="true"
  <Client name="">
    <FileProbe name="/var/lib/bar.gz" encoding="base64"/>

This will result in /etc/foo.conf being retrieved from all clients; if it changes on a client, it will be overwritten by the version that was retrieved initially.

Clients in the blah-servers group will be probed for /etc/blah.conf; if it changes on a client, those changes will be written into the Bcfg2 specification. If the file is deleted from a client, it will be rewritten from Bcfg2. will be probed for /var/lib/bar.gz, which contains non-ASCII characters and so needs to use base64 encoding when transferring the file.

The paths probed by FileProbes must also be included as Path entries in your bundles in order to be handled properly by Cfg. Permissions are handled as usual, with info.xml files in Cfg.

Table Of Contents

Previous topic

Plugin Roles

Next topic


This Page