我正在尝试改进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它正常工作。
你知道为什么会这样吗?
答案 0 :(得分:67)
我找到了一个解决方案,可以让我访问Jenkins用户的常规钥匙串。
除了在接受的答案建议中指定plist中的UserName元素之外,访问您在UserName中指定的用户的普通钥匙串的技巧是还为plist文件添加值为true的SessionCreate元素 - /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构建服务器上使用自定义密钥链中的代码签名 - 我没有在系统密钥链中安装任何证书或密钥。
答案 1 :(得分:20)
在花了几个小时和几天这个问题后,我找到了一个相当简单的解决方案。如果您在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
的{{1}}错误。
还可以使用codesign
注册更多钥匙串。我没有尝试过,但像security list-keychains -s [path to additional keychains]
之类的东西可能会在jenkins中作为预构建shell执行。
编辑:我尝试使用security list-keychains -s $HOME/Library/Keychains/login.keychain
将用户钥匙串添加到搜索路径,但我无法让它工作。所以现在,我们必须将我们的证书和密钥复制到系统密钥链中。
编辑^ 2:阅读并使用joensson'solution代替我的,他设法访问用户的钥匙串而不仅仅是系统钥匙串。
答案 2 :(得分:4)
我们遇到了同样的问题,在Mac OSX Lion上启动了一个hudson slave作为launchdaemon。当我们用webstart启动奴隶时,它起作用了。我们发现的唯一区别是不同的环境变量。
com.apple.java.jvmTask=WebStart
有效,如果我们在没有webstart的情况下启动了slave,那么变量就是
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>
答案 3 :(得分:2)
你可以尝试我的Jenkins.app,https://github.com/stisti/jenkins-app,一种运行Jenkins的替代方法。它在用户会话中运行Jenkins,因此Keychain访问不是问题。
答案 4 :(得分:2)
我遇到了同样的问题,并尝试更改/Library/LaunchDaemons/org.jenkins-ci.plist中的用户名,如其他帖子中所述。但是,它仍然无法正常工作,并且一些模糊的NullPointerException无法帮助我识别问题。因此,我只想分享我的解决方案:我还必须更改JENKINS_HOME目录的所有者(在org.jenkins-ci.plist中定义):
chown -R myBuildUser /Users/Shared/Jenkins
myBuildUser是安装了证书的用户,这是我在plist文件中指定的用户。
当我终于意识到这个问题时,这个解决方案非常明显 - 但我花了几个小时才发现这个问题,所以希望这篇文章能为其他人节省时间: - )
答案 5 :(得分:1)
我们在Lion和SnowLeopard上遇到了完全相同的问题。我们必须以xcodebuild作为服务启动Tomcat / Hudson。从命令行开始时,xcodebuild可以访问login.keychain以使用包含的证书。但重新启动该框后,xcodebuild看不到login.keychain,因此签名失败。
由于我们需要通过钥匙串提供公司证书,因此系统钥匙串不是一个选项。相反,我们通过一个简单的解决方法解决了这个问题。我们删除了用户名,以便启动守护程序在 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将钥匙串与用户分离并将其分配给登录会话。
答案 6 :(得分:1)
为Jenkins / Hudson保留一个分隔的钥匙串,我从
移动了launchctl项目/Library/LaunchDaemons/org.jenkins-ci.plist
到
/Users/Shared/Jenkins/Home/Library/LaunchAgents/org.jenkins-ci.plist
这使我可以访问为Jenkins创建的私钥匙。
答案 7 :(得分:0)
添加 SessionCreate 并在keychain管理器中设置大量证书以“始终信任” 使用buildbot为我工作从plist开始...但在某些时候,codesign开始失败 使用CSSMERR_TP_NOT_TRUSTED。我通过在钥匙串管理器中将iPhone Distribution证书设置为“使用系统默认值”来恢复。即使重启后,无需登录, 然后,buildbot奴隶就可以签署代码了。
答案 8 :(得分:0)
由于存在相同的问题,因此添加了这些内容,但是这些解决方案都不适合我。
我的问题是在签名证书过期后需要更新签名证书时引起的。更新后,xcode和手动运行xcodebuild可以正常工作,但Jenkins无法对应用程序进行签名。
这是我的固定方法:
进入钥匙串并搜索钥匙。由于某种原因,我不明白这给了我们不同的结果。
确保私钥位于系统级别(如果没有,则将其拖放到左侧的系统图标上。
答案 9 :(得分:0)
对于手动签名,将证书从登录名移到钥匙串中的System。在存档和生成iPA期间无法访问登录。