From 422dfaec6f1cb6c4a135634a896b138fe67eb2e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rados=C5=82aw=20Gierwia=C5=82o?= Date: Mon, 12 Aug 2024 10:30:00 +0200 Subject: [PATCH] Add core Docker2PBS class and compose parsing - Basic class structure with configuration handling - Docker compose file loading and validation - Service configuration extraction - Command line argument parsing --- docker2pbs.py | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 docker2pbs.py diff --git a/docker2pbs.py b/docker2pbs.py new file mode 100644 index 0000000..b4ac355 --- /dev/null +++ b/docker2pbs.py @@ -0,0 +1,81 @@ +#!/usr/bin/env python3 +""" +Docker Compose to Proxmox Backup Server +Backup script that reads docker-compose.yaml, extracts service configuration, +stops the service, creates backup on PBS, and restarts the service. +""" + +import argparse +import sys +import os +import subprocess +import yaml +import json +from pathlib import Path +from datetime import datetime +from typing import Dict, List, Any, Optional + + +class Docker2PBS: + def __init__(self, compose_file: str, service_name: str, pbs_config: Dict[str, str], dry_run: bool = False): + self.compose_file = Path(compose_file) + self.service_name = service_name + self.pbs_config = pbs_config + self.dry_run = dry_run + self.compose_data = None + self.service_config = None + self.volumes = [] + self.networks = [] + + def load_compose_file(self) -> None: + """Load and parse docker-compose.yaml file""" + if not self.compose_file.exists(): + raise FileNotFoundError(f"Docker compose file not found: {self.compose_file}") + + with open(self.compose_file, 'r') as f: + self.compose_data = yaml.safe_load(f) + + if 'services' not in self.compose_data: + raise ValueError("No 'services' section found in docker-compose.yaml") + + if self.service_name not in self.compose_data['services']: + available_services = list(self.compose_data['services'].keys()) + raise ValueError(f"Service '{self.service_name}' not found. Available services: {available_services}") + + self.service_config = self.compose_data['services'][self.service_name] + + +def main(): + parser = argparse.ArgumentParser(description='Backup Docker service to Proxmox Backup Server') + parser.add_argument('compose_file', help='Path to docker-compose.yaml file') + parser.add_argument('service_name', help='Name of the service to backup') + parser.add_argument('--pbs-repository', required=True, help='PBS repository (user@host:datastore)') + parser.add_argument('--pbs-username', help='PBS username') + parser.add_argument('--pbs-password', help='PBS password') + parser.add_argument('--pbs-fingerprint', help='PBS server fingerprint') + parser.add_argument('--dry-run', action='store_true', help='Show what would be done without executing commands') + + args = parser.parse_args() + + pbs_config = { + 'repository': args.pbs_repository + } + + if args.pbs_username: + pbs_config['username'] = args.pbs_username + if args.pbs_password: + pbs_config['password'] = args.pbs_password + if args.pbs_fingerprint: + pbs_config['fingerprint'] = args.pbs_fingerprint + + try: + backup_tool = Docker2PBS(args.compose_file, args.service_name, pbs_config, args.dry_run) + backup_tool.load_compose_file() + print(f"Successfully loaded compose file and found service: {args.service_name}") + except Exception as e: + print(f"Error: {e}") + sys.exit(1) + + +if __name__ == '__main__': + main() \ No newline at end of file