El Concurrent Version System es una de las herramientas de desarrollo más utilizadas en el mundo del software libre. Recientemente están apareciendo nuevas alternativas como Subversion. Pero hasta dentro de unos años, CVS seguirá siendo la alternativa que está presente en prácticamente todas las plataformas.
En este artículo se describen algunos trucos para montar un servidor de repositorio con CVS.
Hay mucha literatura existente sobre como administrar un pserver. De hecho, es la modalidad de servidor CVS más documentada que existe; sencillamente, porque es la más cómoda y sencilla de administrar. Pero el mismo pserver es inseguro por naturaleza. Mucha gente lo critica por la falta de cifrado en las transacciones.
Con este artículo ya no pretendo hacer la mejor guía del administrador de CVS (las hay mejores), sino una pequeña receta para manejar el pserver cómodamente.
Que lo disfrutéis.
A continuación un breve resumen sobre la administración del pserver en el CVS. Si queréis una guía más completa podéis mirar en la última sección de éste artículo.
En esta sección, todos los ficheros mencionados se encuentran en $CVSROOT/CVSROOT.
NOTA: Es recomendable que para editar los ficheros del directorio $CVSROOT/CVSROOT uséis el propio cvs, es decir, hacer checkout de los ficheros y luego commit para guardar los cambios. Es el consejo que dan todos los manuales.
La principal razón para montar un pserver es la falta de generosidad a la hora de dar cuentas de usuarios en una máquina (por ejemplo, nuestra máquina). El pserver tiene una gestión de usuarios independiente; ahora, es extremadamente simple. Para que la lista de usuarios del pserver sea realmente independiente tendremos que poner la siguiente línea en el fichero config.
SystemAuth=no
El fichero passwd del pserver tiene el siguiente formato:
usuario:password_encriptado:usuario_sistema
El tercer campo (usuario_sistema) es un usuario de sistema sobre el que usuario será mapeado. Así, todas las interacciones sobre el sistema de ficheros del servidor (pserver) se realizarán con los privilegios de usuario_sistema.
El resto de los ficheros que nos interesa tocar tienen el mismo formato:
EXPRESIÓN_REGULAR ruta_hacia_ejecutable [argumentos]
La expresión regular se compara contra la ruta, relativa a $CVSROOT, del directorio en el que estamos trabajando. Si la ruta coincide con la expresión regular entonces se ejecuta ruta_hacia_ejecutable al cual le podemos pasar cuantos argumentos queramos.
En la parte de la expresión regular podemos poner ALL, que coincide siempre, o DEFAULT, que coincide por defecto.
Para entender mejor el significado de cada fichero de configuración es bueno saber el orden en el que son examinados. Al hacer un commit se examinan los siguientes ficheros, en orden:
Si alguno de los programas ejecutados por commitinfo y verifymsg devuelve un valor diferente de cero el commit se aborta (como el estándar UNIX de toda la vida). En la siguiente sección veremos algunos usos que le podemos dar a cada uno de éstos ficheros.
Si no buscamos hilar fino a la hora de restringir acceso en un repositorio. Nos podemos valer de los archivos readers y/o writers. Normalmente sólo hace falta uno de éstos.
Si ninguno de éstos ficheros existe en $CVSROOT/CVSROOT cualquier usuario CVS tiene acceso total (checkout y commit) al repositorio. Si existe readers los usuarios listados en él tienen acceso de sólo-lectura (checkout) y el resto tienen acceso total. Si existe writers los usuarios listados tienen acceso total y el resto tiene acceso de sólo-lectura. Si existen ambos ficheros, únicamente se tiene en cuenta el writers.
Hay que resaltar que tanto readers como writers NO contienen usuarios de sistema, sino del pserver. Si únicamente utilizamos éste mecanismo para limitar el acceso al repositorio no necesitamos mapear los usuarios CVS sobre usuarios del sistema.
Ahora pasamos a mostrar algunas posibilidades para restringir los accesos de forma más personalizada. Para esta sección asumo que se tienen creadas tres cuentas de usuario en la máquina: cvsadmin, cvsanon, cvsdevel. Donde las dos últimas no pueden acceder a la línea de comandos (sólo las usaremos para mapear usuarios CVS). Además, los siguientes grupos: cvspublic, cvsprivate. Donde cvsadmin y cvsdevel pertenecen a ambos y cvsanon únicamente pertenece a cvspublic.
Reconozco que habrá mejores maneras de organizarlo, pero para nuestros ejemplos lo consideraremos así. El resto depende de vuestra imaginación.
Si queremos limitar los checkouts en términos de público y privado (como vamos a mostrar) haremos uso de las cuentas de sistema cvsanon y cvsdevel. Suponemos que nuestro passwd tiene la siguiente forma:
anonimo:$1$f5028K.X$zzxw7OPiLfZdRaJOOGoNZ1:cvsanon pepe:$1$VUJLvXDS$g/SO6jxwltEGPjP4Jhx8A/:cvsdevel manolo:$1$i.80VddS$av38TR23.au/0cvloVr0e4:cvsdevel
Ahora supongamos que nuestro $CVSROOT tiene la siguiente forma:
drwxrwx--- 3 cvsadmin cvsprivate 1024 6 sep 13:26 CVSROOT/ drwxrwx--- 4 cvsadmin cvspublic 512 24 jun 13:19 gnu_pepe_manolo/ drwxrwx--- 2 cvsadmin cvsprivate 512 6 sep 13:47 pepes/ drwxrwx--- 8 cvsadmin cvsprivate 512 4 sep 04:20 manolos/ drwxrwx--- 5 cvsadmin torpedete 512 2 sep 01:34 privador/
Con todo montado así. Un usuario anónimo únicamente podrá hacer checkout del proyecto gnu_pepe_manolo. Los usuarios pepe y manolo podrán hacer checkout de todo excepto del proyecto privador que pertenece al los usuarios locales pertenecientes al grupo torpedete. Esto nos permite utilizar el mismo repositorio para tareas locales y remotas (con restricciones).
¿Dónde está el truco? En los permisos. El proceso de checkout necesita la creación de ficheros de bloqueo (lockfiles) por el tema de la exclusión mutua; para evitar checkouts y commits inconsistentes (en caso de accesos concurrentes). Por lo tanto se necesita permiso de escritura en el directorio del que se quiere hacer checkout. Si no se tiene dicho permiso, el checkout no se puede llevar a cabo.
Por eso necesitábamos mapear los usuarios CVS con usuarios de sistema. Así, cuando pepe se ha autentificado (cvs login) para cada operación que realiza el sistema (servidor) lo considera como cvsdevel. Ojo, el ''pserver'' lo sigue viendo como pepe.
El único problema que se puede presentar es el caso de que pepe y manolo tengan que hacer una práctica (cada uno) para la misma asignatura. Con esta configuración del repositorio pepe puede hacer checkout de la práctica de manolo y viceversa. Pero esto se puede solucionar con los permisos del sistema, añadiendo más usuarios para ser mapeados.
La limitación de commits es más sencilla de implementar en el sentido de que no implica al sistema donde corre el pserver. Para hacer commits lo que más nos interesa es implementar ACLs (Access Control Lists); las cuales se pueden implementar a través de scripts.
El método es sencillo: simplemente consiste en crear (o utilizar) algún programa o script que recibe varios parámetros (entre ellos el usuario y el directorio afectado) y devuelva cero o distinto de cero según unos requisitos (por ejemplo, una lista de control de acceso). Y todo esto gracias al fichero commitinfo.
Lo montaríamos de la siguiente manera: tenemos un programa, dándole un nombre y una ruta va y lo comprueba en una lista asociativa devolviendo cero o distinto de cero según algún criterio. Para hacerlo funcionar basta con que editemos el fichero commitinfo de la siguiente forma:
ALL ruta_a_mi_programita $USER
El $USER que me acabo de sacar de la manga se expande por el nombre del usuario CVS, en nuestro ejemplo cualquiera de los posibles: anonimo, pepe o manolo. Así si, por ejemplo, es manolo el que hace el commit, ruta_a_mi_programita recibe los parámetros manolo y la ruta hasta el fichero que se pretende insertar. Por lo tanto, aquí no nos sirve de nada el mapeado de usuarios.
Como veis, administrar un pserver da juego a ideas muy creativas y variadas. Desde enviar mensajes de correo electrónico a un grupo de desarrollo tras cada commit, hasta sincronizar varios repositoros de respaldo. También se pueden validar los mensajes asociados al commit a través del fichero verifymsg. Lo mejor es probar o, si eres vago, buscar algo ya hecho ;-)
Si lo que te preocupa es la seguridad has de saber que es posible montar un servidor CVS sobre ssh (también se puede montar en una red kerberos pero no es algo fácil de hacer) sin excesivas complicaciones. De lo que tendréis que prescindir en este caso es del recelo a la hora de crear cuentas de sistema, pues es necesario para poder utilizar ssh.
Montar el servidor así es algo que no he probado todavía pero sé que lo necesitaré pronto, así que me estoy documentando. A continuación os doy algunos enlaces para que os informéis acerca del tema: