Erste Schritte mit BitBucket und Webhooks

In BitBucket lassen sich sogenannte Webhooks für ein Repository erstellen. Diese Webhooks melden dann dem CI Server, wenn sich was im Repository geändert hat. Ich habe meine ersten Schritte mit BitBucket und den Webhooks gemacht. Diese möchte ich hier aufschreiben.

Ein Webhook in BitBucket zu erstellen, sollte recht einfach sein. Als erstes muss man in die Einstellungen von dem gewünschten Repository gehen, in dem man die Webhooks einrichten möchte:

Dort müsste ein Button “Add Webhook” auftauchen:

Wenn man auf “Add Webhook” klickt, dann sollte ein neues Formular auftauchen, in dem man die gewünschten Einstellungen setzen kann:

Der “Title” ist hierbei frei wählbar. Unter “URL” sollte man in etwa folgendes eingeben (natürlich angepasst):

http://<url-of-jenkins>/git/notifyCommit?url=<url-of-repository>

Man sollte hier darauf achten, dass der Teil <url-of-repository> sowohl im Webhook als auch in dem entsprechendem Job in Jenkins gleich sind.

Nun muss man noch sicher stellen, dass auf Jenkinsseite alle Einstellungen korrekt sind. Wie schon erwähnt, sollte die Repository-URL gleich sein. Im Job von Jenkins sollte zu dem noch ein Haken bei Source Code Management abfragen gesetzt sein. Einen Zeitplan muss man hier jedoch nicht unbedingt setzen:


Setzt man den Haken nicht, wird kein Job gestartet und in BitBucket sieht man dann Meldungen wie diese:

No git jobs using repository: https://bitbucket.org/some-repo... and branches:  No Git consumers using SCM API plugin for: https://bitbucket.org/some-repo...

Ich hoffe, mein Post hat euch gefallen / geholfen.

Jenkins Pipeline: Werte von einem Job zum anderen übergeben

Manchmal möchte man Werte zwischen zwei Jobs weiter geben. Dies kann man mit Jenkins Pipeline recht einfach bewerkstelligen. Dazu müssen beide Jobs richtig konfiguriert sein.

Der erste Job muss die Möglichkeit haben einen zweiten Job mit Parametern zu starten. Wie hier in diesem Jenkinsfile:

pipeline {
agent any
stages {
stage("Build") {
steps {
sh "echo First job"
}
}

stage("Trigger") {
steps {
build job: 'Pipe 2', parameters: [string(name: 'VAR2', value: "somevalue2")], wait: false
}
}
}
}

Der zweite Job (hier “Pipe 2” genannt) muss die Möglichkeit haben, Parameters zu empfangen:

pipeline {
agent any
parameters {
string(name: 'VAR2', defaultValue: 'TESTING', description: '')
}
stages {
stage('Build') {
steps {
echo env.VAR2
sh "printenv"
}
}
}
}

git: error: GH007: Your push would publish a private email address.

Vor kurzem bekam ich beim Arbeiten mit git und GitHub diese Fehlermeldung:

remote: error: GH007: Your push would publish a private email address.
remote: You can make your email public or disable this protection by visiting:
remote: http://github.com/settings/emails
To https://github.com/username/some-repo-name
! [remote rejected] master -> master (push declined due to email privacy restrictions)
error: failed to push some refs to 'https://github.com/username/some-repo-name'

Ursache für diese Fehlermeldung waren zwei Punkte. Der erste Punkt ist eine bestimmte E-Mail-Einstellung auf GitHub selbst: Dort kann man einstellen, dass ein Push auf GitHub nicht erfolgt, wenn in den Metadaten die eigene E-Mail-Adresse mitgeliefert wird.

Der zweite Punkt ist die E-Mail-Konfiguration von git auf der Maschine, auf der man arbeitet. Um diese Fehlermeldung zu umgehen und trotzdem seine E-Mail-Adresse nicht zu veröffentlichen, kann man folgende Schritte tun. Als erstes konfiguriert man seine E-Mail-Adresse um. Hierbei kann man eine standardmäßige noreply-E-Mail von GitHub verwenden:

