Skip to content

Python3 - Popen und seine Geheimnisse ;)

Python3
1 1 232
  • Eine der letzten Baustellen in meinem Tool Restic UI war die Funktion zum Mounten eines Restic Backups.

    Das grĂ¶ĂŸte Problem dabei war, das dieser Prozess nicht beendet wird sonder offen bleibt. Das kennt ihr, wenn ihr das schon mal ĂŒber die Konsole gemacht habt, dann erscheint das folgende

    reading repository password from stdin
    repository 6859cd64 opened successfully, password is correct
    Now serving the repository at /home/frank/m5
    When finished, quit with Ctrl-c or umount the mountpoint.
    

    Jetzt kann man in meinem Tool das Passwort mittlerweile abspeichern oder wahlweise auch jedes mal eingeben. Aber, was mache ich wenn das Passwort falsch eingegeben wurde? Ich habe tagelang versucht, die Fehler abzufangen, das geht aber meiner Meinung nach nicht, da der Prozess am Laufen ist. Was machen?

    Ich habe so ziemlich jede Seite im Netz zum Thema Popen durch 😉 Nichts davon brachten den gewĂŒnschten Erfolg.

    Ok, fangen wir von vorne an, was sagt die Dokumentation von Restic?

    EXIT STATUS
    ===========
    
    Exit status is 0 if the command was successful, and non-zero if there was any error.
    

    Gut, wenn ich den richtigen Fehlercode nicht abfangen kann, dann kann ich evt. ermitteln ob der Prozess lĂ€uft oder einen Fehler ausgibt. Das wĂŒrde mir zu mindestens helfen, den User zu informieren.

    Bei den hunderten von Webseiten, hatte ich irgendwo was ĂŒber p.poll() aufgeschnappt. Das steht in der Python Dokumentation.

    Popen.poll()

    Check if child process has terminated. Set and return returncode attribute. Otherwise, returns None.
    

    Das sollte fĂŒr meinen Zweck ausreichend sein. Erster Versuch

    # no passwd in backup_data? Ok, we ask for one
    if len(backup_data[row].password) == 0:
        pwd = get_password(self) ## pwd ('1234', True)
        if pwd[1] is False:
            return False
    
    try:
        cmd = ['restic',
                                        '-r',
                                        backup_data[row].repository,
                                        'mount',
                                        mount_path]
        
       
        # We create the object, here with stdin and open the asynchronous subprocess
        p1 = subprocess.Popen(cmd,stdin=subprocess.PIPE,stderr=subprocess.PIPE) 
        p1.stdin.write(pwd[0].encode()))
        p1.stdin.close()
    
    except Exception:
        pass
    
    finally:
        try:
            if p1.poll() == 1:                          
                 raise Exception("The Restic mount command was not successful. Probable cause: wrong password or no key found")
            else:
                msg_box(self, "Successful mount of the Repository!")    
        except Exception as e:
            msg_box_error(self, repr(e))
    

    Ich hoffe man versteht was ich hier mache.

    • Wir holen uns das Passort ĂŒber eine Usereingabe
    • Wir bauen den Restic Befehl cmd
    • Wir starten den subprocess.Popen
    • Wir senden das Passwort auf stdin
    • Wir schließen stdin
    • In finally machen wir den p1.poll() und werten diesen aus.

    Bei den vielen, vielen, super vielen Test war mir aufgefallen, das das klappte.

    p1.poll() gab einmal None aus und einmal eine 1

    None war ein laufender Prozess, also erfolgreich gemountet.
    Eine 1 war ein Fehler, hier falsche Passwort Eingabe.

    Nach einigen weiteren Tests, ging es auf einmal nicht mehr. Ich wusste aber ganz genau, das es ging, ich konnte das in der Konsole noch lesen. Also meine Kontrollausgaben. Was war passiert. Eine halbe Stunde GrĂŒbeln und ich kam zu der Überzeugung, das muss ein Zeitproblem sein. Ok, also eine Bremse 🙂 einbauen. Im finally vor dem try kommt das rein.

    print("POLL", p1.poll()) 
    import time
    time.sleep(1.0)
    

    Kleine Kontrollausgabe, wir importieren das Modul time (ja, gehört nicht an diese Stelle, ich weiß...) und dann lassen wir den Prozess 1 Sekunde pausieren. Wir geben hier jetzt dem subprocess die Gelegenheit, das falsche Passwort zu erkennen und den richtigen Exit Status zu setzen. Und Bingo es ging so wie ich es mir vorgestellt hatte. đŸ€“

    Wieder extrem viel gelernt.

    Hinweis

    Der Code oben ist nur ein Ausschnitt, ich hoffe das er nachvollziehbar ist. Wenn nicht einfach hier drunter kommentieren, es gibt das dann in lang 😉

    FĂŒr Profis, die evt. hier mal drĂŒber stolpern. Ich nehme jede Verbesserung gerne auf und probiere es auch aus.

    WĂŒnsche mir eigentlich immer noch, das ich die Ausgabe

    Fatal: wrong password or no key found
    

    vernĂŒnftig abfangen und weiterverarbeiten kann. So wie mit

    output = process.stdout
    

    bei einem subprocess.run.


1/1

