Git in Integrata-Seminaren – Teil 3

Verwendung von Git in Seminaren

Für Veranstaltungen mit Programmier-Übungen bietet es sich geradezu an, Git in Integrata-Seminaren einzusetzen. Die Vorteile liegen auf der Hand:

  • Referenten haben Zugriff auf die Musterlösung in verschiedenen Ständen und können Verbesserungen bzw. Fehler einspielen.
  • Referenten und Kunden haben für die Seminarinstallation einen simplen Zugriff für die Installation der Musterlösungen.
  • Mit Hilfe von Tags können Versionsstände der Broschüre direkt mit Versionsständen der Übungen verknüpft werden.
  • Die Teilnehmer des Seminars erhalten im Nachgang Zugriff auf die Musterlösungen. Auch hier können Fehler und Verbesserungen jederzeit gepflegt werden.

Repository-Organisation

Nachdem wir uns in Teil 1 mit den Grundlagen von Git und in Teil 2 mit dem Git-Plugin für Eclipse beschäftigt haben konzentrieren wir uns im Folgenden auf die Organisation des Repositories. Für jedes Seminar wird ein eigenes Repository angelegt, hier beispielsweise für das Seminar Docker und Java das Repository org.javacream.training.docker:

Das Repository für das Docker-Training

Das Repository besteht aus drei Branches:

  • initial kann vom Referenten als Ausgangsbasis des Praktikums benutzt werden.
  • master enthält die aktuellen Musterlösungen.
  • develop enthält alle Commits, die den aktuellen Stand des Praktikums definiert haben. Dieser Branch enthält somit alle Zwischenstände und soll die komplette Historie halten.

Neben den Branches existieren Tags, und zwar jeweils in Paaren. Der Name dieser Tags enthält die Versionsnummer der Broschüre:

  • <broschürenversion> tagged den Stand der Musterlösung für diese Broschürenversion
  • <broschürenversion>_initial tagged die, eventuell leere Praktikumsumgebung dieser Broschürenversion.

Die relevanten Stände des Praktikums befinden sich damit in initial und in master bzw. genauer: In den Tags.

Arbeiten im Seminar

Die im Folgenden dargestellte Arbeitsweise verlangt nicht, dass die Teilnehmer Git kennen und verwenden müssen! Nur der Referent nutzt die Möglichkeiten des Versionsverwaltungssystems.

Zur Vorbereitung der Praktikumsumgebung cloned sich der Referent am Einfachsten das gesamte Repository lokal auf seinen Referentenrechner. Dann wird der Tag, der den initialen Stand zur aktuellen Broschüre enthält ausgechecked.

git checkout  <broschürenversion>_initial

Alternativ kann über GitHub für einen Release auch eine Zip-Datei geladen werden.

Egal wie der initiale Stand erzeugt wurde: Dieser wird nun den Teilnehmern zur Verfügung gestellt.

Nun erzeugt sich der Referent an der Stelle dieses Tags einen neuen Branch, der für dieses Seminar verwendet werden soll. Als Namen verwende ich integrata_<startdatum_des_seminars>. Auf diesem Branch wird nun die Musterlösung für das Seminar fortlaufend ergänzt und relevante Stände werden mit sprechenden Commits gesichert. Der Seminarlauf wird somit auf diesem Branch in nachvollziehbarer Form abgebildet. Die Sourcen für die Muster können dem master-Branch entnommen werden. Zwischenstände findet der Referent bei Bedarf im develop-Branch. Dieser enthält ja alle jemals als relevant erachteten Stände.

Am Ende des Seminars befindet sich der Seminar-Branch auf dem Stand der Lösung für die durchgeführte Schulung. Dieser Stand muss selbstverständlich nicht exakt der Musterlösung entsprechen! Ganz im Gegenteil kann der Referent hier eigene Lösungswege gehen, Vertiefungen einführen oder aber auch nachrangige Themen weglassen.

Ressourcen für die Teilnehmer

