Hyper Backup Script für Backup mit rsync erstellen

Woolfgang359

Benutzer
Mitglied seit
17. Nov 2010
Beiträge
106
Punkte für Reaktionen
14
Punkte
18
Hallo,
nachdem HyperBackup für meine Zwecke ausgeschieden ist möchte ich mit rsync ein Backup-Script (*.sh) erstellen, welches die freigegebenen Ordner auf die USB Platte sichert. Das ist grundsätzlich kein Problem. Was ich aber bräuchte ist, dass ein eventuell erstelltes Fehlerprotokoll per Mail versendet wird.

(( Bitte hier keine Fragen wieso HyperBackup nicht passt.
Wenn es jemanden interessiert gibt es diesen Beitrag mit Post #16
https://www.synology-forum.de/threa...e-eigenartiges-verhalten.136921/#post-1216848 ))

Zum Thema:
Kann jemand sagen, welches Script Kommando eine Datei per Mail versendet?
Ich würde abfragen ob eine Fehlerdatei vorhanden ist und wenn ja, dann an den MailClient zum Versenden
den Empfänger, Betreff, Nachrichtentext und Beilage übergeben..
Bei meiner DS224+ habe ich den MailClient eingerichtet und das DSM kann Mails versenden.
Aber was gebe ich im Script an. Ich kenne den jeweiligen Befehl nicht.
Alles andere um ein gescheites rsync Script zu erstellen wäre vermutlich nicht das Problem.
Ist zwar schon 20 Jahre her als ich Linux Admin war, aber Fahrrad fahren verlernt man ja auch nicht. :D

PS: Und falls jemand bereits ein funktionierendes Script als Vorlage hätte, dann wäre ich auch froh über die ersparte Lebenszeit. :)

Danke!
Wolfgang
 

Tommes

Benutzer
Sehr erfahren
Maintainer
Mitglied seit
26. Okt 2009
Beiträge
9.820
Punkte für Reaktionen
1.781
Punkte
314
Hi!

Da ich grad unterwegs bin, kann ich dir den Code zum versenden einer Mail grad nicht geben, da ich diesen zunächst aus meinen eigenen Scripten herauslösen müsste. Aber in jedem Fall ist hier ssmtp am Werk, soviel kann ich schon mal sagen.

Falls du dir aber Zeit und Mühe für die eigene Scripterstellung ersparen möchtest, kannst du gerne mal einen Blick auf mein CLI-Backup-Tool jarss werfen. Das Script verschickt primär zwar keine Protokolle per Email, wenn du das Script jedoch über den DSM-Aufgabenplaner ausführst kann dir das Protokoll darüber zugeschickt werden. Dafür musst du natürlich die passende Option im Aufgabenplaner aktivieren. Sobald ich wieder zu Hause bin, kann ich dir das genauer erklären, falls Interesse besteht.
 

Woolfgang359

Benutzer
Mitglied seit
17. Nov 2010
Beiträge
106
Punkte für Reaktionen
14
Punkte
18
Wau.... super, danke ! (y)
JA, bitte das würde mir sehr helfen. Vor allem Zeit zu sparen.
Jeder Softwareentwickler weiß, dass der Code schnell geschrieben ist, aber das Testen aller Eventualitäten, sodass es wirklich fehlerfrei funktioniert, und dieses und jenes Problem abgefangen wird, wie etwa falsche Parameterübergabe, zu wenig Platz im Ziel, ausgeworfene USB-Platte und vieles mehr, das ist der Aufwand.
Ich schaue mir inzwischen den Link an den du mitgesendet hast.
Den Code zum Versenden einer Mail benötige ich dann sowieso.
Das Backup wird nicht das Einzige sein wo ich das brauche.
DANKE !!
:)
 
Zuletzt bearbeitet:

Tommes

Benutzer
Sehr erfahren
Maintainer
Mitglied seit
26. Okt 2009
Beiträge
9.820
Punkte für Reaktionen
1.781
Punkte
314
Dir steht es natürlich frei, mein Script an deine eigenen Bedürfnisse anzupassen bzw. zu erweitern. Ich hätte sicherlich noch ein paar weitere Codeschnipsel für dich, um z.B. die UUID eines USB-Datenträgers auszulesen um darüber sicherzustellen, das das Backup immer auf dem richtigen Datenträger landet. Vieles von dem habe ich in meinem mittleren stillgelegten Paket Basic Backup implementiert gehabt. Mein CLI-Script jarss zielt aber eher darauf ab, auf so gut wie jedem unixoiden Betriebssystem lauffähig zu sein, daher sind viele DSM spezifische Dinge weggefallen. Und nein… ich werde das nicht wieder in jarss implementieren.

