在 Mac OS X (服务器) Mavericks 上以特定用户身份启动守护进程

在 Mac OS X (服务器) Mavericks 上以特定用户身份启动守护进程

我想在运行 Mavericks 的 Mac OS X Server 上启动 CI 服务器 (TeamCity 8.1)。我不希望由 root 用户启动 CI 服务器,而是由系统上的其他用户启动。
我想启动服务器的用户是 server1:staff。我在 /Applications/TeamCity 中安装了 TeamCity。TeamCity 文件夹归 server1:staff 所有。
然后我在 /Library/LaunchDaemons 中创建了 2 个 plist,它们归 root:wheel 所有,但指定我希望此过程由 server1:staff 用户启动。

以下是 plist。这个启动服务器:

<?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>WorkingDirectory</key>
    <string>/Applications/TeamCity</string>
    <key>Debug</key>
    <false/>
    <key>Label</key>
    <string>jetbrains.teamcity.server</string>
    <key>OnDemand</key>
    <false/>
    <key>KeepAlive</key>
    <true/>
    <key>ProgramArguments</key>
    <array>
        <string>bin/teamcity-server.sh</string>
        <string>run</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>StandardErrorPath</key>
    <string>logs/launchd.err.log</string>
    <key>StandardOutPath</key>
    <string>logs/launchd.out.log</string>
    <key>UserName</key>
    <string>server1</string>
</dict>
</plist>

这将启动运行构建的构建代理:

<?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>Debug</key>
    <false/>
    <key>KeepAlive</key>
    <true/>
    <key>Label</key>
    <string>jetbrains.teamcity.BuildAgent</string>
    <key>OnDemand</key>
    <false/>
    <key>ProgramArguments</key>
    <array>
        <string>launcher/bin/TeamCityAgentService-macosx-universal-32</string>
        <string>-c</string>
        <string>../conf/wrapper.conf</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>SessionCreate</key>
    <true/>
    <key>StandardErrorPath</key>
    <string>logs/launchd.err.log</string>
    <key>StandardOutPath</key>
    <string>logs/launchd.out.log</string>
    <key>WorkingDirectory</key>
    <string>/Applications/TeamCity/buildAgent</string>
    <key>UserName</key>
    <string>server1</string>
</dict>
</plist>

使用此配置,服务器不会在启动时启动。使用
我的配置,让服务器在启动时启动的唯一方法是不指定 plist 中的用户名/用户组。但使用此配置,服务器会以 root 用户身份启动。
我已经尝试更改 plist 的所有权以匹配 server1:staff 用户,但没有成功。
我对这种配置有点困惑,不知道它有什么问题。
欢迎提供任何提示。

[编辑]
我在 Console.app 中没有发现与 TeamCity 有关的错误。
为确保万无一失,我从头开始重新安装了 TeamCity 等。launchd.err.log
中没有任何内容。虽然我在 launchd.out.log 中发现了这个,但我不知道它什么时候发生的(目前正在删除所有日志文件后重新启动)

BuildId=null, AgentOwnAddress='null', AlternativeAddresses=[10.175.11.48, 192.168.2.92], Port=9090, Version='29939', PluginsVersion='29939-md5-51785f46b7e643a588892acce02b9333', AvailableRunners=[Ant, Duplicator, gradle-runner, Inspection, Ipr, JPS, Maven2, rake-runner, simpleRunner, Xcode], AvailableVcs=[perforce, mercurial, jetbrains.git, svn, cvs], AuthorizationToken='afccc2fae65d1c580e34d4aed4cc55df', PingCode='DX5fzIvbgFCvVghhwuvARdEU33XOfzCW'} 
jvm 1    | Call http://localhost:8111/RPC2 buildServer.registerAgent3: java.net.ConnectException: Connection refused 
jvm 1    | Registering on server http://localhost:8111, AgentDetails{Name='Default Agent', AgentId=null, BuildId=null, AgentOwnAddress='null', AlternativeAddresses=[10.175.11.48, 192.168.2.92], Port=9090, Version='29939', PluginsVersion='29939-md5-51785f46b7e643a588892acce02b9333', AvailableRunners=[Ant, Duplicator, gradle-runner, Inspection, Ipr, JPS, Maven2, rake-runner, simpleRunner, Xcode], AvailableVcs=[perforce, mercurial, jetbrains.git, svn, cvs], AuthorizationToken='afccc2fae65d1c580e34d4aed4cc55df', PingCode='DX5fzIvbgFCvVghhwuvARdEU33XOfzCW'} 
jvm 1    | Call http://localhost:8111/RPC2 buildServer.registerAgent3: java.net.ConnectException: Connection refused 
wrapper  | TERM trapped.  Shutting down.
jvm 1    | Processing shutdown hook. 
jvm 1    | Sending agent force shutdown command to: http://localhost:9090 
jvm 1    | Shutdown command successfully sent. Agent is exiting. 
jvm 1    | Stop command called 
jvm 1    | Agent process finished 
jvm 1    | Agent has exited with code: 30 
jvm 1    | Launcher is exiting 
wrapper  | <-- Wrapper Stopped  

[EDIT2] 重新启动后,服务器日志和 Console.app 中没有任何内容(服务器没有启动,所以我认为这是预期的行为)。

答案1

所有这些相对路径的使用都有点粗略。我认为你没有正确考虑当前的工作目录和相对路径。

例如,构建代理 plist 指定其工作目录是...

/Applications/TeamCity/buildAgent

…但是您传递给启动器二进制文件的程序参数之一是……

../conf/wrapper.conf

我很确定这将被解释为相对于工作目录......

/Applications/TeamCity/buildAgent

…不是二进制文件的目录…

/Applications/TeamCity/buildAgent/launcher/bin

所以你实际上是告诉它查看主要内容……

/Applications/TeamCity/conf

…通常没有wrapper.conf,但我想也许你认为你是在告诉它查看…

/Applications/TeamCity/buildAgent/launcher/conf

…这就是wrapper.conf人们通常居住的地方。

我认为您的 plist 中可能还存在其他一些工作目录/相对路径错误。例如,您似乎有两个单独的logs目录,因此您有两组单独的 launchd stdout/stderr 文件。但也许这就是您想要的。

我认为你应该先理清这些路径问题。这可能是你的全部问题,根本不是 launchd 的问题。但即使不是,你也需要解决这个问题,这样它才不会妨碍进一步的 launchd 故障排除。

相关内容