Setting up a CVS server on Mac OS X

Preamble

This document shows you how to set up a CVS (Concurrent Versioning System) server on Mac OS X. The assumption this document makes are:

Glossary

Overview

Getting the CVS server software

One free implementation of CVS is available at www.cvshome.org and is part of the Mac OS X developer tools. If you have the Develoepr Tools, you have CVS on your computer. You might want to get the latest version of the CVS software though. If you do not, then go directly to "Configuring the CVS server". Usually, the most recent version is not available as "a compiled program" (i.e. a program that is ready to run on your computer). Most recent versions are available in source form at this page. Version 1.11.2 is available here and this is the one this document is based on. Download the file. It is possible that Stuffit Expander laucnhes automatically to expand the file into a folder called "cvs-1.11.2" (maybe inside another folder). Move it to your home directory. If instead you get a file like cvs.1.11.2.tar.gz, then move it directly to your home directory.

Compiling and installing the CVS server software

You need to compile the CVS software using the command-line compiler. Because Mac OS X with the Developer Tools come with a version of CVS, when CVS is configured, it will determine where it should be installed based on the current version installed on your system. You need to compile CVS without the GSS-api (a password authentication API). This is straightforward:


cd tar xvzf cvs.1.11.2.tar.gz cd cvs-1.11.2 ./configure --without-gssapi make sudo make install rehash

Configuring the CVS repository

You have to decide where you will keep the "Modules" (the source code of your projects). This directory is called the repository root directory. I recommend one of these two options:

For the sake of the discussion, we will say that the directory where you will keep the Modules is /usr/local/CVS/. You must create the directory first and initialize it. CVS will put a control module called CVSROOT where information about your repository is kept:


sudo mkdir /usr/local/CVS/ sudo cvs -d /usr/local/CVS/ init

Configuring the actual CVS "server"

Now that you have a repository (empty, but still), you want to be able to do CVS-things to it (check out modules, commit changes, see differences, etc...). There are three methods by which this can be done (at least, three I will discuss): local access, password and secure remote access. Depending upon what you want, you might need to adjust the server setup.

Local CVS access

To allow CVS access locally, you don't have to do anything special on the server (all the work is done by the client, see next section), except that you must make sure the repository is accessible by the user (i.e. the user has read access to the repository). Typically, this is used for a project on which you are the only developer.

Password CVS access

To allow some password protection on the repository, you can use the "password" server that cvs offers. Typically, this is used for a project on which there are more than one developer, or you need access from various machines. It is also the right choice for an anonymous CVS read access. You must configure you Internet Services to make sure they know where the repository is and on what port to listen. You need to use cvspserver for the port or 2401 if you want to use the port number. cvs or cvspserver are sometimes used check in Netinfo/services/ (Mac OS X 10.1.x) or /etc/services (Jaguar 10.2 reverted to using flat files by default). In addition, Mac OS X is slowly transitionning to a new way of managing internet services from inetd (Internet Daemon) to xinetd (Extended Internet Daemon). If you are running 10.2 and up, I recommend you use xinetd, since it is more flexible. Choose one of the following: 1. Configuring and restarting xinetd or 2. Configuring and restarting inetd.

1. Configuring and restarting xinetd

If the directory /etc/xinetd.d/ exists, then xinetd is installed on your computer and you should use it. Create a file called cvspserver with this inside:

service cvspserver { disable = no socket_type = stream wait = no user = root server = /usr/bin/cvs server_args = -f --allow-root=/usr/local/CVS pserver groups = yes flags = REUSE }

Control-X to save your modifications in the /etc/xinetd/ directory. If you have a firewall installed and active, you must allow incoming connections to the cvspserver port (2401). Finally, you must start the cvs server, which you do indirectly by starting or restarting xinetd (the deamon that takes care of all Internet services).

