web-dev-qa-db-de.com

Fehlende Zertifikate und Schlüssel im Schlüsselbund bei Verwendung von Jenkins/Hudson als Continuous Integration für iOS- und Mac-Entwicklung

Ich versuche, Hudson CI für iOS zu verbessern und Hudson zu starten, sobald das System startet. Dazu verwende ich das folgende launchd-Skript:

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

Dies funktioniert in Ordnung, aber wenn xcodebuild, das von Hudson gestartet wird, versucht, eine App zu signieren, schlägt die App fehl, da sie nicht den richtigen Schlüssel/das richtige Zertifikat im Schlüsselbund finden kann. Das Schlüssel/Zertifikat-Paar ist jedoch vorhanden, da es korrekt funktioniert, wenn ich Hudson über die Befehlszeile starte. 

Hast du eine Idee, warum es passiert? 

38
Dmytro

Nachdem ich Stunden und Tage mit diesem Problem verbracht hatte, fand ich eine ziemlich einfache Lösung dafür. Es spielt keine Rolle, ob Sie in Ihrer launchd-Konfiguration einen eindeutigen Benutzernamen haben (siehe oben):

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

Die fehlenden Zertifikate und Schlüssel müssen sich auf dem Systemschlüsselbund befinden (/Library/Keychains/System.keychain). Ich habe dies gefunden, nachdem ich einen jenkins-Job eingerichtet habe, der mehrere security-Shell-Aufrufe ausführt. Interessant ist security list-keychains:

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

Das sind die Schlüsselbunde, nach denen Jenkins die Zertifikate und Schlüssel durchsucht, damit sie dort sein sollten. Nachdem ich meine Zertifikate dort hingezogen habe, funktioniert es. Stellen Sie sicher, dass Sie auch das Zertifikat »Apple Worldwide Developer Relations-Zertifizierungsstelle« in den Systemschlüsselbund kopieren, andernfalls wird ein CSSMERR_TP_NOT_TRUSTED-Fehler von codesign angezeigt.

Es ist auch möglich, weitere Schlüsselbunde mit security list-keychains -s [path to additional keychains] zu registrieren. Ich habe es nicht ausprobiert, aber so etwas wie security list-keychains -s $HOME/Library/Keychains/login.keychain als vorgefertigte Shell-Ausführung in Jenkins könnte funktionieren.

EDIT: Ich habe versucht, mit -s einen Benutzerschlüsselbund zum Suchpfad hinzuzufügen, aber ich konnte es nicht zum Laufen bringen. Daher müssen wir zunächst unsere Zertifikate und Schlüssel in den System-Schlüsselbund kopieren.

EDIT ^ 2: Lesen und verwenden Sie joensson ' solution anstelle von mir.

19
Jens Kohl

Ich habe eine Lösung gefunden, die mir den Zugriff auf die regulären Schlüsselanhänger für meinen Jenkins-Benutzer ermöglicht. 

Neben der Angabe des UserName-Elements in der plist-Datei, wie die akzeptierte Antwort nahelegt, besteht der Trick, um Zugriff auf die normalen Schlüsselbunde für den in UserName angegebenen Benutzer zu erhalten, darin, ein SessionCreate-Element mit dem Wert true zur plist-Datei hinzuzufügen. 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>

Starten Sie dann den Daemon erneut und versuchen Sie, einen Job in Jenkins auszuführen, der Sicherheitslisten-Schlüsselketten aufruft - und Sie sollten System.keychain nicht mehr als einzigen Eintrag sehen, sondern nur das reguläre Login und alle benutzerdefinierten Schlüsselketten, die Sie der Liste der Schlüsselketten hinzugefügt haben der "Jenkins" Benutzer.

Ich verwende jetzt Codesignierungszertifikate aus einem benutzerdefinierten Schlüsselbund auf meinem Jenkins-Buildserver. Ich habe keine Zertifikate oder Schlüssel in meinem Systemschlüsselbund installiert.

66
joensson

Wir hatten das gleiche Problem mit einem Hudson-Slave, der als Launchdaemon unter Mac OSX Lion gestartet wurde. Es hat funktioniert, als wir den Sklaven mit Webstart gestartet haben. Der einzige Unterschied war eine andere Umgebungsvariable.

com.Apple.Java.jvmTask=WebStart

funktioniert, wenn wir den Slave ohne Webstart gestartet haben, war die Variable

com.Apple.Java.jvmTask=CommandLine.Java

Wir haben keine Möglichkeit gefunden, den Wert im Vorfeld zu beeinflussen. Ich schlage vor, dass Sie in Hudson einen neuen Knoten erstellen, der auf derselben Maschine läuft und von webstart gestartet wird. Zum Starten des Slaves verwenden wir folgende launchdaemon-Konfiguration:

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

