Отсутствие сертификатов и ключей в связке ключей при использовании 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 38

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: прочитайте и используйте решение йоэнссона вместо моего, он сумел получить доступ к связке ключей пользователей, а не только к системной связке ключей.

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

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

<?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, которое вызывает список безопасности-брелки-и Вы больше не должны видеть систему.брелок как единственная запись, но обычный логин и любые пользовательские брелки, которые вы могли бы добавить в список брелоков для пользователя "Дженкинс".

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

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

com.apple.java.jvmTask=WebStart

Работает, если мы запустили slave без 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>

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

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

chown -R myBuildUser /Users/Shared/Jenkins

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

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

Мы столкнулись с точно такой же проблемой на Lion, а также на SnowLeopard. Мы должны были начать Tomcat / Hudson с xcodebuild jobs в качестве сервиса. При запуске из командной строки xcodebuild может получить доступ к логину.брелок для использования содержащегося сертификата. Но после перезагрузки коробки, логин.связка ключей не была видна 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

К

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

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

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

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

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

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

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

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

Введите описание изображения здесь

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