44

我正在尝试改进适用于 iOS 的 Hudson CI,并在系统启动后立即启动 Hudson。为此,我使用以下启动脚本:

<?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,密钥/证书对就在那里,因为它工作正常。

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

4

10 回答 10

71

我找到了一个解决方案,让我可以访问我的 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 中运行一个调用 security list-keychains 的作业 - 您不应再将 System.keychain 视为唯一条目,而是将常规登录和您可能已添加到钥匙串列表中的任何自定义钥匙串“詹金斯”用户。

我现在在我的 Jenkins 构建服务器上使用自定义钥匙串中的代码签名证书 - 我没有在我的系统钥匙串中安装任何证书或密钥。

于 2012-02-28T13:22:46.523 回答
21

在这个问题上花费了数小时和数天后,我找到了一个相当简单的解决方案。如上所述,您的启动配置中是否有不同的用户名并不重要:

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

缺少的证书和密钥必须在系统钥匙串 ( /Library/Keychains/System.keychain) 上。我在设置执行多个securityshell 调用的 jenkins 作业后发现了这一点。有趣的是security list-keychains

+ security list-keychains
    "/Library/Keychains/System.keychain"
    "/Library/Keychains/applepushserviced.keychain"
    "/Library/Keychains/System.keychain"

那是詹金斯将搜索证书和密钥的钥匙串,因此它们应该在那里。在我将证书移到那里后,它就可以工作了。确保您还将»Apple Worldwide Developer Relations Certification Authority« 证书复制到系统钥匙串,否则您将看到CSSMERR_TP_NOT_TRUSTED来自codesign.

也可以使用 注册更多钥匙串security list-keychains -s [path to additional keychains]。我还没有尝试过,但是像security list-keychains -s $HOME/Library/Keychains/login.keychainjenkins 中的预构建 shell 执行之类的东西可能会起作用。

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

编辑^2:阅读并使用 joensson 的解决方案而不是我的解决方案,他管理它来访问用户钥匙串,而不仅仅是系统钥匙串。

于 2011-10-18T09:54:36.400 回答
4

我们在 Mac OSX Lion 上作为启动守护程序启动的 hudson slave 遇到了同样的问题。当我们使用 webstart 启动 slave 时,它​​起作用了。我们发现的唯一区别是不同的环境变量。

com.apple.java.jvmTask=WebStart

有效,如果我们在没有 webstart 的情况下启动从站,则变量为

com.apple.java.jvmTask=CommandLine.java

我们发现无法预先影响价值。我建议你在 Hudson 中创建一个新节点,在同一台机器上运行并由 webstart 启动。为了启动从站,我们使用以下启动守护程序配置:

<?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>
于 2011-09-15T15:10:57.317 回答
2

I faced the same problem, and tried changing the user name in /Library/LaunchDaemons/org.jenkins-ci.plist as described in one of the other posts. However, it still did not work, and some obscure NullPointerException did not help me identify the problem. Therefore, I would just share my solution: I had to also change the owner of the JENKINS_HOME directory (defined in org.jenkins-ci.plist as well):

chown -R myBuildUser /Users/Shared/Jenkins

myBuildUser is the user that has the certificates installed, and this is the user that I specified in the plist file.

This solution was quite obvious when I finally realized it - but it took me a couple of hours to find out about this, so hopefully this post can save the time for somebody else :-)

于 2012-11-14T07:31:32.053 回答
2

我们在 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 登录/注销),则钥匙串会丢失。狮子的行为不同。似乎 Lion 将钥匙串与用户分离并将其分配给登录会话。

于 2011-11-08T13:11:49.330 回答
2

你可以试试我的 Jenkins.app,https://github.com/stisti/jenkins-app,这是运行 Jenkins 的另一种方式。它在用户会话中运行 Jenkins,因此钥匙串访问不是问题。

于 2012-04-01T22:08:49.000 回答
2

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

我的问题是我的签名证书已过期。更新后,手动运行 xcode 和运行 xcodebuild 工作正常,但 Jenkins 无法签署应用程序。

这是我修复它的方法:

  1. 查看 Keychain并搜索 key。出于某种我不明白的原因,我有多个结果。

  2. 确保私钥在系统级别(如果不是,则将其拖放到左侧的系统图标。

在此处输入图像描述

于 2018-08-29T14:16:52.920 回答
0

为了为 Jenkins/Hudson 保留一个分隔的钥匙串,我将 launchctl 项目从

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

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

这让我可以访问为 Jenkins 创建的私钥链。

于 2011-11-22T01:54:03.397 回答
0

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

于 2013-04-29T18:11:15.707 回答
0

对于手动签名,将您的证书从登录名移至钥匙串中的系统。在存档和生成 iPA 期间无法访问登录。

于 2018-09-06T04:10:44.520 回答