git config --global user.email "username@users.noreply.github.com"

Wichtig: Statt username in diesem Kommando sollte man seinen eigenen Benutzernamen verwenden. Nun muss man in dem lokalen git-Repository die Metadaten ändern. Das kann man durch den folgenden Befehl erreichen:

git commit --amend --reset-author

Jedenfalls musste ich danach nichts mehr machen, außer einen neuen Push zu probieren.

git push origin master

Will man aber nochmal prüfen, ob in den Metadaten jetzt die richtige, “anonyme” GitHub-E-Mail-Adresse steht, kann man folgendes Kommando ausführen:

git log --raw

Wenn es sich um ein größeres Repo handelt, kann das Log länger werden. Ich hatte jetzt nur ein kleineres Repo zu Hand, da war der Befehl kein Problem.

Azure SLQ Server mit Azure CLI erstellen

Mit Azure CLI kann man mit wenigen Kommandos einen Azure SQL Server aufsetzen.

Zuerst wird eine eine Ressourcegruppe benötigt. Diese wird mit Hilfe folgenden Kommandos erstellt:

az group create --name "rg_sqlserver_example1" --location westeurope

Den Standort und den Namen muss man gegebenenfalls anpassen. Anschließend erstellt man den SQL Server in Azure mit folgendem Kommando:

az sql server create --name "somesqlservername123" \
--resource-group "rg_sqlserver_example1" \
--location westeurope \
--admin-user "someadminname" \
--admin-password "<yourpassword>"

Auch hier sollte man die Einstellungen für die eigenen Zwecke anpassen. Wenn alles gut gegangen ist, müsste man den SQL Server auch im Portal sehen:

Anschließend kann man jetzt noch eine Datenbank erstellen:

az sql db create --resource-group "rg_sqlserver_example1" \
--server "somesqlservername123" \
--name "database_name_1"

Auch hier müsste man nach einer Weile die neu erstellte Datenbank im Portal sehen:

Es gibt auch noch andere Wege, wie man ein SQL Server in Azure aufsetzt. Mehr dazu in diesem kurzen Video (ist aber auch englisch):

LXC, LXD und “Error: not found”

Beim Lernen wie LXC und LXD funktionieren ist mir eine Meldung recht häufig aufgetreten. Das war die Fehlermeldung

Error: not found

Wie es sich herausgestellt hat, habe ich ein LXD Kommando ausgeführt und wollte das auf einen Container anwenden, den ich aber mit LXC erstellt hatte. Das führt aber zur Frage: Was ist der Unterschied zwischen LXC und LXD.

LXC ist eine Abkürzung für “Linux Container”. Sie funktioniert wie eine normale VM, jedoch mit weniger Overhead als andere Hypervisor.

LDX ist hingegen eine Erweiterung von LXC. LXD ist ein Systemdaemon und dieser verbindet sich mit libxlc, der Bibliothek, auf der LXC aufgebaut ist. Um mit dem Daemon zu kommunizieren, benutzt man eine REST API. LXD ist hierbei der neue Weg, Container zu erstellen und zu verwalten und ist eine Alternative zu den LXC Werkzeugen. Es wird abgerate, LXC und LXD gleichzeitig laufen zu lassen.

Den Unterschied zwischen LXC und LXD bemerkt man auch an den Kommandos, die man aufruft. Kommandos, die ein Bindestrich enthalten wie z.B. lxc-ls oder lxc-create sind LXC Kommandos. Kommandos ohne ein Bindestrich wie z.B. lxc info kommen von LXD.

Quellen

Kleiner Einblick in Snapshots mit LXC

Mit LXC lassen sich Snapshots von Containers erstellen. Auf diese Weise wird ein gewissen Zustand von dem System abgespeichert. Diesen kann man später nutzen, um damit einen neuen Container zu schaffen, ohne die mühselige Arbeit von Anfang an. In diesem Post will ich zeigen, wie man das mit wenigen LXC-Kommandos erreicht.

