Compare commits
6 commits
d5ea5e64ee
...
717d6a63b3
Author | SHA1 | Date | |
---|---|---|---|
717d6a63b3 | |||
b9a8b87e7f | |||
8e4deb7d36 | |||
a8d0148f72 | |||
589a9125f4 | |||
259c2ec8d7 |
3 changed files with 50 additions and 35 deletions
22
containerctl
22
containerctl
|
@ -17,28 +17,22 @@ 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
|
||||||
py="python3.13"
|
pyver="13"
|
||||||
|
py="python3.${pyver}"
|
||||||
else
|
else
|
||||||
printf '%b' "${py}"
|
printf '%b' "${py}"
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if /usr/bin/env "${py}" 2> /dev/null
|
while [ "${pyver}" -ge 11 ]
|
||||||
then
|
do
|
||||||
return
|
if /usr/bin/env "${py}" -c "print('${py}')" 2> /dev/null
|
||||||
fi
|
|
||||||
|
|
||||||
py="python3.12"
|
|
||||||
if /usr/bin/env "${py}" 2> /dev/null
|
|
||||||
then
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
|
|
||||||
py="python3.11"
|
|
||||||
if /usr/bin/env "${py}" 2> /dev/null
|
|
||||||
then
|
then
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
|
pyver=$((pyver - 1))
|
||||||
|
py="python3.${pyver}"
|
||||||
|
done
|
||||||
|
|
||||||
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,6 +186,7 @@ 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)
|
||||||
|
|
||||||
|
@ -252,7 +253,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 present, but malformed.")
|
logger.log_warning("Volume key is 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()
|
||||||
|
@ -319,7 +320,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 present, but malformed!")
|
logger.log_warning("Secret key is malformed!")
|
||||||
return []
|
return []
|
||||||
secrets = []
|
secrets = []
|
||||||
for key in val:
|
for key in val:
|
||||||
|
@ -332,6 +333,9 @@ 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:
|
||||||
|
@ -393,7 +397,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 present, but malformed!")
|
logger.log_warning("Environment key is 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()], "")
|
||||||
|
|
||||||
|
@ -440,7 +444,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 present, but malformed!")
|
logger.log_warning("Ports key is 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")
|
||||||
|
@ -499,13 +503,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:
|
if mode is None or not isinstance(mode, str):
|
||||||
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(str(mode), [])
|
return cls(mode, [])
|
||||||
return cls(str(mode), options)
|
return cls(mode, options)
|
||||||
|
|
||||||
def command(self) -> str:
|
def command(self) -> str:
|
||||||
"""Option for podman container create."""
|
"""Option for podman container create."""
|
||||||
|
@ -537,7 +541,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(str(registry), str(image), str(tag), cmd)
|
return cls(registry, image, tag, cmd)
|
||||||
|
|
||||||
def command(self) -> str:
|
def command(self) -> str:
|
||||||
"""Option for podman container create."""
|
"""Option for podman container create."""
|
||||||
|
@ -589,9 +593,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_error("Servers key is not an array!")
|
logger.log_warning("Servers key is not an array!")
|
||||||
return cls([], "")
|
return cls([], search)
|
||||||
return cls(servers, str(search))
|
return cls(servers, search)
|
||||||
|
|
||||||
def command(self) -> str:
|
def command(self) -> str:
|
||||||
"""Option for podman container create."""
|
"""Option for podman container create."""
|
||||||
|
@ -716,14 +720,30 @@ 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!")
|
||||||
return
|
raise ConfigError("Container has no name")
|
||||||
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!")
|
||||||
return
|
raise ConfigError("Container has no image")
|
||||||
|
|
||||||
|
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:
|
||||||
return
|
raise ConfigError("Config seems to be invalid?")
|
||||||
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.13"
|
GENERATE_VERSION = "0.0.15"
|
||||||
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,11 +76,12 @@ 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)
|
||||||
data = load_container_config(Path(config_file), logger)
|
conf = Path(config_file)
|
||||||
|
data = load_container_config(conf, logger)
|
||||||
if data is None:
|
if data is None:
|
||||||
logger.log_error(f"{config_file} is invalid, aborting!")
|
logger.log_error(f"{conf.name} is invalid, aborting!")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
logger.set_prefix(Path(config_file).name)
|
logger.set_prefix(conf.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