12. Aug. 2021, 15:43


  • 0 Stimmen
    1 BeitrÀge
    222 Aufrufe
    Niemand hat geantwortet
  • 0 Stimmen
    2 BeitrÀge
    569 Aufrufe
    Ich habe den Sonntag mal genutzt um ein wenig was einzubauen. Einmal habe ich mit datatables.net die Tabelle etwas funktionaler gestaltet. [image: 1736705735786-00a95363-1f41-4bbf-884a-34f21aea81e4-grafik.png] Man kann nun suchen, sortieren und wenn man mehr als 10 Datenpunkte hat, hat die Tabelle auch Pagination. Ein nettes Projekt, macht einiges einfacher Das nĂ€chste, ich hatte es im Video ja kurz erwĂ€hnt, mir fehlte ja noch die Restore Funktion von Restic. Ok, ist jetzt auch drin. Da die Benutzerverwaltung mittlerweile komplett eingebaut ist, werde ich demnĂ€chst meine Test Datenbanken und alles was damit zu tuen hat, aus dem Code entfernen. Brauch ich jetzt nicht mehr. Habe jetzt zwei Benutzer, einen Produktiven und einen zum Testen. Langfristig steht auch noch eine zweite Sprache auf dem Zettel. Aber, dafĂŒr muss ich Lust haben, das Thema juckt nicht so richtig
  • Restic v0.16.2

    Linux restic linux 30. Okt. 2023, 19:29
    0 Stimmen
    1 BeitrÀge
    168 Aufrufe
    Niemand hat geantwortet
  • Restic UI - Stand Februar 2023

    PyWebIO restic-ui 5. Feb. 2023, 13:22
    0 Stimmen
    5 BeitrÀge
    360 Aufrufe
    Und solltest Du was finden, was kaputt ist, ich freue mich immer ĂŒber Feedback
  • Restic v0.12.0 released

    Restic linux restic 14. Feb. 2021, 20:44
    0 Stimmen
    1 BeitrÀge
    256 Aufrufe
    Niemand hat geantwortet
  • Restic v0.10.0 released

    Restic restic 19. Sept. 2020, 17:31
    0 Stimmen
    2 BeitrÀge
    289 Aufrufe
    Gerade erst gelesen, man kann folgendes machen, damit es sich aktualisiert. root@debian:~# restic self-update writing restic to /usr/bin/restic find latest release of restic at GitHub latest version is 0.10.0 download SHA256SUMS download SHA256SUMS.asc GPG signature verification succeeded download restic_0.10.0_linux_amd64.bz2 downloaded restic_0.10.0_linux_amd64.bz2 saved 18378752 bytes in /usr/bin/restic successfully updated restic to version 0.10.0 root@debian:~# restic version restic 0.10.0 compiled with go1.15.2 on linux/amd64 Klasse!
  • Rest-Server aufsetzen

    Angeheftet Restic rest-server restic linu 11. Mai 2020, 15:11
    0 Stimmen
    9 BeitrÀge
    2k Aufrufe
    @FrankM Hallo Frank, vielen Dank fĂŒr deine Antwort. Die Clients greifen alle via REST-Schnittstelle auf den restic-Server zu. Da der restic-Server im append-only Modus lĂ€uft, können die Clients prinzipiell keine Snapshots entfernen, ihnen fehlt das Recht. Derzeit teste ich ein lokales, auf dem REST-Server liegendes Skript, welches per cron ausgefĂŒhrt wird. Dieses Skript stellt eine lokale Verbindung zum REPO her, also nicht ĂŒber die REST-Schnittstelle. Damit wĂŒrde erstmal das Löschen Ă€lterer Snapshots funktionieren. Vielleicht hat ja noch jemand eine andere Idee??
  • 0 Stimmen
    2 BeitrÀge
    935 Aufrufe
    So, dann mal das Ganze testen wenn man seinen Haupt-PC neu installiert hat und ein paar Daten braucht. [image: 1534692579149-img_20180819_090116_ergebnis-resized.jpg] Also, mal Restic installiert. sudo apt-get install restic Nach erfolgter Installation ein Test frank@frank-MS-7A34:~/restic$ restic version restic 0.8.3 compiled with go1.10 on linux/amd64 Geht so weit. Snapshots auflisten. restic -r sftp:rock64@IP:/home/rock64/backup snapshots Sieht dann so aus. frank@frank-MS-7A34:~$ sudo restic -r sftp:rock64@192.168.3.207:/home/rock64/backup snapshots [sudo] Passwort fĂŒr frank: rock64@192.168.3.207's password: enter password for repository: password is correct ID Date Host Tags Directory ---------------------------------------------------------------------- 7e2eddcb 2018-08-18 10:10:40 frank-MS-7A34 /home/frank/Bilder 073b7cb4 2018-08-18 14:21:17 frank-MS-7A34 /home/frank 6bc9b21b 2018-08-18 16:11:19 frank-MS-7A34 /home/frank ---------------------------------------------------------------------- 3 snapshots Snapshot wiederherstellen sudo restic -r sftp:rock64@IP:/home/rock64/backup restore latest --target /tmp/backup Hiermit stellen wir das Backup im temporĂ€ren Ordner /tmp/backup wieder her. Hat ewig gedauert, aber ging !?!?!?