Bis später
 
  • Like
Reaktionen: maxblank und Benie

Woolfgang359

Benutzer
Mitglied seit
17. Nov 2010
Beiträge
106
Punkte für Reaktionen
14
Punkte
18
Super Script von dir, so wie es sein soll. Danke!
Für mich noch ein Send Mail rein und ich bin zufrieden.

Ich habe in Windows ein robocopy Script. Alle Sicherungsziele müssen von mir explizit eingerichtet werden. Denn dort muss sich immer eine bestimmte Dummy-Datei befinden. Dann weiß das Script, dass die Übergabeparameter und das Ziellaufwerk stimmen. Und nur dann geschieht die Sicherung dort hin. Sonst Fehlermeldung. So mache ich es, damit das Script mit einfachen Befehlen funktioniert und überall lauffähig ist.
Nicht gerade für den Verkauf bestimmt (haha....) aber das läuft seit 15 Jahren auf Win-Server (als redundante Sicherung zur windowseigenen Sicherung) und auf Win-Clients fehlerfrei. :D
 

Tommes

Benutzer
Sehr erfahren
Maintainer
Mitglied seit
26. Okt 2009
Beiträge
9.820
Punkte für Reaktionen
1.781
Punkte
314
Hier das (absolut rudimentäre) Mail-Script.

Bash:
#!/bin/bash

# Die E-Mail Adresse des Absenders (emailto) muss gleich der im DSM unter
# Hauptmenü > Systemsteuerung > Benachrichtigung > E-Mail angegebenen
# Absenderadresse sein. Ansonsten wird keine E-Mail zugestellt.
emailto="name1@email.tld"
emailfrom="name2ſemail.tld"
tempfile="/tmp/tempfile.tmp"

echo "To: ${emailto}" > ${tempfile}
echo "From: ${emailfrom}" >> ${tempfile}
echo "Subject: Testmail" >> ${tempfile}
echo "" >> ${tempfile}
echo "Lorem ipsum dolor sit amet, consetetur sadipscing elitr" >> ${tempfile}
echo "" >> ${tempfile}
ssmtp "${emailto}" < ${tempfile}
 

Woolfgang359

Benutzer
Mitglied seit
17. Nov 2010
Beiträge
106
Punkte für Reaktionen
14
Punkte
18
Danke, es funktioniert!
Jetzt kommt es mir auch bekannt vor. Ich habe vor 25 Jahren auf RedHat oder HP Unix "sendmail" verwendet.

Kann man die Mailadresse nicht gleich aus dem DSM auslesen? Vermutlich nicht, wird irgendwo in einer proprietären Synology Datenbank stehen.
Damit ist schon ein Fehler vorprogrammiert. Denn wenn ich irgendwann in 1 Jahr dort im DSM die Mailadresse ändere, dann müsste ich diese im Script auch anpassen. Sonst glaube ich die Datensicherung ist immer fehlerfrei, dabei wird nur kein Error.log gesendet. Ich glaube nicht, dass dann jemand daran denkt.
Da werde ich dann wohl eine wöchentliche Kontrollmail senden müssen um zu sehen, dass es funktioniert. Ist vielleicht grundsätzlich eh nicht schlecht das zu machen. :)

Falls du weißt ob man eine Datei als Attachment dazufügen kann würde mich das interessieren. Aber ich kann schon selbst im Web schauen. Nur falls du weißt, dass es nicht geht, dann wäre eine Info gut, weil ich dann nicht umsonst suche.
(Nachtrag: Habe schon etwas gefunden, scheint etwas komplizierter zu sein. Da muss ich nochmal genauer schauen.)

Danke für deine Unterstützung!
 
Zuletzt bearbeitet:

Tommes

Benutzer
Sehr erfahren
Maintainer
Mitglied seit
26. Okt 2009
Beiträge
9.820
Punkte für Reaktionen
1.781
Punkte
314
Kann man die Mailadresse nicht gleich aus dem DSM auslesen?
Klar!
Bash:
# Absender
synogetkeyvalue /usr/syno/etc/synosmtp.conf smtp_from_mail
# Empfänger
synogetkeyvalue /usr/syno/etc/synosmtp.conf eventmails

