The Maintenance

The Maintenance

Let's imagine a sample team undernet (and here I would like to thank Starkey Laboratories, a marvelous hearing-aid manufacturer headquartered in Eden Prairie, Minnesota, for permission to use portions of the undernet I built during a project I did for them in the winter of 2000 “2001). It looks like Figure 6-1 . With this undernet, we took individual empowerment to the next level. We were already using CVS, the Concurrent Versioning System, to manage source code for several projects. One of the concerns expressed when we set up the undernet was that content needed to be backed up, and the network administrators were reluctant to put a desktop PC into their backup scheme. "No problem," I said. "I'll keep the whole Web site in the CVS repository on one of the main Unix servers."

Figure 6-1. Konquerer grab of undernet homepage.

We need to step aside from the undernet story for a moment to introduce you to CVS.

CVS Basics

Concurrent Versioning System is a very powerful and complete version-control system. It has many features and options, and fully effective use of the system has many nuances . CVS is worthy of a book in itself and is, in fact, the subject of more than one such book, the most widely used being the free Guide to Using CVS , by Cederqvist et. al, listed in the Bibliography section at the end of this chapter. None theless, we don't wish to leave you high and dry. Here we will introduce just enough of CVS to get you going.

Core Concepts

CVS is another example of the well-known client/server model. There is a CVS server, which handles the central archive of files, called the repository, and one to many clients that manage the working copies of individual users, which we like to call sandboxes, because they are places where each user may play with his or her own copy of the CVS-managed files without let or hindrance from other users.

A user checks out a sandbox. The user then commits changes to the repository and updates her sandbox with other users' changes made to the repository since the last checkout or update.

Sometimes it will happen that another user has changed a file that our user has also changed in her sandbox. When that happens, there is a collision, and whoever commits last must merge the changes together. Most of the time, CVS is able to handle this all by itself. But if two or more users have made changes to the same parts of a file, a conflict occurs, and the person committing must manually resolve this conflict.

I know this is a lot to throw at you all at once, but we'll show you the commands and where each of these concepts come into play. We'll show you an example of each of these concepts and briefly explain them. Above all, don't panic! CVS really works. It is used by most Open Source projects, including wine and plex86, among many others, and it allows hundreds of developers, most of whom have never met one another, to work together on the same pile of source code at the same time. This very book was written using CVS to coordinate changes between this book's multiple authors. So relax, and let us show a little of what CVS can do.

The Repository

The repository is the base of all CVS-managed files. A CVS server can manage one to many repositories. The CVS client needs to be told where a repository is for almost all commands. You can specify the repository on the command line with each command, but it is more common to put the repository into an environment variable called CVSROOT. The repository may be local, in which case there really isn't a CVS server program; the client just uses the local file system. In this case the CVSROOT is just a pathname, for example:

 export CVSROOT=/usr/local/secureprojects 

The repository need not be local. It may be accessed using a number of methods . The general form for a remote access is

 :<method>:<user/host spec>:<pathspec> 

where method is one of the following

·                 pserver: This is CVS's own client/server protocol.

·                 ext: This uses an external program that can run the CVS command on the remote machine. The default program is rsh, the remote shell program. However, CVS will use any program named in the environment variable CVS_RSH to run the command. It is common to use this variable to specify secure shell (ssh/OpenSSH) instead of the insecure RSH protocol.

·                 kserver: This is the Kerberos version 4 security protocol. We won't cover this here.

·                 gserver: This is Generic Security Services API and/or Kerberos version 5. We won't cover this one here either.

The user/host spec is generally like an rsh/ssh login specification:

 user@some.hostname.org 

This is the form used both by pserver and ext.

pathspec is the path to the repository on the named host.

CVS Commands

I wish we had room to go into CVS's commands in detail. Alas, we can only offer you a glimpse and direct you to more complete resources. The general form of a CVS client invocation is:

  cvs  cvs-options  cvs-command  cvs-command-options [filespecs] 

The most heavily used CVS commands are listed in the following table. This is by no means a complete list of CVS commands, nor is it even remotely complete documentation of these commands. It is meant to be enough to get you started.

