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

问题描述 投票:39回答:10

我正在尝试改进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它正常工作。

你知道为什么会这样吗?

ios hudson jenkins keychain launchd
10个回答
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_TRUSTEDcodesign错误。

也可以使用security list-keychains -s [path to additional keychains]注册更多的钥匙串。我没有尝试过,但是像jazkins这样的预制shell执行的security list-keychains -s $HOME/Library/Keychains/login.keychain可能会有效。

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

编辑^ 2:阅读并使用joensson'solution而不是我的,他设法访问用户的钥匙串而不仅仅是系统钥匙串。


0
投票

对于手动签名将证书从登录状态移动到钥匙串中的“系统”。存档期间无法访问登录并生成iPA。


67
投票

我找到了一个解决方案,让我可以访问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构建服务器上的自定义密钥链中的代码签名证书 - 我没有在我的系统密钥链中安装任何证书或密钥。


4
投票

我们遇到了同样的问题,一个哈德逊奴隶在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>

2
投票

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


2
投票

我遇到了同样的问题,并尝试更改/Library/LaunchDaemons/org.jenkins-ci.plist中的用户名,如其他帖子中所述。但是,它仍然无法正常工作,并且一些模糊的NullPointerException无法帮助我识别问题。因此,我只想分享我的解决方案:我还必须更改JENKINS_HOME目录的所有者(在org.jenkins-ci.plist中定义):

chown -R myBuildUser /Users/Shared/Jenkins

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

当我终于意识到这个问题时,这个解决方案非常明显 - 但我花了几个小时才发现这个问题,所以希望这篇文章能为其他人节省时间:-)


1
投票

我们在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将钥匙串与用户分离并将其分配给登录会话。


1
投票

为了保留Jenkins / Hudson的分隔钥匙链,我移动了launchctl项目

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

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

这允许我访问为Jenkins创建的私钥板链。


0
投票

在keychain管理器中添加SessionCreate并将大量证书设置为“始终信任”,我从buildist开始使用plist ...但在某些时候,使用CSSMERR_TP_NOT_TRUSTED开始失败。我通过在钥匙串管理器中将iPhone Distribution证书设置为“使用系统默认值”来恢复。即使在重新启动之后,没有登录,buildbot slave也能够签署代码。


0
投票

添加这个,因为我有同样的问题,但这些解决方案都不适合我。

我的问题是在签名证书需要更新之后,在它过期后引起的。更新后,xcode和运行xcodebuild手动工作正常,但詹金斯无法签署该应用程序。

以下是我修复它的方法:

  1. 查看Keychain并搜索密钥。由于某些原因,我不明白这给了我们不同的结果。
  2. 确保私钥处于系统级别(如果不是,则将其拖放到左侧的“系统”图标中。

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.