Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I want to launch a CI server (TeamCity 8.1) on startup on a Mac OS X Server running Mavericks. I don't want the CI server to be launched by the root user but by another user on the system.
The user I want to start the server with is server1:staff. I installed TeamCity in /Applications/TeamCity. The TeamCity folder is owned by server1:staff.
Then I created 2 plists in /Library/LaunchDaemons owned by root:wheel but specifying that I want this process to be started by the server1:staff user.

Here are the plists. This one starts the server:

<?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>

This one starts the build agent that runs the builds:

<?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>

With this configuration the server does not launch on startup.
The only way to have the server launch on startup with my configuration is without specifying the UserName/UserGroup in the plist. But with this the server launches with the root user.
I already tried to change the ownership of the plist to match the server1:staff user but with no success.
I'm kind of stuck with this configuration and I don't know what is wrong with it.
Any tips are welcome.

[EDIT]
I have nothing wrong in Console.app concerning TeamCity.
To be sure I reinstalled TeamCity from scratch etc.
There is nothing in launchd.err.log. Though I found this in launchd.out.log but I don't know when it happened (currently rebooting after deleting all log files)

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] After restarting I have nothing in the server logs and Console.app (the server does not start so I think it is expected behavior).

share|improve this question
    
Anything interesting in the Console.app logs after it fails to start? – Daniel Beck Mar 18 '14 at 13:45

The use of all these relative paths is a bit sketchy. I think you're not thinking through your current working directory and relative paths correctly.

For example, the build agent plist specifies that its working directory is…

/Applications/TeamCity/buildAgent

…but one of the program arguments that you pass to the launcher binary is…

../conf/wrapper.conf.

I'm pretty sure this would be interpreted as relative to the working directory of…

/Applications/TeamCity/buildAgent

…not the binary's directory of…

/Applications/TeamCity/buildAgent/launcher/bin.

So you're actually telling it to look in the main…

/Applications/TeamCity/conf

…which doesn't typically have a wrapper.conf, but I think maybe you thought you were telling it to look in…

/Applications/TeamCity/buildAgent/launcher/conf

…which is where wrapper.conf typically lives.

I think you may have some other working directory / relative path mistakes in your plists as well. For example, it looks like you have two separate logs directories, so you have two separate sets of launchd stdout/stderr files. Buy maybe that's what you wanted.

I think you should probably straighten out these path problems first. This may be your whole problem, not a launchd problem at all. But even if it isn't, you need to get this cleared up so it doesn't get in the way of further launchd troubleshooting.

share|improve this answer

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .