Installation instructions for the LysCVS system.

by Erik Forsberg <>

1. Introduction

LysCVS is a system that provides access to CVS in a easily administered way for both local and external users.

In this release, a local user is a user that's present in NIS. An external user is all other users, they are present in a MySQL database.

The functionality is similar to the functionality of sourceforge's CVS server, with some exceptions:

  • Local users still use their passwords to access the system.
  • Only local users can create projects.

Aside from that, LysCVS is hopefully a bit less complex to setup, for a small environment.

2. Theory of operation


There are local users, present in the NIS database, and external users, not present in the NIS database but kept in a MySQL database.

Local users can create external users and add them to their projects. External users can administrate projects (add/remove users of it), but not create them. This way, limits of what projects may be created are imposed by local rules, that local users hopefully obey :).

External users account data is accessed through libpam-mysql (for password information) and nss_mysql (for other user information).

Local users also have a dummy entry in the MySQL database because of the way nss works.


Projects created by local users get their own cvsroot and can have as many modules as the users with write access to the repository wants.

Anonymous read-only access is also possible, using pserver. The pserver is a special patched version. See the part about cvs for details.

When anonymous read-only access is enabled, a special user called anoncvs_<projectname> is created and used in the CVSROOT/passwd file.

Web-based administration

A mod_python program makes administration of projects easy. It also frees the system administrator from boring tasks such as adding/deleting users/projects. The administration webpages are using a template system (HTMLgen) which means altering the look and feel of the system is easy (very little hardcoded HTML).


Optionally, using Postfix as Mail Transfer Agent, LysCVS gives each user (local or external) an email address on the form <username>@<>.

Also, LysCVS can create a mailing list for each project that each project member can decide if he/she want to be a member of. Commit logs are automatically sent to that mailing list.

The reason you have to use Postfix is that both the mail addresses of users, and the lists, are created using MySQL alias/virtual tables. I do not know about any other MTA that can use MySQL, but if there are such MTAs, you can probably use them after some hacking. Please report any success doing that.

Note: If you don't want commit logs to be sent to a mailinglist, you'll have to comment out two lines in scripts/ and scripts/

3. Installation

First, find LysCVS. You've probably succeeded doing that :-).

Unpack the sources. In my examples, they are unpacked to /opt/lyscvs

Create your MySQL database using the file <installroot>/src/nss.sql. Setup access rights correctly for MySQL.

Install nss_mysql, it's available from if your distributions doesn't support it.

Configure nss_mysql. I use the following configuration files:

--start /etc/nss-mysql.conf-- # This is the user configuration part = localhost; users.where_clause = user.status = 'A'; # fully qualifed where clause users.database = nss; users.db_user = nss; users.db_password = <password>; users.table = user; users.user_column = user_name; users.password_column = password; # not used if you have enabled the shadow support users.userid_column = uid; users.uid_column = uid; users.gid_column = gid; # not used if you have run configure --with-default_gid=GID users.realname_column = realname; users.homedir_column = homedir; # not used if you have run configure --with-default_home=DIR users.shell_column = shell; users.default_gid = 30; # GID of users default group users.default_home = /home; # used only if you have run configure --with-default_home=DIR

# This is the groups configuration part # This is only used if you have enabled the group support = localhost; groups.where_clause = groups.status = 'A'; #fully qualified where clause groups.database = nss; groups.db_user = nss; groups.db_password = <password>; groups.group_info_table = groups; groups.group_name_column = group_name; groups.groupid_column = group_id; groups.members_table = user_group; groups.member_userid_column = user_id; groups.member_groupid_column = group_id; # At this time, we do not support a GID column. We use # the following trick to choose a GID : gid = group_id + first_gid. # You should not set first_gid to less than 1000 groups.first_gid = 1000; --end /etc/nss-mysql.conf--

--start /etc/resolv.conf-- # /etc/nsswitch.conf # # Example configuration of GNU Name Service Switch functionality. # If you have the `glibc-doc' and `info' packages installed, try: # `info libc "Name Service Switch"' for information about this file.

System Message: WARNING/2 (<string>, line 144); backlink

Inline interpreted text or phrase reference start-string without end-string.

System Message: WARNING/2 (<string>, line 144); backlink

Inline interpreted text or phrase reference start-string without end-string.

System Message: WARNING/2 (<string>, line 144); backlink

Inline interpreted text or phrase reference start-string without end-string.

passwd: compat mysql group: compat mysql shadow: compat

hosts: files dns networks: files

protocols: db files services: db files ethers: db files rpc: db files

netgroup: nis --end /etc/resolv.conf--

You also need libpam-mysql. I have a /etc/pam.d/sshd that looks like this:

--snip-- auth required auth required # [1] auth sufficient auth required user=pam_auth passwd=<password> db=nss passwdcolumn=password usercolumn=user_name crypt=1

account sufficient account required user=pam_account passwd=<password> db=nss passwdcolumn=password usercolumn=user

session required session optional # [1] session optional # [1] session optional standard # [1]

password required --snap--

Compile cvs. Grab a recent stable version from and apply the patch <installroot>/src/cvs-sf-patch. Compile it and place the cvs binary where your ssh logins can find it.

(In my setup, LysCVS has it's own openSSHD daemon with a restrictive configuration (no port forwards, no X11 etc..) - but you don't have to do this.)

Configure pserver, I use xinetd with the following configuration:

--snip-- service cvspserver {

System Message: ERROR/3 (<string>, line 200)

Unexpected indentation.
socket_type = stream protocol = tcp wait = no user = root server = /opt/lyscvs/bin/cvs server_args = --allow-root=/cvsroot pserver bind =

System Message: WARNING/2 (<string>, line 207)

Block quote ends without a blank line; unexpected unindent.



Make sure you fix that ip in the bind statement. It's not mandatory, but it helps, since people won't access the wrong IP by mistake.

Install apache, with mod_python. The latter is available from

Modify the lib/ file. Most things should be pretty straightforward to understand. Make sure all directories exists.

Modify your apache configuration. Something like this must be added:

--snip-- Listen Listen

<VirtualHost> DocumentRoot /opt/lyscvs/web/root RedirectMatch 301 /cvsadm.*$ </VirtualHost>

<VirtualHost> DocumentRoot /opt/lyscvs/web/root

Alias /cvsadm/ /opt/lyscvs/web/pybin/

<Directory "/opt/lyscvs/web/pybin">
Options -Indexes SetHandler python-program PythonHandler cvsadm PythonDebug on

System Message: WARNING/2 (<string>, line 241)

Definition list ends without a blank line; unexpected unindent.


RedirectMatch 301 /cvsadm/$ RedirectMatch 301 /cvsadm$

</VirtualHost> --snap--

(You probably want to enable SSL too..)

Now, start blaming me because the installation instructions are too short, and try to (re)start apache, and access your newly created cvs server.

4. Mail

As noted earlier, LysCVS can optionally cooperate with the Postfix MTA to create mail addresses and mailing lists. This section describes how to do this.

First, get and install Postfix, available from Make sure you compile it with MySQL support (read the file MYSQL_README included in the source distribution).

Next, configure Postfix. One of the nice features of Postfix is that for most installations, the default values of the configuration parameters are correct. There are only a few values you need to change. See src/ for an example of what you probably need to add to your /etc/postfix/ (or wherever you chose to place your postfix configuration).

Use the *.mysql files that also resides in the src/ directory. Each of them defines an alias table that's used to create different parts of the mail system. Check out the files in question, they have some comments that describe their function.

System Message: WARNING/2 (<string>, line 272); backlink

Inline emphasis start-string without end-string.

Also note that inserts a line in each new projects CVSROOT/loginfo that mails the project-specific list with info about each commit.

Some people probably don't want commit messages when they do commit's themselves. Unfortunately, they won't be satisifed by this system. On the other hand, they can construct their own line in loginfo to send mail only when they're not the person doing the commit. Such a line could look like this:

ALL (if [ /usr/bin/id -un != "username" ]; then (/bin/cat | /usr/bin/mail -s %s; fi)

(Thanks goes to Peter ├ůstrand <> for the above line)

This section probably needs more work, but since I'm so familiar with mail systems and Postfix, I probably can't see what's unclear. Please give me feedback on this!