Samstag, 11. Dezember 2021

FHEM auf neues System umziehen

Eigentlich ist der Weg einfach:

  1. Neues System installieren (Perl Module dokumentiert?)
  2. Altes System beenden und sichern
  3. Restore der Sicherung, Test und Start neues System
Die Downtime beim finalen Umzug soll möglichst gering sein. Punkt 3 kann, vor allem auch zur Übung, mehrfach durchlaufen werden. 

Hinweis: Es gibt zu diesem Thema auch eine aktualisierte Schritt für Schritt Anleitung.

Am Setup eines Raspberry hat sich seit 2019 bei mir nichts geändert. Aber ich habe ein paar neue Ideen getestet. Es ist gut wenn man ein Testsystem oder die neue Hardware bereits zur Vorbereitung hat! 
Will man es auf gleicher Hardware vorbereiten, sollte man sich meinen Artikel BootStick für den RaspberryPi anschauen. 

Neues System fit für mein FHEM?

Ist die Installationsdokumentation des bestehenden FHEM Systems ungenügend, kann das neu installierte System zunächst mit dem Installermodul im Developermodus zur Analyse der fhem.cfg verwendet werden. Ich habe dafür ein leicht zu verwendendes Script gebaut. Damit schafft man sich eine funktionierende und getestete Grundlage. Die zu testende config wird dafür mit scp, cp oder dem Tool seiner Wahl im HomeDir von Pi bereitgestellt. Das Script installiert auch FHEM, falls das noch nicht erfolgt ist. Das Script ist umfangreich kommentiert, ich spare mir hier eine extra Doku.

Man kann das natürlich auch von Hand machen, zunächst 

apt install apt-file libperl-prereqscanner-notquitelite-perl

Dann in FHEM den Installer definieren

define installer Installer
attr installer installerMode developer

Die fhem.cfg als Datei lokal zur Verfügung stellen und dann mit get installer checkPrereqs /Pfad/fhem.cfg die fhem.cfg überprüfen. 

Nachteil: Man bekommt nur die fehlenden Perl Module angezeigt. Mein Script ermittelt auch noch die debian Pakete (Beschreibung), damit man nicht mit cpan installieren muss, was aus meiner Sicht Nachteile hat. 

Hat man das neue System entsprechend vorbereitet und geprüft, kann man das alte System aufspielen. Entweder über ein vorhandenes FHEM Backup (Anleitung) oder direkt von System zu System wie ich im nächsten Abschnitt zeige.

Transfer über ssh

Die Verwendung von tar hat dabei den  Vorteil, dass die Übertragung schnell erfolgt und die Berechtigungen erhalten bleiben. Das Verfahren ist flexibel, man kann die Daten entweder direkt per USB Datenträger oder per ssh direkt übers Netzwerk von System A zu System B übertragen.

Diese Beispiel zeigt die Befehle in der Konsole/ssh Terminal am neuen System B:

remote=user@host
ssh $remote sudo systemctl stop fhem
sudo systemctl stop fhem
ssh $remote 'sudo tar -cf - -C /opt/fhem ./' | sudo tar -xvf - -C /opt/fhem

Eventuell vorhandene ssh Keys werden mit dem obigen Befehl für den User fhem mit übertragen. Die Server Keys und Keys anderer Benutzer kann man auch noch übertragen. Analog kann man auch für andere Dateien verfahren.

ssh $remote 'sudo tar -cf - -C / home/pi/.ssh etc/ssh' | sudo tar -xvf - -C / home/pi/.ssh --wildcards etc/ssh/ssh_host_ecdsa_*

Prinzipiell kann man auch von System A nach System B "schieben" oder komplett lokal arbeiten. Siehe Artikel Bootstick mit SD Card Reader

Erklärung zur verwendeten copy Codezeile

ssh $remote 'sudo tar -cf - -C /opt/fhem ./' | sudo tar -xvf - -C /opt/fhem

  • Der rot hinterlegte Codebereich erzeugt einen ssh Tunnel zu System A und überträgt über die Pipeline auch die kopierten Daten (den 'tarball').
  • Der grün hinterlegte Bereich wird auf dem System A ausgeführt.
  • Der blau hinterlegte Code wird auf dem System B ausgeführt.

Der Syntax für den tar Befehl ist ziemlich "filigran". Als 'Sicherungsdatei' wird hier stdOut am Ende des ssh Tunnels gepackt und am Anfang des Tunnels über stdIn wieder entpackt. Da alle Daten verarbeitet werden sollen wird im sudo Kontext gearbeitet.

Kurzbeschreibung der tar Befehle

