1
0
Fork 0
containerctl/generate/generate.py
Enno Tensing e4051fe4e4
generate: generate: Bump to 0.0.8
Signed-off-by: Enno Tensing <tenno@suij.in>
2025-08-07 20:14:02 +02:00

126 lines
3.7 KiB
Python

#!/usr/bin/env python3
# SPDX-FileCopyrightText: (C) 2025 Enno Tensing <tenno+containerctl@suij.in>
#
# 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.8"
HEADER = f"""#!/bin/sh
# This script was generated by containerctl v{GENERATE_VERSION}
# Report bugs with _this script_ to <tenno+containerctl@suij.in>
"""
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)
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()