LoxBerry Update (für Core-Entwickler)

Updates auf dem Entwicklungssystem

Grundsätzlich LoxBerry Update auf einem Core-Entwicklungssystem ausschalten (sobald man es einschalten kann)! Jeder neue Release bügelt potentiell über eure Dateien. update_exclude.userdefined oder dryrun verwenden (siehe unten)

Alle Plugin-Verzeichnisse sind ausgeschlossen, somit beeinträchtigt das LBUpdate nicht die Plugin-Entwicklung.

Github / Neuer Release

Der Release-Tag (also nicht der Name oder die Beschreibung) darf nur Zahlen, Punkte und Underscores enthalten. Underscrores sind Entwicklungsversionen, die VOR einem Release der gleichen Versionsnummer gereiht werden.

Der Release-Tag muss immer höher sein als der vorherige (auch wenn eine kleinere Nummer bei Github geht, updatet LoxBerry dann nicht mehr). Sub-Releases (vierte Zahl) sind möglich.

Das ist die Sortierung

  • 0.3.7
  • 0.3.8
  • 0.3.8.1 (Subrelease kommt nach Hauptrelease)
  • 0.3.8.2
  • 0.3.9
  • 0.3.10 (sortiert numerisch richtig)
  • 0.3.11

Wird bei GitHub ein Release erstellt, der dieser Syntax nicht entspricht (z.B. String in Versiontag), wird der Release von LoxBerry ignoriert (nicht abgebrochen) und die Releaselist weiter abgearbeitet. 

Dem Nummernvergabeschema von Michael folgend, schlage ich folgende Nummerierung vor:

  • Die ersten drei Zahlen "gehören" Michael: Immer wenn Michael ein neues Image einer Minor macht, gibt es ein Release oder Prerelease mit 0.3.2, 0.3.3, 0.3.4 usw.
  • Jeder Release auf diesem Image basierend, bekommt dann die vierte Stelle: 0.3.4.1, 0.3.4.2, 0.3.4.2 usw.
  • Da das Update ja nicht alles austauscht, sieht man damit weiterhin, auf welchem Image ein Release basiert. Am individuellen LoxBerry eines Benutzers lässt sich allerdings nicht mehr feststellen, mit welchem Image der Benutzer gestartet hat.

Update-Routinen

loxberryupdatecheck.pl

# Schaut nach dem neuesten Prerelease
/opt/loxberry/sbin/loxberryupdatecheck.pl querytype=prerelease
 
# Schaut nach dem neuesten Release
/opt/loxberry/sbin/loxberryupdatecheck.pl querytype=release
 
# Installiert den neuesten Prerelease
/opt/loxberry/sbin/loxberryupdatecheck.pl querytype=prerelease update=1 nofork=1
 
# Für die Entwicklung der Update-Routinen:
/opt/loxberry/sbin/loxberryupdatecheck.pl querytype=prerelease update=1 keepupdatefiles=1
# Überschreibt das lokale loxberryupdate.pl, loxberryupdatecheck.pl, exclude-file NICHT durch jene aus dem Release
 
# Dryrun - Ändert nichts. Ruft loxberryupdate.pl auch mit dryrun=1 auf
/opt/loxberry/sbin/loxberryupdatecheck.pl querytype=prerelease update=1 dryrun=1
 
# Installiert den neuesten Commit
/opt/loxberry/sbin/loxberryupdatecheck.pl querytype=latest update=1
 
 
# Installiert den neuesten Commit - gaukelt ein Update auf Version 1.2.5 vor. Die general.cfg wird auch gesetzt.
/opt/loxberry/sbin/loxberryupdatecheck.pl querytype=latest update=1 release=v1.2.5
 
 

Das Update wird in /tmp/loxberryupdate/<generierterName>/ entzippt.

Bevor loxberryupdate.pl installiert wird:

  • … wird aus dem Update die loxberryupdate.pl in sbin/ kopiert und ggf. chmod +x gesetzt.
  • … wird aus dem Update die loxberryupdatecheck.pl in sbin/ kopiert und ggf. chmod +x gesetzt.
  • … wird das exclude-File aus dem Release ins config/system kopiert.
  • … auch wenn loxberryupdate.pl im neuen Release nicht mehr enthalten ist, wird in dem Fall die alte loxberryupdate.pl aus der aktuellen Version aufgerufen. So kann auch das loxberryupdate.pl selbst in einem Release umbenannt werden. 

Wird an loxberryupdate.pl, loxberryupdatecheck.pl oder dem exludefile entwickelt, dann den Parameter keepupdatefiles=1 setzen, damit diese Dateien nicht durch den Release überschrieben werden.

Andernfalls würde die Änderung (ohne Prüfung eines Timestamps) einfach aus dem Release überschrieben.

In loxberryupdatecheck.pl ist oben der Relase-Filter definiert:

my $min_version = "0.3.0";
my $max_version = "0.5.0";

Releases kleiner oder größer dieser Versionen werden ignoriert - die Releaseliste wird weiter abgearbeitet.

Bei diesem Filterbeispiel: Ein Release 0.3.0 wird installiert, ein 0.5.0 wird ebenfalls installiert.

Die erste Version, die nicht installiert wird, ist 0.5.1 oder 0.5.0.1.

Möchte man später eine höhere Version installieren lassen, muss man davor mit einem Release unter $max_version ein modifiziertes loxberryupdatecheck.pl ausliefern, das einen höheren Filter setzt.

loxberryupdatecheck.pl ist so geschrieben, dass es als Cronjob UND direkt von der Webseite ausgeführt werden kann. Für die Webseite liefert es ein json für jQuery mit Daten zum Update zurück. 

loxberryupdate.pl

Ist eigentlich nur dafür gedacht, von loxberryupdateckeck.pl ausgeführt zu werden.

Zum Debuggen kann es auch über die Commandline aufgerufen werden, wenn /tmp/loxberryupdate/ schon existiert. Dann wird auch die loxberryupdate.pl nicht überschrieben.

/opt/loxberry/sbin/loxberryupdate.pl updatedir=/tmp/loxberryupdate/<generierterName> release=0.3.10
# release ist die Zielversion! (so wird es von loxberryupdatecheck.pl ausgeführt)
 
/opt/loxberry/sbin/loxberryupdate.pl updatedir=/tmp/loxberryupdate/<generierterName> release=config
# Zum Testen, oder für Update auf Commit-Basis. Dabei wird die Zielversion aus der general.cfg des Updates ausgelesen.
 
# Dryrun
/opt/loxberry/sbin/loxberryupdate.pl updatedir=/tmp/loxberryupdate/<generierterName> release=0.3.10 dryrun=1
# Es werden keine Dateien geändert. RSync wird mit --dry-run aufgerufen, die Update-Scripts werden übersprungen, die Config-Version nicht geändert.


Vor dem eigentlichen Start des Updates wird ein Pre-Check ausgeführt. Dazu wird in sbin/loxberryupdate/ nach Dateien updateprecheck_vX.Y.Z.pl gesucht (siehe unten).

Bei rsync werden die exclude-Files /opt/loxberry/config/system/update_exclude.system und update_exclude.userdefined übergeben und somit dessen Pfade ausgeschlossen.

Das update_exclude.userdefined ist für Sachen, die der User selbst eintragen will. Das File wird nicht überschrieben.

rsync wird so aufgerufen, dass es pro Verzeichnis ein .rsync-filter File auswertet. Siehe rsync Manpage.

rsync legt ein Backup der geänderten und gelöschten Dateien an in /opt/backup.loxberry

Nach rsync werden die Update-Scripts ausgeführt.

Diese liegen in /opt/loxberry/sbin/loxberryupdate und heißen update_<maj>.<min>.<build>.<dev>.pl also z.B. update_0.3.2.pl oder update_0.3.2.1.pl.

Die Dateien werden ausgeführt in der richtigen Reihenfolge von Altversion+1 bis Neuversion. Es werden nie ältere und nie neuere Scripts ausgeführt, d.h. man kann ein neues Script im Verzeichnis schon entwickeln, bevor der Release erfolgt, ohne Gefahr, dass das Script ausgeführt wird.

Es ist kein Fehler, wenn es für einen Release kein Script gibt, d.h. die Scripts sind optional.

Ist alles erfolgreich, wird die Zielversion in die general.cfg geschrieben.

general.cfg Parameter

Gelb hinterlegt sind die Parameter, mit der man manuell das Update über die general.cfg beeinflussen kann.

Grün hinterlegt sind die Parameter, die der Benutzer auch im UI ändern kann

Parameter Mögliche Werte
Standardwert
Bedeutung
UPDATE.DRYRUN True, False (0, 1) Kein Austauschen der loxberryupdate.pl/loxberryupdatecheck.pl Dateien, kein rsync, kein Ausführen der Updatescripts, kein Updaten der Versionsnummer
UPDATE.KEEPUPDATEFILES True, False Kein Austauschen der loxberryupdate.pl/loxberryupdatecheck.pl Dateien
UPDATE.KEEPINSTALLFILESTrue, False Aufbewahren des entpackten Installationsordners in der Ram-Disk (/tmp/loxberryupdate/). Macht das Testen von Updatescripts einfacher.
UPDATE.BRANCH master, Branch von GitHub Gilt nur für 'latest'. Installiert aus dem angegebenen Branch.
UPDATE.RELEASETYPE release, prerelease, latest release, prerelease oder latest. Wird über das GUI gesetzt
UPDATE.INSTALLTYPE notify, install, disabled(?)notify, install, disabled(?). Wird über das GUI gesetzt. Bei notify wird nur gemeldet, bei install automatisch installiert. Bei was anderem wird nicht geprüft. Ich weiß nicht mehr, ob disabled wirklich disabled heißt, es wird nie auf diesen String geprüft.
UPDATE.LATESTSHA Leer, Commit-SHA von Github Information für LBUpdate bei "Latest Release", was der letzte, installierte Commit gewesen ist. Wenn der neue SHA anders ist, wird das als neuer Stand angezeigt
UPDATE.FAILED_SCRIPT Leer, Versionsnummer Merker, welche Versionsnummer eines Updatescripts fehlgeschlagen ist. Ist das gesetzt, kommt im GUI die Meldung und der Button zum Zurücksetzen der Versionsnummer.

Commandline/Querystring Parameter

Parameter Mögliche Werte
Standardwert
Bedeutung
dryrun 0, 1 Wie general.cfg.
keepupdatefiles 0, 1 Wie general.cfg
keepinstallfiles0, 1 Wie general.cfg
cron 0, 1 Ist 1, wenn der Aufruf aus dem Cronjob für automatische Updates kommt. (setzt im Script $cron=1)

Setzt implizit den Parameter querytype auf jenen in der general.cfg gesetzten.

Erzeugt und wartet bei UPDATE.INSTALLTYPE die Notification.

Installiert automatisch neue Updates entsprechend UPDATE.INSTALLTYPE
nofork 0, 1 Verwendet Michael, wenn er ein neues Image macht (weiß nicht mehr, wofür genau)

Funktioniert nicht mit 'latest'
nobackup 0, 1 Deaktiviert das Backup von rsync. Verwendet Michael, wenn er ein neues Image macht
nodiskspacecheck0, 1 Deaktiviert alle Prüfungen auf ausreichend Speicherplatz. Verwendet Michael, wenn er ein neues Image macht
querytype release, prerelease, latest Überschreibt die Einstellung aus der general.cfg
output leer, json Wenn json, ist die gesamte Ausgabe ein json-File. Wird für die Requests vom GUI verwendet.

Setzt implizit den Parameter querytype auf jenen in der general.cfg gesetzten.
update 0, 1 Ist der Parameter gesetzt, wird kein Check, sondern gleich ein Update durchgeführt. Wird aus dem GUI beim Install-Button benutzt
release Es kann eine Versionsnummer mitgegeben werden (z.B. v1.2.5). LBUpdate verhält sich so, als wäre es ein Update auf diese Version, dabei werden entsprechend die Updatescripts ausgeführt. Die general.cfg wird auf diese Version gesetzt!

Funktioniert nur mit 'latest'.
branch master, Branch von GitHubInstalliert bei querytype=latest aus dem angegebenen Branch.


Pre-Check Scripts updateprecheck_vx.y.z.pl

z.B. updateprecheck_v3.0.0.pl

Liegen in /opt/loxberry/sbin/loxberryupdate

Vor dem eigentlichen Start des Updates wird der Pre-Check ausgeführt.

Ausgeführt wird nur ein Pre-Check-Script, nach diesen Regeln:

  1. Es wird nur das neueste updateprecheck_ -Script ausgeführt.
  2. Dessen Version muss gleich oder kleiner als die gerade zu installierende Version sein.
  3. Der Check ist OK, wenn vom Script ein Errorlevel = 0 zurückgegeben wird.

Das Update bricht vollständig ab, wenn das Pre-Check-Script einen Fehler liefert.

Der Logging-Kontext wird an das Script übergeben und per use LoxBerry::Update; init(); übernommen, somit kann normal gelogged werden wie in den Update-Scripts. Das Script läuft als root.

Update-Scripts update_vx.y.z.pl

z.B. update_v1.2.0.1.pl

Liegen in  /opt/loxberry/sbin/loxberryupdate

Ein Update-Script kann ein beliebiges Perl-Script sein. Die Scripte werden als root ausgeführt.

LoxBerry::System funktioniert.

LoxBerry::Update enthält die Funktion init() (initialisiert Logfile usw.) sowie Funktionen zum Kopieren von Dateien und Ausführung von apt Paketverwaltungstasks (ab LoxBerry 2.0)

LoxBerry::System::lbversion() liefert die Altversion zurück, außer ein vorheriges Update-Script hat die Version geändert.

Um zu melden, dass dieses Update-Script einen Reboot benötigt:

  • LoxBerry::System::reboot_required("Text tum Update"); ausführen.
  • Enthält der reboot_required-Aufruf einen Text, wird zusätzlich zur Reboot-Info dieser am Reboot-Dialog (power.cgi) angezeigt.
  • Der Text wird HTML-Encoded, d.h. Leerzeilen mit \n werden korrekt umgewandelt.

Das reboot.required File liegt in der RAM-Disk, und wird zur Sicherheit (sofern dies doch keine RAM-Disk ist) in der initloxberry.sh (also beim Systemstart) gelöscht.

Mögliche Exitcodes eines Update-Scripts:

  • = 0 → kein Fehler
  • > 0 → Das Script hatte einen oder mehrere Fehler. LBUpdate speichert in dem Fall in der general.cfg unter <UPDATE.FAILED_SCRIPT> die Versionsnummer des Scripts, setzt aber beim nächsten Script fort (wenn mehrere Scripts einen Fehler haben, wird die niedrigste Script-Versionsnummer gespeichert). Das LBUpdate-WebIf zeigt beim nächsten Aufruf einen großen gelben Block, um die Version zurückzusetzen, damit der Benutzer das Update ab dem ersten Fehlerscript nochmals zu starten. Ein gesetzter Parameter FAILED_SCRIPT wird vom Healthcheck als Fehler gemeldet.
  • = 250 → Das Update-Script hat den Abbruch des Update-Script-Processing ohne Fehler angefordert. Die Version des Update-Scripts wird in die general.cfg <MAIN.VERSION> geschrieben. reboot_required wird gesetzt. reboot_force_popup wird gesetzt.  (Ab LoxBerry 2.0)
  • = 251 → Wie 250, jedoch hat das Update-Script auch einen Fehler zurückgemeldet. Zusätzlich zu 250 wird FAILED_SCRIPT gesetzt.  (Ab LoxBerry 2.0)

Die speziellen Exitcodes 250 und 251 werden benötigt, wenn ein späteres Update-Script sicher erst nach einem Reboot ausgeführt werden soll. Dies ist speziell für dist-upgrades erforderlich. Spätere Update-Scripts erwarten Binaries/Configs/Verzeichnisse/usw., die vor dem Reboot noch nicht verfügbar sind.

resetpermissions.sh

Dieses Script in /sbin setzt nach rsync die Filepermissions auf die Ordner und Dateien.

generatelegacytemplates.pl

Das Script, dass die alten Header und Footer erzeugt, wird ebenfalls aufgerufen.

Ablauf des Updates

lbhome ist /opt/loxberry (bzw. Unterverzeichnisse), release ist das temporäre Releaseverzeichnis

  1. Das Update wird heruntergeladen und nach /tmp/zipname/ (release) entpackt
  2. Wenn vorhanden, werden loxberryupdatecheck.pl und loxberryupdate.pl ins lbhomedir kopiert
  3. Das exclude-file wird ins lbhome kopiert (wenn nicht vorhanden→die)
  4. Release wird chown loxberry:loxberry gesetzt
  5. Pre-Check Script wird ausgeführt
  6. Release wird mit rsync in lbhome kopiert
  7. resetpermissions.sh wird ausgeführt
  8. Update-Scripts werden ausgeführt
  9. Legacytemplates werden aktualisiert
  10. general.cfg wird auf die neue Version gesetzt


Testaufrufe

In der general.cfg gibt es zwei Parameter unter [UPDATE] zum Testen:

KEEPUPDATEFILES=1 überschreibt beim Update loxberryupdate.pl und loxberryupdatecheck.pl NICHT. Alles andere wird normal durchgeführt. 

DRYRUN=1 überschreibt die Updatefiles nicht, führt rsync ohne Schreiben aus, verhindert die Update-Scripts und ändert die general.cfg nicht (d.h. kein wirkliches Update).