mirror of
https://github.com/Cian-H/I-Form_Server_Node_Deployer.git
synced 2025-12-23 14:42:02 +00:00
Fully working end-to-end locally with validation
This commit is contained in:
146
main.py
146
main.py
@@ -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__":
|
||||
|
||||
Reference in New Issue
Block a user