chocolatey unter Windows mit lokaler Repository

Ich bin aktuell dabei einige Software Pakete auf Windows Systeme möglichst automatisiert auszurollen. Das Ziel sollte sein dabei immer eine definierte Version, eventuell je nach Stage (development, qa, production) installiert zu haben. Als Tool zum Software Rollout und Configuration Management kommt selbstverständlch Puppet zum Einsatz. Bisher habe ich das über den standardmäßigen MSI Package Provider in Puppet gelöst.

Generell hat dies leider einige unschöne Nachteile. Einer ist, das man jedes mal sein Puppet Manifest anpassen muss um auf das korrekte MSI Paket zu verweisen. Mit Umwegen (z.B. statischen Namen auf einem CIFS-Share) könnte man das durchaus noch lösen und damit leben. Deutlich unschöner ist aber das man auf die schnelle nicht herausfinden kann, welche Pakete bisher überhaupt installiert wurden und vorallem in welcher Version, sollte es tatsächlich mal Probleme beim Rollout/Upgrade gegeben haben.

Eine Alternative ist hier chocolatey, das ich bereits seit längerem kenne und aktiv nutze. Das Tool chocolatey stellt eine Art APT-Repository für Windows bereit. Das Rad wude dabei nicht komplett neu entwickelt, sondern chocolatey nutzt NuGet als Backend. NuGet wird dem einen oder anderen Windows Developer ein Begriff sein und kann genutzt werden um Dependencies für Visual Studio Projekte herunterzuladen. Grundsätzlich könnte man also auch direkt NuGet benutzen. Leider hat das Command Line Util von Microsoft nicht alle Funktionen zur Verfügung, weshalb man aufwändig die Visual Studio Extensions installieren müsste.

Als offizielle Microsoft Lösung kann man künftig auch das OneGet Powershell CMDlet verwenden. Dies ist im Prinzip eine Implementation der Chocolatey Funktionalitäten, die in den neuen PowerShell und Windows Releases direkt einfließen soll. Auch OneGet basiert auf der NuGet API und kann somit z.B. mit chocolatey.org sprechen. Leider gibt es hier noch keinen Puppet Package Provider, was aber sicherlich nur eine Frage der Zeit ist.

Der chocolatey Client kann generell mit einem einzigen PowerShell Befehl installiert werden. Puppetlabs hat bereits ein offizielles Powershell Modul, was man dazu durchaus verwenden kann.

iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1'))

Das Problem an der chocolatey.org Repository ist für mich jedoch der Punkt, das es bis vor kurzem keinerlei Überprüfungen der Pakete gab. Dies hat sich zwar nun geändert, leider sind Pakete (z.B. NSClient++) massiv veraltet und somit kaum benutzbar. Dies war auch bis dato der Grund warum ich chocolatey in Produktion nicht in Betracht gezogen habe. Nun habe ich mich heute aber kurz mit dem Thema NuGet genauer auseinandergesetzt und festgestellt das das bauen eigener Pakete wirklich extrem simpel ist.

Für eine einfache Installation eine MSI Pakets benötigt man ledeglich zwei Dateien:

  • meinpaket.nuspec
  • tools/chocolateyInstall.ps1

Die meinpaket.nuspec (z.B. puppet.nuspec) ist im Prinzip ein Metafile, was das Paket beschreibt. Das ganze ist in einfachem XML aufgebaut.

<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
  <metadata>
    <id>puppet</id>
    <version>3.7.3</version>
    <authors>Puppetlabs</authors>
    <description>Puppet Agent for Windows</description>
    <language>en-US</language>
    <projectUrl>http://blog.simlau.net</projectUrl>
    <licenseUrl>http://blog.simlau.net</licenseUrl>
  </metadata>
</package>

Das zweite benötigte File ist die chocolateyInstall.ps1. Ein PowerShell Script, das die MSI Source angibt.

Install-ChocolateyPackage 'puppet' 'MSI' '/qn' 'http://downloads.puppetlabs.com/windows/puppet-3.7.3.msi' 'http://downloads.puppetlabs.com/windows/puppet-3.7.3-x64.msi' -validExitCodes @(0)

Das CMDlet „Install-ChocolateyPackage“ wird dabei von „cinst“ aufgerufen, um das Paket zu bauen. Angegeben werden neben dem Paketnamen und den Install Parametern (für das MSI-Paket) zwei URLs, jeweils eine für 32-Bit und eine für 64-Bit Installationen. Chocolatey wählt automatisch das passende Paket anhand der Systemarchitektur (und des entsprechenden HKEYs in der Registry) aus.

Wer Paket für chocolatey.org bauen will, sollte sich die Doku genauer ansehen. Es gibt „Powershell-Templates“, die verwendet werden sollten um z.B. Fehler bei Installationen abzufangen. Für ein Beispielpaket reicht der obige Code jedoch vollkommen aus.

Um nun ein Paket darus zu schnüren reicht ein einziger Befehl.

PS C:\Users\Simon\puppet> cpack.exe .\puppet.nuspec
Calling 'C:\ProgramData\chocolatey\chocolateyinstall\nuget.exe pack .\puppet.nuspec -NoPackageAnalysis -NonInteractive'

Es wird versucht, das Paket aus "puppet.nuspec" zu erstellen.
Das Paket "C:\Users\Simon\puppet\puppet.3.7.3nupkg" wurde erfolgreich erstellt.

Installieren kann man das Paket nun unter der Angabe des Parameters -source

cinst -source C:\Users\Simon\puppet puppet

Leider nicht dokumentiert ist, wie man die standardmäßige Repository „chocolatey.org“ für den Client deaktiviert, dies ist jedoch auch möglich. Chocolatey bringt unter C:\ProgramData\chocolatey\chocolateyinstall\chocolatey.config eine Konfigurationsdatei mit, in der die Standardrepository hinterlegt ist.

<?xml version="1.0"?>
<chocolatey>
    <useNuGetForSources>false</useNuGetForSources>
    <checksumFiles>true</checksumFiles>
    <virusCheck>false</virusCheck>
    <sources>
        <source id="chocolatey" value="https://chocolatey.org/api/v2/" />
    </sources>
</chocolatey>

Um nun nicht bei jedem „cinst“ die Source mit angeben zu müssen und zudem die chocolatey.org Repository zu deaktivieren, kann man die Zeile z.B. einfach wie folgt anpassen.

<source id="custom" value="C:\chocolatey_repo" />

Chocolatey kann hier auch mit UNC Pfaden umgehen, womit man das ganze auch auf einen internen CIFS-Share auslagern kann.

Alles nötige für das Management von chocolatey (Installation und Konfiguration) auf Windows habe ich bereits in ein Puppet Modul einfließen lassen, das ich beizeiten auch noch in der Puppet Forge veröffentlichen möchte.

Kommentare (2)

tbd01.07.2015 um 14:04 Uhr

Zum deaktivieren der chocolatey Paketquelle kann auch
choco source disable -n=chocolatey
genutzt werden. Als Alternative zu ‚disable‘ gibts auch ‚remove’…

Simon13.07.2015 um 23:58 Uhr

Sehr nett, Danke! War mir nicht bekannt. Entweder kam der Parameter erst vor kurzem rein, oder ich habe ihn tatsächlich übersehen. Momentan tut sich da ja sehr viel beim Chocolatey Projekt.

Gruß, Simon

Einen Kommentar hinterlassen

Dein Kommentar