Am Ende des Seminars erhalten die Teilnehmer

  • Den Ausgangsstand,
  • die in der Broschüre verwendete Musterlösung, also den Stand mit dem korrespondierenden Tag,
  • den Seminar-Stand.

Die ersten  beiden werden als Zip-Dateien verteilt, letzteres sinnvoll als Git-Repository: Die Teilnehmer sollen ja bei Bedarf auch die Zwischenstände nachvollziehen können. Die hierfür notwendigen Kenntnisse von Git sollten vorausgesetzt werden können oder werden vom Referenten kurz vermittelt. Hierzu kann vom Teilnehmer beispielsweise Eclipse mit dem Git-Plugin benutzt werden, wie es im zweiten Teil dieser Serie beschrieben wurde.

Ressourcen für den Seminar-Verantwortlichen

Sind im Rahmen des Seminars Verbesserungen, kreative Ideen oder Fehlerbehebungen erfolgt, so wird der Seminar-Branch als Git-Repository dem Seminar-Verantwortlichen zur Verfügung gestellt. Dies erfolgt aktuell über einen Filetransfer per Mail oder ähnlichem.

 

Seminare zum Thema

Weiterlesen

Git in Java-Seminaren – Teil 2: Git Eclipse-Plugin

Das Git Eclipse-Plugin

Nachdem wir uns im im ersten Teil mit den Grundlagen von Git beschäftigt haben, führen wir entsprechend in diesem Beitrag das Git Eclipse-Plugin ein. Für ein komfortables Arbeiten unterstützen praktisch alle Entwicklerwerkzeuge Git, folglich bringt auch die Eclipse-Standard-Installation die Git-Unterstützung mit.

Die Git-Perspektive

Wie üblich gruppiert Eclipse zusammengehörige Funktionen in einer Perspektive:

Die Git-Perspektive in Eclipse

Diese Perspektive dient insbesondere zum Arbeiten mit entfernten Repositories. Das eigentliche Arbeiten mit der Versionsverwaltung wird deshalb dadurch umgesetzt, dass beispielsweise in der Java-Perspektive geänderte Klassen etc. speziell gekennzeichnet werden.

Klonen eines Repositories

Diese Perspektive ermöglicht es uns deshalb auf einfach Weise, lokale oder entfernte Repositories zu verwalten. So wird beispielsweise das folgende GitHub-Repository

Training-Projekt

eingebunden:

2: Auswahl der Branches
3: Remote-
Konfiguration

Das eingefügte Repository wird anschliessend in der Git-Perspektive dargestellt. Wir erkennen die 3 Branches sowie einen Tag:

Das eingebundene Repository

Arbeiten mit dem Repository

Die gebräuchlichen Aktionen, die mit Git durchgeführt werden können, sind im Kontext-Menü eingerichtet.

Git-Kommandos im Kontextmenü

Umgang mit Java-Projekten

Die Java-Projekte, die in dem Repository vorhanden waren, können dann in den Workspace importiert werden:

Import eines Projekts im Repository

Ein vorhandenes Projekt, das nicht unter Versionskontrolle steht kann schließlich in der Java-Perspektive dem Repository hinzugefügt werden:

Schritt 1: Teilen des Projekts mit dem Team
Schritt 2: Auswahl des Repositories

Arbeiten mit dem lokalen Repository

Der Status einer Datei wird durch Dekorationen gekennzeichnet. Staging, Commit und Push erfolgen weiterhin über die Git Staging-View:

Ein dem Repository hinzugefügtes Java-Projekt ist natürlich noch nicht dem Index zugeordnet. Dies wird in Eclipse mit kleinen ?-Dekorationen zum Ausdruck gebracht:

Ein neu hinzugefügtes Projekt

In der Staging-View werden die Dateien ebenfalls angezeigt und können dem Index hinzugefügt werden:

Die hinzuzufügenden Dateien