CVS Command

Description and Examples

import

The import command is used to bring an entire subdirectory tree into the repository at once. This command is generally used when first putting an existing project into a repository. It may also be used when starting a project from scratch, but it is more common to use the add command to add files and directories as they are created.

Example: $ cvs import book addison_wesley initial

The first argument follwing the import command is the directory name the import will be given in the repository. Warning! This is unlike all other CVS commands! The import will begin at the present working directory and recurse down, with the files in the present directory being placed in the repository at the directory named by the first argument. Most CVS commands by default will work on the specified directory and all subdirectories unless told otherwise . The second argument is a vendor tag. This has uses well beyond our scope here, but, alas, you must specify one even if you never will use it. After the vendor tag, at least one initial revision tag must be specified. Revision tags are a way to give a full set of files at various revision numbers a single name, so you don't have to remember the different revision numbers of various files that make up a given release of your files. Again, you may not need this initial tag, since all of your files are probably starting at revision 1.1 anyway, but the command requires it. Most people can just make up a couple of tag names here and never care again. Consult some of the CVS resources if you would like to know more.

checkout

This command creates a sandbox. Unlike many other source-control systems, this does not lock files. You can check out the whole project and the resulting copy is yours to do with as you please . If, however, you wish to make changes that will be shared with others and become part of the project revision history, you must use the commit command to put your changes in the repository. If other users of the repository make changes to the files, you must use the update command to bring their changes into your sandbox.

Example: $ cvs checkout book

commit

If you make changes to the files in your sandbox, and you wish those changes to become part of the history in the repository, you must commit the changes to the repository. This will make the versions of the files in your sandbox a permanent part of the history stored in repository. The commit may fail if another user has made changes to any of the same files since you last checked out or updated your sandbox. To reconcile the conflict, you must use the update command. When you commit, your chosen editor will open, and you may write a comment describing the changes that will become a part of the CVS log for each revised file.

Example: $ cvs commit

update

The update command brings your sandbox up to date with changes made to the repository by others. If you have changed some files locally, the changes from the repository are automatically merged with your changes. This usually happens automatically. Sometimes, however, other users' modifications may be to the same parts of files as yours. When that happens, the update command will tell you that a merge conflict has occurred and that you will have to resolve it. See the next subsection, Resolving Conflicts.

Example: $ cvs update

add

The add command allows you to add new files to the repository. The add command merely marks the file or files for inclusion. You must still issue a commit to put the files in the repository.

Example: $ cvs add newfile.java newdir newdir/newpage.html

As you can see, you add directories in the same way.

remove

The remove command "deletes" files and/or directories from the repository. This command merely marks the files for deletion. You must still issue a commit to actually remove them from the reposi tory. You must actually delete the file from your sandbox before you issue the remove command. Removing does not erase the file! Remember, CVS is a versioning system that can bring a collection of files back to any previous state, which means that "removing" a file merely means ending its "future," if you will. Files that are removed are relocated to a special directory in the repository called Attic. In this way, the file disappears from current and future updates and checkouts, but the file is still available when looking into the history of the repository.

Example: $ rm droppedfile.java $ cvs remove droppedfile.java

Resolving Conflicts

Usually, CVS is able to merge other people's changes to files into your changed files seamlessly and quietly . Let's walk through two changes to a file, one where the other user's changes do not conflict with ours, and one where they do, so that you can see how this works.

Here is the original state of our sample file:

 This is a sample text file that will 
 allow us to demonstrate how 
 CVS can allow many users to work 
 on the same files at the same 
 time. Not only that, but it will 
 show how users may merge changes 
 and how sometimes conflicts will 
 occur, and how those conflicts can 
 be resolved. 
 
 Enjoy. 

Our first scenario will show the merging of two users' changes without conflicts. Let's say one user makes the following change and commits it:

 This is a sample text file that will 
 allow us to demonstrate how 
 CVS can allow many users to work 
 on the same files at the same 
 time. Not only that, but it will 
 show how users  can  merge changes 
 and how sometimes conflicts will 
 occur, and how those conflicts can 
 be resolved. 
 
 Enjoy. 

Here's what his command session looks like:

 first@mars:~/user1/project$ cvs commit 
 cvs commit: Examining . 
 Checking in sample.txt; 
 /usr/local/projects/project/sample.txt,v <-- sample.txt 
 new revision: 1.2; previous revision: 1.1 
 done 
 first@mars:~/user1/project$ 

Now let's assume the second user, oblivious to the changes made by the first user, modifies his sandbox copy of the file thusly:

 This is an  example  text file that will 
 allow us to demonstrate how 
 CVS can allow many users to work 
 on the same files at the same 
 time. Not only that, but it will 
 show how users may merge changes 
 and how sometimes conflicts will 
 occur, and how those conflicts can 
 be resolved. 
 
 Enjoy. 

Now, user 2, having made this change, attempts to commit the change. This fails, as shown here:

 second@mars:~/user2/project$ cvs commit 
 cvs commit: Examining . 
 cvs commit: Up-to-date check failed for 'sample.txt' 
 cvs [commit aborted]: correct above errors first! 
 second@mars:~/user2/project$ 

This failure tells us that the file sample.txt has been modified since we checked out or last updated our sandbox. The cvs update command brings our sandbox up to date with the repository. Now, you might think that this means the repository will overwrite our changes, but this is not so. If we have locally modified files, the update command will merge in the other user's changes. It looks like this:

 second@mars:~/user2/project$ cvs update 
 cvs update: Updating . 
 RCS file: /usr/local/projects/project/sample.txt,v 
 retrieving revision 1.1.1.1 
 retrieving revision 1.2 
 Merging differences between 1.1.1.1 and 1.2 into sample.txt 
 M sample.txt 
 second@mars:~/user2/project$ 

Now let's look at the file:

 second@mars:~/user2/project$ cat sample.txt 
 This is an example text file that will 
 allow us to demonstrate how 
 CVS can allow many users to work 
 on the same files at the same 
 time. Not only that, but it will 
 show how users can merge changes 
 and how sometimes conflicts will 
 occur, and how those conflicts can 
 be resolved. 
 
 Enjoy. 
 
 second@mars:~/user2/project$ 

As you can see, the changes of both users are now in the file. These are still merely local. Remember, our last commit failed, so we must commit again.

 second@mars:~/user2/project$ cvs commit 
 cvs commit: Examining . 
 Checking in sample.txt; 
 /usr/local/projects/project/sample.txt,v <-- sample.txt 
 new revision: 1.3; previous revision: 1.2 
 done 
 second@mars:~/user2/project$ 

This makes a nice lead-in to our discussion of merge conflicts. Remember, our second user has modified the first line of the file, but the first user has neither modified it nor updated to bring in the second user's changes. Let's suppose now that our first user modifies the first line like this:

 This is a sample  flat ASCII  file that will 
 allow us to demonstrate how 
 CVS can allow many users to work 
 on the same files at the same 
 time. Not only that, but it will 
 show how users can merge changes 
 and how sometimes conflicts will 
 occur, and how those conflicts can 
 be resolved. 
 
 Enjoy. 

Now our first user tries to commit, but he gets the same failure our second user saw before, telling him the repository copy of this file has changed:

 first@mars:~/user1/project$ cvs commit 
 cvs commit: Examining . 
 cvs commit: Up-to-date check failed for 'sample.txt' 
 cvs [commit aborted]: correct above errors first! 
 first@mars:~/user1/project$ 

Just as before, our first user needs to use the update command to bring his sandbox up to date with the repository:

 first@mars:~/user1/project$ cvs update 
 cvs update: Updating . 
 RCS file: /usr/local/projects/project/sample.txt,v 
 retrieving revision 1.2 
 retrieving revision 1.3 
 Merging differences between 1.2 and 1.3 into sample.txt 
 rcsmerge: warning: conflicts during merge 
 cvs update: conflicts found in sample.txt 
 C sample.txt 
 first@mars:~/user1/project$ 

