web-dev-qa-db-fra.com

Certificats et clés manquants dans le trousseau lors de l'utilisation de Jenkins/Hudson comme intégration continue pour le développement iOS et Mac

J'essaie d'améliorer Hudson CI pour iOS et de démarrer Hudson dès que le système démarre. Pour ce faire, j'utilise le script launchd suivant:

<?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>

Cela fonctionne bien, mais lorsque xcodebuild, qui est démarré par Hudson, tente de signer une application, il échoue car il ne parvient pas à trouver la clé/le certificat approprié dans le trousseau. Cependant, la paire clé/certificat est présente car elle fonctionne correctement si je lance Hudson à partir de la ligne de commande. 

Avez-vous des idées pourquoi cela se produit? 

38
Dmytro

Après avoir passé des heures et des jours à traiter ce problème, j'ai trouvé une solution assez simple à ce problème. Peu importe si vous avez un nom d'utilisateur distinct dans votre configuration launchd, comme indiqué ci-dessus:

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

Les certificats et les clés manquants doivent se trouver sur le trousseau de clés du système (/Library/Keychains/System.keychain). J'ai trouvé cela après avoir configuré un travail Jenkins qui exécute plusieurs appels security Shell. Celui qui est intéressant est security list-keychains:

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

Ce sont les porte-clés que jenkins recherchera dans les certificats et les clés, ils devraient donc être là. Après avoir déplacé mes certs là-bas, cela fonctionne. Veillez également à copier le certificat »Autorité de certification Apple Worldwide Developer Relations« dans le trousseau système, sinon une erreur CSSMERR_TP_NOT_TRUSTED de codesign apparaîtra.

Il est également possible d’enregistrer plus de trousseaux avec security list-keychains -s [path to additional keychains]. Je ne l'ai pas essayé, mais quelque chose comme security list-keychains -s $HOME/Library/Keychains/login.keychain en tant qu'exécution de shell pré-construit dans Jenkins pourrait fonctionner.

EDIT: J'ai essayé d'ajouter un trousseau d'utilisateurs au chemin de recherche avec -s mais je n'ai pas réussi à le faire fonctionner. Donc, pour l'instant, nous devons copier nos certificats et nos clés dans le trousseau système.

EDIT ^ 2: Lire et utiliser joensson ' solution au lieu du mien, il a réussi à accéder au trousseau des utilisateurs au lieu du trousseau système.

19
Jens Kohl

J'ai trouvé une solution qui me donne accès aux porte-clés standard pour mon utilisateur Jenkins. 

En plus de spécifier l'élément UserName dans la liste de sélection comme le suggère la réponse acceptée, l'astuce pour accéder aux trousseaux de clé normaux de l'utilisateur spécifié dans Nom d'utilisateur consiste également à ajouter un élément SessionCreate avec la valeur true au fichier 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>

Relancez ensuite le démon et essayez d’exécuter dans Jenkins un travail appelant des trousseaux de sécurité liste - et vous ne devriez plus voir System.keychain comme la seule entrée, mais la connexion habituelle et les chaînes de clés personnalisées que vous auriez éventuellement ajoutées à la l'utilisateur "jenkins".

J'utilise maintenant des certificats de signature de code à partir d'un trousseau personnalisé sur mon serveur de génération Jenkins - je n'ai installé aucun certificat ni clé dans mon trousseau Système.

66
joensson

Nous avons eu le même problème avec un esclave hudson lancé comme lanceur de lancement sur Mac OSX Lion. Cela a fonctionné lorsque nous avons démarré l'esclave avec Webstart. La seule différence que nous avons vue était une variable d'environnement différente.

com.Apple.Java.jvmTask=WebStart

fonctionne, si nous avons commencé l'esclave sans Webstart la variable était

com.Apple.Java.jvmTask=CommandLine.Java

Nous n'avons trouvé aucun moyen d'influencer la valeur dès le départ. Je vous suggère de créer un nouveau noeud dans Hudson, fonctionnant sur le même ordinateur et démarré par Webstart. Pour démarrer l'esclave, nous utilisons la configuration suivante 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
cemonds