Nach dem Hinzufügen sind die Dateien dem Index des Repositories bekannt, aber noch nie committed. Dies wird durch eine Sternchen-Dekoration angezeigt:

Noch nicht bestätigte Änderungen

Nach dem Commit, natürlich unter Angabe einer Commit-Message, sind die Dateien endgültig im Repository angekommen:

Das Projekt ist committed

Achten Sie hierbei auch auf die Information rechts oben: Wir befinden uns auf dem Branch develop, der infolge des Commits dem Remote Branch einen Schritt voraus steht. Dies ändert sich jedoch nach einem Push des Branches.

 

Das Auschecken von Branches oder Tags erfolgt genauso einfach über einen Doppelklick.

Weitere Git-Views

Neben der Perspektive stellt das Git-Plugin von Eclipse auch eine Vielzahl von Views zur Verfügung, die die Inhalte des Repositories visualisieren und damit benutzerfreundlich darstellen. Am Einfachsten ist es, diese Views live in Aktion zu betrachten.

Im dritten und abschließenden Teil dieser Reihe zeigen wir schliesslich, wie Git für Integrata-Seminare eingesetzt werden kann.

Seminare zum Thema

Weiterlesen

Nexus als Docker-Registry

Nachdem im vorigen Artikel Nexus für Maven eingerichtet wurde zeige ich nun, wie Nexus als Docker-Registry benutzt werden kann.

Einrichten der Repositories

Docker unterstützt für Images kein Snapshot-Konzept. Folglich sind drei Repositories notwendig:

  • DockerProxy als Proxy für Dockerhub
  • DockerHost für die eigenen Images
  • DockerGroup als Gruppe für Hosted und Proxy

Zugriff über http

Docker verlangt im Standard eine gesicherte Kommunikation über https. Um unsichere Verbindungen zu erlauben muss die Docker-Engine in /etc/docker/daemon.json für “unsichere” Registries konfiguriert werden:

{
 "insecure-registries": [
   "10.72.2.55:8082", 
   "10.72.2.55:8083", 
   "10.72.2.55:8084"], 
 "disable-legacy-registry": true 
}

Nach Neustart der Docker-Engine ist damit ein Zugriff über http erlaubt:

service docker restart

Vorsicht: Alle laufenden Container sind nach dem Neustart gestoppt!

Authentifizierung und Pull

Die Authentifizierung gegen das Repository erfolgt durch

docker login -u admin -p admin123 10.72.2.55:8084

Hierbei wird im User-Home eine Datei mit den angegebenen Credentials angelegt und für jegliche Kommunikation mit dieser Registry benutzt.
Nun können Images vom Nexus geladen werden, der selbst wiederum die Daten von Dockerhub lädt und chached.
docker pull 10.72.2.55:8084/nginx

Push eines eigenen Images

Der Push erfolgt auf das Hosted Repository. Dazu ist ein weiterer Login notwendig:

docker login -u admin -p admin123 10.72.2.55:8083

Nun muss das vorhandene Image neu getagged werden, und zwar mit den Repository-Informationen:

docker tag javacream/javabase:1.0 10.72.2.55:8083/javacream/javabase:1.0

dann kann letztendlich gepushed werden:

docker push 10.72.2.55:8083/javacream/javabase:1.0

Push über Maven

In einem Maven-basierten Build-Prozess, der in diesem Artikel vorgestellt wurde, wird das Bauen der Docker-Images in einem Parent-POM definiert. Soll noch gepushed werden wird einfach der Name des Repositories mit konfiguriert:

<properties>
<repository_base_url>http://10.72.2.55:8081</repository_base_url>
<docker.namespace.prefix>10.72.2.55:8083/javacream</docker.namespace.prefix>
</properties>

Dann erfolgt das Push einfach über docker:push. Die Anmeldeinformationen erfolgen über die durch den docker login gespeicherten Informationen.

Benutzung von Nexus in Docker-Seminaren

