Serviço OSX com usuário customizado não grava Preferências Java

0

Esta é a configuração:

  • OSX Yosemite
  • Serviço baseado em Java que está sendo iniciado usando um LaunchDaemon
  • O serviço é iniciado com um usuário customizado que está sendo criado durante a instalação
  • O usuário tem um diretório pessoal personalizado para salvar certas informações, como preferências

Aqui está como o usuário é criado:

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

O serviço geralmente cria preferências de usuário que são armazenadas no ~/Library/Preferences diretório - em uma loja de suporte plist.

Mas não com o usuário criado acima. As preferências nunca são salvas. Eu sei que existe um serviço que mantém as preferências em sincronia com a memória e o sistema de arquivos (não está sendo executado para o novo usuário).

A questão é: o que há de errado com o Java - o que seria necessário para corrigi-lo - ou com a maneira como o usuário do sistema é criado.

Mesmo um programa java simples como o seguinte não aciona as preferências a serem escritas:

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" ) );
    }
}

A execução deste programa com o usuário do serviço resultará na saída incorreta e não criará um arquivo de preferências Java para atualizar um existente.

gamma
fonte
Parece que você está misturando usuários humanos e usuários do sistema, e fazendo algumas coisas nas formas Linux / BSD / Windows, e outras no modo de sessão de usuários humanos do Mac OS X. Escolha uma abordagem e siga-a para melhores resultados ;-) também, o método de iniciar seu aplicativo Java é importante.
John Keates
Ok, se importa em explicar? O uso de dscl para um usuário do serviço foi recomendado várias vezes, criando o diretório inicial do usuário em vez de usar o modelo deve ser OK. O exemplo Java é apenas uma configuração mínima que deve funcionar, no entanto. O serviço é iniciado via LaunchDaemon. Há mais alguma coisa que eu possa adicionar para diminuir o problema?
gamma
Se você iniciar um programa Java a partir da linha de comando sem uma sessão de usuário Aqua, ele não terá automaticamente acesso às preferências do usuário, etc. Quando você inicia um arquivo JAR no Finder, o SO adiciona muitas variáveis ​​de ambiente, opções de linha de comando para o launcher e launchservices incluem entradas / var / private / folders e diretórios temporários nos quais o acesso do Java é protegido por sandbox. Na saída, ele é redirecionado para o perfil do usuário. Na próxima inicialização, ele é revertido, uma nova entrada de pastas e tmp é feita, mas as alterações pré-persistentes estão disponíveis para o aplicativo java.
John Keates

Respostas:

1

Parece que encontrei uma solução por conta própria. John Keates fez alguns bons pontos que me fizeram checar a web um pouco mais.

Eu resolvi usando as duas linhas seguintes com o script de criação de usuário:

dscl . -delete /Users/_helpdesk PasswordPolicyOptions
dscl . -delete /Users/_helpdesk AuthenticationAuthority
gamma
fonte