Sie könnten meine Jenkins.app, https://github.com/stisti/jenkins-app ausprobieren, eine alternative Möglichkeit, Jenkins auszuführen. Es führt Jenkins in der Benutzersitzung aus, sodass der Zugriff auf den Schlüsselbund kein Problem darstellt.

2
sti

Ich hatte das gleiche Problem und versuchte, den Benutzernamen in /Library/LaunchDaemons/org.jenkins-ci.plist wie in einem der anderen Beiträge beschrieben zu ändern. Es hat jedoch immer noch nicht funktioniert, und einige obskure NullPointerException hat mir nicht geholfen, das Problem zu identifizieren. Deshalb würde ich einfach meine Lösung freigeben: Ich musste auch den Besitzer des JENKINS_HOME-Verzeichnisses (ebenfalls in org.jenkins-ci.plist definiert) ändern:

chown -R myBuildUser /Users/Shared/Jenkins

myBuildUser ist der Benutzer, auf dem die Zertifikate installiert sind. Dies ist der Benutzer, den ich in der plist-Datei angegeben habe. 

Diese Lösung war offensichtlich, als ich es endlich realisierte - aber ich habe ein paar Stunden gebraucht, um das herauszufinden. Hoffentlich kann dieser Beitrag die Zeit für jemanden anderen sparen :-)

2
JRV

Um einen unterteilten Schlüsselbund für Jenkins/Hudson aufzubewahren, habe ich den launchctl-Eintrag von verschoben

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

zu

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

Und so kann ich auf den privaten Schlüsselbund zugreifen, der für Jenkins erstellt wurde.

1
igorsales

Auf Lion und SnowLeopard hatten wir genau das gleiche Problem. Wir mussten einen Tomcat/Hudson mit xcodebuild-Jobs als Service starten. Beim Start von der Befehlszeile aus kann das xcodebuild auf die login.keychain zugreifen, um das enthaltene Zertifikat zu verwenden. Aber nach dem Neustart der Box war die login.keychain für xcodebuild nicht sichtbar und daher schlug die Signatur fehl.

Da wir unser Unternehmenszertifikat über einen Schlüsselbund bereitstellen mussten, war der Systemschlüsselbund keine Option. Stattdessen haben wir das Problem durch eine einfache Problemumgehung gelöst. Wir haben den Benutzernamen entfernt, sodass der Start-Daemon den Prozess unter root startet. 

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

Der Start-Daemon rief ein einfaches Skript ( start.sh ) auf, simulierte eine vollständige Anmeldung und führte das gewünschte Programm aus

su -l username -c program

Jetzt kann das xcodebuild auch nach dem Booten auf die login.keychain zugreifen. Dies funktioniert auch bei Snow Leopard, aber wenn Sie die benutzerspezifische login.keychain in einer parallelen Sitzung schließen (z. B. vnc login/logout), geht der Schlüsselbund verloren. Löwe verhält sich anders. Es scheint, dass Lion den Schlüsselbund vom Benutzer abkoppelt und ihn einer Login-Sitzung zuordnet.

1
hieroGlype

Für das manuelle Signieren Verschieben Sie Ihr Zertifikat aus dem Login in das System im Schlüsselbund. Login ist während des Archivierens und dem Generieren von iPA nicht verfügbar. 

0
Shauket Sheikh

Das Hinzufügen, da ich das gleiche Problem hatte, aber keine dieser Lösungen funktionierte für mich. 

Mein Problem wurde verursacht, als das Signaturzertifikat nach Ablauf der Gültigkeitsdauer aktualisiert wurde. Nach dem Update funktionierten xcode und xcodebuild manuell, BUT Jenkins konnte die App jedoch nicht signieren.

So habe ich es behoben:

  1. Schauen Sie in Schlüsselbund und suchen Sie nach dem Schlüssel. Aus irgendeinem Grund, aus dem ich nicht verstehe, haben wir unterschiedliche Ergebnisse erhalten. 

  2. Stellen Sie sicher, dass sich der private Schlüssel in der Systemebene befindet (andernfalls ziehen Sie ihn auf das Systemsymbol links. 

 enter image description here

0
Francois Nadeau

Hinzufügen von SessionCreate und viele Zertifikate auf 'immer vertrauen' im Schlüsselbund-Manager setzen .__ arbeitete für mich mit buildbot von plist aus ... aber irgendwann schlug codeign mit mit CSSMERR_TP_NOT_TRUSTED fehl. Ich erholte mich, indem ich das iPhone Distribution-Zertifikat so eingestellt habe, dass es im Schlüsselbund-Manager "Systemeinstellungen" verwendet. Selbst nach einem Neustart, ohne sich anzumelden, konnte der Buildbot-Slave den Code signieren.

0
Dan Kegel