Mit den oben genannten Konfigurationen kann in der Umgebung der Integrata ein fertig eingerichteter Nexus-Server benutzt werden. Dieser ist gemäß der obigen Ausführungen konfiguriert.  Allerdings darf nur der Referenten Images pushen und somit den Teilnehmern zur Verfügung stellen.

 

Weiterlesen

Nexus Maven-Repositories

Nexus als Maven-Repository

Das Endergebnis der Softwareentwicklung ist ein so genanntes Artefakt, das in einem Artefakt-Repository verwaltet werden wird. In diesem Artikel zeige ich, wie Nexus als Maven-Repository für Java-Projekte konfiguriert wird. In einem zweiten Teil wird Nexus zusätzlich für Docker-Images eingerichtet.

Der Nexus-Server im Docker-Container

Zum Betrieb des Nexus kann am Einfachsten ein Docker-Container benutzt werden. Nexus wird in diesem Beitrag zwar nur für Java-Artefakte konfiguriert, kann aber später auch als Docker-Repository oder für npm benutzt werden. Deshalb werden neben dem Port 8081, der in der Standard-Konfiguration für die Administrations-Oberfläche und als Endpunkt für Maven benutzt wird gleich weitere Port-Mappings eingeführt.

Die Konfigurationsdateien des Nexus sowie die Stores der Artefakte werden innerhalb des Containers im Verzeichnis abgelegt. Um einen Upgrade des Containers ohne Datenverlust durchführen zu können wird dieses Container-Directory über ein Docker-Volume oder, so wie hier, über ein externes Verzeichnis auf der Host-Maschine gemounted:

mkdir nexus

docker create --name nexus3 -v /nexus:/nexus-data -p 8081:8081 -p 8082:8082 -p 8083:8083 -p 8084:8084 sonatype/nexus3

docker start nexus3

Nexus als Maven-Repository

Die Standardkonfiguration des Nexus-Servers beinhaltet die für einen Maven-basierten Build-Prozess nötigen 4 Repositories:

  • Ein Proxy-Repository ermöglicht es, im Nexus nicht abgelegte Artefakte über das Internet-Repository zu laden. Damit fungiert Nexus als Cache.
  • In ein Snapshot-Repository darf ein authentifizierter Benutzer Snapshot-Artefakte ausbringen. Diese dürfen bei jedem Build-Prozess überschrieben werden, Nexus verwaltet zusätzlich eine Historie. Snapshots werden in der Regel automatisch nach Ablauf eines Verfallsdatums gelöscht.
  • Das Releases-Repository dient zur Aufnahme von echten Release-Ständen. Diese dürfen selbstverständlich nur von einem ausgewählten Personenkreis hochgeladen werden und sind nicht überschreibbar.
  • Eine Gruppe dient als zentraler Endpunkt für alle Anfragen und holt sich das angeforderte Artefakt aus den einzelnen Sub-Repositories.

Nexus Maven-Repositories

Konfiguration des Maven-Clients mit settings.xml

Zur Benutzung des Nexus-Repositories muss die Maven-Umgebung beispielsweise auf einem Entwickler-Rechner umkonfiguriert werden. Dazu werden ein oder mehrere Dateien namens settings.xml benutzt. Darin wird typischerweise konfiguriert:

  • Ein Mirror-Server. Dies ist der Endpunkt der Maven-Gruppe im Nexus.
  • Benutzer-Credentials zur Authentifizierung. Damit diese Informationen geschützt sind wird diesettings.xml im vom Betriebssystem geschützten Benutzerverzeichnis abgelegt.

Das folgende Beispiel zeigt exemplarisch eine Konfiguration mit Developer-Credentials, die einen Upload in das Snapshot-Repository des Nexus ermöglichen:

