ProGet als bessere Chocolatey Repository Verwaltung

So, eine kleine Forsetzung vom letzten Beitrag. Ich hatte gezeigt das Chocolatey auch CIFS-Shares bzw. UNC-Pfade und lokale Verzeichnise als Install Source supportet. Für eine sehr kleine lokale Repository reicht das auch aus. Leider muss man dann natürlich auf das nette Feature von pushen von Paketen verzichten. Außerdem bin ich als Linux Admin selbst kein wirklicher Freund von CIFS. Generell war ich mit der Lösung nicht voll zufrieden.

Mein primäres Ziel war eigentlich einen NuGet.Server aufzusetzen. Versucht habe ich es, aber nach einigen Studen Arbeit in Visual Studio for Web und der Anpassung IIS Konfiguration habe ich es nun aufgegeben. Viel mehr als die Startseite funktionierte nicht, beim Package Discovery blieb es bei einem HTTP Error 404.

Durch das Debugging bin ich aber über eine Google Group an eine deutlich schönere und auch einfachere Lösung gestoßen. ProGet ist ein Repository Server für NuGet und Chocolatey mit kommerziellen Hintergrund, den es aber auch freie Version gibt.

Die Installation ist Windowstypisch extrem einfach. Durchklicken und es funktioniert. ProGet benötigt einen SQL-Server (SQL Express) und einen Webserver (wahlweise einen eigenen eine vorhandene IIS Instanz). Das wars.

ProGet

ProGet hat viele nette Features. Pakete können über Web oder den NuGet Push hochgeladen werden. Das Caching sowie das Staging von Paketen in verschiedenen Environments ist möglich und die Webadministration kann sauber in eine LDAP Struktur integriert werden.

An dieser Stelle sei nochmal erwähnt: Microsofts One-Get setzt auf dem Chocolatey Paketmanagement auf. Mit dem offiziellen Release von PowerShell v5 (aktuell ist das Projekt noch im “Preview” Status) können diese Repositorys auch nativ in Windows genutzt werden.

Ich halte Chocolatey und NuGet für eine zukunftsweisende Lösung von einfacher Softwareverteilung unter Windows. Gerade dann, wenn man das ganze als eine Art Framework nutzt und in Puppet etc. einbindet. Wir werden sehen wie es mit dem Chocolatey Projekt weiter geht. Aktuell läuft hier auf Kickstarter ein Crowdfunding, mit dem sich das Projekt dann sein Büro einrichten möchte und eine kommerzielle “Chocolatey Enterprise” Lösung schaffen möchte. Dazu kommt natürlich Microsoft, die durch One-Get hier auch einiges voran bringen sollten.

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.

LDAPAdmin Directory Browser

LDAPAdmin LDAPAdmin ist ein nettes Tool, was ich nun bereits seit längerer Zeit für mich und für Kunden verwende und ich kann es mittlerweile nur uneingeschränkt weiterempfehlen. Bei LDAPAdmin handelt es sich um ein Windows Tool, das die eher lästige Arbeit bei der Anbindung von Systemen an eine (Windows) LDAP-Authentifizierung etwas vereinfacht.

Es handelt es sich schlicht um einen recht einfach gehaltenen Browser für LDAP Verzeichnise. Man kann sich durch seine gewohnte Windows DC/OU-Struktur klicken und sich die DN zu Computer, User oder Group Objekten direkt in die Zwischenablage kopieren um Sie anschließend direkt für seinen LDAP Filter verwenden zu können. Jedem der schon einmal mit LDAP zu tun hatte, sollte hier zumindest die BaseDN ein Begriff sein.

Der Zugriff LDAP Objekte ist sowohl lesend als auch schreibend möglich. Dadurch geht z.B. auch das setzen von neuen AD-Attributen (z.B. Unix Attribute: UID, HomeDirectory usw.) deutlich schneller, als über die (versteckten?) Bordmittel von Microsoft. Auch das zurücksetzen von Usern Kennwörtern ist selbstverständlich möglich.

LDAPAdmin ist OpenSource und kann hier heruntergeladen werden.

Puppet: Node spezifische Module

Leider immer wieder nötig: Puppet Module bzw. Klassen, die explizit für eine Node benötigt werden. In der Regel wird dabei ein Modul ala “funktion_server21″ gestrikt. Dieses Modul wird dann explizit dem einen Server via Node Definition, ENC oder Hiera zugewiesen. Das bläht Hiera, den ENC oder die Node Definition unnötig auf, obwohl man sich das eigentlich auch sparen könnte.

Hier mein aktuelles Konzept zu diesem Thema, was wirklich extrem simpel ist, dennoch aber wunderbar funktioniert.

# modules/nodes/manifests/init.pp
class nodes {
  if defined("nodes::node::${hostname}") {
    include "nodes::node::${hostname}"
  }
}

Ich habe mir ein Modul “nodes” geschrieben, das prinzipiell auf jedem Host includiert wird. Das Modul hat als einzige Funktion zu prüfen ob z.B. die Klasse node::node::server21 auf dem Puppet Master vorhanden ist. Wenn ja, wird das Modul includiert.

