Add Email-Forwarder watch container

This commit is contained in:
DonVoo 2026-07-05 22:09:53 +02:00
parent 88e82286d8
commit ba53f8bb19
5 changed files with 36 additions and 10 deletions

View file

@ -21,7 +21,10 @@ import (
// //
// name = Konto-Name oder "all". watch = true -> Delta-Schleife bis Abbruch // name = Konto-Name oder "all". watch = true -> Delta-Schleife bis Abbruch
// (Cutover-Fenster), sonst einmaliger Durchlauf. // (Cutover-Fenster), sonst einmaliger Durchlauf.
func RunMigration(name string, watch bool) error { func RunMigration(name string, watch bool, interval time.Duration) error {
if interval <= 0 {
interval = 60 * time.Second
}
for { for {
var accounts []Account var accounts []Account
var err error var err error
@ -32,21 +35,29 @@ func RunMigration(name string, watch bool) error {
a, err = GetAccount(name) a, err = GetAccount(name)
accounts = []Account{a} accounts = []Account{a}
} }
if err != nil { if err != nil && !watch {
return err return err
} }
for _, a := range accounts { if err != nil {
if !a.Active { log.Printf("watch load accounts failed: %v", err)
continue } else {
} for _, a := range accounts {
if err := migrateAccount(a); err != nil { if !a.Active {
return err continue
}
if err := migrateAccount(a); err != nil {
if !watch {
return err
}
log.Printf("watch migration failed for %s: %v", a.Name, err)
}
} }
} }
if !watch { if !watch {
return nil return nil
} }
time.Sleep(60 * time.Second) log.Printf("watch sleeping %s", interval)
time.Sleep(interval)
} }
} }

View file

@ -31,6 +31,7 @@ install -m0644 "$APP_DIR/Containerfile" "$APP_DIR/build/Containerfile"
podman build -t "$IMAGE_NAME" -f "$APP_DIR/build/Containerfile" "$APP_DIR/build" podman build -t "$IMAGE_NAME" -f "$APP_DIR/build/Containerfile" "$APP_DIR/build"
podman rm -f "${WATCH_CONTAINER_NAME:-email-forwarder-watch}" >/dev/null 2>&1 || true
podman rm -f "$CONTAINER_NAME" >/dev/null 2>&1 || true podman rm -f "$CONTAINER_NAME" >/dev/null 2>&1 || true
podman pod rm -f "$POD_NAME" >/dev/null 2>&1 || true podman pod rm -f "$POD_NAME" >/dev/null 2>&1 || true
podman pod create --name "$POD_NAME" --network "$NETWORK" -p "$HOST_BIND:$APP_PORT:$APP_PORT" >/dev/null podman pod create --name "$POD_NAME" --network "$NETWORK" -p "$HOST_BIND:$APP_PORT:$APP_PORT" >/dev/null
@ -40,6 +41,14 @@ podman run -d --name "$CONTAINER_NAME" --pod "$POD_NAME" \
-v "$APP_DIR/backup:/app/backup:Z" \ -v "$APP_DIR/backup:/app/backup:Z" \
"$IMAGE_NAME" >/dev/null "$IMAGE_NAME" >/dev/null
if [ -n "${WATCH_ACCOUNT:-}" ]; then
podman run -d --name "${WATCH_CONTAINER_NAME:-email-forwarder-watch}" --pod "$POD_NAME" \
--restart=unless-stopped \
-v "$APP_DIR/data:/app/data:Z" \
-v "$APP_DIR/backup:/app/backup:Z" \
"$IMAGE_NAME" --run "$WATCH_ACCOUNT" --watch --watch-interval "${WATCH_INTERVAL:-60s}" >/dev/null
fi
for _ in {1..20}; do for _ in {1..20}; do
if curl -fsS "http://$HOST_BIND:$APP_PORT/" >/dev/null 2>&1; then if curl -fsS "http://$HOST_BIND:$APP_PORT/" >/dev/null 2>&1; then
echo "Email-Forwarder reachable at http://$HOST_BIND:$APP_PORT/" echo "Email-Forwarder reachable at http://$HOST_BIND:$APP_PORT/"

View file

@ -5,6 +5,7 @@ set -a
source ./config.env source ./config.env
set +a set +a
podman rm -f "${WATCH_CONTAINER_NAME:-email-forwarder-watch}" >/dev/null 2>&1 || true
podman rm -f "$CONTAINER_NAME" >/dev/null 2>&1 || true podman rm -f "$CONTAINER_NAME" >/dev/null 2>&1 || true
podman pod rm -f "$POD_NAME" >/dev/null 2>&1 || true podman pod rm -f "$POD_NAME" >/dev/null 2>&1 || true
echo "Runtime removed. Persistent data kept at $APP_DIR/data and $APP_DIR/backup" echo "Runtime removed. Persistent data kept at $APP_DIR/data and $APP_DIR/backup"

View file

@ -1,10 +1,13 @@
SERVICE_NAME=Email-Forwarder SERVICE_NAME=Email-Forwarder
POD_NAME=email-forwarder-pod POD_NAME=email-forwarder-pod
CONTAINER_NAME=email-forwarder CONTAINER_NAME=email-forwarder
WATCH_CONTAINER_NAME=email-forwarder-watch
IMAGE_NAME=localhost/email-forwarder:test IMAGE_NAME=localhost/email-forwarder:test
NETWORK=base-net NETWORK=base-net
HOST_BIND=127.0.0.1 HOST_BIND=127.0.0.1
APP_PORT=8087 APP_PORT=8087
WATCH_ACCOUNT=codex-to-vdevop03
WATCH_INTERVAL=60s
BUILD_SRC=/mnt/DATA/Build/Email-Forwarder BUILD_SRC=/mnt/DATA/Build/Email-Forwarder
DEVOP_CONTAINER=DevOp-Pod-build DEVOP_CONTAINER=DevOp-Pod-build
APP_DIR=/mnt/DATA/Containers/Test-Container/Email-Forwarder-Pod APP_DIR=/mnt/DATA/Containers/Test-Container/Email-Forwarder-Pod

View file

@ -7,6 +7,7 @@ import (
"log" "log"
"net/http" "net/http"
"os" "os"
"time"
"emailforwarder/backend" "emailforwarder/backend"
) )
@ -17,6 +18,7 @@ var frontend embed.FS
func main() { func main() {
runOnce := flag.String("run", "", "einen Umzugs-Job einmalig ausfuehren (Konto-Name oder 'all'), ohne Web-UI") runOnce := flag.String("run", "", "einen Umzugs-Job einmalig ausfuehren (Konto-Name oder 'all'), ohne Web-UI")
watch := flag.Bool("watch", false, "Delta-Sync in Schleife bis Stop (Cutover-Fenster)") watch := flag.Bool("watch", false, "Delta-Sync in Schleife bis Stop (Cutover-Fenster)")
watchInterval := flag.Duration("watch-interval", 60*time.Second, "Pause zwischen Watch-Durchlaeufen")
seedAccount := flag.String("seed-account", "", "Konto aus lokaler JSON-Datei in die DB schreiben (nur CLI/Test)") seedAccount := flag.String("seed-account", "", "Konto aus lokaler JSON-Datei in die DB schreiben (nur CLI/Test)")
checkAccount := flag.String("check-account", "", "Konto-Logins pruefen und INBOX zaehlen, ohne zu kopieren") checkAccount := flag.String("check-account", "", "Konto-Logins pruefen und INBOX zaehlen, ohne zu kopieren")
flag.Parse() flag.Parse()
@ -42,7 +44,7 @@ func main() {
// CLI-Modus: ohne Web laufen lassen (Cronjob / Cutover). // CLI-Modus: ohne Web laufen lassen (Cronjob / Cutover).
if *runOnce != "" { if *runOnce != "" {
must(backend.RunMigration(*runOnce, *watch)) must(backend.RunMigration(*runOnce, *watch, *watchInterval))
return return
} }