If the file /var/run/xinetd.pid exists (xinetd is running), then do this to restart it: sudo kill -HUP `cat /var/run/xinetd.pid` If the file /var/run/xinetd.pid does not exist (xinetd is not running), then do this to start it: sudo /System/Library/StartupItems/IPServices/IPServices start

You are now ready to connect to your CVS server.

2. Configuring and restarting inetd

If you want or have to use inetd instead of xinetd, then add the following line to /etc/inetd.conf:

Type sudo pico /etc/inetd.conf and add this line (anywhere, it does not matter) cvspserver stream tcp nowait root /usr/bin/env env -i /usr/bin/cvs -f --allow-root=/usr/local/CVS pserver

Control-X to save your modifications. /usr/bin/env -i is to ignore the root environment and the annoying "can't open .cvsignore" error message. If you have a firewall installed and active, you must allow incoming connections to the cvspserver port (2401). Finally, you must start the cvs server, which you do indirectly by restarting inetd (the deamon that takes care of all Internet services):

If the file /var/run/inetd.pid exists (inetd is running), then restart it: sudo kill -HUP `cat /var/run/xinetd.pid` If the file /var/run/inetd.pid does not exist (inetd is not running), then start it with: sudo /System/Library/StartupItems/IPServices start

Passwords and usernames

If you don't do anything special, the CVS server will get its usernames and passwords from the Mac OS X database (i.e. your actual username and password from when you log in). This isn't so good, since the password (although encrypted) is still not as strongly encrypted as a real secure SSH connection. You can override the default usernames and passwords (from the system) and replace them with your own usernames and passwords. All you need to do, is create a file called passwd in your repository (in this case /usr/local/CVS/CVSROOT/passwd) with entries on each line for each user with their username, hash password (don't panic, see below) and the actual Mac OS X username under which the calls will be made (i.e. the login username of the administrator or some "cvsserver" user that you would make). For instance, on my system (where I am called dccote) it looks like this:

dccote:5H/pui3NSpfmo:dccote anonymous:msFNaNtb.ndZE:dccote

which means that dccote can login with some password, and anonymous can login with some other password (which by the way is empty, but you still need to put it there: it took me forever to figure this out). You obtain the hash passwords with the command openssl passwd in Mac OS X:

% openssl passwd Password: 123 Verifying - Password: 123 yrp85EUNQl01E

(Side note, irrelevant to CVS: the hash password you get will be different because the first two letters (yr in this case) will be different. These are called the salt (and are chosen randomly). You may force a given salt by using openssl passwd -salt yr). You are now ready to connect to your CVS server.

Secure remote CVS access

To allow secure remote CVS access, you don't have to do much on the server, since everything is done by the Secure Shell software (SSH), except that you must make sure the repository is accessible by the user (i.e. the user has read access to the repository). Note however, that the "passwd" file discussed in the previous section is not used.

Configuring your client

Now that everything is ready on the server, you must configure your client to be able to connect to that particular CVS server. There are four things your client must know to connect:

All of that information is kept in an environment variable called CVSROOT. Depending upon the way you want to connect to the server (locally, insecure remote, secure remote), you set this variable differently. You use the following command to set the value of the CVSROOT variable:

Local access setenv CVSROOT /usr/local/CVS (no need to login) Password access (local or remote) setenv CVSROOT :pserver:username@ipaddress.domain.com:/usr/local/CVS cvs login Secure remote access setenv CVS_RSH ssh setenv CVSROOT :ext:username@ipaddress.domain.com:/usr/local/CVS (no need to use "cvs login", but you will be required to provide your password every time)

You can now request modules on that repository (e.g. cvs checkout CVSROOT/modules to get a list of the installed modules. If you have not imported any modules yet, this will be empty.) A few notes:

Configuring the repository

Now that you are logged in, you can configure the repository. ( I haven't had time to write anything up yet, so you should take a look at Onlamp or Apple for a good introduction to CVS.)

Contact information

You can email me at dccote@novajo.ca for corrections, comments or questions.