<settings>
  <mirrors>
    <mirror>
      <!--This sends everything else to /public -->
      <id>nexus</id>
      <mirrorOf>*</mirrorOf>
      <url>http://10.72.2.55:8081/repository/maven-public/</url>
    </mirror>
  </mirrors>
  <profiles>
    <profile>
      <id>nexus</id>
      <!--Enable snapshots for the built in central repo to direct -->
      <!--all requests to nexus via the mirror -->
      <repositories>
        <repository>
          <id>central</id>
          <url>http://central</url>
          <releases><enabled>true</enabled></releases>
          <snapshots><enabled>true</enabled></snapshots>
        </repository>
      </repositories>
     <pluginRepositories>
        <pluginRepository>
          <id>central</id>
          <url>http://central</url>
          <releases><enabled>true</enabled></releases>
          <snapshots><enabled>true</enabled></snapshots>
        </pluginRepository>
      </pluginRepositories>
    </profile>
  </profiles>
  <activeProfiles>
    <!--make the profile active all the time -->
    <activeProfile>nexus</activeProfile>
  </activeProfiles>

<servers>
    <server>
      <id>nexus</id>
      <username>developer</username>
      <password>developer</password>
    </server>
  </servers>
</settings>

Konfiguration des Maven-Buildprozesses mit einer Parent-POM

Um über den Maven-Buildprozess ein Artefakt ausbringen zu können, müssen neben dem Mirror in der settings.xml die Distribution-Settings innerhalb des POM definiert werden. Dies geschieht am Einfachsten über ein Parent-POM:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>org.javacream.training</groupId>
	<artifactId>org.javacream.training.maven.parent.java</artifactId>
	<version>1.0-java8</version>
	<packaging>pom</packaging>
	<dependencies>
	<dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    	<scope>test</scope>
      </dependency>
	
	</dependencies>
	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-dependency-plugin</artifactId>
				<executions>
					<execution>
						<id>copy-dependencies</id>
						<phase>package</phase>
						<goals>
							<goal>copy-dependencies</goal>
						</goals>
						<configuration>
							<outputDirectory>${project.build.directory}/libs</outputDirectory>
							<overWriteReleases>false</overWriteReleases>
							<overWriteSnapshots>false</overWriteSnapshots>
							<overWriteIfNewer>true</overWriteIfNewer>
						</configuration>
					</execution>
				</executions>
			</plugin>

			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.1</version>
				<configuration>
					<source>1.8</source>
					<target>1.8</target>
				</configuration>
			</plugin>
		</plugins>
	</build>
	<distributionManagement>
		<repository>
			<uniqueVersion>false</uniqueVersion>
			<id>nexus</id>
			<name>Corporate Repository</name>
			<url>http://10.72.2.55:8081/repository/maven-releases/</url>
			<layout>default</layout>
		</repository>
		<snapshotRepository>
			<uniqueVersion>true</uniqueVersion>
			<id>nexus</id>
			<name>Corporate Snapshots</name>
			<url>http://10.72.2.55:8081/repository/maven-snapshots/</url>
			<layout>legacy</layout>
		</snapshotRepository>
	</distributionManagement>
</project>

Für eigene Build-Prozesse genügt es damit, diesen Parent anzugeben, um Snapshot-Artefakte in den konfigurierten Nexus auszubringen.

Benutzung von Nexus in Java-Seminaren

Mit den oben genannten Konfigurationen kann in der Umgebung der Integrata ein fertig eingerichteter Nexus-Server benutzt werden. Dieser ist gemäß der obigen Ausführungen konfiguriert. Allerdings dürfen von Teilnehmern nur Snapshots gebaut und hochgeladen werden. Diese werden auch automatisch nach Seminarende gelöscht. Referenten dürfen mit eigenen Settings auch Releases bauen, die dazu notwendigen Credentials werden jedoch nur intern vergeben.

Um die notwendigen Dateien zu erhalten, genügt es den Server  http://10.72.2.55 aufzurufen. Es erscheint eine Seite mit Links auf die settings.xml und das Parent-POM. Referenten benutzen die Seite http://10.72.2.55/referent, die nach Authentifizierung ebenfalls einen Download der settings.xml ermöglicht.

Weiterlesen