Compare commits
No commits in common. "717d6a63b3ac7cf7b06f78521d5d6d3043111578" and "d5ea5e64ee51f7ca0177e3655a812297427b0bdf" have entirely different histories.
717d6a63b3
...
d5ea5e64ee
3 changed files with 35 additions and 50 deletions
28
containerctl
28
containerctl
|
@ -17,22 +17,28 @@ get_python_path()
|
||||||
pyver="$(/usr/bin/env "${py}" -c 'import sys; print(sys.version_info.minor)')"
|
pyver="$(/usr/bin/env "${py}" -c 'import sys; print(sys.version_info.minor)')"
|
||||||
if [ "${pyver}" -lt "11" ]
|
if [ "${pyver}" -lt "11" ]
|
||||||
then
|
then
|
||||||
pyver="13"
|
py="python3.13"
|
||||||
py="python3.${pyver}"
|
|
||||||
else
|
else
|
||||||
printf '%b' "${py}"
|
printf '%b' "${py}"
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
|
|
||||||
while [ "${pyver}" -ge 11 ]
|
if /usr/bin/env "${py}" 2> /dev/null
|
||||||
do
|
then
|
||||||
if /usr/bin/env "${py}" -c "print('${py}')" 2> /dev/null
|
return
|
||||||
then
|
fi
|
||||||
return
|
|
||||||
fi
|
py="python3.12"
|
||||||
pyver=$((pyver - 1))
|
if /usr/bin/env "${py}" 2> /dev/null
|
||||||
py="python3.${pyver}"
|
then
|
||||||
done
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
py="python3.11"
|
||||||
|
if /usr/bin/env "${py}" 2> /dev/null
|
||||||
|
then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
log_error 'containerctl needs at least Python 3.11 to run!'
|
log_error 'containerctl needs at least Python 3.11 to run!'
|
||||||
exit 1
|
exit 1
|
||||||
|
|
|
@ -186,7 +186,6 @@ class Memory:
|
||||||
reservation = maybe_or(val, "reservation", "")
|
reservation = maybe_or(val, "reservation", "")
|
||||||
swap = maybe_or(val, "swap", "")
|
swap = maybe_or(val, "swap", "")
|
||||||
if limit == "":
|
if limit == "":
|
||||||
logger.log_warning("No limit set, memory config is not needed")
|
|
||||||
return cls("", "", "")
|
return cls("", "", "")
|
||||||
return cls(limit, reservation, swap)
|
return cls(limit, reservation, swap)
|
||||||
|
|
||||||
|
@ -253,7 +252,7 @@ class Volume:
|
||||||
if val is None:
|
if val is None:
|
||||||
return []
|
return []
|
||||||
if not isinstance(val, dict):
|
if not isinstance(val, dict):
|
||||||
logger.log_warning("Volume key is malformed.")
|
logger.log_warning("Volume key is present, but malformed.")
|
||||||
return []
|
return []
|
||||||
return [
|
return [
|
||||||
Volume.from_json_entry(key, value) for key, value in val.items()
|
Volume.from_json_entry(key, value) for key, value in val.items()
|
||||||
|
@ -320,7 +319,7 @@ class Secret:
|
||||||
if val is None:
|
if val is None:
|
||||||
return []
|
return []
|
||||||
if not isinstance(val, dict):
|
if not isinstance(val, dict):
|
||||||
logger.log_warning("Secret key is malformed!")
|
logger.log_warning("Secret key is present, but malformed!")
|
||||||
return []
|
return []
|
||||||
secrets = []
|
secrets = []
|
||||||
for key in val:
|
for key in val:
|
||||||
|
@ -333,9 +332,6 @@ class Secret:
|
||||||
if isinstance(target, str):
|
if isinstance(target, str):
|
||||||
target = [target]
|
target = [target]
|
||||||
if not isinstance(target, list):
|
if not isinstance(target, list):
|
||||||
logger.log_warning(
|
|
||||||
f"Secret {name} has no target and will be ignored"
|
|
||||||
)
|
|
||||||
target = []
|
target = []
|
||||||
options = maybe_or(val[key], "options", "")
|
options = maybe_or(val[key], "options", "")
|
||||||
if options is None:
|
if options is None:
|
||||||
|
@ -397,7 +393,7 @@ class Environment:
|
||||||
if val is None:
|
if val is None:
|
||||||
return cls([], "")
|
return cls([], "")
|
||||||
if not isinstance(val, dict):
|
if not isinstance(val, dict):
|
||||||
logger.log_warning("Environment key is malformed!")
|
logger.log_warning("Environment key is present, but malformed!")
|
||||||
return cls([], "")
|
return cls([], "")
|
||||||
return cls([f"{key}='{value}'" for key, value in val.items()], "")
|
return cls([f"{key}='{value}'" for key, value in val.items()], "")
|
||||||
|
|
||||||
|
@ -444,7 +440,7 @@ class Ports:
|
||||||
if val is None:
|
if val is None:
|
||||||
return cls([], [])
|
return cls([], [])
|
||||||
if not isinstance(val, dict):
|
if not isinstance(val, dict):
|
||||||
logger.log_warning("Ports key is malformed!")
|
logger.log_warning("Ports key is present, but malformed!")
|
||||||
return cls([], [])
|
return cls([], [])
|
||||||
tcp_ports = maybe(val, "tcp")
|
tcp_ports = maybe(val, "tcp")
|
||||||
udp_ports = maybe(val, "udp")
|
udp_ports = maybe(val, "udp")
|
||||||
|
@ -503,13 +499,13 @@ class Network:
|
||||||
return cls("", [])
|
return cls("", [])
|
||||||
mode = maybe(val, "mode")
|
mode = maybe(val, "mode")
|
||||||
options = maybe(val, "options")
|
options = maybe(val, "options")
|
||||||
if mode is None or not isinstance(mode, str):
|
if mode is None:
|
||||||
err = "Network configuration is missing or has malformed elements!"
|
err = "Network configuration is missing or has malformed elements!"
|
||||||
logger.log_error(err)
|
logger.log_error(err)
|
||||||
return cls("", [])
|
return cls("", [])
|
||||||
if options is None or not isinstance(options, list):
|
if options is None or not isinstance(options, list):
|
||||||
return cls(mode, [])
|
return cls(str(mode), [])
|
||||||
return cls(mode, options)
|
return cls(str(mode), options)
|
||||||
|
|
||||||
def command(self) -> str:
|
def command(self) -> str:
|
||||||
"""Option for podman container create."""
|
"""Option for podman container create."""
|
||||||
|
@ -541,7 +537,7 @@ class Image:
|
||||||
image = maybe_or(val, "image", "")
|
image = maybe_or(val, "image", "")
|
||||||
tag = maybe_or(val, "tag", "")
|
tag = maybe_or(val, "tag", "")
|
||||||
cmd = maybe_or(val, "command", "")
|
cmd = maybe_or(val, "command", "")
|
||||||
return cls(registry, image, tag, cmd)
|
return cls(str(registry), str(image), str(tag), cmd)
|
||||||
|
|
||||||
def command(self) -> str:
|
def command(self) -> str:
|
||||||
"""Option for podman container create."""
|
"""Option for podman container create."""
|
||||||
|
@ -593,9 +589,9 @@ class Dns:
|
||||||
search = maybe_or(val, "search", "")
|
search = maybe_or(val, "search", "")
|
||||||
servers = maybe(val, "servers")
|
servers = maybe(val, "servers")
|
||||||
if not isinstance(servers, list):
|
if not isinstance(servers, list):
|
||||||
logger.log_warning("Servers key is not an array!")
|
logger.log_error("Servers key is not an array!")
|
||||||
return cls([], search)
|
return cls([], "")
|
||||||
return cls(servers, search)
|
return cls(servers, str(search))
|
||||||
|
|
||||||
def command(self) -> str:
|
def command(self) -> str:
|
||||||
"""Option for podman container create."""
|
"""Option for podman container create."""
|
||||||
|
@ -720,30 +716,14 @@ class Container:
|
||||||
name = maybe(json, "name")
|
name = maybe(json, "name")
|
||||||
if name is None:
|
if name is None:
|
||||||
logger.log_error("No container name set, aborting!")
|
logger.log_error("No container name set, aborting!")
|
||||||
raise ConfigError("Container has no name")
|
return
|
||||||
image = maybe(json, "image")
|
image = maybe(json, "image")
|
||||||
if image is None:
|
if image is None:
|
||||||
logger.log_error("No image set, aborting!")
|
logger.log_error("No image set, aborting!")
|
||||||
raise ConfigError("Container has no image")
|
return
|
||||||
|
|
||||||
self.image = Image.from_json(image, logger)
|
|
||||||
image_valid = True
|
|
||||||
if self.image.image == "":
|
|
||||||
logger.log_error("Image has no image set!")
|
|
||||||
image_valid = False
|
|
||||||
if self.image.registry == "":
|
|
||||||
logger.log_error("Image has no registry set!")
|
|
||||||
image_valid = False
|
|
||||||
if self.image.tag == "":
|
|
||||||
logger.log_error("Image has no tag set!")
|
|
||||||
image_valid = False
|
|
||||||
if not image_valid:
|
|
||||||
raise ConfigError("Image is missing required keys!")
|
|
||||||
|
|
||||||
self.name = name
|
|
||||||
ct_opts = ContainerOptions.from_json(json, logger)
|
ct_opts = ContainerOptions.from_json(json, logger)
|
||||||
if not ct_opts.is_valid:
|
if not ct_opts.is_valid:
|
||||||
raise ConfigError("Config seems to be invalid?")
|
return
|
||||||
env = maybe(json, "env")
|
env = maybe(json, "env")
|
||||||
secrets = maybe(json, "secrets")
|
secrets = maybe(json, "secrets")
|
||||||
volumes = maybe(json, "volumes")
|
volumes = maybe(json, "volumes")
|
||||||
|
|
|
@ -14,7 +14,7 @@ from pathlib import Path
|
||||||
from container import ConfigError, Container
|
from container import ConfigError, Container
|
||||||
from log import Log
|
from log import Log
|
||||||
|
|
||||||
GENERATE_VERSION = "0.0.15"
|
GENERATE_VERSION = "0.0.13"
|
||||||
HEADER = f"""#!/bin/sh
|
HEADER = f"""#!/bin/sh
|
||||||
# This script was generated by containerctl v{GENERATE_VERSION}
|
# This script was generated by containerctl v{GENERATE_VERSION}
|
||||||
# Report bugs with _this script_ to <tenno+containerctl@suij.in>
|
# Report bugs with _this script_ to <tenno+containerctl@suij.in>
|
||||||
|
@ -76,12 +76,11 @@ def main() -> None:
|
||||||
if len(sys.argv) > log_threshold:
|
if len(sys.argv) > log_threshold:
|
||||||
base = sys.argv[3]
|
base = sys.argv[3]
|
||||||
logger = Log(log_file)
|
logger = Log(log_file)
|
||||||
conf = Path(config_file)
|
data = load_container_config(Path(config_file), logger)
|
||||||
data = load_container_config(conf, logger)
|
|
||||||
if data is None:
|
if data is None:
|
||||||
logger.log_error(f"{conf.name} is invalid, aborting!")
|
logger.log_error(f"{config_file} is invalid, aborting!")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
logger.set_prefix(conf.name)
|
logger.set_prefix(Path(config_file).name)
|
||||||
ct = create_container_from_config(data, logger)
|
ct = create_container_from_config(data, logger)
|
||||||
if ct is None:
|
if ct is None:
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
Loading…
Add table
Reference in a new issue