Motivación
Revisando el código de qemu me encontré con que es bastante tedioso el buscar las definiciones de algunas funciones, por lo que pensé en utilizar opengrok para poder navegar de forma más fácil en el código. Ya que normalmente utilizo jetty como web server para aplicaciones java pensé en utilizarlo para ejecutar opengrok, en lugar de utilizar tomcat como es sugerido.
Instalación y configuración de opengrok
En la página web de opengrok se indica que se requiere un servlet container, por lo que jetty debería poder utilizarse, ya que en la descripción de la página web se indica:
Eclipse Jetty provides a Web server and javax.servlet container
Se comienza instalando las dependencias (o asegurandose que estén) a nivel de sistema:
sudo apt-get install -Vy default-jre-headless universal-ctags
Luego se crea la estructura de directorios que utilizará opengrok, para descargar y descomprimir jetty y opengrok:
WORKDIR=/path/to/opengrok
mkdir -p "$WORKDIR"/{src,data,dist,etc,log}
wget -P "$WORKDIR" 'https://repo1.maven.org/maven2/org/eclipse/jetty/jetty-distribution/9.4.28.v20200408/jetty-distribution-9.4.28.v20200408.tar.gz'
mkdir "$WORKDIR"/jetty
tar --strip-components=1 -xzf jetty-distribution-9.4.28.v20200408.tar.gz -C "$WORKDIR"/jetty
wget -P "$WORKDIR" 'https://github.com/oracle/opengrok/releases/download/1.3.13/opengrok-1.3.13.tar.gz'
tar --strip-components=1 -xzf opengrok-1.3.13.tar.gz -C "$WORKDIR"/dist
Continuando con la documentación de instalación de opengrok se copia la configuración de logs a utilizar (se utiliza la configuración por defecto):
cp "$WORKDIR"/dist/doc/logging.properties "$WORKDIR"/etc
sed -i 's#^\(java.util.logging.FileHandler.pattern =\).*$#\1 '"$WORKDIR"'/log/opengrok%g.%u.log#' "$WORKDIR"/etc/logging.properties
Para el deploy de la aplicación web se crea un enlace simbólico del archivo
source.war
en dist
al directorio jetty/webapps
.
ln -s "$WORKDIR"/dist/lib/source.war "$WORKDIR"/jetty/webapps
Como se indica en la documentación respecto al deploy de la aplicación
web, el archivo web.xml
contiene el
context-param
CONFIGURATION cuyo valor por defecto es
/opengrok/etc/configuration.xml
(en realidad, para la versión 1.3.13 el
valor es /var/opengrok/etc/configuration.xml
). Para sobreescribir dicho valor
podemos utilizar la opción override-web.xml
de jetty
que permite reescribir o agregar nuevos elementos al archivo web.xml
.
Para esto se crea el archivo source.xml
en la carpeta jetty/webapps
indicando el archivo que tendrá la configuración que sobreescribirá el valor de
CONFIGURATION:
cat <<END > "$WORKDIR"/jetty/webapps/source.xml
<?xml version="1.0" encoding="UTF-8"?>
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
<Set name="war">${WORKDIR}/jetty/webapps/source.war</Set>
<Set name="overrideDescriptor">${WORKDIR}/override-web.xml</Set>
</Configure>
END
NOTA: Los detalles para configurar el archivo anterior se pueden encontrar en:
- https://www.eclipse.org/jetty/documentation/current/configuring-contexts.html#using-the-webapp-provider
- https://www.eclipse.org/jetty/javadoc/9.4.28.v20200408/org/eclipse/jetty/webapp/WebAppContext.html
Obviamente, debe crearse el archivo override-web.xml
que indica el valor de
configuración a sobreescribir:
cat <<END > "$WORKDIR"/override-web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<!--
This web.xml format file is an override file that is applied to the
opengrok webapp (source.war) AFTER it has been configured by the default
descriptor and the WEB-INF/web.xml descriptor
-->
<!-- Override context init parameter CONFIGURATION -->
<context-param>
<param-name>CONFIGURATION</param-name>
<param-value>${WORKDIR}/etc/configuration.xml</param-value>
</context-param>
</web-app>
END
Ya creados los archivos anteriores se inicia jetty:
cd "$WORKDIR"/jetty
java -jar start.jar > /tmp/jetty.out 2>&1 &
Para corroborar que la configuración funciona correctamente y que el archivo
web.xml
fué escrito correctamente es busca por el error esperado de que no se
encuentra el archivo $WORKDIR/etc/configuration.xml
:
$ grep 'java.io.FileNotFoundException: .* (No such file or directory)' /tmp/jetty.out
java.io.FileNotFoundException: <<WORKDIR>>/etc/configuration.xml (No such file or directory)
(en la salida anterior se sustituyó el valor de la variable $WORKDIR
por el
texto <<WORKDIR>>
.
Lo que queda es realizar la indexación inicial, la cual también crea el archivo
faltante configuration.xml
.
En mi caso, el código de qemu ya fué descargado en el directorio QEMUDIR
:
QEMUDIR=/path/to/qemu
cd "$QEMUDIR"/..
git clone https://git.qemu.org/git/qemu.git
cd qemu
git submodule init
git submodule update --recursive
Se utiliza un enlace simbólico para que opengrok tenga acceso al código:
ln -s "$QEMUDIR" "$WORKDIR"/src
Y se pasa a indexar el código del repositorio de qemu:
java \
-Djava.util.logging.config.file="$WORKDIR"/etc/logging.properties \
-jar "$WORKDIR"/dist/lib/opengrok.jar \
-c /usr/bin/ctags-universal \
-s "$WORKDIR"/src \
-d "$WORKDIR"/data -H -P -S -G \
-W "$WORKDIR"/etc/configuration.xml \
-U http://localhost:8080/source
El comando anterior genera además el archivo "$WORKDIR"/etc/configuration.xml
que será utilizado por el archivo war de opengrok al ser
deployado.
Por último, se reinicia jetty
y ya se puede acceder a opengrok.
Script para instalación y configuración de opengrok con jetty
Se crea el script install-opengrok-using-jetty.sh utilizando los comandos de la parte anterior.
Este script utilizará dos parámetros, el primero la ruta donde se desea realizar la instalación de opengrok. El segundo, la rutas donde se encuentra el código fuente a indexar.
También se agrega el directorio bin
con los scripts reindex
y up
para
facilitar la administración y no tener que estar recordando los comandos
utilizados luego de un tiempo.
Conclusiones
Sin duda que opengrok es una herramienta útil a la hora de recorrer el código
fuente de un proyecto. Como ejemplo, la definición de type_init
en el código
de qemu, que resultó ser una macro (y el motivo de porqué pensé en instalar
opengrok), lo encontré al momento.
Otro punto positivo fué el uso de jetty, ya que al utilizar override-web.xml
facilita el deployment de opengrok respecto a tomcat en el sentido de que
según las instrucciones de instalación hay que buscar el archivo web.xml
y
modificarlo manualmente (o con sed
).