• No results found

Incorporating a Source Code Control System

Chapter 5. TCP/IP Name Services

5.1. Host Files

5.1.4. Incorporating a Source Code Control System

In a moment we're going to move on to the next approach to the IP Address−to−Name mapping problem.

Before we do, we'll want to add another twist to our host file creation process, because a single file suddenly takes on network−wide importance. A mistake in this file will affect an entire network of machines. To give us a safety net, we'll want a way to back out of bad changes, essentially going back in time to a prior

configuration state.

The most elegant way to build a time machine like this is to add a source control system to the process.

Source control systems are typically used by developers to:

Keep a record of all changes to important files

Prevent multiple people from changing the same file at the same time, inadvertently undoing each other's efforts

Allow them to revert back to a previous version of a file, thus backing out of problems

This functionality is extremely useful to a system administrator. The error−checking code we added to the conversion process earlier, in Section 5.1.2, "Error Checking the Host File Generation Process", can help with certain kinds of typo and syntax errors, but it does not offer any protection against semantic errors (e.g., deleting an important hostname, assigning the wrong IP address to a host, misspelling a hostname). You could add semantic error checks into the conversion process, but you probably won't catch all of the possible errors.

As we've quoted before, nothing is foolproof, since fools are so ingenious.

You might think it would be better to apply source control system functionality to the initial database editing process, but there are two good reasons why it is also important to apply it to the resultant output:

Time

For large data sets, the conversion process might take some time. If your network is flaking out and you need to revert to a previous revision, it's discouraging to have to stare at a Perl process chugging away to generate the file you need (presuming you can get at Perl in the first place at that point).

Database

If you choose to use a real database engine for your data storage (and often this is the right choice), there may not be a convenient way to apply a source control mechanism like this. You'll probably

The Five−Minute RCS Tutorial (Perl for System Administration)

5.1.4. Incorporating a Source Code Control System 165

have to write your own change control mechanisms for the database editing process.

My source control system of choice is the Revision Control System (RCS). RCS has some Perl− and system administration−friendly features:

It is multiplatform. There are ports of GNU RCS 5.7 to most Unix systems, Windows NT, MacOS, etc.

It has a well−defined command−line interface. All functions can be performed from the command line, even on GUI−heavy operating systems

It is easy to use. There's a small command set for basic operations that can be learned in five minutes (see Appendix A, "The Five−Minute RCS Tutorial" ).

It has keywords. Magic strin gs can be embedded in the text of files under RCS that are automatically expanded. For instance, any occurrence of $ Date:$ in a file will be replaced with the date the file was last entered into the RCS system.

It's free. The source code for the GNU version of RCS is freely redistributable, and binaries for most systems are also available. A copy of the source can be found at ftp://ftp.gnu.org/gnu/rcs.

If you've never dealt with RCS before, please take a moment to read Appendix A, "The Five−Minute RCS Tutorial". The rest of this section assumes a cursory knowledge of the RCS command set.

Craig Freter has written an object−oriented module called Rcs which makes using RCS from Perl easy. The steps are:

1.

Load the module.

2.

Tell the module where your RCS command−line binaries are located.

3.

Create a new Rcs object; configure it with the name of the file you are using.

4.

Call the necessary object methods (named after their corresponding RCS commands).

Let's add this to our host file generation code so you can see how the module works. Besides the Rcs module code, we've also changed things so the output is sent to a specific file and not STDOUT as in our previous versions. Only the code that has changed is shown. Refer to the previous example for the omitted lines represented by "...":

$outputfile="hosts.$$"; # temporary output file

$target="hosts"; # where we want the converted data stored ...

open(OUTPUT,"> $outputfile") or

die "Unable to write to $outputfile:$!\n";

print OUTPUT "#\n\# host file − GENERATED BY $0\n

5.1.4. Incorporating a Source Code Control System 166

# DO NOT EDIT BY HAND!\n#\n";

print OUTPUT "# Converted by $user on ".scalar(localtime)."\n#\n";

...

foreach my $dept (keys %depts) {

print OUTPUT "# number of hosts in the $dept department:

$depts{$dept}.\n";

}

print OUTPUT "# total number of hosts: ".scalar(keys %entries)."\n#\n\n";

# iterate through the hosts, printing a nice comment and the entry foreach my $entry (sort byaddress keys %entries) {

print OUTPUT

# where our RCS binaries are stored Rcs−>bindir('/usr/local/bin');

# create a new RCS object my $rcsobj = Rcs−>new;

# configure it with the name of our target file

$rcsobj−>file($target);

# check it out of RCS (must be checked in already)

$rcsobj−>co('−l');

# rename our newly created file into place rename($outputfile,$target) or

die "Unable to rename $outputfile to $target:$!\n";

# check it in

$rcsobj−>ci("−u","−m"."Converted by $user on ".scalar(localtime));

This code assumes the target file has been checked in at least once already.

To see the effect of this code addition, we can look at three entries excerpted from the output of rloghosts:

revision 1.5

date: 1998/05/19 23:34:16; author: dnb; state: Exp; lines: +1 −1 Converted by David N. Blank−Edelman (dnb) on Tue May 19 19:34:16 1998

−−−−−−−−−−−−−−−−−−−−−−−−−−−−

revision 1.4

date: 1998/05/19 23:34:05; author: eviltwin; state: Exp; lines: +1 −1 Converted by Divad Knalb−Namlede (eviltwin) on Tue May 19 19:34:05 1998

−−−−−−−−−−−−−−−−−−−−−−−−−−−−

revision 1.3

The Five−Minute RCS Tutorial (Perl for System Administration)

5.1.4. Incorporating a Source Code Control System 167

date: 1998/05/19 23:33:35; author: dnb; state: Exp; lines: +20 −0 Converted by David N. Blank−Edelman (dnb) on Tue May 19 19:33:16 1998

The previous example doesn't show much of a difference between file versions (see the lines: part of the entries), but you can see that we are tracking the changes every time the file gets created. If we needed to, we could use the rcsdiff command to see exactly what changed. Under dire circumstances, we would be able to revert to previous versions if one of these changes had wreaked unexpected havoc on the network.

4.6. References for More Information