tar -cf - -C /opt/fhem ./

  • Die Optionen stehen für: einpacken -cf , auspacken -xvf , anzeigen -tvf. 
  • Option f steht für Archivdatei und ist hier stdOut/In
  • Der Kopiervorgang erfolgt relativ zum aktuellen "Standort", dieser wird mit einem absolutem Pfadnamen -C /pfad/pfad gesetzt! 
  • Die zu packenden Daten sind entweder ein Dateiname(n) am aktuellen Standort oder ein relativer Pfadname(n) welcher komplett rekursiv eingepackt wird. Beim Auspacken kann zusätzlich zu Datei/Pfad noch den Zusatz --wildcards verwenden -> etc/ssh/ssh_host_ecdsa_*. Beim ein- und auspacken kann man mit --exclude Dateien/Pfade ausschließen.

Docker Volumes kopieren

Der Transfer mit tar funktioniert auch lokal von Volume zu Volume. 

Beispiel: docker Volume (ccu) und docker-compose Arbeitspfad (docker) zwischen dem laufendem System und einem Stick der als /dev/sda steckt. Die jeweilige Zeile für die Richtung muss aktiviert werden (Kommentarzeichen entfernen und mit erhöhten Rechten ausführen - sudo su).

dest='/mnt/dest'
mkdir -p ${dest}
mount /dev/sda2 ${dest}

for dir in '/var/lib/docker/volumes/docker_ccu_data' '/home/pi/docker'
do
  # tar -cf - -C ${dest}${dir} ./ | tar -xvf - -C ${dir} # vom USB Stick zur SD Card 
  # tar -cf - -C ${dir} ./ | tar -xvf - -C ${dest}${dir} # von der SD Card zum USB Stick  
done

umount ${dest}

Hinweis: die Docker Container sollten nicht aktiv laufen! Die Pfade (volumes) müssen existieren. Will man den Datentransfer vorm ersten Start der Container machen, muss man die Volumes mit dem docker volume create Befehl vorher anlegen. Das Volume ccu_data im compose Projekt "docker" bekommt den Namen docker_ccu_data.

Docker komplett kopieren

Angeregt durch diesen Beitrag einfach mal ausprobiert. Mit Bootstick auf dem Raspberry mit cp anstatt rsync umgesetzt:

# Bootstick mounten
dev='sda'
part=${dev}2
dest=/mnt/${part}
sudo mkdir -p ${dest}
sudo mount /dev/${part} ${dest}
# Originalzustand sichern
sudo mv ${dest}/var/lib/docker ${dest}/var/lib/docker-backup
# Docker beenden
sudo service docker stop
# Dockerinhalt kopieren
sudo cp -r /var/lib/docker ${dest}/var/lib/docker/
sudo cp -r /etc/docker ${dest}/etc/docker/
# docker compose bzw. Arbeitspfad kopieren
sudo cp -r /home/pi/docker ${dest}/home/pi/docker/
# Neustart vom Bootstick
sudo mv /boot/bootcode.bin /boot/bootcode.bak
sudo reboot

Zusätzlich kann/muss man noch weitere Einstellungen und Pfade kopieren!

ToDo

Code Block

Text

5 Kommentare:

  1. Hallo, ich habe dein Script versucht. Tolle Sache. Nur liefert das bei den Debian Paketen eine ellenlange Liste, die beim Versuch, sie zu installieren nur Fehler wirft. Kann es sein, dass das auftritt, wenn ich von einem älteren Debian zu Bullseye wechsle?

    AntwortenLöschen
    Antworten
    1. Ich werde das mal aktuell unter bullseye testen und berichten. Mit einem älteren Quellsystem hat das nichts zu tun, da ja die FHEM Voraussetzungen getestet werden. Das alte System ist ja nicht bekannt. Es kann aber sein, dass irgendwann das installer Modul nicht mehr läuft.

      Löschen
  2. Ja, das Problem habe ich auch: was soll man mit der Datei DebianPaket und PerlModul anfangen, um das System zu aktualisieren?

    AntwortenLöschen
    Antworten
    1. Das Installermodul von FHEM wirft Perl Module aus die fehlen. Anhand der Liste der fehlenden Perl Module ermittle ich die Debian Pakte die diese Module installieren würden. wie oben verlinkt gibt es einen neuen Artikel, der erklärt die Verwendung beider Dateien: https://heinz-otto.blogspot.com/2022/08/howto-fhem-umzug-von-system-nach-system.html

      Löschen
  3. Hallo Otto,
    ich habs jetzt endlich angepackt und ziehe FHEM von einem 2-Raspi auf einen 4-Raspi um. Dein Skript war super hilfreich. Vielen Dank dafür!!

    AntwortenLöschen