Fully working end-to-end locally with validation

This commit is contained in:
Cian Hughes
2023-10-26 17:29:42 +01:00
parent 2a8d3c21fe
commit c14c0742b0
13 changed files with 333 additions and 111 deletions

146
main.py
View File

@@ -1,101 +1,62 @@
import ipaddress
import json
from fnmatch import fnmatch
from typing import Annotated
import typer
from autoignition import json_to_img
from config import (
CLEANUP_IMAGES,
CLIENT,
CWD_MOUNTDIR,
DOCKERFILE_DIR,
ROOT_DIR,
)
from create_img import create_img
from debug import debug_mode
import docker
MAX_PORT: int = 65535
def filter_validation_response(response: str) -> str:
return "\n".join(
filter(
# Filter out the warning about unused key human_readable, this always exists in
# configurations produced by fuel-ignition
lambda x: not fnmatch(x.strip(), "warning at*Unused key human_read"),
response.split("\n"),
)
).strip()
def load_template() -> dict:
with open("templates/fuelignition.json", "r") as f:
out = json.load(f)
return out
def apply_ignition_settings(
template: dict,
hostname: str,
password: str,
swarm_config: str,
) -> dict:
ignition_config = template.copy()
ignition_config["hostname"] = hostname
ignition_config["login"]["users"][0]["passwd"] = password
# Add files that will define a service to ensure that the node joins the swarm
with open("templates/join_swarm.sh", "r") as f1, open(
"templates/join_swarm.service", "r"
) as f2:
swarm_script, swarm_service = f1.read(), f2.read()
ignition_config["storage"] = ignition_config.get("storage", {})
ignition_config["storage"]["files"] = ignition_config["storage"].get("files", [])
ignition_config["storage"]["files"] += [
{
"path": "/root/join_swarm.json",
"source_type": "data",
"mode": 420,
"overwrite": True,
"data_content": swarm_config,
},
{
"path": "/root/join_swarm.sh",
"source_type": "data",
"mode": 420,
"overwrite": True,
"data_content": swarm_script,
},
]
ignition_config["systemd"] = ignition_config.get("systemd", {})
ignition_config["systemd"]["units"] = ignition_config["systemd"].get("units", [])
ignition_config["systemd"]["units"] += [
{
"name": "join_swarm.service",
"enabled": True,
"contents": swarm_service,
},
]
return ignition_config
def create_img(
hostname: str, password: str, switch_ip_address: str, switch_port: str, swarm_token: str
) -> None:
switch_ip_address = ipaddress.ip_address(switch_ip_address)
if switch_port > MAX_PORT:
raise ValueError(f"Port must be less than {MAX_PORT}")
# get swarm configuration as JSON
swarm_config = json.dumps(
{
"SWITCH_IP_ADDRESS": str(switch_ip_address),
"SWITCH_PORT": switch_port,
"SWARM_TOKEN": swarm_token,
}
def validation_result() -> str:
dockerfile = DOCKERFILE_DIR / "validate.dockerfile"
image = CLIENT.images.build(
path=".",
dockerfile=str(dockerfile),
tag="validate",
buildargs={"CWD_MOUNTDIR": str(CWD_MOUNTDIR)},
rm=CLEANUP_IMAGES,
pull=True,
quiet=True,
)
# Create ignition configuration
ignition_config = load_template()
ignition_config = apply_ignition_settings(
ignition_config,
hostname,
password,
swarm_config,
response = CLIENT.containers.run(
image,
mounts=[
docker.types.Mount(
target=str(CWD_MOUNTDIR),
source=str(ROOT_DIR),
type="bind",
)
],
remove=True,
)
if CLEANUP_IMAGES:
image.remove(force=True)
return response
# export ignition configuration
with open("build/fuelignition.json", "w") as f:
json.dump(ignition_config, f, indent=4)
# convert ignition configuration to image
json_to_img("build/fuelignition.json", "build/ignition.img")
def validate() -> (bool, str):
response = validation_result().decode()
response = filter_validation_response(response)
return (not bool(response), response)
def main(
@@ -119,10 +80,17 @@ def main(
debug: Annotated[bool, typer.Option(help="Enable debug mode")] = False,
) -> None:
debug_mode(debug)
f = create_img
if debug:
f = ss(f) # noqa: F821, # type: ignore #? ss is installed in debug_mode
f(hostname, password, switch_ip_address, switch_port, swarm_token)
# f = create_img
# if debug:
# f = ss(f) # noqa: F821, # type: ignore #? ss is installed in debug_mode
# f(hostname, password, switch_ip_address, switch_port, swarm_token)
create_img(hostname, password, switch_ip_address, switch_port, swarm_token)
valid, response = validate()
if not valid:
print(response)
raise typer.Exit(1)
else:
print("Valid ignition image created!")
if __name__ == "__main__":