Wichtig an dieser Stelle ist es unbedingt defined() statt defined(Class['nodes::node::nodename']) zu verwenden. Das reine “define()” prüft ob die Klasse grundsätzlich auf dem Puppetmaster vorhanden ist, während die Erweiterte Form mit Class[] prüft, ob die Klasse bereits im Katalog eingebunden ist. Letztes würde natürlich immer ins leere laufen, da die Klasse noch nicht includiert wurde.

Dazu beispielhaft die Klasse für den “server21″.

# modules/nodes/manifests/node/server21.pp
class nodes::node::server21 {
  file { '/etc/apache2/conf.d/deflate.conf':
    ensure => absent,
  }
}

Sollte in der Umgebung ein Overlapping bei den Hostnamen bestehen, lässt sich dieses Prinzip natürlich mit etwas mehr Logik auch mit dem Fact $::fqdn o.ä. (echo $fqdn | sed 's/\.//_//g') realisieren.

Damit hat man nun alle “Sonderkonstrukte” auf einem Blick, zentral an einer Stelle in einem Modul. Diese Klasse kann man nun pauschal auf alle Nodes einbinden lassen.

node default {
        # Include des Moduls
        include 'nodes'

        # Oder alternativ auch via Hiera
        hiera_include('classes')
}

Das ganze kann natürlich auch in jeder Hinsicht erweitert werden. Denkbar wäre auch nicht den Namespace nodes::node, sondern direkt nodes::$hostname zu verwenden und darunter ein komplettes Submodul zu bauen.

XenMobile 9.0: MTC Deployment Script

Bei der Citrix XenMobile MTC (Abkürzung für “Multi-Tentant Console”) handelt es sich um ein XenMobile Deployment-Tool, mit dem man XenMobile DeviceManager (XDM) Instanzen automatisiert ausrollen und mit mehreren Tentants austatten kann.

Um das Deployment der MTC etwas zu erleichtern, habe ich mir erlaubt ein kleines Script zu schreiben. Mit diesem Script ist es nicht länger nötig das Google Web Toolkit, GWT und die Sysinternals nur zum starten des Deployments der MTC extra im Windows Environment bzw. $PATH zu haben. Das Script setzt das korrekte Environment und startet die zdm_mtc.bat.

:: Deployment Script for XenMobile MTC
:: @author: Simon Lauger <simon@lauger.name>
:: @date:   20.08.2014
::
:: Example of C:\xenmobile
:: ##############################################################
:: 18.08.2014  12:47    <DIR>          .
:: 18.08.2014  12:47    <DIR>          ..
:: 18.08.2014  12:21    <DIR>          grails-1.3.7
:: 18.08.2014  12:21    <DIR>          gwt-windows-1.5.3
:: 18.08.2014  11:37    <DIR>          SysinternalsSuite
:: 18.08.2014  12:23    <DIR>          XenMobile_MTC-9.0.0.35278
:: ##############################################################
:: 
@echo off

:: Setting grails and gwt environment 
SET GWT_HOME=C:\xenmobile\gwt-windows-1.5.3
SET GRAILS_HOME=C:\xenmobile\grails-1.3.7
SET SYSINTERNALS=C:\xenmobile\SysinternalsSuite

:: Specify JAVA_HOME (change, if needed)
SET JAVA_HOME=C:\Program Files\Java\jdk1.7.0_67

:: Include Java and sysinternals in %PATH%
SET PATH=%PATH%;%JAVA_HOME%\bin;%SYSINTERNALS%

:: Change directory 
cd C:\xenmobile\XenMobile_MTC*

:: Start Deployment
zdm_mtc.bat

Für die MTC werden folgende Tools/Pakete benötigt (die Versionen sind zu beachten). Sämtliche Tools sind herunterzuladen und zusammen mit dem Script im Ordner C:\xenmobile zu entpacken.

Aus den Sysinternals werden grundsätzlich nur psexec.exe und psservice.exe benötigt, jedoch sollte es keine Schmerzen bereiten das komplette Archiv herunterzuladen. Achtung: hier unbedingt vorher Lizenz/EULA aktzeptieren (dazu die Files manuell einmalig öffnen)!

Die MTC wird von Citrix leider etwas “stiefmütterlich” behandelt. Bis gestern gab es in der Download Sektion für XenMobile 9.0 keinen Download für den “Device Manager for Multi-Tentant”. Erst nachdem ich im Citrix Forum einen Topic eröffnet hatte wurde der Download nun nachgereicht. Beim “Device Manager for Multi-Tentant” handelt es sich u nahezu die identische Installationsroutine wie für den “normalen” XenMobile DeviceManager. Einzger Unterschied: es wird ein leerer Tomcat, ohne mitgelieferte XDM Instanz (Deployment-File/War-File) installiert.

Ein Deploymentversuch unter dem aktuellen Java 8x JDK brach bei mir im übrigen mit diversen Exceptions (u.a. ClassNotFoundException) ab und scheint derzeit wohl nicht möglich zu sein. Eine Info hierzu seitens Citrix konnte ich nicht finden.