What's this? It looks a little different from the last time we merged in another user's changes. Why? Because the two changes were made to the same part of the file, that's why. CVS couldn't figure out how to merge them without undoing somebody's work. What does it do? Well, it punts. Take a look at the file in the first user's sandbox now:

 first@mars:~/user1/project$ cat sample.txt 
 <<<<<<< sample.txt 
 This is a sample flat ASCII file that will 
 ======= 
 This is an example text file that will 
 >>>>>>> 1.3 
 allow us to demonstrate how 
 CVS can allow many users to work 
 on the same files at the same 
 time. Not only that, but it will 
 show how users can merge changes 
 and how sometimes conflicts will 
 occur, and how those conflicts can 
 be resolved. 
 
 Enjoy. 
 
 first@mars:~/user1/project$ 

Yikes! What's all that junk in the file? CVS has " marked up" the file. It couldn't figure out whose changes should win, so it dumped both versions into the sandbox of the person trying to commit. Yessir, it just says, "Sorry, buddy. It's your problem." The user must edit the file, deciding for himself how to reconcile the versions. The user must also delete the "markup" CVS put in the file.

So the first user might edit the file to look like this:

 This is an example flat ASCII file that will 
 allow us to demonstrate how 
 CVS can allow many users to work 
 on the same files at the same 
 time. Not only that, but it will 
 show how users can merge changes 
 and how sometimes conflicts will 
 occur, and how those conflicts can 
 be resolved. 
 
 Enjoy. 

Now the first user may commit:

 first@mars:~/user1/project$ cvs commit 
 cvs commit: Examining . 
 Checking in sample.txt; 
 /usr/local/projects/project/sample.txt,v <-- sample.txt 
 new revision: 1.4; previous revision: 1.3 
 done 
 first@mars:~/user1/project$ 

And that's how you resolve CVS conflicts!

This is only the very briefest of introductions to CVS. We haven't covered tagging, branching, branch merges, diffs , status, or any of a host of other topics. CVS is a powerful and multifeatured tool. Our goal here has been merely to introduce you to it.

And Now, Back to Our Story

When we last left the undernet, I had proposed keeping the critical parts of the system on one of the primary Unix servers so that no critical content could be lost in the event of a failure of the Linux PC “based undernet.

This plan was acceptable to the client, and it turned out to have enormous and unanticipated benefits for the project.

