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
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