Una de las muchas formas de "vender humo" en este mundo consiste en ofrecer soluciones a problemas inexistentes. Entre los tantos requisitos para certificar la norma ISO 9001:2015, una empresa debe contar con un sistema de registro y gestión de no conformidades. Como dentro de mi organización se está buscando certificar dicha norma, se solicitó al área de sistemas evaluar alternativas de software para implementar dicha herramienta.

A simple vista, el cuento de la certificación ISO parece un gran negocio para las empresas consultoras. Esto se hace evidente cuando uno descubre que la mayoría de las herramientas de software para la gestión de calidad son de licencia propietaria. Es decir, hay empresas que se dedican exclusivamente a desarrollar soluciones cerradas para requerimientos impuestos por terceros (el consultor cobra una suma importante por venderte el problema y su socio por venderte la solución). Aunque, afortunadamente, investigando un largo rato en Internet, surgió la oportunidad de instalar y probar KMKey Quality, gracias al Catálogo de Software Libre de la Universidad de La Laguna.

KMKey Quality es un software de gestión de calidad ideal para la implantación y mantenimiento de un Sistema de Gestión de calidad (SGC) de cualquier tipo: ISO 9001, ISO 14001, OHSAS 18001, etc, o de una combinación de los mismos, facilitando la gestión de un sistema integrado.

KMKey es liberado bajo la licencia GPLv2, pero su creador y principal impulsor es la empresa Earcon, quien hace lo mínimo indispensable para cumplir con dicha licencia.

En el mundo existe software libre y open source de todo tipo. Hay proyectos importantes desarrollados por grandes comunidades, proyectos medianos desarrollados por grupos más pequeños, y proyectos chicos desarrollados por individuos. Pero a pesar de las diferencias en cuestiones de importancia/magnitud, en general todos cultivan los valores del software libre hablando en términos de calidad de software. El software comunitario en general está cuidadosamente documentado, tanto en forma de manuales como a nivel de comentarios en el código fuente. Además se cuida mucho la limpieza del código, ya que se piensa desde el día cero en que el código fuente estará a la vista de todo el mundo. Así sea un solo individuo quien desarrolle/mantenga una pieza de software libre, si es un miembro de la comunidad open source, muy posiblemente respete y promulgue estas ideas. Pienso que más aún siendo el caso de un individuo, pues si su intención es sumar desarrolladores a su proyecto, debe saber que probablemente pocos sientan deseos de aportar código o soluciones a un proyecto cuyo código fuente es desprolijo y/o pobremente documentado.

En el software privado es diferente, porque los desarrolladores tienen la certeza de que nadie fuera de la empresa verá su código fuente. Entonces la calidad del software se reduce a las políticas de calidad de software de la empresa.

Pero hay otra clase de proyectos libres u open source, y son aquellos desarrollados y mantenidos por una única empresa de software comercial. Y digo comercial porque el código fuente se libera bajo licencias libres u open source, sólo que la empresa detrás del "producto" es quien lucra con el mismo. Esto no está mal, por supuesto. Si estuviese prohibido hacer dinero con el software libre, éste simplemente no existiría.

El problema surge cuando la empresa que mantiene una pieza de software libre hace todo lo posible para monopolizar su soporte. Por ejemplo, libera todo su código fuente sin comentarios (quien haya examinado código fuente de systemd puede comprobarlo), hace todo lo posible por ofuscar su configuración, y peor aún no provee documentación alguna. Es decir, hace lo mínimo indispensable para cumplir con la licencia.

Tal vez uno se pregunte por qué entonces estas empresas liberan el código bajo una licencia libre u open source, si no tienen deseos de sus productos de software sean en esencia libre. Esto ocurre porque en muchos países, notablemente en la Unión Europea, han tomado al sabia decisión de forzar el uso de software libre en entidades gubernamentales. La consecuencia de esta decisión, es que las empresas proveedoras de software para el estado se vieron obligadas a liberar sus productos bajo licencias abiertas. Incluso puede ser que hayan tenido que abrir el código de productos antes cerrados, lo cual pone en evidencia lo ordinario que es el software de código cerrado.

A ésto se reduce mi experiencia con KMkey y por ello que decidí compartir este artículo. Tanto la arquitectura de KMKey como el proceso de instalación y configuración, carecen de una documentación mínima. A causa de esto es necesario realizar un trabajo de ingeniería inversa, a partir de un appliance disponible en Internet, e invertir largas horas, sólo para entender cómo funciona, cómo se relacionan sus diferentes componentes, y cómo lograr ponerlo en funcionamiento en uno de nuestros servidores.

