将Jenkins / Hudson用作iOS和Mac开发的持续集成时,在钥匙串中缺less证书和密钥

我正在努力改善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尝试签名应用程序时,它会失败,因为它无法在钥匙串中find正确的密钥/证书。 然而,密钥/证书对在那里,因为它正常工作,如果我从命令行启动Hudson。

你有什么想法,为什么发生?

花了几个小时和这个问题后,我发现了一个相当简单的解决scheme。 如果您在launchdconfiguration中具有不同的用户名,则无关紧要:

 <key>UserName</key> <string>user</string> 

缺less的证书和密钥必须位于系统钥匙串( /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将search证书和密钥,所以他们应该在那里。 在我移动我的证书后,它的工作。 确保您还将“Apple全球开发者关系authentication中心”证书复制到系统钥匙串,否则您将看到来自CSSMERR_TP_NOT_TRUSTED错误。

也可以使用security list-keychains -s [path to additional keychains]注册更多的keychains。 我还没有尝试过,但像security list-keychains -s $HOME/Library/Keychains/login.keychain作为预编译shell程序执行在jenkins可能工作。

编辑:我试图添加用户钥匙链到searchpath与-s但我无法得到它的工作。 所以现在,我们必须将我们的证书和密钥复制到系统钥匙串中。

编辑^ 2:读取和使用joensson' 解决scheme,而不是我的,他pipe理它访问用户钥匙串,而不是只是系统钥匙串。

我find了一个解决scheme,让我可以访问我的Jenkins用户的常规钥匙链。

除了在plist中指定UserName元素作为接受的答案build议之外,访问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看作唯一的项目,而是将常规login和任何可能添加到钥匙串列表的自定义钥匙链“jenkins”用户。

我现在在我的Jenkins构build服务器上使用来自自定义钥匙串的密码证书 – 我没有在我的系统密钥链中安装任何证书或密钥。

在Mac OSX Lion上,我们遇到了一个以启动守护进程启动的哈德森从站的问题。 它起作用了,当我们用webstart启动slave的时候。 我们发现的唯一区别是一个不同的环境variables。

 com.apple.java.jvmTask=WebStart 

工程,如果我们启动的奴隶没有webstart的variables是

 com.apple.java.jvmTask=CommandLine.java 

我们没有办法影响价值的前期。 我build议你在Hudson中创build一个新的节点,运行在同一台机器上,并由webstart启动。 为了启动slave,我们使用下面的launchdaemonconfiguration:

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

我们在Lion和SnowLeopard上遇到了同样的问题。 我们不得不用xcodebuild作为服务启动Tomcat / Hudson。 从命令行开始,xcodebuild可以访问login.keychain来使用包含的证书。 但重新启动后,login.keychain对于xcodebuild不可见,因此签名失败。

由于我们需要通过钥匙链提供我们公司的证书,系统钥匙串不是一个选项。 相反,我们通过一个简单的解决方法解决了这个问题。 我们删除了用户名,以便启动守护进程启动根目录下的进程。

 <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 ),模拟一个完整的login和运行程序想要的

 su -l username -c program 

现在,即使启动后,xcodebuild也可以访问login.keychain。 这也适用于Snow Leopard,但是,如果在并行会话(如vnclogin/注销)中closures用户特定的login.keychain,则钥匙串会丢失。 狮子performance不同。 似乎狮子从用户decouples钥匙链,并分配给一个login会话。

为了保留Jenkins / Hudson的分区钥匙串,我从中移动了launchctl项目

 /Library/LaunchDaemons/org.jenkins-ci.plist 

 /Users/Shared/Jenkins/Home/Library/LaunchAgents/org.jenkins-ci.plist 

这使我可以访问为Jenkins创build的私人钥匙串。

你可以试试我的Jenkins.app, https://github.com/stisti/jenkins-app ,另一种运行Jenkins的方法。 它在用户会话中运行Jenkins,所以Keychain访问不成问题。

我遇到了同样的问题,并尝试更改/Library/LaunchDaemons/org.jenkins-ci.plist中的用户名,如其他post中所述。 然而,它仍然没有工作,一些晦涩的NullPointerException并没有帮助我找出问题。 因此,我只是分享我的解决scheme:我还必须更改JENKINS_HOME目录的所有者(也在org.jenkins-ci.plist中定义):

 chown -R myBuildUser /Users/Shared/Jenkins 

myBuildUser是安装证书的用户,这是我在plist文件中指定的用户。

当我终于意识到这个问题的时候,这个解决scheme非常明显 – 但是花了我几个小时才发现这个问题,希望这篇文章可以节省时间给别人:-)

添加SessionCreate,并设置许多证书,以“始终信任”钥匙串pipe理器为我工作buildbot从plist开始…但在某些时候,codeign开始与CSSMERR_TP_NOT_TRUSTED失败。 我通过将iPhone Distribution cert设置为钥匙串pipe理器中的“使用系统默认值”来恢复。 即使在重新启动后,如果没有login,buildbot从服务器也可以签署代码。