Отсутствующие сертификаты и ключи в связке ключей при использовании Jenkins/Hudson в качестве непрерывной интеграции для разработки iOS и Mac

Я пытаюсь улучшить Hudson CI для iOS и запустить 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>

это работает нормально, но когда xcodebuild, который запускается Hudson, пытается подписать приложение, оно терпит неудачу, потому что не может найти правильный ключ/сертификат в связке ключей. Однако пара ключ / сертификат существует, так как она работает правильно, если я запускаю Hudson из командной строки.

У вас есть идеи, почему это происходит?

10 ответов


проведя часы и дни с этой проблемой, я нашел довольно простое решение. Не имеет значения, есть ли у вас отдельное имя пользователя в конфигурации launchd, как указано выше:

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

отсутствующие сертификаты и ключи должны быть на системном брелке (/Library/Keychains/System.keychain). Я нашел это после установки задания Дженкинса, которое выполняет несколько security оболочке звонков. Интересно то, что 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.keychain как выполнение оболочки предварительной сборки в jenkins может работа.

EDIT: я попытался добавить брелок пользователя в путь поиска с помощью -s но я не смог заставить его работать. Поэтому на данный момент мы должны скопировать наши сертификаты и ключи в системный брелок.

EDIT^2: читать и использовать joensson' решение вместо моего, ему удалось получить доступ к связке ключей пользователей, а не только к системной связке ключей.


Я нашел решение, дающее мне доступ к обычным цепочкам ключей для моего пользователя Jenkins.

в дополнение к указанию элемента UserName в plist, как предполагает принятый ответ, трюк для получения доступа к обычным цепочкам ключей для пользователя, указанного в UserName, также должен добавить элемент SessionCreate со значением true в файл plist - /Library/LaunchDaemons / org.Дженкинс-Си.файл 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>

затем перезапустите демон и попробуйте запустить задание в Дженкинс, который вызывает список безопасности-брелки - и вы больше не должны видеть систему.keychain как единственная запись, но обычный логин и любые пользовательские цепочки ключей, которые вы могли бы добавить в список цепочек ключей для пользователя "jenkins".

теперь я использую сертификаты codesigning из пользовательского брелка на моем сервере сборки Jenkins - я не установил никаких сертификатов или ключей в своем системном брелке.


У нас была такая же проблема с Hudson slave, запущенным как launchdaemon на Mac OSX Lion. Это сработало, когда мы начали раба с webstart. Единственное различие, которое мы заметили, - это другая переменная среды.

com.apple.java.jvmTask=WebStart

работает, если мы запустили ведомое устройство без webstart, переменная была

com.apple.java.jvmTask=CommandLine.java

мы не нашли способа повлиять на значение авансом. Я предлагаю вам создать новый узел в Hudson, работающий на той же машине и запущенный webstart. Для начала slave мы используем следующую конфигурацию 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>

вы можете попробовать мой Дженкинс.app,https://github.com/stisti/jenkins-app, альтернативный способ запуска Дженкинса. Он запускает Jenkins в сеансе пользователя, поэтому доступ к связке ключей не является проблемой.


я столкнулся с той же проблемой и попытался изменить имя пользователя в /Library/LaunchDaemons/org.Дженкинс-Си.plist как описано в одном из других постов. Однако это все еще не сработало, и какое-то неясное исключение NullPointerException не помогло мне определить проблему. Поэтому я бы просто поделился своим решением: мне также пришлось изменить владельца каталога JENKINS_HOME (определенного в org.Дженкинс-Си.plist также):

chown -R myBuildUser /Users/Shared/Jenkins

myBuildUser-это пользователь, у которого установлены сертификаты, и это пользователь, которого я указал в файле plist.

это решение было совершенно очевидно, когда я, наконец, понял это, но мне потребовалось несколько часов, чтобы узнать об этом, поэтому, надеюсь, этот пост может сэкономить время для кого-то другого: -)


мы столкнулись с точно такой же проблемой на Lion, а также на SnowLeopard. Нам пришлось запустить Tomcat / Hudson с xcodebuild jobs в качестве сервиса. При запуске из командной строки xcodebuild может получить доступ к логину.keychain для использования сертификата. Но после перезагрузки окно входа.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 может получить доступ к логину.брелок. Это работает и на Snow Leopard, но, если закрыть логин конкретного пользователя.брелок в параллельной сеанс (например, VNC login/ logout) брелок теряется. Лев ведет себя иначе. Кажется, что Lion отделяет брелок от пользователя и назначает его сеансу входа в систему.


чтобы сохранить разделенный брелок для Дженкинса / Хадсона, я переместил элемент launchctl из

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

to

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

и это позволяет мне получить доступ к частной связке ключей, созданной для Дженкинса.


добавить SessionCreate и установка множества сертификатов на "всегда доверять" в keychain manager работал на меня с buildbot, начиная с plist... но в какой-то момент codesign начал терпеть неудачу с CSSMERR_TP_NOT_TRUSTED. Я восстановился, установив сертификат дистрибутива iPhone "использовать системные значения по умолчанию" в keychain manager. Даже после перезагрузки, без регистрации, затем раб buildbot смог подписать код, whew.


добавив Это, так как у меня была та же проблема, но ни одно из этих решений не сработало для меня.

моя проблема была вызвана, когда после подписания сертификата необходимо было обновить, после того, как он истек. После обновления xcode и запуск xcodebuild вручную работали нормально, но Дженкинс не смог подписать приложение.

вот как я это исправил:

  1. посмотрите в Keychain и поиск ключа. По какой-то причине я этого не понимаю. дали нам разные результаты.

  2. убедитесь, что закрытый ключ находится на системном уровне (если это не так, перетащите его на значок системы слева.

enter image description here


для ручной подписи переместите сертификат из login в System в keychain. Вход не доступен во время архивирования и генерации iPA.