Pregunta
¿Alguien ha podido iniciar una aplicación web con éxito a través de una configuración webappctl
que especifica una configuración launchd en su clave webapp.plist
launchKeys
?
Fondo
Específicamente, con Server.app instalado, uno puede, en teoría, configurar aplicaciones web personalizadas que se mostrarán en la GUI de Server.app en la "Configuración avanzada" de la configuración de un sitio web.
Si echas un vistazo al ReadMe.txt
en /Library/Server/Web/Config/apache2
hay una sección que dice:
webapps/
This directory contains the webapp.plist files for all defined webapps.
See the man page for webapp.plist(8) and webappctl(8).
(Server app man pages are present in /Applications/Server.app/Contents/ServerRoot/usr/share/man/.)
Administrators are strongly encouraged to use the webapp mechanism
instead of modifying virtual host config files directly.
In general, you can place Apache configuration directives in an "Include" file,
and create a webapp.plist file that references that Include file.
You can then activate or de-activate that Include file for the default
sites, or for specific custom sites, by using webappctl(8).
También puede leer las entradas del manual, como lo sugieren estos comandos de terminal en el archivo ReadMe.txt:
man -M /Applications/Server.app/Contents/ServerRoot/usr/share/man/ webapp.plist
man -M /Applications/Server.app/Contents/ServerRoot/usr/share/man/ webappctl
También hay un ejemplo de configuración de la aplicación web /Library/Server/Web/Config/apache2/com.example.mywebapp.plist
que contiene algunos comentarios sobre cómo se podría configurar este error.
Configuración
En mi caso, agregué webapp.plist
al directorio /Library/Server/Web/Config/apache2/
que se ve así:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<!-- See man pages for webapp.plist(5) and webappctl(8) for information about webapp.plist -->
<plist version="1.0">
<dict>
<key>includeFiles</key>
<array/> <!-- Include files are activated in virtual host when webapp is started -->
<key>launchKeys</key>
<array> <!-- Launchd plists in /Applications/Server.app/Contents/ServerRoot/System/Library/LaunchDaemons are loaded when webapp is started -->
<string>org.levi.foo</string>
</array>
<key>name</key>
<string>org.apache.tomcat</string>
<key>displayName</key> <!-- Name shown in Server app -->
<string>Tomcat</string>
<key>proxies</key> <!-- ProxyPass/ProxyPassReverse directives are activated when webapp is started -->
<dict/>
<key>requiredModuleNames</key>
<array/>
<key>installationIndicatorFilePath</key> <!-- The presence of this file indicates web app is installed -->
<string>/Library/Tomcat/Home/bin/catalina.sh</string>
<key>sslPolicy</key> <!-- Determines webapp SSL behavior -->
<integer>0</integer> <!-- 0: default, UseSSLWhenEnabled -->
<!-- 1: UseSSLAlways -->
<!-- 2: UseSSLOnlyWhenCertificateIsTrustable -->
<!-- 3: UseSSLNever -->
<!-- 4: UseSSLAndNonSSL -->
</dict>
</plist>
Prestando especial atención a:
<key>launchKeys</key>
<array>
<string>org.levi.foo</string>
</array>
que especifica mi launchd.plist
que se encuentra en /Applications/Server.app/Contents/ServerRoot/System/Library/LaunchDaemons/org.levi.foo.plist
y se ve así:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>org.levi.foo</string>
<key>RunAtLoad</key>
<true/>
<key>Program</key>
<string>/Library/Tomcat/start.sh</string>
</dict>
</plist>
que simplemente debería llamar al script /Library/Tomcat/start.sh
, que es simplemente:
#!/bin/bash
BASENAME='basename $0'
LOGGER_B="/usr/bin/logger"
function log {
MESSAGE="$1"
${LOGGER_B} -i -p daemon.notice -t ${BASENAME} ${MESSAGE}
}
log "Here I am!"
Problema
Si uso launchctl
para cargar manualmente el org.levi.foo.plist
:
$ sudo launchctl load org.levi.foo.plist
Recibo el mensaje esperado en /var/log/system.log
:
Apr 2 16:12:01 host sudo[85791]: levi : TTY=ttys000 ; PWD=/Applications/Server.app/Contents/ServerRoot/System/Library/LaunchDaemons ; USER=root ; COMMAND=/bin/launchctl load org.levi.foo.plist
Apr 2 16:12:01 host start.sh[85795]: Here I am!
Sin embargo, si uso webappctl
para iniciar la configuración de mi aplicación web (arriba):
$ sudo webappctl start org.apache.tomcat
Recibo un error en /var/log/system.log
:
Apr 2 16:18:46 host sudo[85904]: levi : TTY=ttys000 ; PWD=/Applications/Server.app/Contents/ServerRoot/System/Library/LaunchDaemons ; USER=root ; COMMAND=/Applications/Server.app/Contents/ServerRoot/usr/sbin/webappctl start org.apache.tomcat
Apr 2 16:18:47 host serverctl[85914]: ERROR: The operation couldn’t be completed. Operation not permitted
Apr 2 16:18:49 host serverctl[85915]: ERROR: The operation couldn’t be completed. Operation not permitted
Apr 2 16:18:49 host servermgr_web[85908]: XSWebConfig:ERROR: Failed on second attempt to load /Applications/Server.app/Contents/ServerRoot/System/Library/LaunchDaemons/org.levi.foo.plist
y no veo mi "¡Aquí estoy!" mensaje.
Esto parece indicar que mi launchd.plist
no está llegando tan lejos como ejecutando el script al intentar iniciar a través de webappctl
, pero no tengo idea de qué operación no se pudo completar, o por qué no. Todos los archivos que he mencionado son propiedad de root:wheel
con rw-r--r--
permisos, excepto el script, que es rwx-r-xr-x
.
Entonces, ¿qué magia se debe realizar para que mi aplicación web cargue / descargue la configuración de mi launchd al iniciar / detener?
Nota al margen: Obviamente, estas configuraciones y scripts son ejemplos simples que he usado para propósitos de depuración y para simplificar los detalles aquí. En realidad, estoy tratando de presentar una instancia de Tomcat como una "aplicación web" para ejecutar detrás de Apache 2 en mi servidor, de modo que pueda implementar aplicaciones web reales a través de Tomcat y hacer que se publiquen en la web.)
Nota al margen 2:
Sé que puedo instalar mi launchd.plist
en /Library/LaunchDaemons
y omitir el launchKeys
de mi webapp.plist
como solución alternativa, pero esto no me permite iniciar / detener la aplicación web a través de Server.app (o la línea de comandos equivalente), y, quiero decir, debería funcionar, ¿no?
Muchas gracias,
Levi
(crosspost from enlace )