KMKey se instala sobre una plataforma Open Source conformada por: GNU/Linux como sistema operativo; Apache como servidor HTTP; Zope como servidor de aplicaciones Python (el equivalente a Glassfish/Jetty para Java); ZODB como base de datos orientada a objetos para Python; PostgreSQL como base de datos relacional; y Python como lenguaje de programación.

Desde el siguiente enlace es posible descargar KMKey y sus diferentes productos (Quality, Project y HelpDesk):

KMKey: Project Management Software

Este artículo explica el proceso de instalación de KMKey 12 "Zapata", específicamente la versión "12.12.01-zapata".

Manos a la obra

Partiendo de un servidor Debian 6 (debe ser específicamente esta versión de Debian, y se debe agregar el repositorio LTS para disponer de las actualizaciones de seguridad), se deben realizar las siguientes tareas de pre-instalación.

Crear un directorio donde almacenar el código fuente de KMKey:

# mkdir /usr/local/src/kmkey
# cd /usr/local/src/kmkey

Si se accede a Internet a través de un servidor proxy, es necesario configurar wget:

# nano /etc/wgetrc

Configurar las siguientes variables:

http_proxy = http://proxy.linuxito.com:8080/
https_proxy = http://proxy.linuxito.com:8080/
ftp_proxy = http://proxy.linuxito.com:8080/

Luego es posible descargar los fuentes:

# wget https://joinup.ec.europa.eu/system/files/project/5b/e5/d2/quality.pgdump.gz
# wget https://joinup.ec.europa.eu/system/files/project/9a/b0/54/project.pgdump.gz
# wget https://joinup.ec.europa.eu/system/files/project/72/fb/22/helpdesk.pgdump.gz
# wget https://joinup.ec.europa.eu/system/files/project/0f/97/5e/kmkey_installer.tar.bz2

El siguiente paso consiste en agregar los repositorios "contrib", "non-free" y los fuentes, necesarios para instalar dependencias de KMKey. Editar el archivo /etc/apt/sources.list, debe quedar de la siguiente forma:

deb http://ftp.ca.debian.org/debian/ squeeze main contrib non-free
deb http://ftp.ca.debian.org/debian/ squeeze-updates main contrib non-free
deb http://security.debian.org/ squeeze/updates main
deb http://ftp.ca.debian.org/debian squeeze-lts main contrib non-free
 
deb-src http://ftp.ca.debian.org/debian/ squeeze main contrib non-free
deb-src http://ftp.ca.debian.org/debian/ squeeze-updates main contrib non-free
deb-src http://ftp.ca.debian.org/debian squeeze-lts main contrib non-free

Actualizar los repositorios y paquetes:

# apt-get update
# apt-get upgrade
# apt-get autoremove

Instalar Apache MPM Prefork (la versión tradicional de Apache sin threads):

# apt-get install apache2-mpm-prefork

Instalación de KMKey

Descomprimir el contenido del archivo kmkey_installer.tar.bz2:

# tar xf kmkey_installer.tar.bz2

Se genera el directorio kmkey_installer, el cual que contiene el script de instalación debian-installer.sh. Antes de comenzar la instalación es necesario realizar algunas modificaciones en dicho script:

# cd kmkey_installer
# nano debian-installer.sh

Cambiar el directorio temporal para la instalación a un filesystem con suficiente espacio libre (si no se cuenta con espacio suficiente en /tmp). Agregar la opción --no-check-certificate en el comando para descargar RelStorage utilizando wget (línea 142 del script).

Comenzar la instalación ejecutando el script:

# ./debian-installer.sh

Seguir los pasos de instalación atentamente.

Durante la instalación de PosgreSQL se deben generar al menos los locales: en_US.UTF-8 y es_ES.UTF-8.

Prestar atención al momento de instalar OpenOffice (lo utiliza sin entorno gráfico, sólo para generar reportes en formato PDF) ya que primero ofrece la versión de 32 bits y luego la de 64 bits. Instalar la versión que corresponda con el sistema operativo.

Instalar las dependencias y paquetes opcionales. Por supuesto instalar Python cuando el script lo pregunte. También RelStorage. Indicar al instalador que Apache NO está dedicado a KMKey (para que no guarde la configuración en el VirtualHost "default" y en lugar de eso cree uno aparte). Finalmente, agregar productos (este paso lleva su tiempo porque hace un update desde el repositorio SVN).

Al finalizar la instalación, realizar la siguiente modificación en el script de inicio de ZOORRA /etc/init.d/zoorrad.sh:

#dir=`dirname $0`
dir="/usr/local/zoorra"

Instalación de productos

Cada producto de KMKey es básicamente una base de datos PostgreSQL. En la misma se almacenan todos los objetos Python necesarios para implementar cada aplicación. Esto implica que los productos son simplemente volcados de bases de datos PostgreSQL, utilizando un formato binario.

PostgreSQL permite utilizar diferentes formatos para crear volcados con pg_dump. Los productos disponibles para descargar desde el sitio poseen extensión gz, lo cual da la pauta de que se trata de archivos comprimidos en formato Gzip. Pero no existe documentación alguna que indique en qué formato están, de qué tipo de volcado de PostgreSQL se trata, ni cómo extraerlos.

root@kmkey:/usr/local/src/kmkey# ls -l *.gz
-rw-r--r-- 1 root staff 4390524 ago 13 11:28 helpdesk.pgdump.gz
-rw-r--r-- 1 root staff 2627706 ago 13 08:26 project.pgdump.gz
-rw-r--r-- 1 root staff 3989063 ago 13 10:25 quality.pgdump.gz

Si se ejecuta file, éste reporta que efectivamente se trata de archivos Gzip:

root@kmkey:/usr/local/src/kmkey# file quality.pgdump.gz 
quality.pgdump.gz: gzip compressed data, from Unix

Entonces, para descomprimirlos, ejecutar:

# gunzip quality.pgdump.gz

Se extrae el archivo quality.pgdump (tener en cuenta que gunzip elimina el archivo origen).

Si se trata de restaurar la base de datos de Quality desde este dump, pg_restore falla porque no reconoce el formato. Si se examina el archivo extraído del .gz con la herramienta file, se observa que también es de tipo Gzip:

root@kmkey:/usr/local/src/kmkey# file quality.pgdump
quality.pgdump: gzip compressed data, from Unix

Se trata de un Gzip dentro de otro, como una especie de ofuscación para desalentar Sysadmins novicios. Es necesario extraer nuevamente con gunzip:

# mv quality.pgdump quality.pgdump.gz
# gunzip quality.pgdump.gz

Ahora sí, se extrae un archivo con formato PostgreSQL binario:

root@kmkey:/usr/local/src/kmkey# file quality.pgdump
quality.pgdump: PostgreSQL custom database dump - v1.11-0

Luego de extraer los volcados de PostgreSQL es posible crear y generar las bases de datos.

Pasar a usuario "postgres":

# su - postgres

Cambiar al directorio donde se encuentran los volcados y conectarse al motor de bases de datos:

$ cd /usr/local/src/kmkey/
$ psql

Crear las bases de datos para los productos deseados y luego cambiar el encoding a "LATIN9":

create database quality_src template template0;
create database project_src template template0;
create database helpdesk_src template template0;
update pg_database set encoding=16 where datname='quality_src';
update pg_database set encoding=16 where datname='project_src';
update pg_database set encoding=16 where datname='helpdesk_src';
\q

Restaurar las tablas de la base de datos utilizando pg_restore:

$ pg_restore -v -d quality_src quality.pgdump > /tmp/quality.pgdump.out 2>&1
$ pg_restore -v -d project_src project.pgdump > /tmp/project.pgdump.out 2>&1
$ pg_restore -v -d helpdesk_src helpdesk.pgdump > /tmp/helpdesk.pgdump.out 2>&1

Luego cambiar propietario (owner) de las bases de datos al usuario "zope", creado durante la instalación de KMKey:

$ psql
alter database quality_src owner to zope;
alter database project_src owner to zope;
alter database helpdesk_src owner to zope;
\q

Configuración de Zope

Para cada base de datos es necesario configurar un montaje en la configuración de Zope (para que el servidor de aplicación sea capaz de conectarse y gestionar las mismas), el cual a su vez representa el alias que será utilizado al acceder mediante HTTP.

Editar la configuración de zope y zope2:

# cd /usr/local/kmkey/zope/etc/
# nano zope.conf

Agregar las siguientes líneas (en este caso he instalado los tres productos: Quality, Project y HelpDesk):

<zodb_db helpdesk_src>
mount-point /helpdesk_src
cache-size 10000
pool-size 12
<relstorage>
<postgresql>
	# The dsn is optional, as are each of the parameters in the dsn.
	dsn dbname='helpdesk_src' user='zope' host='localhost'
</postgresql>
</relstorage>
</zodb_db>

<zodb_db quality_src>
mount-point /quality_src
cache-size 5000
pool-size 12
<relstorage>
<postgresql>
	# The dsn is optional, as are each of the parameters in the dsn.
	dsn dbname='quality_src' user='zope' host='localhost'
