Este es el montaje:
- OSX Yosemite
- Servicio basado en Java que se inicia mediante un LaunchDaemon
- El servicio se inicia con un usuario personalizado que se crea durante la instalación
- El usuario tiene un directorio personal para guardar cierta información, como las preferencias
Así es como se crea el usuario:
DEAMON_USER="{{daemonUser}}"
HOME_DIRECTORY="{{homeDirectory}}"
SERVICE_DESCRIPTION="{{displayName}}"
# find the next UID and GID that is below 500, so that we can create the service user
# if the user or group already exists, it will use this existing ID and still do the rest. We might have changes to commit.
NEXTUID=$(ID=`dscl . -read "/Users/${DEAMON_USER}" UniqueID 2> /dev/null | awk '{print $2}'` && [ ! -z "$ID" ] && echo "$ID" || dscl . -list /Users UniqueID | awk 'BEGIN{i=0}{if($2>i&&$2<500)i=$2}END{print i+1}')
NEXTGID=$(ID=`dscl . -read "/Groups/${DEAMON_USER}" PrimaryGroupID 2> /dev/null | awk '{print $2}'` && [ ! -z "$ID" ] && echo "$ID" || dscl . -list /Groups PrimaryGroupID | awk 'BEGIN{i=0}{if($2>i&&$2<500)i=$2}END{print i+1}')
echo "Will use '${NEXTUID}' as UserID and '${NEXTGID}' as group ID for User '${DEAMON_USER}'"
#########################################################################################################
dscl . -create "/Users/${DEAMON_USER}" UniqueID "${NEXTUID}"
dscl . -create "/Users/${DEAMON_USER}" PrimaryGroupID "${NEXTGID}"
dscl . -create "/Users/${DEAMON_USER}" NFSHomeDirectory "${HOME_DIRECTORY}"
# Can't login as standard user
dscl . -create "/Users/${DEAMON_USER}" UserShell /usr/bin/false
dscl . -create "/Users/${DEAMON_USER}" RealName "${SERVICE_DESCRIPTION} Administrator"
# Unusable password for standard users
dscl . -create "/Users/${DEAMON_USER}" Password \*
#########################################################################################################
#########################################################################################################
dscl . -create "/Groups/${DEAMON_USER}" PrimaryGroupID "${NEXTGID}"
# Unusable password for standard users
dscl . -create "/Groups/${DEAMON_USER}" Password \*
#########################################################################################################
# make home directory
mkdir -p "${HOME_DIRECTORY}/Library/Preferences" && chown -R "${DEAMON_USER}:${DEAMON_USER}" "${HOME_DIRECTORY}" || true
El servicio suele crear las preferencias del usuario que luego se almacenan en el ~/Library/Preferences
en un almacén respaldado por plist.
Pero no con el usuario creado anteriormente. Las preferencias nunca se guardan. Sé que hay un servicio que mantiene las preferencias sincronizadas con la memoria y el sistema de archivos (no se está ejecutando para el nuevo usuario).
La pregunta es: ¿qué es lo que está mal, ya sea en Java - qué haría falta para corregirlo - o en la forma de crear el usuario del sistema?
Incluso un simple programa java como el siguiente no hace que se escriban las preferencias:
import java.util.prefs.BackingStoreException;
import java.util.prefs.Preferences;
public class prefTest {
public static void main( String[] args ) throws BackingStoreException {
System.out.println( System.getProperty( "user.home" ) );
Preferences userRoot = Preferences.userRoot();
userRoot.put( "Test", "Value" );
userRoot.flush();
System.out.println( userRoot.get( "Test", "DEFAULT" ) );
}
}
Si se ejecuta este programa con el usuario de servicio, el resultado será erróneo y no se creará un archivo de preferencias de Java para actualizar uno existente.
0 votos
Parece que estás mezclando usuarios humanos y usuarios del sistema, y haciendo algunas cosas en formas de Linux/BSD/Windows, y otras en formas de sesión de usuario humano de Mac OS X. Elige un enfoque y quédate con él para obtener mejores resultados ;-) además, el método de lanzamiento de tu aplicación Java es importante.
0 votos
Vale, ¿te importaría explicarlo? El uso de dscl para un usuario de servicio se recomendó varias veces, la creación de los usuarios directorio de inicio en lugar de utilizar la plantilla debe estar bien. El ejemplo de Java es sólo una configuración mínima que debería funcionar sin embargo. El servicio se inicia a través de LaunchDaemon. ¿Hay algo más que pueda añadir para reducir el problema?
0 votos
Si se lanza un programa Java desde la línea de comandos sin una sesión de usuario de Aqua, no se accede automáticamente a las preferencias del usuario, etc. Cuando se inicia un archivo JAR desde el Finder, el sistema operativo añade un montón de variables de entorno, opciones de línea de comandos para el lanzador, y launchservices añade entradas en /var/privado/carpetas y directorios temporales donde el acceso de Java está aislado. Al salir, se devuelve al perfil del usuario. En el siguiente lanzamiento, se invierte, se hace una nueva entrada de carpetas y tmp, pero los cambios pre-persistidos están disponibles para la aplicación java.