Trial-Setup-Script entfernt, funktionierende Trial-URL dokumentiert
Das Script hat den Erstkonfigurationsassistenten zwar zuverlaessig uebersprungen, aber nicht das eigentliche Ziel erreicht: der Schalter ConfigWizardDone gibt nur Administrationskonsole und Admin-API frei und aktiviert keinen Testzeitraum. Ohne Lizenzschluessel bleiben IMAP, POP3 und Webmail gesperrt, damit taugt der Weg nicht fuer echten Mailbetrieb. An seiner Stelle steht jetzt ein README-Abschnitt mit der Adresse, die tatsaechlich funktioniert. Der Link im Assistenten zeigt noch auf kerio.com; GFI hat auf gfi.ai umgestellt, und alle alten Download- und Trial-Adressen leiten auf https://gfi.ai/products-and-solutions/email-and-messaging-solutions/kerioconnect/free-trial Dazu zwei Punkte zur Fehlersuche, falls ein Schluessel abgelehnt wird: error.log unterscheidet zwischen ungueltig und abgelaufen ("License is expired"), und registration.kerio.com ist nicht mehr aufloesbar, waehrend secure.kerio.com es noch ist. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
5011491067
commit
ba21a3aa7d
@@ -5,12 +5,11 @@ Werkzeuge für Kerio Connect auf der Kommandozeile.
|
||||
| Datei | Zweck |
|
||||
| --- | --- |
|
||||
| [`kerio_rename_user.py`](kerio_rename_user.py) | Benutzer umbenennen — Login-Name **und** Mailbox-Verzeichnis im Store |
|
||||
| [`kerio_trial_setup.py`](kerio_trial_setup.py) | Am Erstkonfigurationsassistenten vorbei, wenn dessen Lizenzschritt klemmt |
|
||||
| [`kerio_users_config.py`](kerio_users_config.py) | Lesen und Ändern von `users.cfg` |
|
||||
| [`kerio_common.py`](kerio_common.py) | Gemeinsame Bausteine: Admin-API-Client, Dienststeuerung |
|
||||
|
||||
Beide Scripts laufen **lokal auf dem Kerio-Server als root**, brauchen nur die
|
||||
Python-Standardbibliothek und bieten `--dry-run`.
|
||||
Das Script läuft **lokal auf dem Kerio-Server als root**, braucht nur die
|
||||
Python-Standardbibliothek und bietet `--dry-run`.
|
||||
|
||||
Getestet gegen **Kerio Connect 10.0.9 patch 2** auf Debian 12.
|
||||
|
||||
@@ -147,48 +146,55 @@ legt anschließend in der Administrationskonsole einen Alias an.
|
||||
|
||||
---
|
||||
|
||||
# Erstkonfigurationsassistent überspringen
|
||||
# Testlizenz besorgen
|
||||
|
||||
## Warum
|
||||
Der Erstkonfigurationsassistent verlangt im Schritt „Registrierte Testaktivierung"
|
||||
eine Testlizenznummer samt CAPTCHA. Der Link „Lizenznummer für Testversion
|
||||
erhalten" im Assistenten zeigt noch auf die alte `kerio.com`-Adresse und läuft
|
||||
ins Leere: GFI hat die Domain auf **`gfi.ai`** umgestellt.
|
||||
|
||||
Der Assistent verlangt im Schritt „Registrierte Testaktivierung" eine
|
||||
Testlizenznummer samt CAPTCHA. Der dokumentierte Link „Im unregistrierten Modus
|
||||
aktivieren" fehlt je nach Version oder ist im Fenster abgeschnitten, und die
|
||||
verlinkte Registrierungsseite ist seit der Übernahme durch GFI teilweise tot —
|
||||
man kommt im Assistenten nicht weiter.
|
||||
Die funktionierende Adresse — dort die E-Mail-Adresse eintragen, die Nummer kommt
|
||||
per Mail:
|
||||
|
||||
Kerio kennt dafür den Schalter `ConfigWizardDone` in `mailserver.cfg`. Steht er
|
||||
auf `1`, öffnet die Administrationskonsole den Assistenten nicht mehr.
|
||||
**<https://gfi.ai/products-and-solutions/email-and-messaging-solutions/kerioconnect/free-trial>**
|
||||
|
||||
## Was das bringt — und was nicht
|
||||
Die alten Adressen `www.gfi.com/.../kerio-connect/download` und
|
||||
`gfi.ai/.../kerio-connect/download` leiten inzwischen alle dorthin um.
|
||||
|
||||
Danach sind **Administrationskonsole und Admin-API voll nutzbar**, und dieses
|
||||
Repo lässt sich damit testen.
|
||||
Die Nummer lässt sich entweder im Assistenten eintragen oder später aus der
|
||||
laufenden Instanz heraus: **Dashboard → „Become a registered trial user"**.
|
||||
Beides braucht ausgehendes HTTPS auf Port 443.
|
||||
|
||||
**Der Mailbetrieb bleibt aber gesperrt.** Ohne Lizenzschlüssel weisen IMAP, POP3
|
||||
und Webmail jede Verbindung ab (`Server license expired` beim Client,
|
||||
`Product name does not match` im Log), und `error.log` meldet beim Start
|
||||
`No license key found`. Der Schalter überspringt nur den Dialog — er aktiviert
|
||||
keinen Testzeitraum.
|
||||
## Ohne Lizenz geht kein Mailbetrieb
|
||||
|
||||
Für echten Mailbetrieb führt kein Weg an einer Trial-Lizenznummer vorbei:
|
||||
**Dashboard → „Become a registered trial user"**, oder auf der GFI-Downloadseite
|
||||
„Try free for 30 days". Braucht ausgehendes HTTPS auf Port 443.
|
||||
Der Schalter `ConfigWizardDone` in `mailserver.cfg` überspringt zwar den
|
||||
Assistenten und gibt Administrationskonsole und Admin-API frei — er aktiviert
|
||||
aber **keinen Testzeitraum**. Ohne Lizenzschlüssel weisen IMAP, POP3 und Webmail
|
||||
jede Verbindung ab (`Server license expired` beim Client, `Product name does not
|
||||
match` im Log), und `error.log` meldet beim Start `No license key found`. Eine
|
||||
API zum Aktivieren gibt es nicht.
|
||||
|
||||
## Benutzung
|
||||
Wer den Assistenten neu durchlaufen will, setzt `ConfigWizardDone` zurück auf `0`
|
||||
oder löscht `mailserver.cfg` ganz — Kerio legt beim nächsten Start eine frische
|
||||
an. Achtung: die Domänendefinition steht in dieser Datei, die Benutzer in
|
||||
`users.cfg` sind danach verwaist.
|
||||
|
||||
```bash
|
||||
./kerio_trial_setup.py --status # Zustand anzeigen (kein root nötig)
|
||||
sudo ./kerio_trial_setup.py --skip-wizard # Assistenten überspringen
|
||||
sudo ./kerio_trial_setup.py --restore # Backup zurückspielen
|
||||
**`mailserver.cfg` und `users.cfg` dürfen nur bei gestopptem Dienst bearbeitet
|
||||
werden.** Kerio schreibt seine Konfiguration beim Beenden aus dem Speicher
|
||||
zurück und überschreibt sonst jede Änderung am laufenden Dienst.
|
||||
|
||||
## Wenn der Schlüssel abgelehnt wird
|
||||
|
||||
Lohnt ein Blick in `store/logs/error.log` — die Meldung dort unterscheidet
|
||||
zwischen ungültig und abgelaufen:
|
||||
|
||||
```
|
||||
registration.cpp: License error: Unable to set license (License is expired).
|
||||
```
|
||||
|
||||
## Der springende Punkt
|
||||
|
||||
`mailserver.cfg` darf **nur bei gestopptem Dienst** bearbeitet werden. Kerio
|
||||
schreibt seine Konfiguration beim Beenden aus dem Speicher zurück und würde eine
|
||||
Änderung am laufenden Dienst wieder überschreiben. Das gilt für `users.cfg`
|
||||
genauso — beide Scripts halten sich daran.
|
||||
Und ein DNS-Test: `registration.kerio.com` ist nicht mehr auflösbar,
|
||||
`secure.kerio.com` schon. Ein Assistent, der noch den alten Host kontaktiert,
|
||||
kann die Nummer nicht validieren.
|
||||
|
||||
---
|
||||
|
||||
@@ -197,5 +203,5 @@ genauso — beide Scripts halten sich daran.
|
||||
- [Administration API — Users](https://manuals.gfi.com/en/kerio/api/connect/admin/reference/interfacekerio_1_1jsonapi_1_1admin_1_1_users.html)
|
||||
- [Sample communication (Session.login, X-Token)](https://manuals.gfi.com/en/kerio/api/connect/admin/reference/sample_communication.html)
|
||||
- [Registering Kerio Connect (unregistered mode)](https://manuals.gfi.com/en/kerio/connect/content/registration-and-licenses/registering-kerio-connect-1134.html)
|
||||
- [Initial Wizard Settings Are Not Saving (ConfigWizardDone)](https://support.kerioconnect.gfi.com/article/114858-initial-wizard-settings-are-not-saving-in-kerio-connect)
|
||||
- [Kerio Connect Testversion (30 Tage)](https://gfi.ai/products-and-solutions/email-and-messaging-solutions/kerioconnect/free-trial)
|
||||
- [Modifying the mailserver.cfg](https://support.kerioconnect.gfi.com/en-us/article/114788-modifying-the-mailserver-cfg)
|
||||
|
||||
@@ -1,360 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Bringt eine frische Kerio-Connect-Installation am Erstkonfigurationsassistenten
|
||||
vorbei, wenn dessen Lizenzierungsschritt nicht durchlaufbar ist.
|
||||
|
||||
Hintergrund: Der Assistent verlangt im Schritt "Registrierte Testaktivierung"
|
||||
eine Testlizenznummer samt CAPTCHA. Der Link "Im unregistrierten Modus
|
||||
aktivieren" fehlt je nach Version oder ist im Fenster abgeschnitten, und die
|
||||
verlinkte Registrierungsseite ist seit der Uebernahme durch GFI teilweise tot.
|
||||
|
||||
Kerio kennt dafuer den Schalter ConfigWizardDone in mailserver.cfg. Steht er
|
||||
auf 1, oeffnet die Administrationskonsole den Assistenten nicht mehr und der
|
||||
Server laeuft 30 Tage ab Installation im unregistrierten Modus.
|
||||
|
||||
Was im unregistrierten Modus fehlt: Antivirus-Updates, ActiveSync, Greylisting,
|
||||
Hersteller-Support. Nach 30 Tagen stoppt die Engine. Benutzerverwaltung,
|
||||
Administrationskonsole und Admin-API sind nicht eingeschraenkt.
|
||||
|
||||
WICHTIG: mailserver.cfg darf nur bei gestopptem Dienst bearbeitet werden.
|
||||
Kerio schreibt seine Konfiguration beim Beenden aus dem Speicher zurueck und
|
||||
wuerde eine Aenderung am laufenden Dienst wieder ueberschreiben. Genau das
|
||||
erledigt dieses Script in der richtigen Reihenfolge.
|
||||
|
||||
Das Script muss LOKAL AUF DEM KERIO-SERVER ALS ROOT laufen.
|
||||
|
||||
Beispiele:
|
||||
|
||||
./kerio_trial_setup.py --status # nur anzeigen
|
||||
sudo ./kerio_trial_setup.py --skip-wizard # Assistenten ueberspringen
|
||||
sudo ./kerio_trial_setup.py --restore # letztes Backup zuruecksetzen
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
import sys
|
||||
import time
|
||||
from datetime import datetime, timedelta
|
||||
from pathlib import Path
|
||||
|
||||
from kerio_common import (
|
||||
DEFAULT_INSTALL_DIR,
|
||||
DEFAULT_SERVICE,
|
||||
AbortedError,
|
||||
ServiceController,
|
||||
)
|
||||
|
||||
# Kerio deaktiviert die Engine 30 Tage nach der Installation.
|
||||
TRIAL_DAYS = 30
|
||||
|
||||
BACKUP_SUFFIX = ".bak-trial-setup"
|
||||
|
||||
# <variable name="ConfigWizardDone">0</variable>
|
||||
WIZARD_PATTERN = re.compile(
|
||||
r'(<variable\s+name="ConfigWizardDone"\s*>)([^<]*)(</variable>)'
|
||||
)
|
||||
|
||||
|
||||
class ConfigFile:
|
||||
"""Liest und schreibt mailserver.cfg mit Backup."""
|
||||
|
||||
def __init__(self, path: Path) -> None:
|
||||
self.path = path
|
||||
if not path.is_file():
|
||||
raise AbortedError(
|
||||
f"'{path}' existiert nicht. Installationsverzeichnis mit "
|
||||
"--install-dir angeben."
|
||||
)
|
||||
self.text = path.read_text(encoding="utf-8")
|
||||
|
||||
# -- Lesen -------------------------------------------------------------
|
||||
|
||||
def wizard_done(self) -> str | None:
|
||||
match = WIZARD_PATTERN.search(self.text)
|
||||
return match.group(2).strip() if match else None
|
||||
|
||||
def trial_id(self) -> str | None:
|
||||
match = re.search(
|
||||
r'<variable\s+name="TrialID"\s*>([^<]*)</variable>', self.text)
|
||||
return match.group(1).strip() if match else None
|
||||
|
||||
def store_dir(self) -> str | None:
|
||||
match = re.search(
|
||||
r'<variable\s+name="StoreDir"\s*>([^<]*)</variable>', self.text)
|
||||
return match.group(1).strip() if match else None
|
||||
|
||||
# -- Schreiben ---------------------------------------------------------
|
||||
|
||||
def set_wizard_done(self, value: str = "1") -> bool:
|
||||
"""Setzt ConfigWizardDone. Gibt False zurueck, wenn schon so."""
|
||||
match = WIZARD_PATTERN.search(self.text)
|
||||
if match is None:
|
||||
raise AbortedError(
|
||||
"ConfigWizardDone steht nicht in der Konfiguration. "
|
||||
"Andere Kerio-Version? Bitte die Datei von Hand pruefen."
|
||||
)
|
||||
if match.group(2).strip() == value:
|
||||
return False
|
||||
self.text = WIZARD_PATTERN.sub(rf"\g<1>{value}\g<3>", self.text, count=1)
|
||||
return True
|
||||
|
||||
def backup(self) -> Path:
|
||||
target = self.path.with_name(self.path.name + BACKUP_SUFFIX)
|
||||
shutil.copy2(self.path, target)
|
||||
return target
|
||||
|
||||
def save(self) -> None:
|
||||
# Ueber eine temporaere Datei im selben Verzeichnis, damit die
|
||||
# Konfiguration nie halb geschrieben auf der Platte liegt.
|
||||
temp = self.path.with_name(self.path.name + ".tmp-trial-setup")
|
||||
temp.write_text(self.text, encoding="utf-8")
|
||||
shutil.copystat(self.path, temp)
|
||||
os.replace(temp, self.path)
|
||||
|
||||
|
||||
def estimate_install_date(install_dir: Path, config: ConfigFile) -> datetime | None:
|
||||
"""Schaetzt den Installationszeitpunkt.
|
||||
|
||||
Kerio fuehrt kein Installationsdatum in der Konfiguration, deshalb bleibt
|
||||
nur der Umweg ueber Zeitstempel:
|
||||
|
||||
1. der Eintrag der Paketverwaltung - am zuverlaessigsten
|
||||
2. sonst der aelteste Zeitstempel unter den Store-Unterverzeichnissen,
|
||||
die Kerio einmalig beim ersten Start anlegt
|
||||
|
||||
Verzeichnisse wie store/ selbst taugen nicht: ihr Zeitstempel wandert
|
||||
mit jeder Aenderung darin. Der Wert ist eine Schaetzung, kein Beweis.
|
||||
"""
|
||||
for package_file in (
|
||||
Path("/var/lib/dpkg/info/kerio-connect.list"),
|
||||
Path("/var/lib/dpkg/info/kerio-connect:amd64.list"),
|
||||
):
|
||||
if package_file.is_file():
|
||||
try:
|
||||
return datetime.fromtimestamp(package_file.stat().st_mtime)
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
store = Path(config.store_dir() or (install_dir / "store"))
|
||||
stamps = []
|
||||
for name in ("queue", "saas", "spamassassin", "logs"):
|
||||
path = store / name
|
||||
if path.is_dir():
|
||||
try:
|
||||
stamps.append(path.stat().st_mtime)
|
||||
except OSError:
|
||||
continue
|
||||
if stamps:
|
||||
return datetime.fromtimestamp(min(stamps))
|
||||
return None
|
||||
|
||||
|
||||
def print_status(config: ConfigFile, install_dir: Path,
|
||||
service: ServiceController) -> None:
|
||||
print("Status")
|
||||
print("------")
|
||||
print(f" Konfiguration : {config.path}")
|
||||
|
||||
running = service.is_running()
|
||||
state = {True: "laeuft", False: "gestoppt", None: "unbekannt"}[running]
|
||||
print(f" Dienst : {service.describe()} -> {state}")
|
||||
|
||||
wizard = config.wizard_done()
|
||||
if wizard == "1":
|
||||
wizard_text = "1 (Assistent wird uebersprungen)"
|
||||
elif wizard == "0":
|
||||
wizard_text = "0 (Assistent erscheint beim Oeffnen der Konsole)"
|
||||
else:
|
||||
wizard_text = f"{wizard!r} (unerwarteter Wert)"
|
||||
print(f" ConfigWizard : {wizard_text}")
|
||||
|
||||
trial = config.trial_id()
|
||||
print(f" TrialID : {trial or '(leer - unregistrierter Modus)'}")
|
||||
|
||||
license_dir = install_dir / "license"
|
||||
if license_dir.is_dir():
|
||||
entries = [e for e in license_dir.iterdir() if not e.name.startswith(".")]
|
||||
print(f" Lizenzdateien : {len(entries) or 'keine'}")
|
||||
|
||||
installed = estimate_install_date(install_dir, config)
|
||||
if installed:
|
||||
expires = installed + timedelta(days=TRIAL_DAYS)
|
||||
remaining = (expires - datetime.now()).days
|
||||
print(f" Installiert : ~{installed:%Y-%m-%d %H:%M} (geschaetzt)")
|
||||
if remaining >= 0:
|
||||
print(f" Testzeitraum : laeuft ~{expires:%Y-%m-%d} ab "
|
||||
f"(noch ~{remaining} Tage)")
|
||||
else:
|
||||
print(f" Testzeitraum : seit ~{expires:%Y-%m-%d} abgelaufen "
|
||||
"- die Engine wird deaktiviert sein")
|
||||
|
||||
|
||||
def skip_wizard(config: ConfigFile, service: ServiceController,
|
||||
args: argparse.Namespace) -> int:
|
||||
if config.wizard_done() == "1":
|
||||
print("\nConfigWizardDone steht bereits auf 1 - nichts zu tun.")
|
||||
return 0
|
||||
|
||||
service.preflight()
|
||||
|
||||
print("\nGeplante Aenderung")
|
||||
print("------------------")
|
||||
print(f" {config.path}")
|
||||
print(" ConfigWizardDone: 0 -> 1")
|
||||
print(f" Backup nach : {config.path.name}{BACKUP_SUFFIX}")
|
||||
print(f" Dienst : {service.describe()} (stoppen, aendern, starten)")
|
||||
|
||||
if args.dry_run:
|
||||
print("\n--dry-run: es wurde nichts geaendert.")
|
||||
return 0
|
||||
|
||||
if not args.yes:
|
||||
print("\nAchtung: der Kerio-Dienst wird dabei kurz gestoppt.")
|
||||
if input("Jetzt durchfuehren? [j/N] ").strip().lower() not in ("j", "ja", "y", "yes"):
|
||||
print("Abgebrochen.")
|
||||
return 1
|
||||
|
||||
print()
|
||||
was_running = service.is_running()
|
||||
service.stop()
|
||||
|
||||
try:
|
||||
# Erst nach dem Stoppen neu einlesen: Kerio hat die Datei beim
|
||||
# Beenden zurueckgeschrieben, unsere Kopie von vorhin ist veraltet.
|
||||
fresh = ConfigFile(config.path)
|
||||
backup = fresh.backup()
|
||||
print(f" Backup: {backup}")
|
||||
|
||||
if not fresh.set_wizard_done("1"):
|
||||
print(" ConfigWizardDone stand nach dem Stoppen schon auf 1.")
|
||||
else:
|
||||
fresh.save()
|
||||
print(" ConfigWizardDone auf 1 gesetzt.")
|
||||
except (AbortedError, OSError) as exc:
|
||||
print(f"\nFEHLER: {exc}", file=sys.stderr)
|
||||
if was_running:
|
||||
service.start()
|
||||
return 2
|
||||
finally:
|
||||
if was_running:
|
||||
service.start()
|
||||
|
||||
# Gegenlesen: haelt der Wert, nachdem Kerio wieder laeuft?
|
||||
time.sleep(2)
|
||||
check = ConfigFile(config.path)
|
||||
if check.wizard_done() != "1":
|
||||
print("\n WARNUNG: Der Wert steht nach dem Start nicht mehr auf 1. "
|
||||
"Lief der Dienst beim Schreiben doch noch?", file=sys.stderr)
|
||||
return 2
|
||||
|
||||
print("\nFertig. Die Administrationskonsole oeffnet den Assistenten nicht mehr.")
|
||||
print("Kerio laeuft im unregistrierten Modus - 30 Tage ab Installation.")
|
||||
return 0
|
||||
|
||||
|
||||
def restore(config_path: Path, service: ServiceController,
|
||||
args: argparse.Namespace) -> int:
|
||||
backup = config_path.with_name(config_path.name + BACKUP_SUFFIX)
|
||||
if not backup.is_file():
|
||||
raise AbortedError(f"Kein Backup gefunden: {backup}")
|
||||
|
||||
print(f"\nStellt '{backup}' nach '{config_path}' wieder her.")
|
||||
if args.dry_run:
|
||||
print("--dry-run: es wurde nichts geaendert.")
|
||||
return 0
|
||||
if not args.yes:
|
||||
if input("Jetzt zuruecksetzen? [j/N] ").strip().lower() not in ("j", "ja", "y", "yes"):
|
||||
print("Abgebrochen.")
|
||||
return 1
|
||||
|
||||
print()
|
||||
was_running = service.is_running()
|
||||
service.stop()
|
||||
try:
|
||||
shutil.copy2(backup, config_path)
|
||||
print(f" Wiederhergestellt aus {backup}")
|
||||
finally:
|
||||
if was_running:
|
||||
service.start()
|
||||
return 0
|
||||
|
||||
|
||||
def parse_args(argv: list[str]) -> argparse.Namespace:
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Kerio Connect am Erstkonfigurationsassistenten vorbeibringen.",
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
epilog=__doc__,
|
||||
)
|
||||
parser.add_argument("--install-dir", default=DEFAULT_INSTALL_DIR,
|
||||
help=f"Kerio-Installationsverzeichnis "
|
||||
f"(Standard: {DEFAULT_INSTALL_DIR})")
|
||||
parser.add_argument("--service-name", default=DEFAULT_SERVICE,
|
||||
help=f"Name des Kerio-Dienstes (Standard: {DEFAULT_SERVICE})")
|
||||
parser.add_argument("--service-manager", default="auto",
|
||||
choices=("auto", "systemd", "initd", "none"),
|
||||
help="Wie der Dienst gestoppt wird")
|
||||
parser.add_argument("--service-wait", type=int, default=90,
|
||||
help="Sekunden Wartezeit aufs Stoppen (Standard: 90)")
|
||||
|
||||
action = parser.add_mutually_exclusive_group()
|
||||
action.add_argument("--status", action="store_true",
|
||||
help="Nur den Zustand anzeigen (Standard)")
|
||||
action.add_argument("--skip-wizard", action="store_true",
|
||||
help="ConfigWizardDone auf 1 setzen")
|
||||
action.add_argument("--restore", action="store_true",
|
||||
help="Konfiguration aus dem Backup zuruecksetzen")
|
||||
|
||||
parser.add_argument("--dry-run", action="store_true",
|
||||
help="Nur anzeigen, was passieren wuerde")
|
||||
parser.add_argument("--yes", action="store_true",
|
||||
help="Rueckfrage ueberspringen")
|
||||
|
||||
args = parser.parse_args(argv)
|
||||
|
||||
if (args.skip_wizard or args.restore) and not args.dry_run and os.geteuid() != 0:
|
||||
parser.error(
|
||||
"Zum Aendern der Konfiguration werden root-Rechte benoetigt. "
|
||||
"Mit sudo starten (oder --dry-run zum Testen)."
|
||||
)
|
||||
return args
|
||||
|
||||
|
||||
def main(argv: list[str]) -> int:
|
||||
args = parse_args(argv)
|
||||
install_dir = Path(args.install_dir)
|
||||
config_path = install_dir / "mailserver.cfg"
|
||||
|
||||
service = ServiceController(
|
||||
name=args.service_name,
|
||||
mode=args.service_manager,
|
||||
wait_seconds=args.service_wait,
|
||||
dry_run=args.dry_run,
|
||||
)
|
||||
|
||||
try:
|
||||
if args.restore:
|
||||
return restore(config_path, service, args)
|
||||
|
||||
config = ConfigFile(config_path)
|
||||
print_status(config, install_dir, service)
|
||||
|
||||
if args.skip_wizard:
|
||||
return skip_wizard(config, service, args)
|
||||
return 0
|
||||
except AbortedError as exc:
|
||||
print(f"\nFEHLER: {exc}", file=sys.stderr)
|
||||
return 2
|
||||
except PermissionError as exc:
|
||||
print(f"\nFEHLER: Keine Berechtigung: {exc}\nMit sudo starten.", file=sys.stderr)
|
||||
return 2
|
||||
except KeyboardInterrupt:
|
||||
print("\nAbgebrochen.", file=sys.stderr)
|
||||
return 130
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main(sys.argv[1:]))
|
||||
Reference in New Issue
Block a user