</postgresql>
</relstorage>
</zodb_db>

<zodb_db project_src>
mount-point /project_src
cache-size 5000
pool-size 12
<relstorage>
<postgresql>
	# The dsn is optional, as are each of the parameters in the dsn.
	dsn dbname='project_src' user='zope' host='localhost'
</postgresql>
</relstorage>
</zodb_db>

Repetir estos pasos para zope2 (/usr/local/kmkey/zope2/etc/zope.conf) y reiniciar Zope:

# /etc.init.d/zope restart

Configuración de aplicaciones desde el panel de Zope

En este punto KMkey ya está instalado y funcionando, sólo resta terminar de importar las aplicaciones.

Desde un navegador Web, ingresar al Panel de Control de Zope:

http://kmkey.linuxito.com:8083/manage

Utilizar el usuario "admin" y la contraseña establecida durante la instalación.

Notar que al utilizar el puerto 8083 se está accediendo directamente al servidor de aplicación Zope sin pasar por Apache (lógicamente sólo es posible si dicho puerto está abierto en el firewall). Luego será necesario verificar que la redirección y el balanceador de carga en Apache estén funcionando correctamente.

Dirigirse a la carpeta raíz mediante el enlace "Root Folder" y seleccionar "ZODB Mount Point" en el desplegable de la derecha. Clic en "Add" para agregar nuevos montajes.

En esta ventana deben aparecer las bases de datos de PostgreSQL recuperadas desde los volcados. Si no es así, verificar que los montajes estén correctamente definidos. Seleccionar las nuevas bases de datos PostgreSQL y ejecutar "Create selected mount points".

Una vez finalizado, en el panel de la izquierda deben aparecer las carpetas correspondientes a los productos, por ejemplo "quality_src" si se ha agregado el montaje "quality_src" correspondiente a la base de datos PostgreSQL "quality_src".

Verificar el funcionamiento de la aplicación ingresando a:

http://kmkey.linuxito.com:8083/quality_src/kmkey

El usuario/contraseña por defecto es:

adminkmkey:demokm

Configuración de Apache

KMKey utiliza Apache como front-end a dos instancias de Zope: una para servir todos los productos instalados y otra específica para manejar las solicitudes de exportación de reportes en formato PDF utilizando OepnOffice (levantar toda la suite de OOo para convertir documentos me parece un despropósito, hay otras herramientas y librerías más eficientes para realizar dicho trabajo, sobre todo si se está trabajando con Python). Además Apache provee soporte para SSL (HTTPS).

Antes de comenzar a configurar Apache, borrar todos los sitios instalados por KMkey, excepto los VirtualHost "default" y "default-ssl:"

Activar los modulos "rewrite2 y "ssl":

# a2enmod ssl
# a2enmod rewrite

Crear el directorio /etc/apache2/ssl y agregar el certificado junto con su clave privada y certificados de la cadena (pueden utilizar un certificado autofirmado en caso de no contar con uno válido o generar uno gratis). Luego modificar el VirtualHost ssl para agregar la referencia la los archivos del certificado en /etc/apache2/sites-available/default-ssl:

[...] 
SSLCertificateFile /etc/apache2/ssl/server.crt
SSLCertificateKeyFile /etc/apache2/ssl/server.key
SSLCertificateChainFile /etc/apache2/ssl/server-ca.crt
[...]

Crear los archivos kmkey-proxy, kmkey y kmkey-ssl:

/etc/apache2/sites-available/kmkey-proxy

<Proxy balancer://lb>
	BalancerMember http://127.0.0.1:8083
	Order allow,deny
	Allow from all
</Proxy>

ProxyRequests Off
ProxyVia Full

/etc/apache2/sites-available/kmkey

Include sites-available/kmkey-proxy

RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^/(.*) balancer://lb/VirtualHostBase/http//%{HTTP_HOST}:80/VirtualHostRoot/$1 [L,P]

/etc/apache2/sites-available/kmkey-ssl

Include sites-available/kmkey-proxy

RewriteEngine On
RewriteCond %{HTTPS} on
RewriteRule ^/(.*) balancer://lb/VirtualHostBase/https//%{HTTP_HOST}:443/VirtualHostRoot/$1 [L,P]

Luego agregar al final del archivo /etc/apache2/sites-available/default:

[...]
# Redirección a HTTPS
RewriteEngine On
RewriteLog "${APACHE_LOG_DIR}/rewrite.log"
RewriteLogLevel 2
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}

Include sites-available/kmkey

Y al final del archivo /etc/apache2/sites-available/default-ssl:

[...]
Include sites-available/kmkey-ssl

Finalmente activar los alias "default" y "default-ssl":

# a2ensite default
# a2ensite default-ssl

Reiniciar Apache:

# service apache2 restart

Script de inicio de servicios

Los scripts de inicio de servicios /etc/init.d/kmkey y /etc/init.d/zoorrad.sh están mal diseñados y tienen muchos errores. Por lo tanto, borrarlos y reemplazarlos por un único script de inicio:

# rm /etc/init.d/kmkey
# rm /etc/rc*.d/S*zoorrad.sh

Crear el nuevo archivo /etc/init.d/kmkey con el siguiente contenido:

#! /bin/sh
### BEGIN INIT INFO
# Provides:          kmkey
# Required-Start:    $remote_fs $syslog postgresql
# Required-Stop:     $remote_fs $syslog postgresql
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: KmKey
# Description:       KmKey
### END INIT INFO

# PATH should only include /usr/* if it runs after the mountnfs.sh script
PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="KmKey"
NAME=kmkey
DAEMON=/usr/sbin/$NAME
DAEMON_ARGS="--options args"
PIDFILE=/var/run/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME

. /etc/profile

# Exit if the package is not installed
#[ -x "$DAEMON" ] || exit 0

# Read configuration variable file if it is present
[ -r /etc/default/$NAME ] && . /etc/default/$NAME

# Load the VERBOSE setting and other rcS variables
. /lib/init/vars.sh

# Define LSB log_* functions.
# Depend on lsb-base (>= 3.2-14) to ensure that this file is present
# and status_of_proc is working.
. /lib/lsb/init-functions

#
# Function that starts the daemon/service
#
do_start()
{
	# Return
	#   0 if daemon has been started
	#   1 if daemon was already running
	#   2 if daemon could not be started
	
	su -c "/usr/local/kmkey/zeo/bin/zeoctl start" zope
	su -c "/usr/local/kmkey/zope/bin/zopectl start" zope
	/usr/local/zoorra/zoorrad.sh start
	return 0
}

#
# Function that stops the daemon/service
#
do_stop()
{
	# Return
	#   0 if daemon has been stopped
	#   1 if daemon was already stopped
	#   2 if daemon could not be stopped
	#   other if a failure occurred
	
	su -c "/usr/local/kmkey/zeo/bin/zeoctl stop" zope
	su -c "/usr/local/kmkey/zope/bin/zopectl stop" zope
	/usr/local/zoorra/zoorrad.sh stop
	return 0
}

#
# Function that sends a SIGHUP to the daemon/service
#
do_reload() {
	su -c "/usr/local/kmkey/zeo/bin/zeoctl reload" zope
	su -c "/usr/local/kmkey/zope/bin/zopectl reload" zope
	su -c "/usr/local/zoorra/zope/bin/zopectl reload" zope
	/usr/local/zoorra/zoorrad.sh status
	return 0
}

case "$1" in
start)
	[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
	do_start
	case "$?" in
		0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
		2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
	esac
	;;
stop)
	[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
	do_stop
	case "$?" in
		0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
		2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
	esac
	;;
status)
	su -c "/usr/local/kmkey/zeo/bin/zeoctl status" zope
	su -c "/usr/local/kmkey/zope/bin/zopectl status" zope
	/usr/local/zoorra/zoorrad.sh status
	;;
#reload|force-reload)
	#
	# If do_reload() is not implemented then leave this commented out
	# and leave 'force-reload' as an alias for 'restart'.
	#
	#log_daemon_msg "Reloading $DESC" "$NAME"
	#do_reload
	#log_end_msg $?
	#;;
restart|force-reload)
	#
	# If the "reload" option is implemented then remove the
	# 'force-reload' alias
	#
	log_daemon_msg "Restarting $DESC" "$NAME"
	do_stop
	case "$?" in
	0|1)
		do_start
		case "$?" in
			0) log_end_msg 0 ;;
			1) log_end_msg 1 ;; # Old process is still running
			*) log_end_msg 1 ;; # Failed to start
		esac
		;;
	*)
		# Failed to stop
		log_end_msg 1
		;;
	esac
	;;
*)

	echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
	exit 3
	;;
esac

Por último, reiniciar el servicio kmkey y verificar el acceso a la aplicación desde el puerto 80:

# service kmkey restart

Enjoy!

Referencias

KMKey: Project Management Software

KMKey Quality

MANUAL DE INSTALACION PARA DEBIAN 4.0 (así de desactualizada está la documentación)

Comunidad KMKey en Español - Guía de Instalación de KMKey


Tal vez pueda interesarte


Compartí este artículo