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

Я пытаюсь улучшить Hudson CI для iOS и запускать Hudson, как только система запустится. Для этого я использую следующий запуск script:

<?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 из командной строки.

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

Ответ 1

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

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

Недопустимые сертификаты и ключи должны находиться в системной цепочке ключей (/Library/Keychains/System.keychain). Я нашел это после того, как я установил работу jenkins, которая выполняет несколько вызовов оболочки security. Интересным является security list-keychains:

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

Это keychains jenkins будет искать сертификаты и ключи, чтобы они были там. После того, как я перевел свои сертификаты, он работает. Убедитесь, что вы также скопировали сертификат "Сертификат владения сертификатами Apple Worldwide" в системный брелок, иначе вы увидите ошибку CSSMERR_TP_NOT_TRUSTED от codesign.

Также возможно зарегистрировать больше брелок с помощью security list-keychains -s [path to additional keychains]. Я не пробовал, но что-то вроде security list-keychains -s $HOME/Library/Keychains/login.keychain, так как работа с готовой оболочкой в ​​jenkins может работать.

РЕДАКТИРОВАТЬ: Я попытался добавить пользовательский брелок в путь поиска с помощью -s, но я не смог заставить его работать. Поэтому на данный момент мы должны скопировать наши сертификаты и ключи в системный брелок.

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

Ответ 2

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

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

Ответ 3

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

com.apple.java.jvmTask=WebStart

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

com.apple.java.jvmTask=CommandLine.java

Мы не нашли способа повлиять на значение вверх. Я предлагаю вам создать новый node в Хадсоне, работающий на том же компьютере и запущенный 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>

Ответ 4

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

Демон запуска, называемый простым script (start.sh), симуляция полного входа и запуск программы, требуемой

su -l username -c program

Теперь, даже после загрузки, xcodebuild может получить доступ к login.keychain. Это работает и на Snow Leopard, но если вы закрываете пользовательский login.keychain в параллельном сеансе (например, vnc login/logout), цепочка ключей теряется. Лев ведет себя иначе. Кажется, что Лев отделяет брелок от пользователя и назначает его сеансу входа в систему.

Ответ 5

Чтобы сохранить разделительный брелок для Jenkins/Hudson, я переместил элемент launchctl из

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

к

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

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

Ответ 6

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

Ответ 7

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

chown -R myBuildUser /Users/Shared/Jenkins

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

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

Ответ 8

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