Before we get to that, let me describe how we set things up. First, we set up a very simple (almost HTML 2.0) homepage. We set this up on a Debian system, so the index.html file resides at /var/www. It is shown here.

 <HTML> 
 <HEAD> 
 <TITLE>Frigate</TITLE> 
 </HEAD> 
 <BODY BGCOLOR="#F0F8FF"> 
 <TABLE> 
 <TR> 
 <TD> 
 <IMG src="see/images/senses_n_star.jpg" ALT="project logo" 
 HEIGHT=100 
 WIDTH=100 
 ALIGN=BOTTOM> 
 </TD> 
 <TD> 
 <H1>CQ Messenger - Project Homepage</H1> 
 </TD> 
 </TR> 
 </TABLE> 
 <P> 
 <H2>Run CQ Messenger: (Iter. 1)</H2> 
 <UL> 
 <li>in DEVELOPMENT (frigate) 
 <TABLE cellpadding=10 cellspacing=10><TR> 
 <td><a href="/servlet/starkey.track.ui.CQMessenger"> 
 in a full browser</a></td> 
 <td><a href="http://frigate.starkey.com/see/CQMessenger.html"> 
 like a real user (bare window)</a></td> 
 <td><a href="/servlet/starkey.track.ui.CQMessenger?admin=users"> 
 USER status</a></td> 
 <td><a href="/servlet/starkey.track.ui.CQMessenger?admin=boxes"> 
 BOX status</a></td> 
 <td><a href="/servlet/starkey.track.ui.CQMessenger?admin=show"> 
 LOG Settings</a></td> 
 </TR></TABLE><BR> 
 <li>in PRODUCTION (cqm a.k.a. hulk) 
 <TABLE cellpadding=10 cellspacing=10><TR> 
 <td><a href="http://cqm.starkey.com/see/CQMessenger.html"> 
 CQ Messenger</a></td> 
 <td><a href="http://cqm.starkey.com/servlet/starkey.track.ui. CQMessenger?admin=users"> 
 USER status</a></td> 
 <td><a href="http://cqm.starkey.com/servlet/starkey.track.ui. CQMessenger?admin=boxes"> 
 BOX status</a></td> 
 </TR></TABLE> 
 </UL> 
 <HR> 
 <H2>CQ Messenger Project Documentation</H2> 
 <UL> 
 <li><a href="/cgi-bin/prbarcode.cgi"> 
 <H3><img src="code39.gif" HEIGHT="50" WIDTH="50"> 
 Print a barcode</H3></a> 
 <li><a href="/CQ/docs/">Project Documents Repository (copy)</a> 
 <li><a href="http://frigate.starkey.com/cgi-bin/cvsweb">CVS Repository (read-only)</a> 
 <li><a href="http://cq-dev.starkey.com/see/XFiles/index.html"> 
 CQ Messenger Object classes</a> 
 <P> 
 <li><a href="/javadoc/">Sun Java documentation</a> 
 <li><a href="/javadoc/api">JDK1.2.2 Class Documentation</a> 
 <P> 
 </UL> 
 <HR> 
 <H2>Frigate search engine</H2> 
 <P> 
 Enter search keywords below. Press search button to find matching documents. 
 Share and enjoy. This site uses the freely available ht://Dig search 
 engine.</p> 
 <P> 
 </p> 
 <form method="post" action="cgi-bin/htsearch"> 
 
 Keyword(s): <input type=text maxlength=80 name=words size=25>Match: 
 <select name="method"> 
 <option value="and" selected>All 
 <option value="or">Any 
 <option value="boolean">Boolean 
 </select> 
 Format: 
 <select name="format"> 
 <option value="builtin-long">Long 
 <option value="builtin-short" selected>Short 
 </select> 
 <input type=hidden name="config" value="htdig"> 
 <input type=submit value="Search" name="SUBMIT"> 
 </form> 
  <HR>  
  <H2>Frigate</H2>  
  Read <a href="frigateFacts.html">some allegedly interesting information</a> about  
  Frigate and how the CQ Messenger Web site is set up  
  <HR>  
  </BODY>  
  </HTML>  

The critical information is in the link to /CQ/docs. This directory, under /var/www, was created by executing the CVS command:

  # cd /var/www  
  # cvs checkout CQ/docs  

That created a CVS sandbox (as I like to call CVS working directories). All of our project documentation is maintained in CVS. Each user has his or her own checked-out copy of the files. Some use WinCVS on windows machines, some use accounts on Linux boxes, some HP/UX, some IRIX. Because we standardized on HTML for our documents, it doesn't matter how they are written or on what system. Some users use MS Word (not me!). Some use Netscape's Composer (not me!). But the point is, it does not matter.

Each user commits and updates his or her own copies as needed. The magic lies in how the documents are deployed to the Web server. The root account on the Web server box has the following crontab:

  frigate:~# crontab -l  
  */11 5-19 * * * cd /var/www/CQ/docs; cvs update -d > /dev/null 2> /dev/null  

This means that every 11 minutes, from 5 am to 7 pm, the copy of the documents under the Web server is automatically refreshed from the CVS repository. That means that whenever a user creates or modifies one of her documents, within 11 minutes of committing that change it will be up on the Web site! The user need not even have an account on the Web server box!

In the last section we described how to give a group access to the Web server documents. By making use of CVS, we can give any number of people the ability to put content on the Web server, but none of them need have any direct access. Also, because CVS is a versioning system, we have the ability to "roll" the Web content back in time to any previous set of content.

 



Multitool Linux. Practical Uses for Open Source Software
Multitool Linux: Practical Uses for Open Source Software
ISBN: 0201734206
EAN: 2147483647
Year: 2002
Pages: 257

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net