testing/: bisherige Testversion inkl. Erweiterungen einchecken
Erstmalig getrackt (war bisher lokal ungetrackt). Enthält gegenüber dem Root-Stand: PBSPORT, DYNROUTE/DDNS-Konfig, zfs_replace()/wait_replace() für Resilver-Abwarten vor Shutdown, BatchMode SSH, write_zsync_config()- Anpassungen (Snapshot-Label-Präfix, checkzfs_spool_maxage).
This commit is contained in:
1 parent
1619f22f18
commit
d83c3113f8
5 files changed
+1315
No files matched your search
@@ -0,0 +1,91 @@
|
||||
#!/usr/bin/env python3
|
||||
import os, sys, subprocess, logging, time, tempfile, shutil
|
||||
from pathlib import Path
|
||||
from datetime import datetime
|
||||
|
||||
# === Logging Setup ===
|
||||
SCRIPT_NAME = Path(sys.argv[0]).stem
|
||||
LOGFILE = f"/var/log/{SCRIPT_NAME}.log"
|
||||
logging.basicConfig(
|
||||
filename=LOGFILE,
|
||||
level=logging.INFO,
|
||||
format='[%(asctime)s] %(message)s',
|
||||
datefmt='%Y-%m-%d %H:%M:%S'
|
||||
)
|
||||
console = logging.StreamHandler()
|
||||
console.setLevel(logging.INFO)
|
||||
formatter = logging.Formatter('[%(asctime)s] %(message)s', '%Y-%m-%d %H:%M:%S')
|
||||
console.setFormatter(formatter)
|
||||
logging.getLogger().addHandler(console)
|
||||
|
||||
def log(msg):
|
||||
logging.info(msg)
|
||||
|
||||
# === Config Loader ===
|
||||
import yaml
|
||||
|
||||
CONFIG = {}
|
||||
def load_config(path):
|
||||
global CONFIG
|
||||
if not os.path.isfile(path):
|
||||
log(f"ERROR: Config file not found: {path}")
|
||||
sys.exit(1)
|
||||
with open(path) as f:
|
||||
CONFIG = yaml.safe_load(f)
|
||||
log("Config loaded successfully")
|
||||
|
||||
# === SSH / SCP Wrappers ===
|
||||
def rssh(cmd, port=None, host=None):
|
||||
port = port or CONFIG.get('SOURCEPORT', 22)
|
||||
host = host or CONFIG.get('SOURCEHOST')
|
||||
ssh_cmd = ["ssh", "-o", "BatchMode=yes", "-o", "ConnectTimeout=10", "-p", str(port), f"root@{host}"] + cmd
|
||||
return subprocess.run(ssh_cmd, capture_output=True, text=True)
|
||||
|
||||
def rscp(local, remote, port=None, host=None):
|
||||
port = port or CONFIG.get('SOURCEPORT', 22)
|
||||
host = host or CONFIG.get('SOURCEHOST')
|
||||
scp_cmd = ["scp", "-P", str(port), local, f"root@{host}:{remote}"]
|
||||
return subprocess.run(scp_cmd)
|
||||
|
||||
# === Beispiel-Funktionen 1:1 ===
|
||||
def get_sourcehostname():
|
||||
if not CONFIG.get('SOURCEHOSTNAME'):
|
||||
log(f"SOURCEHOSTNAME empty, retrieving from {CONFIG['SOURCEHOST']}...")
|
||||
result = rssh(["hostname"])
|
||||
CONFIG['SOURCEHOSTNAME'] = result.stdout.strip()
|
||||
log(f"Detected SOURCEHOSTNAME: {CONFIG['SOURCEHOSTNAME']}")
|
||||
|
||||
def shutdown_now():
|
||||
if CONFIG.get('SHUTDOWN', 'no').lower() == 'yes':
|
||||
# Hier würde Python wait_replace() aufrufen, send_piggyback() etc.
|
||||
log("Shutdown requested. Would execute now...")
|
||||
else:
|
||||
log("No shutdown requested.")
|
||||
|
||||
# === Weitere Funktionen nach Bash ===
|
||||
# zfs_replace(), wait_replace(), write_zsync_config(), run_zsync(),
|
||||
# run_remote_updates(), send_piggyback(), run_pbs_backup(), etc.
|
||||
|
||||
# === Main Execution ===
|
||||
def main():
|
||||
import argparse
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("-c", "--config", help="Path to config")
|
||||
parser.add_argument("function", nargs='?', help="Run specific function")
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.config:
|
||||
load_config(args.config)
|
||||
|
||||
if args.function:
|
||||
func = globals().get(args.function)
|
||||
if func:
|
||||
func()
|
||||
else:
|
||||
log(f"Function {args.function} not found")
|
||||
sys.exit(1)
|
||||
else:
|
||||
# Full backup run
|
||||
log("Running full backup...")
|
||||
# Full run calls all functions like in Bash
|
||||
# wait(), set_dynamic_route(), write_zsync_config(), run_zsync(), etc.
|
||||
Reference in new issue
Block a user