In diesem Beispiel habe ich schon einen Container namens container1 erstellt und werde ihn nun auch weiterhin verwenden. D.h. überall, wo bei mir container1 steht, solltet ihr euren Containernamen hinschreiben.

Um herauszufinden, ob ein gewählter Container schon Snapshots besitzt, findet man durch das Kommando

sudo lxc-snapshot -n container1 --list

heraus. Falls noch keine Snapshots existieren, wird hier die Meldung No snapshots auftauchen.

Bevor wir ein Snapshot erstellen, müssen wir sichergehen, dass der Container gestoppt ist, was wir mittels folgendem Kommando sehen:

sudo lxc-ls --fancy

Nur noch mal kurz zur Erinnerung: Einen LXC Container stoppt man mittels

sudo lxc-stop -n container1

Nun erstellen wir ein Snapshot von dem gewünschten Container:

sudo lxc-snapshot -n container1

Wenn alles erfolgreich gelaufen ist, müssten wir nun einen Snapshot sehen, wenn wir das Kommando

sudo lxc-snapshot -n container1 --list

aufrufen.

Snapshots des Containers container1 aufgelistet.

Um jetzt einen neuen Container aus einem bestehenden Snapshot zu schaffen, muss man folgendes Kommando aufrufen (in meinem Fall war es der Snapshot mit dem Namen snap0):

sudo lxc-snapshot -n container1 --restore snap0 --newname container2

Nun müsstet ihr einen weiteren Container sehen wenn ihr wieder alle Container auflistet. Mehr Informationen zum Thema Snapshots von LXC Containern findet man in der Dokumentation.

Erste Schritte mit LXC

In diesem Post möchte ich kurz zeigen, wie man mit LXC recht schnell einen ersten Container starten kann. Ich habe hierfür Ubuntu 18.04.2 als Hostsystem gehabt, aber auf anderen System müssten die meisten Kommandos genauso funktionieren.

Als erstes müssen wir die entsprechenden Pakete installieren:

sudo apt install lxc lxc-templates bridge-utils

Nachdem diese Pakete installiert sind, muss geprüft werden, ob alle Einstellungen OK sind. Soweit mir bekannt, kann der folgende Befehl ohne sudo ausgeführt werden.

lxc-checkconfig

Man müsste nun eine Ausgabe sehen, die in etwa so aussieht

Wenn alles gut aussieht, kann man anfangen, LXC Container zu erstellen und diese dann starten. Beim Erstellen eines Containers muss man in der Regel ein Template dazu angeben. Eine Liste der möglichen Templates findet man in dem Ordner /usr/share/lxc/templates. Die Templates werden über das apt-Paket lxc-templates installiert, was ich weiter oben aber schon getan hab.

In meinem ersten Versuch habe ich das Ubuntu-Template genommen. Um ein LXC Container zu erstellen, muss man nun diese Befehl ausführen:

sudo lxc-create -n <containername> -t <template>

In meinem Fall sah der Befehl so aus:

sudo lxc-create -n container1 -t ubuntu

Nun braucht LXC eine Weile, bis alles eingerichtet ist. Am Ende müsste man jedoch diesen Text zu sehen bekommen:

#
The default user is 'ubuntu' with password 'ubuntu'!
Use the 'sudo' command to run tasks as root in the container.
#

Bis jetzt haben wir nur einen Container erstellt. Nun müssen wir ihn zum Laufen bekommen:

sudo lxc-start -n container1

Um zu sehen, ob ein Container läuft oder nicht, sieht man mit diesem Befehl:

sudo lxc-ls --fancy

Wenn ein Container läuft, können wir uns nun mit ihm verbinden:

sudo lxc-console -n container1

Hier kommt der typische Bash-Login:

Hier bitte nicht vom Containernamen verwirren lassen 🙂

Für den Login gibt man als Benutzer ubuntu und als Passwort ebenfalls ubuntu ein (wie in der Ausgabe weiter oben beschrieben).

