我想在运行 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 故障排除。