Falls du weißt ob man eine Datei als Attachment dazufügen kann würde mich das interessieren.
Jein!
Bash:
# Fügt den Dateiinhalt der Email hinzu...
file="/[PFAD]/[ZUR]/[DATEI]/[DATEINAME.EXT]"
cat "${file}" >> "{$tempfile}"

Einen Dateianhang mitzuschicken, müsste ich selbst nochmal nachschauen, wie das ging... sollte aber auch möglich sein.
 
  • Like
Reaktionen: Woolfgang359

Woolfgang359

Benutzer
Mitglied seit
17. Nov 2010
Beiträge
106
Punkte für Reaktionen
14
Punkte
18
Textfile in Mailtext anhängen kenne ich, danke. Ich meinte Dateianhang. Brauchst aber nicht schauen. Ich brauche es derzeit nicht und es ist mit MIME dann vermutlich etwas komplizierter.

Danke, du hast mir sehr geholfen!
 

Woolfgang359

Benutzer
Mitglied seit
17. Nov 2010
Beiträge
106
Punkte für Reaktionen
14
Punkte
18
@Tommes
Da du dich mit Synology spezifischen Dingen gut auskennst, weißt du evtl. wo ich die Namen der freigegebenen Ordner auslesen kann? Ich möchte nämlich in meinem Script alle Freigaben sichern. Und wenn ich später eine neue Freigabe anlege soll diese automatisch mitgesichert werden. Ich will nicht erst im Script die Freigabe einfügen müssen. Das wäre eine Fehlerquelle die ich vermeiden möchte. Okay, ich könnte es als Übergabeparameter machen, aber auch hier darf ich nicht vergessen. Im Web finde ich nichts bzw. kommen nur Infos innerhalb des DSM und nicht die Info wie ich auf der Konsole die Namen der Freigaben auslesen kann.
Danke ! Wolfgang :)

Nachtrag: Ich sehe du machst das über eine Konfig Datei. Also Übergabeparameter. Ja, werde ich auch so machen. In meiner Windows-Sicherung arbeite ich ja auch so.

(Aus /etc/samba/smb.share.conf könnte man es theoretisch auslesen.)
:unsure:
 
Zuletzt bearbeitet:

Tommes

Benutzer
Sehr erfahren
Maintainer
Mitglied seit
26. Okt 2009
Beiträge
9.820
Punkte für Reaktionen
1.781
Punkte
314
weißt du evtl. wo ich die Namen der freigegebenen Ordner auslesen kann?
Auch das... jedoch würde ich die freigegebenen Ordner über ein Script auslesen wollen, anstatt mir dir Daten aus irgendeiner Config-Datei auszulesen. Das nachfolgende Script wirft dir alle internen freigegebenen Ordner aus, jedoch keine externen Datenträger (/volumeUSB und /volumeSATA).

Bash:
#!/bin/bash

while IFS= read -r volume; do
    [[ -z "${volume}" ]] && continue

    while IFS= read -r share; do
        [[ -z "${share}" ]] && continue

        if [[ "${share}" == /volumeUSB* || "${share}" == /volumeSATA* ]]; then
            continue
        else
            echo "${share}"
        fi

    done <<< "$( find ${volume}/* -type d ! -path '*/lost\+found' ! -path '*/\@*' ! -path '*/\$RECYCLE.BIN' ! -path '*/Repair' ! -path '*/System Volume Information' -maxdepth 0 )"
done <<< "$( find /volume* -maxdepth 0 -type d )"
unset volume share
 

Woolfgang359

Benutzer
Mitglied seit
17. Nov 2010
Beiträge
106
Punkte für Reaktionen
14
Punkte
18
Danke, ja, ich sehe das mittlerweile auch so.
Ich werde das lediglich für einen Hinweis verwenden, falls ein Freigabeordner vorhanden ist, aber nicht gesichert wird.
(Natürlich in der Konfig abschaltbar, falls ich das explizit so haben will.)

PS: Dein Script hilft mir echt gut mit Code-Schnippsel, um das was ich mittlerweile vergessen habe wieder aufzufrischen. Danke!
 

Tommes

Benutzer
Sehr erfahren
Maintainer
Mitglied seit
26. Okt 2009
Beiträge
9.820
Punkte für Reaktionen
1.781
Punkte
314

Woolfgang359

Benutzer
Mitglied seit
17. Nov 2010
Beiträge
106
Punkte für Reaktionen
14
Punkte
18
Ahh, okay, danke für die Info. Und danke für das Nachfragen dort in dem Beitrag! :)

Ich wollte dir auch noch eine Info senden und zwar:

Du schreibst in Post #6 in den Sourcecode Zeilen:
# Die E-Mail Adresse des Absenders (emailto) muss gleich der im DSM unter
# Hauptmenü > Systemsteuerung > Benachrichtigung > E-Mail angegebenen
# Absenderadresse sein. Ansonsten wird keine E-Mail zugestellt.

Ich bin zufällig drauf gestossen (weil ich mich verschrieben hatte), dass es egal ist was bei "mailto" als auch bei "mailfrom" eingetragen wird.
Die Mail wurde immer zugestellt.
"mailto" muss nur irgendeine gültige Mailadresse haben, egal welche. Klar, sonst kann nichts zugestellt werden. Und "mailfrom" ist überhaupt nur ein Text, egal was da steht. Natürlich sollte eine brauchare Antwortadresse dort stehen.

Kann es sein, dass ssmtp immer die Postausgangsdaten des MailClients verwendet der im DSM angelegt ist, egal was man in mailto eintragt. Vielleicht war es früher anders. Aber jetzt kann man an jede beliebige Mailadresse senden.
Man braucht also nichts aus dem DSM auslesen oder die korrekte Empfängeradresse eingeben.
Ich habe z.B. als "mailto" die Adresse meiner Frau angegeben (die das DSM nicht kennt) und sie hat die Mail erhalten. Und als mailfrom habe ich testweise völlig blödsinnig einfach nur "yxz@yxz.at" eingegeben.
Das Script sendet einfach immer erfolgreich, wenn irgendeine gültige mailto-Adresse eingegeben wurde.
Oder habe ich deine Infozeilen im Script falsch interpretiert?

Ich finde das toll, dass immer gesendet wird. Ich wollte es nur mitteilen. :)
 
Zuletzt bearbeitet:
  • Like
Reaktionen: Tommes

Tommes

Benutzer
Sehr erfahren
Maintainer
Mitglied seit
26. Okt 2009
Beiträge
9.820
Punkte für Reaktionen
1.781
Punkte
314
Ich bin da ehrlich gesagt nicht up to Date was das angeht. Früher war es mal so, das die Absender Adresse gleich der DSM Konfiguration sein musste, daher habe ich das im Kommentar so erwähnt. Wenn das aktuell nicht mehr so ist um so besser.
 
  • Like
Reaktionen: Woolfgang359

DaveR

Benutzer
Sehr erfahren
Mitglied seit
30. Mrz 2022
Beiträge
383
Punkte für Reaktionen
731
Punkte
144
mailto can be any email address.

The email will always be sent by whatever email account is configured in DSM, or msmtp's or mutt's config file.

Note: If you send the email with a different from address the recipient's email program may flag the email as spam or malicious because the displayed from address does not match the from address does not match the sender's address in the email's header.

In Linux mstp's config file can be either:

Code:
/etc/msmtprc
~/.msmtprc
$XDG_CONFIG_HOME/msmtp/config

In Asustor's ADM it's:

/usr/builtin/etc/msmtp/msmtprc

By default the msmtp config file contains:

Code:
# Set default values for all following accounts.
defaults
timeout 15
tls on
tls_trust_file /usr/builtin/etc/msmtp/ca-certificates.crt
#logfile ~/.msmtplog

# The SMTP server of the provider.
#account user@gmail.com
#host smtp.gmail.com
#port 587
#from user@gmail.com
#auth on
#user user@gmail.com
#password passwd

# Set a default account
#account default: user@gmail.com

Mutt also has a config file.

In msmtp and mutt you can setup multiple email account profiles and select which one to use when you send the email.
 

Woolfgang359

Benutzer
Mitglied seit
17. Nov 2010
Beiträge
106
Punkte für Reaktionen
14
Punkte
18
Danke DaveR, ich muss mir das erst anschauen.
Vorerst noch eine andere Frage zum SicherungsScript, wo ich gerade auf der Zielgeraden bin. :D

Es gibt unzählige Prüfungen und Fehlermöglichkeiten. Diese fange ich alle ab.
Nur: Ich will dann das Progrtamm nicht einfach mit exit 1 beenden, sondern in eine Fehlerabwicklung verzweigen.
Das würde ich machen, indem das eigentliche Script in einer Endlosschleife abläuft, welche ich bei Bedarf mit break verlassen kann.
Ich meine, gibt es einen Fehler, dann verlasse ich die Schleife mit "break" und komme hinter "done" zur Fehlerabwicklung.
Und: Am Ende der Schleife, also vor dem "done" ist sowieso ein "break", damit die Schleife nur einmal durchlaufen wird, falls kein Fehler auftritt.

Sinn der Sache ist, dass ich im Fehlerfall den Programmablauf überspringen kann und sofort zur Fehlerbehandlung verzweige.
Falls es nichts gescheiteres gibt würde ich das so machen:

Code:
exit_code=0

while true
do

    DatensicherungsScript hier in der Endlosschleife

    Bei kritischem Fehler:
    errortext="ERROR: Sicherungsziel ${target} nicht gefunden!"
    exit_code=1
    break

    DatensicherungsScript weiter hier in der Endlosschleife

break   (Ein break vor dem done, damit die Schleife zwingend nur einmal durchlaufen wird)
done

Und hier dann die Fehlerbehandlung (z.B. Fehlerbericht per Mail wenn exit_code größer 0)


Oder gibt es etwas praktikableres?
 
Zuletzt bearbeitet:

DaveR

Benutzer
Sehr erfahren
Mitglied seit
30. Mrz 2022
Beiträge
383
Punkte für Reaktionen
731
Punkte
144
I translated your code to English so I could understand it while replying.

Bash:
exit_code=0

while true
do

    # Data backup script here in an endless loop

    # In case of critical error:
    errortext="ERROR: Backup target ${target} not found!"
    exit_code=1
    break

    # Data backup script continues here in the endless loop

break     # (A break before done so that the loop only runs once)
done

# And here is the error handling (e.g. error report by email if exit_code is greater than 0)

In bash I sometimes use a trap to process unexpected errors, cleanup tmp files and send an email.

The script ends with exit 0 which triggers the trap code, or I can call the cleanup function from within the code.

Bash:
# Create trap and clean up function

# Tmp logs clean up function
# shellcheck disable=SC2329
cleanup(){
    arg1=$?
    # Move tmp_error_log to error log if tmp_error_log is not empty
    if [[ -s $Tmp_Err_Log_File ]] && [[ -d $Backup_Directory ]]; then
        mv "${Tmp_Err_Log_File}" "${Err_Log_File}"
        if [[ $? -gt "0" ]]; then
            echo "WARNING Failed moving ${Tmp_Err_Log_File} to ${Err_Log_File}"\
                |& tee -a "${Err_Log_File}"
        fi
    fi
    # Delete our tmp directory
    if [[ -d $Tmp_Dir ]]; then
        rm -rf "${Tmp_Dir}"
        if [[ $? -gt "0" ]]; then
            echo "WARNING Failed deleting ${Tmp_Dir}" |& tee -a "${Err_Log_File}"
        fi
    fi

    # Log and notify of success or errors
    if [[ -f $Err_Log_File ]]; then
        # Log and notify backup had errors
        if [[ ! -f $Log_File ]]; then
            # Add script name to top of log file
            basename -- "$0" |& tee -a "${Log_File}"
        fi
        echo -e "\n\e[41mWARNING\e[0m Plex backup had errors! See error log:"
        echo -e "\nWARNING Plex backup had errors! See error log:" >> "${Log_File}"
        echo -e "$(basename -- "${Err_Log_File}")\n" |& tee -a "${Log_File}"
    else
        # Log and notify of backup success
        echo -e "\nPlex backup completed successfully" |& tee -a "${Log_File}"
    fi

    # Send log via email if both logging and emails are enabled
    if [[ $to_email_address && $from_email_address ]]; then
        echo -e "\nSending email..."
        email_contents="email_contents.txt"
        send_email "$to_email_address" "$from_email_address" "$Backup_Directory"\
            "$email_contents" "$Nas - $script log"
    fi

    exit "${arg1}"
}

