Flashbacks to CVS

by Ostatic Staff - May. 14, 2014

The Concurrent Version System (CVS) is one of the oldest version control systems available, so old in fact that alternatives and drop in replacements have largely superseded it's use. However, believe it or not, there are still pockets of developers that have never migrated off of the ancient system. One of the latest systems administrator tasks I was assigned was to migrate one such code base from one server to another. In doing so, I wound up learning quite a bit more about how CVS works than I expected I would need.

In our particular setup, CVS doesn't run it's own daemon, it is stopped and started through xinetd. The file that governs how CVS runs when a developer or process attempts to access it is /etc/xinetd.d/cvspserver. That file looks like this:

service cvspserver
{
port = 2401
socket_type = stream
protocol = tcp
user = root
wait = no
type = UNLISTED
server = /usr/bin/cvs
server_args = -f --allow-root /opt/ABC --allow-root /opt/DEF --allow-root pserver
disable = no
log_on_success += DURATION
nice = 10
}

This configuration tells xinetd to listen for incoming requests on port 2401 on behalf of CVS. When one comes in, it runs the cvs binary with the arguments listed in server_args. Each of the server_args statement defines the root of a separate CVS repository. Inside of each repository is a special directory named CVSROOT, and inside of each CVSROOT directory is a file named passwd. That passwd file has a list of users and MD5 hashed passwords, and the CVS daemon checks that file when a user attempts to connect. However, having the username and password correct is not enough.

In addition to the passwd file, CVS requires that every user listed in the file also be a system user, defined in /etc/passwd. The local user account doesn't need a local system password, it simply needs to exist. Once the user is in both the system and the CVSROOT passwd file, the user also needs to be part of a group that has Unix permissions to access the directories where the CVS repository lives. Once all of these things are in place, remote user authentication works well.

CVS stopped being actively developed in 2008, although the core team will still respond to bugs. The popular Apache Subversion (SVN) system was developed in 2000 and aimed to be a direct replacement for CVS. Subversion addresses many of the shortcomings of CVS, including atomic commits, file renames, symbolic links, merge tracking, and unicode filename support. If I were looking for a replacement to our code base in CVS, Subversion would be the most logical choice, and probably the one with the least likelihood of disrupting an entrenched workflow. However, if starting from scratch, one of the popular distributed version control systems like Git) or Mercurial would be far more attractive.