Vous pouvez essayer mon Jenkins.app, https://github.com/stisti/jenkins-app , une méthode alternative pour exécuter Jenkins. Il exécute Jenkins dans la session utilisateur, donc l'accès au trousseau n'est pas un problème.

2
sti

J'ai rencontré le même problème et essayé de changer le nom d'utilisateur dans /Library/LaunchDaemons/org.jenkins-ci.plist comme décrit dans l'un des autres articles. Cependant, cela ne fonctionnait toujours pas et certaines obscures NullPointerException ne m'ont pas aidé à identifier le problème. Par conséquent, je voudrais simplement partager ma solution: je devais également changer le propriétaire du répertoire JENKINS_HOME (défini également dans org.jenkins-ci.plist):

chown -R myBuildUser /Users/Shared/Jenkins

myBuildUser est l'utilisateur sur lequel les certificats sont installés et il s'agit de l'utilisateur que j'ai spécifié dans le fichier plist. 

Cette solution était assez évidente quand je l'ai finalement réalisée - mais cela m'a pris quelques heures pour le découvrir, alors espérons-le, cet article pourra faire gagner du temps à quelqu'un d'autre :-)

2
JRV

Pour conserver un porte-clés compartimenté pour Jenkins/Hudson, j'ai déplacé l'élément launchctl

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

à

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

Et cela me permet d'accéder au trousseau privé créé pour Jenkins.

1
igorsales

Nous avons rencontré exactement le même problème sur Lion ainsi que sur SnowLeopard. Nous devions démarrer Tomcat/Hudson avec des travaux xcodebuild en tant que service. En commençant à partir de la ligne de commande, xcodebuild pourrait accéder à la chaîne login.keychain pour utiliser le certificat contenu. Mais après le redémarrage de la boîte, le login.keychain n'était pas visible pour xcodebuild et la signature a donc échoué.

Comme nous avions besoin de fournir notre certificat d'entreprise par un trousseau, le trousseau système n'était pas une option. Au lieu de cela, nous avons résolu le problème par une solution de contournement simple. Nous avons supprimé le nom d'utilisateur afin que le démon de lancement lance le processus sous 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>

Le démon de lancement a appelé un simple script ( start.sh ), la simulation un login complet et l’exécution du programme voulu

su -l username -c program

Maintenant, même après l’amorçage, xcodebuild peut accéder à la chaîne login.keychain. Cela fonctionne également sur Snow Leopard, mais si vous fermez le login.keychain spécifique à l'utilisateur dans une session parallèle (comme vnc login/logout), le trousseau est perdu. Lion se comporte différemment. Il semble que Lion dissocie le trousseau de l'utilisateur et l'assigne à une session de connexion.

1
hieroGlype

Pour la signature manuelle Déplacez votre certificat de connexion au système dans le trousseau. La connexion n'est pas accessible pendant l'archivage et la génération d'iPA. 

0
Shauket Sheikh

En ajoutant cela depuis que j'ai eu le même problème, mais aucune de ces solutions n'a fonctionné pour moi. 

Mon problème est survenu après que le certificat de signature ait dû être mis à jour, après son expiration. Après la mise à jour, xcode et l'exécution de xcodebuild ont fonctionné correctement, MAIS Jenkins n'a pas pu signer l'application.

Voici comment je l'ai corrigé:

  1. Regardez dans le trousseau et recherchez la clé. Pour une raison que je ne comprends pas, cela nous a donné des résultats différents. 

  2. Assurez-vous que la clé privée est au niveau système (sinon, faites-la glisser vers l'icône système à gauche. 

 enter image description here

0
Francois Nadeau

Ajouter SessionCreate et en configurant de nombreux certificats pour "toujours faire confiance" au gestionnaire de trousseau travaillé pour moi avec buildbot démarré depuis plist ... mais à un moment donné, codesign a commencé à échouer avec CSSMERR_TP_NOT_TRUSTED. J'ai récupéré en réglant le certificat de distribution iPhone sur «utiliser les paramètres système par défaut» dans le gestionnaire de trousseau. Même après un redémarrage, sans connexion, .__, le buildbot slave était alors capable de signer du code, ouf.

0
Dan Kegel