我正在尝试改进iOS的Hudson CI,并在系统启动后立即启动Hudson。为此,我使用以下launchd脚本:
<?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>Label</key>
<string>Hudson CI</string>
<key>ProgramArguments</key>
<array>
<string>/usr/bin/java</string>
<string>-jar</string>
<string>/Users/user/Hudson/hudson.war</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>UserName</key>
<string>user</string>
</dict>
</plist>
这工作正常,但是当由Hudson启动的xcodebuild尝试签署应用程序时,它失败了,因为它无法在钥匙串中找到正确的密钥/证书。但是密钥/证书对是存在的,因为如果我从命令行启动Hudson它正常工作。
你知道为什么会这样吗?
在花了几个小时和几天这个问题后,我找到了一个相当简单的解决方案。如上所述,如果您的launchd配置中有不同的用户名,则无关紧要:
<key>UserName</key>
<string>user</string>
丢失的证书和密钥必须在系统密钥链(/Library/Keychains/System.keychain
)上。在我设置了一个执行几个security
shell调用的jenkins作业后,我发现了这个。有趣的是security list-keychains
:
+ security list-keychains
"/Library/Keychains/System.keychain"
"/Library/Keychains/applepushserviced.keychain"
"/Library/Keychains/System.keychain"
这是钥匙链jenkins将搜索证书和密钥,因此他们应该在那里。我将证书移到那里后就可以了。确保您还将“Apple全球开发者关系认证中心”证书复制到系统钥匙串,否则您将看到来自CSSMERR_TP_NOT_TRUSTED
的codesign
错误。
也可以使用security list-keychains -s [path to additional keychains]
注册更多的钥匙串。我没有尝试过,但是像jazkins这样的预制shell执行的security list-keychains -s $HOME/Library/Keychains/login.keychain
可能会有效。
编辑:我试图用-s
将用户钥匙串添加到搜索路径,但我无法让它工作。所以现在,我们必须将我们的证书和密钥复制到系统密钥链中。
编辑^ 2:阅读并使用joensson'solution而不是我的,他设法访问用户的钥匙串而不仅仅是系统钥匙串。
对于手动签名将证书从登录状态移动到钥匙串中的“系统”。存档期间无法访问登录并生成iPA。
我找到了一个解决方案,让我可以访问Jenkins用户的常规钥匙串。
除了在接受的答案建议中指定plist中的UserName元素之外,访问您在UserName中指定的用户的普通键链的技巧是还将一个值为true的SessionCreate元素添加到plist文件中 - / Library / LaunchDaemons / org.jenkins-ci.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>EnvironmentVariables</key>
<dict>
<key>JENKINS_HOME</key>
<string>/Users/Shared/Jenkins/Home</string>
</dict>
<key>GroupName</key>
<string>wheel</string>
<key>KeepAlive</key>
<true/>
<key>Label</key>
<string>org.jenkins-ci</string>
<key>ProgramArguments</key>
<array>
<string>/bin/bash</string>
<string>/Library/Application Support/Jenkins/jenkins-runner.sh</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>UserName</key>
<string>jenkins</string>
<key>SessionCreate</key>
<true />
</dict>
然后重新启动守护程序并尝试在Jenkins中运行调用安全列表 - 密钥链的作业 - 您不应再将System.keychain视为唯一的条目,而是常规登录和您可能已添加到密钥链列表中的任何自定义密钥链“jenkins”用户。
我现在正在使用Jenkins构建服务器上的自定义密钥链中的代码签名证书 - 我没有在我的系统密钥链中安装任何证书或密钥。
我们遇到了同样的问题,一个哈德逊奴隶在Mac OSX Lion上作为一个启动守护程序启动。当我们用webstart启动奴隶时,它起作用了。我们发现的唯一区别是不同的环境变量。
com.apple.java.jvmTask=WebStart
工作,如果我们启动没有webstart的奴隶变量是
com.apple.java.jvmTask=CommandLine.java
我们发现无法预先影响价值。我建议你在Hudson中创建一个新节点,在同一台机器上运行并由webstart启动。为了启动从站,我们使用以下launchdaemon配置:
<?xml version"1.0" encoding="UTF-8"?>
<plist version="1.0">
<dict>
<key>Label</key>
<string>jenkins</string>
<key>UserName</key>
<string>apple</string>
<key>Program</key>
<string>/usr/bin/javaws</string>
<key>ProgramArguments</key>
<array>
<string>-verbose</string>
<string>-wait</string>
<string>http://<hudson-hostname>:8080/computer/<node-name>/slave-agent.jnlp</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
<key>WorkingDirectory</key>
<string>/Users/apple</string>
</dict>
</plist>
你可以尝试我的Jenkins.app,https://github.com/stisti/jenkins-app,一种运行Jenkins的替代方法。它在用户会话中运行Jenkins,因此Keychain访问不是问题。
我遇到了同样的问题,并尝试更改/Library/LaunchDaemons/org.jenkins-ci.plist中的用户名,如其他帖子中所述。但是,它仍然无法正常工作,并且一些模糊的NullPointerException无法帮助我识别问题。因此,我只想分享我的解决方案:我还必须更改JENKINS_HOME目录的所有者(在org.jenkins-ci.plist中定义):
chown -R myBuildUser /Users/Shared/Jenkins
myBuildUser是安装了证书的用户,这是我在plist文件中指定的用户。
当我终于意识到这个问题时,这个解决方案非常明显 - 但我花了几个小时才发现这个问题,所以希望这篇文章能为其他人节省时间:-)
我们在Lion和SnowLeopard上遇到了完全相同的问题。我们必须以xcodebuild作为服务启动Tomcat / Hudson。从命令行开始时,xcodebuild可以访问login.keychain以使用包含的证书。但重新启动该框后,login.keychain对xcodebuild不可见,因此签名失败。
由于我们需要通过钥匙串提供公司证书,因此系统钥匙串不是一种选择。相反,我们通过一个简单的解决方法解决了这个问题。我们删除了用户名,以便启动守护程序在root下启动进程。
<plist version="1.0">
<dict>
<key>Label</key>
<string>${LAUNCH_LABEL}</string>
<key>Disabled</key>
<false/>
<key>RunAtLoad</key>
<true/>
<key>ProgramArguments</key>
<array>
<string>${INSTALL_DIR}/start.sh</string>
</array>
<key>StandardOutPath</key>
<string>${INSTALL_DIR}/tomcat-stdout.log</string>
<key>StandardErrorPath</key>
<string>${INSTALL_DIR}/tomcat-stderr.log</string>
</dict>
</plist>
启动守护进程称为简单脚本(start.sh),模拟完整登录并运行所需的程序
su -l username -c program
现在,即使在启动之后,xcodebuild也可以访问login.keychain。这也适用于Snow Leopard,但是,如果您在并行会话中关闭用户特定的login.keychain(如vnc login / logout),则钥匙串会丢失。狮子表现不同。似乎Lion将钥匙串与用户分离并将其分配给登录会话。
为了保留Jenkins / Hudson的分隔钥匙链,我移动了launchctl项目
/Library/LaunchDaemons/org.jenkins-ci.plist
至
/Users/Shared/Jenkins/Home/Library/LaunchAgents/org.jenkins-ci.plist
这允许我访问为Jenkins创建的私钥板链。
在keychain管理器中添加SessionCreate并将大量证书设置为“始终信任”,我从buildist开始使用plist ...但在某些时候,使用CSSMERR_TP_NOT_TRUSTED开始失败。我通过在钥匙串管理器中将iPhone Distribution证书设置为“使用系统默认值”来恢复。即使在重新启动之后,没有登录,buildbot slave也能够签署代码。