Nochmal "apt-get ... " starten innerhalb der control-Skripts eines .deb-Installers ... [Gelöst]

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
jmar83
Beiträge: 962
Registriert: 20.06.2013 20:20:15
Wohnort: CH
Kontaktdaten:

Nochmal "apt-get ... " starten innerhalb der control-Skripts eines .deb-Installers ... [Gelöst]

Beitrag von jmar83 » 01.12.2020 16:14:19

Hallo zusammen

Weiss jemand von euch, wie und ob das irgendwie geht? Scheinbar lässt sich "apt-get upgrade" in diesen control-Skripts ausführen, alles andere (wie z.b. install, remove, purge, clean, autoremove) nicht. (Na ja, das ist mir vorher schon aufgefallen, also nix neues)

Mein Problem ist folgendes:

Egal ob man nun den prod. (domain.net) Server oder den zum Testen/Entwickeln (domain.li) in der Datei `/etc/apt/sources.list/UnsereSoftware.list` eingetragen hat soll nach dem ausführen des Befehls "apt-get install UnsereSoftware" nochmal erneut nachgefragt werden (siehe viewtopic.php?f=27&t=179437 ) ob nun vom domain.net (prod) oder domain.li (test/dev) die SW geholt werden soll. Anschliessend wird der Eintrag in der Datei `/etc/apt/sources.list/UnsereSoftware.list` verändert und dann noch mal ein `apt-get update` gemacht.

Und: In der Datei `/etc/apt/sources.list/UnsereSoftware.list` wird ein "Marker" auf der lezten Zeile abgelegt (`# ... `), damit das keine Endlos-Schleife gibt.

Nur kriege ich es nicht hin, innerhalb des ersten "apt-get install UnsereSoftware" dann noch mal das gleiche (nach der Anpassung) zu starten. ("apt-get update" klappt wie gesagt problemlos)

- `exit` oder `exit 0` füher in der postinst dazu, dass die installation als abgeschlossen betrachtet wird
- den apt-Prozess über kill oder killall abzutöten klappt ebenfalls nicht, die nächste Zeile im Skript kommt dann nicht an die Reihe. Des weiteren kommt beim erneusten Installationsversucht die Meldung ich müsse was über dpkg reparieren.
- Einfach nochmal "apt-get install UnsereSoftware" (ohne was explizit abzubrechen) klapp auch nicht: Da kommt irgend ne Meldung mit "sub-process" oder so.
- Mit Prozess-Forks zu arbeiten ist auch nicht ganz trivial


Aktuell sieht die preinst-Datei so aus:

Code: Alles auswählen

# J.M., 2020-12-01 {
if ! grep -q '# ... ' /etc/apt/sources.list.d/raspi.list; then
  PS3='Bitte APT-Repository für die Installation wählen: ';
  options=("1.) Verwende UnsereSoftware.li als APT-Repo = Development / Test" "2.) Verwende UnsereSoftware.net als APT-Repository = Produktiv / Release");
  USE_PROD=$(cat /dev/null);
  select opt in "${options[@]}";
  do
    case $opt in
      *"1"*)
        echo "Verwende UnsereSoftware.li als APT-Repository = Development / Test";
        USE_PROD="0";
        break;
          ;;
      *"2"*)
        echo "Verwende UnsereSoftware.net als APT-Repository = Produktiv / Release";
        USE_PROD="1";
        break;
          ;;
      *)
        echo "Ungültige Wahl: $REPLY";
        exit -1;
          ;;
      esac;
  done;
  set -x;
  if [ "$USE_PROD" == "0" ]; then
    sed -i "s/UnsereSoftware.net/UnsereSoftware.li/" /etc/apt/sources.list.d/raspi.list;
    echo "UnsereSoftware.li wurde als APT-Repository ausgewählt ... ";
  else
    if [ "$USE_PROD" == "1" ]; then
      sed -i "s/UnsereSoftware.li/UnsereSoftware.net/" /etc/apt/sources.list.d/raspi.list;
      echo "UnsereSoftware.net wurde als APT-Repository ausgewählt ... ";
    fi;
  fi;
  echo "# ... " >> /etc/apt/sources.list.d/raspi.list;
  
  apt-get update ||:;
  apt-get clean && apt-get autoremove --purge;
  #killall -9 apt-get ||:;  
  #apt-get install --yes --force-yes UnsereSoftware;
  exit 0;
fi;
# } J.M., 2020-12-01


...das "exit 0" macht im preinst keinen Stress - wenn Exit-Code 0 dann geht's zur Installation über.

Ich weiss, dass meine Anforderungen "etwas speziell" tönen, aber die INstallation soll quasi idiotensicher sein. ;-)

Vielen DAnk für die Feedbacks
Zuletzt geändert von jmar83 am 26.01.2021 14:22:03, insgesamt 1-mal geändert.
Freundliche Grüsse, Jan

jmar83
Beiträge: 962
Registriert: 20.06.2013 20:20:15
Wohnort: CH
Kontaktdaten:

Re: Nochmal "apt-get ... " starten innerhalb der control-Skripts eines .deb-Installers (prerm, postrm, preinst, postinst

Beitrag von jmar83 » 01.12.2020 16:17:32

Nachtrag: Die Entscheidung ob prod. oder test/dev dient später auch dazu um das .ini-File korrekt zu definieren - ob der Cloud-Server von welchem unser System pollt der prod- oder der dev/test-Server sein soll.

Also quasi 2 Fliegen mit einer Klappe... ;-)
Freundliche Grüsse, Jan

jmar83
Beiträge: 962
Registriert: 20.06.2013 20:20:15
Wohnort: CH
Kontaktdaten:

Re: Nochmal "apt-get ... " starten innerhalb der control-Skripts eines .deb-Installers (prerm, postrm, preinst, postinst

Beitrag von jmar83 » 01.12.2020 16:19:28

Ab hier crasht's

Code: Alles auswählen

apt-get clean && apt-get autoremove --purge;
  #killall -9 apt-get ||:;  
  #apt-get install --yes --force-yes UnsereSoftware;
  exit 0;
Freundliche Grüsse, Jan

jmar83
Beiträge: 962
Registriert: 20.06.2013 20:20:15
Wohnort: CH
Kontaktdaten:

Re: Nochmal "apt-get ... " starten innerhalb der control-Skripts eines .deb-Installers (prerm, postrm, preinst, postinst

Beitrag von jmar83 » 01.12.2020 16:21:39

Wahrscheinlich ist das gar nicht möglich mit APT, so wie's aussieht?

Evtl. besser auf APT verzichten und "wget http://.../blabla.deb" sowie "dpkg -i blabla.deb" verwenden? Das hätte man wenigstens unter Kontrllelr ganz im Ggs. zum APT-Zeugs...
Freundliche Grüsse, Jan

JTH
Moderator
Beiträge: 3077
Registriert: 13.08.2008 17:01:41
Wohnort: Berlin

Re: Nochmal "apt-get ... " starten innerhalb der control-Skripts eines .deb-Installers (prerm, postrm, preinst, postinst

Beitrag von JTH » 01.12.2020 17:15:31

Das kann aus guten Gründen nicht funktionieren. Du wirst aus einem Maintainerskript (postinst etc.) heraus nie, nie, nie erneut apt(-get) install und auch nicht dpkg -i aufrufen können.

Ein Maintainerskript wird ja gerade schon ausgeführt, wenn du die Installation eines Pakets per apt oder „manueller“ per dpkg angestoßen hast – im Hintergrund läuft in beiden Fällen ein dpkg-Prozess. Während der Installation ist aber die Datenbank von dpkg für Änderungen von zweiten dpkg-Prozessen gesperrt. Eine zusätzlich gestartete Installation scheitert also sofort. Zwei gleichzeitig laufende Installationen würden den ganzen Ablauf völlig unvorhersagbar machen.

Für deine Problemstellung scheint mir ein alleinstehendes Skript – außerhalb eines .debs – sinnvoller, das ausschließlich, nach Auswahl prod/dev, den sources.list-Eintrag anlegt und dann meinetwegen die Installation anstößt.

Für eine Frage während der Installation eines Pakets gibt es z.B. debconf, das lässt sich aber auch ohne lösen. Mit Hilfe der Antworten könntest du dann z.B. deine Ini generieren.

jmar83 hat geschrieben: ↑ zum Beitrag ↑
01.12.2020 16:14:19
- den apt-Prozess über kill oder killall abzutöten klappt ebenfalls nicht, die nächste Zeile im Skript kommt dann nicht an die Reihe. Des weiteren kommt beim erneusten Installationsversucht die Meldung ich müsse was über dpkg reparieren.
Klar. Die Maintainerskripte laufen als Kindprozesse von apt bzw. dem von apt gestarteten dpkg. Wenn du den Elternprozess killst, killst du das postinst mit, brichst also die komplette Installation in einem beliebig inkonsistenten Zustand ab. Halleluja. (Wie kommt man auf die Idee? ;) )
Manchmal bekannt als Just (another) Terminal Hacker.

jmar83
Beiträge: 962
Registriert: 20.06.2013 20:20:15
Wohnort: CH
Kontaktdaten:

Re: Nochmal "apt-get ... " starten innerhalb der control-Skripts eines .deb-Installers (prerm, postrm, preinst, postinst

Beitrag von jmar83 » 01.12.2020 17:46:19

"Halleluja. (Wie kommt man auf die Idee? ;) )"

Vielen Dank für die Klarstellung!! :THX: Manchmal versuche ich kreativ sein sein, klappt aber nicht immer.. ;-)

Hatte schon von Anfang nicht allzu viel Zuversicht was das Thema betrifft - dachte aber versuche es trotzdem mal.

Was noch was sein könnte (?):

Irgendwohin muss das Zeugs ja entpackt werden - wohl zuerst in ein temp. Verzeichnis bevor es ins Zielverzeichnis (bei uns /opt/...) kopiert wird. Eigentlich könnte man über `debconf` die Frage stellen was man nun installieren will und je nach Auswahl das .deb-File vom APT-Repo-Server herunterladen und in dieses temp. Verzeichnis entpacken? (Dann würde prod. mit dev/test oder vice versa überscreiben werden) Anschliessend kopiert der Installer die Dateien vom temp. Verzeichnis ins def. Verzeichnis unter /opt/...

Theoretisch möglich, oder ist in diesem temp. Verzeichnis was gelockt und/oder werden Hash-Signaturen angelegt welche bei den neuen Dateien (durch welche die alten überschrieben wurden) dann (teilweise) nicht mehr übereinstimmen?

** bastel, bastel *** ;-)
Freundliche Grüsse, Jan

JTH
Moderator
Beiträge: 3077
Registriert: 13.08.2008 17:01:41
Wohnort: Berlin

Re: Nochmal "apt-get ... " starten innerhalb der control-Skripts eines .deb-Installers (prerm, postrm, preinst, postinst

Beitrag von JTH » 01.12.2020 20:13:03

jmar83 hat geschrieben: ↑ zum Beitrag ↑
01.12.2020 17:46:19
Irgendwohin muss das Zeugs ja entpackt werden - wohl zuerst in ein temp. Verzeichnis bevor es ins Zielverzeichnis (bei uns /opt/...) kopiert wird.
Hmm, interessante Frage, habe mich grad mal ein bisschen belesen.

Nein, ein Paket wird tatsächlich nie komplett irgendwo temporär hin entpackt und dann verschoben. Ein deb-Paket enthält üblicherweise zwei Archive, ein komprimiertes control.tar und ein data.tar. Das data.tar enhält 1-zu-1 den Verzeichnisbaum, wie er am Ende installiert wird (also z.B. usr/bin/foobar, usr/lib/libfoobar.so). Die Dateien aus dem data.tar werden direkt an ihren Zielort entpackt – nicht in ein temporäres Verzeichnis. Für den Fall, dass während der Installation was schiefgeht, werden gleichnamige, ältere Versionen von Dateien umbenannt und solange behalten, bis ein Paket komplett installiert und konfiguriert (postinst) ist.

jmar83 hat geschrieben: ↑ zum Beitrag ↑
01.12.2020 17:46:19
und/oder werden Hash-Signaturen angelegt welche bei den neuen Dateien (durch welche die alten überschrieben wurden) dann (teilweise) nicht mehr übereinstimmen?
Jupp. Jedes Paket enhält eine md5sums-Datei aller zu installierenden Dateien, die liegt später in /var/lib/dpkg/info/PAKET.md5sums. Überprüfen, ob ein Paket noch fehlerfrei ist, kann man später mit z.B.

Code: Alles auswählen

dpkg --verify PAKET
Es ist allerdings tatsächlich nicht kritisch, wenn die Checksummen mal später nicht übereinstimmen.

Trotzdem würde ich aus Erfahrung davon abraten, so viel Manipulation an den installierten Dateien im postinst o.ä. zu machen. Das fällt einem irgendwann doch auf die Füße – und man baut sich halt zu einem gewissen Grad damit eine eigene Installationsroutine, obwohl man ja das mächtige, erprobte dpkg + apt verfügbar hätte. Ein deb-Paket sollte m.M.n. ein möglichst eindeutiges, naja, Paket sein, das seinen Inhalt nicht später möglicherweise komplett überschreibt.

Nicht ganz ungewöhnlich wäre es noch, ein relativ leeres deb-Paket zu haben und die Dateien generell erst während der Installation runterzuladen (macht z.B. Debianvirtualbox-ext-pack). Aber damit hat man auch in gewisser Weise seine eigene, dpkg-unabhängige, Installationsroutine. Wird meist aus Lizenzgründen gemacht, nicht aus technischen Gründen.

Ich würde das, was du im ersten Beitrag als preinst gepostet hast, in ein Skript packen, aus dem heraus dann sources.list für prod oder dev gefüllt wird und Paketinstallation angestoßen wird. Oder biete von vornherein zwei deb-Pakete (prod/dev) an, die dann ohne extra Benutzerfrage jeweils passende sources.lists enthalten, aber nur für Updates, nicht für ihre eigene Installation selbst.
Manchmal bekannt als Just (another) Terminal Hacker.

jmar83
Beiträge: 962
Registriert: 20.06.2013 20:20:15
Wohnort: CH
Kontaktdaten:

Re: Nochmal "apt-get ... " starten innerhalb der control-Skripts eines .deb-Installers (prerm, postrm, preinst, postinst

Beitrag von jmar83 » 01.12.2020 21:12:59

Nochmal vielen Dank!! :THX:
Freundliche Grüsse, Jan

Antworten