Hier noch eine wichtige Info: Wenn man nach dem Login irgendwann exit ausführt, wird man gleich wieder nach einem Benutzer und Passwort gefragt. Um aus der Containerumgebung wieder in die Hostumgebung zu kommen, muss man die Tastenkombination STRG+A und Q drücken. Das heißt, erst STRG+A gleichzeitig drücken und direkt danach nur Q.

lxd auf Ubuntu 18.04.2 LTS installieren

In diesem Post will ich mit ein paar Stichpunkten beschreiben, wie man lxd auf Ubuntu 18.04.2 LTS installiert. Da es sich bei mir um die Server Version handelt, musste ich am Ende nicht so viel manuell machen.

Für die, die nicht wissen was lxd ist: lxd ist eine Software um Container zu verwalten. In diesem Fall um Linux Container.

Der erste Schritt besteht also darin, lxd zu installieren:

$ sudo apt install lxd

Anschließend wird ZFS installiert. Dies ist sinnvoll, weil die Container mit ZFS die Copy-on-Write-Funktionalität nutzen und dadurch schneller werden:

$ sudo apt install zfsutils-linux

Nachdem die Pakete lxd und zfsutils-linux installiert worden sind, müsste man in der neu angelegten Gruppe lxd sein. Damit diese Änderung aber aktiv wird, muss man sich neu einloggen. Anschließend muss man nur noch das Kommando

$ sudo lxd init

aufrufen. Nun wird man einige Dinge gefragt. In meinem Fall habe ich die Standardwerte so gelassen wie sie sind, nur bei dem Namen für den Storagepool habe ich einen anderen genommen:

$ sudo lxd init
Would you like to use LXD clustering? (yes/no) [default=no]:
Do you want to configure a new storage pool? (yes/no) [default=yes]: yes
Name of the new storage pool [default=default]: lxd-pool
Name of the storage backend to use (btrfs, dir, lvm, zfs) [default=zfs]:
Create a new ZFS pool? (yes/no) [default=yes]:
Would you like to use an existing block device? (yes/no) [default=no]:
Size in GB of the new loop device (1GB minimum) [default=15GB]:
Would you like to connect to a MAAS server? (yes/no) [default=no]:
Would you like to create a new local network bridge? (yes/no) [default=yes]:
What should the new bridge be called? [default=lxdbr0]:
What IPv4 address should be used? (CIDR subnet notation, “auto” or “none”) [default=auto]:
What IPv6 address should be used? (CIDR subnet notation, “auto” or “none”) [default=auto]:
Would you like LXD to be available over the network? (yes/no) [default=no]:
Would you like stale cached images to be updated automatically? (yes/no) [default=yes]
Would you like a YAML "lxd init" preseed to be printed? (yes/no) [default=no]:

Das sollte es eigentlich gewesen sein.

findstr: Die Zeile darüber ausgeben

Manchmal hat man Probleme ähnlich wie dieses hier: Man möchte nicht die gesuchte Zeile in einer Datei ausgeben, sondern die Zeile darüber. Und das Ganze soll mit einem Batch-Skript ausgeführt werden. Für dieses Problem habe ich mir einer Testdatei erstellt, die in etwas so aussieht:

123
abc
234
qwe
345
qwe
456
abc

Alle Zeilen, die über dem gesuchten String abc stehen, sollen ausgegeben werden, also

123
456

Das habe ich anschließend in einem Batch-Skript realisiert. Ich hoffe, die Kommentare hierfür sind ausreichend:

@echo off
SetLocal EnableDelayedExpansion

rem set initial values for the variables
set index=0
set "previous_line="
set "current_line="

rem Iterate over file, line by line
For /F "tokens=*" %%L in (array_data2.txt) do (
set "previous_line=!current_line!"
set "current_line=%%L"

rem check if current line has searched
string echo %%L| findstr /C:"abc" > nul

rem if it has searched string, print previous
rem and current line
if not errorlevel 1 (
echo !index!: !previous_line!
set /a "curr_index=index+1"
echo !curr_index!: !current_line!
echo.
)

rem add 1 to the index
set /a "index=index+1"
)

Quellen: