#!/usr/bin/env python3 # SPDX-FileCopyrightText: (C) 2025 Enno Tensing # # SPDX-License-Identifier: GPL-2.0-only """Generate the control files..""" import json import stat import sys from pathlib import Path from container import ConfigError, Container from log import Log GENERATE_VERSION = "0.0.13" HEADER = f"""#!/bin/sh # This script was generated by containerctl v{GENERATE_VERSION} # Report bugs with _this script_ to """ def load_container_config(file: Path, log: Log) -> dict | None: """Load a container config.""" if not file.exists(): log.log_error(f"{file.name} does not exist!") return None data = {} with file.open("r", encoding="utf-8") as fp: try: data = json.load(fp) except json.JSONDecodeError as e: log.log_error(f"{file.name} is not a valid JSON file!") log.log_error(f"Exception: {e}") return None except UnicodeDecodeError as e: log.log_error(f"{file.name} is not a valid UTF8 file!") log.log_error(f"Exception: {e}") return None except OSError as e: log.log_error(f"{file.name} could not be read!") log.log_error(f"Exception: {e}") return None return data def create_container_from_config(data: dict, log: Log) -> Container | None: """Create a container object.""" ct: Container | None = None try: ct = Container(data) except ConfigError as e: log.log_error(f"{e}") return None return ct def main() -> None: """Run the program.""" config_threshold = 2 log_threshold = 3 if len(sys.argv) < config_threshold: logger = Log("/dev/stdout") logger.log_error("No arguments passed!") sys.exit(1) config_file = "" log_file = "" base = "/var/lib/containerctl/containers" if len(sys.argv) >= config_threshold: config_file = sys.argv[1] if len(sys.argv) >= log_threshold: log_file = sys.argv[2] if len(sys.argv) > log_threshold: base = sys.argv[3] logger = Log(log_file) data = load_container_config(Path(config_file), logger) if data is None: logger.log_error(f"{config_file} is invalid, aborting!") sys.exit(1) logger.set_prefix(Path(config_file).name) ct = create_container_from_config(data, logger) if ct is None: sys.exit(1) scripts = { "create-volumes": ct.create_volumes, "create-secrets": ct.create_secrets, "create-environment": ct.create_environment, "remove-volumes": ct.remove_volumes, "remove-secrets": ct.remove_secrets, "create": ct.create_container, "remove": ct.remove_container, "purge": ct.purge_container, "start": ct.start_container, "stop": ct.stop_container, "restart": ct.restart_container, "upgrade": ct.upgrade_container, } base = f"{base}/{ct.name}" if not Path(base).exists(): Path(base).mkdir() for script, method in scripts.items(): s = Path(f"{base}/{script}") script_content = "" if script == "create": script_content += ct.create_volumes() script_content += ct.create_secrets() script_content += ct.create_environment() script_content += method() if script_content == "": script_content = "true\n" with s.open("w+", encoding="utf-8") as f: f.write(HEADER) f.write(script_content) s.chmod( stat.S_IRWXU | stat.S_IRGRP | stat.S_IXGRP | stat.S_IROTH | stat.S_IXOTH, ) if __name__ == "__main__": main()