trap cleanup EXIT

The send_email command calls the send_email function from from here

To capture critical errors I use:

Bash:
response=$("command arg1 arg1"  2>&1)
if [[ -n $response ]]; then
    echo -e "\nWARNING An error occurred while running command."\
    "The error was: $response\n\n" |& tee -a "${Log_File}"
fi
 
  • Like
Reaktionen: Woolfgang359

Woolfgang359

Benutzer
Mitglied seit
17. Nov 2010
Beiträge
106
Punkte für Reaktionen
14
Punkte
18
Danke für deine Info. (y)
Ich schreibe deutsch weil wir im deutschen Forum sind. :)

Ich habe mir "trap" angeschaut. Das ist die professionelle Variante um Programmabbrüche abzufangen.
Vor allem wenn es darum geht, dass nach dem unvorhergesehenen Abbruch noch Daten bereinigt werden müssen.
z.B: wenn temporäre Dateien gelöscht werden müssen und das Script nicht einfach abbrechen soll.
Eine gute Information. DANKE !

Mein Problem mit "trap" ist, dass ich ein neues Kommando dieser Komplexität erst in einem Script verwende, wenn ich es ausführlich getestet habe.
Im Internet finde ich viel Information dazu, aber es gibt immer die gleichen Beispiele.
Und ich habe so viele Fragen zu diesem Kommando, dass es mir zu umständlich ist diese in englisch zu stellen oder in einer deutschen Formulierung die der Übersetzer gut bearbeiten kann.

Bei meinem Script geht es darum, dass ich vor allem eigene Überprüfungen mache, die nicht zu einem plötzlichen Programmabbruch führen. Also wo ich im Script selbst entscheide, dass die Ausführung mit einer Fehlermeldung beendet werden soll. Das sind geplante Programmbeendigungen mit Fehlermeldung per Mail. Da funktioniert meine Variante die ich oben angegeben habe ausreichend gut. Der Vorteil ist, dass ich "while do done" gut kenne.

Im Falle eines unvorhergesehenen Programmabbruchs (z.B. duch Benutzereingriff oder durch falsche Syntax...) wäre "trap" die richtige Methode. Aber der Taskmanager im Synology DSM sendet ohnehin eine Mail, falls ein Script ungeplant abbricht. Somit bekomme ich zumindest eine Nachricht bei einem ungeplanten Systemabbruch. In meinem Fall ist eine Fehlerbehandlung (cleanup) nach einem ungeplanten Abbruch nicht erforderlich. Daher benötige ich "trap" in meinem Fall nicht.

Ich würde "trap" trotzdem verwenden, aber dann müsste ich das Kommando genau kennen.
Falls ich ein Script erstelle wo eine Fehlerbehandlung bei einem ungeplanten Abbruch erforderlich ist, dann werde ich mich mit "trap" genau beschäftigen.

Danke für deine professionelle Information! :)
 
  • Like
Reaktionen: DaveR

Woolfgang359

Benutzer
Mitglied seit
17. Nov 2010
Beiträge
106
Punkte für Reaktionen
14
Punkte
18
Als Abschluß dieses Beitrags noch eine Frage zum Aufgabenplaner.
Wenn ich das Sicherungsscript von Montag bis Samstag ausführen will, dann kann ich das im Aufgabenplaner gar nicht einstellen.
Ist das wirklich so?
Ich würde mein Sicherungs-Script nämlich Mo-Sa mit dem Parameter "ERRLOG" starten, was bei mir bedeutet, dass ich nur im Fehlerfall die LogDatei per Mail bekomme.
Am Sonntag würde ich die Sicherung mit Parameter "LOG" starten, was in meinem Script bedeutet, dass ich in jedem Fall die LogDatei per Mail bekomme.
Blöd für mich jetzt, dass man eine Aufgabe nicht einem Wochentag zuordnen kann.
Ist das wirklich so, oder stehe ich auf der Leitung?

Screenshot 2025-01-05 195904.jpg
 


 

Kaffeautomat

Wenn du das Forum hilfreich findest oder uns unterstützen möchtest, dann gib uns doch einfach einen Kaffee aus.

Als Dankeschön schalten wir deinen Account werbefrei.

:coffee:

Hier gehts zum Kaffeeautomat