mirror of
https://github.com/Cian-H/I-Form_Server_Node_Deployer.git
synced 2025-12-22 22:22:02 +00:00
Full type coverage with mypy
This commit is contained in:
17
poetry.lock
generated
17
poetry.lock
generated
@@ -328,6 +328,21 @@ websocket-client = ">=0.32.0"
|
||||
[package.extras]
|
||||
ssh = ["paramiko (>=2.4.3)"]
|
||||
|
||||
[[package]]
|
||||
name = "docker-stubs"
|
||||
version = "0.1.0"
|
||||
description = "Stubs package for the Python Docker API."
|
||||
optional = false
|
||||
python-versions = "^3.8"
|
||||
files = []
|
||||
develop = false
|
||||
|
||||
[package.source]
|
||||
type = "git"
|
||||
url = "https://github.com/rdozier-work/docker-stubs"
|
||||
reference = "HEAD"
|
||||
resolved_reference = "9de7906804ae912f1d644c97b617ac77e784fca8"
|
||||
|
||||
[[package]]
|
||||
name = "executing"
|
||||
version = "2.0.1"
|
||||
@@ -1092,4 +1107,4 @@ h11 = ">=0.9.0,<1"
|
||||
[metadata]
|
||||
lock-version = "2.0"
|
||||
python-versions = "^3.12"
|
||||
content-hash = "c74d1dcf762e5266d41c81b62bef444f065124fede9b3a34176cd9a6b93d9c2b"
|
||||
content-hash = "0da96ff6654ff4c33b776829e34f78ba2725a0de30980ec5eaab86a8b7abbead"
|
||||
|
||||
@@ -25,6 +25,7 @@ black = "^23.10.1"
|
||||
snoop = "^0.4.3"
|
||||
pytest = "^7.4.3"
|
||||
mypy = "^1.6.1"
|
||||
docker-stubs = {git = "https://github.com/rdozier-work/docker-stubs"}
|
||||
|
||||
[tool.poetry.scripts]
|
||||
node_deployer = "node_deployer.__main__:main"
|
||||
|
||||
@@ -81,8 +81,11 @@ def convert_json_via_fuelignition(
|
||||
bytestream = io.BytesIO(b"".join(chunk for chunk in filestream))
|
||||
bytestream.seek(0)
|
||||
tar = tarfile.open(fileobj=bytestream)
|
||||
container_image = tar.extractfile(tar.getmembers()[0].name)
|
||||
if container_image is None:
|
||||
raise Exception("Failed to extract image from tarfile")
|
||||
with open(host_image_path, "wb+") as f:
|
||||
f.write(tar.extractfile(tar.getmembers()[0].name).read())
|
||||
f.write(container_image.read())
|
||||
|
||||
|
||||
def build_fuelignition() -> docker.models.images.Image:
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
from pathlib import Path
|
||||
from types import SimpleNamespace
|
||||
from typing import Union
|
||||
|
||||
import docker
|
||||
import tomllib
|
||||
@@ -9,7 +10,7 @@ CLIENT = docker.from_env(version="auto")
|
||||
MAX_PORT: int = 65535
|
||||
PROJECT_ROOT: Path = Path(__file__).parent.parent.parent.absolute()
|
||||
|
||||
type ConfigLabel = str | list[str]
|
||||
ConfigLabel = Union[str, list[str]] # After PEP695 support: type ConfigLabel = str | list[str]
|
||||
|
||||
|
||||
class Config(SimpleNamespace):
|
||||
|
||||
@@ -1,19 +1,20 @@
|
||||
from fnmatch import fnmatch
|
||||
import ipaddress
|
||||
from typing import Annotated
|
||||
from typing import Annotated, Optional, Union
|
||||
|
||||
from docker.types import Mount
|
||||
import typer
|
||||
from typing import Tuple
|
||||
|
||||
from .config import config
|
||||
from .cli import cli_spinner
|
||||
from .config import config
|
||||
from .create_img import create_img
|
||||
from .debug import debug_guard
|
||||
from .utils import ensure_build_dir
|
||||
|
||||
|
||||
type IPAddress = ipaddress.IPv4Address | ipaddress.IPv6Address
|
||||
# When PEP695 is supported this line should be:
|
||||
# type IPAddress = ipaddress.IPv4Address | ipaddress.IPv6Address
|
||||
IPAddress = Union[ipaddress.IPv4Address, ipaddress.IPv6Address]
|
||||
|
||||
|
||||
def filter_validation_response(response: str) -> str:
|
||||
@@ -60,18 +61,18 @@ def validation_result() -> str:
|
||||
)
|
||||
if config.CLEANUP_IMAGES:
|
||||
image.remove(force=True)
|
||||
return response
|
||||
return response.decode()
|
||||
|
||||
|
||||
@cli_spinner(description="Validating ignition image", total=None)
|
||||
def validate() -> Tuple[bool, str]:
|
||||
def validate() -> tuple[bool, str]:
|
||||
"""Validates the ignition image
|
||||
|
||||
Returns:
|
||||
Tuple[bool, str]: A tuple containing a boolean indicating whether
|
||||
tuple[bool, str]: A tuple containing a boolean indicating whether
|
||||
the validation was successful and the response from the validation
|
||||
"""
|
||||
response = validation_result().decode()
|
||||
response = validation_result()
|
||||
response = filter_validation_response(response)
|
||||
return (not bool(response), response)
|
||||
|
||||
@@ -96,7 +97,7 @@ def write_disk(disk: str) -> None:
|
||||
@ensure_build_dir
|
||||
def create_ignition_disk(
|
||||
disk: Annotated[
|
||||
str,
|
||||
Optional[str],
|
||||
typer.Option(
|
||||
"--disk",
|
||||
"-d",
|
||||
@@ -114,7 +115,7 @@ def create_ignition_disk(
|
||||
),
|
||||
] = "node",
|
||||
password: Annotated[
|
||||
str,
|
||||
Optional[str],
|
||||
typer.Option(
|
||||
"--password",
|
||||
"-p",
|
||||
@@ -125,7 +126,7 @@ def create_ignition_disk(
|
||||
),
|
||||
] = None,
|
||||
switch_ip: Annotated[
|
||||
IPAddress,
|
||||
Optional[IPAddress],
|
||||
typer.Option(
|
||||
"--switch-ip",
|
||||
"-ip",
|
||||
@@ -146,7 +147,7 @@ def create_ignition_disk(
|
||||
),
|
||||
] = 4789,
|
||||
swarm_token: Annotated[
|
||||
str,
|
||||
Optional[str],
|
||||
typer.Option(
|
||||
"--swarm-token",
|
||||
"-t",
|
||||
@@ -194,6 +195,10 @@ def create_ignition_disk(
|
||||
Raises:
|
||||
typer.Exit: Exit CLI if the ignition image is invalid
|
||||
"""
|
||||
# Guard against the user specifying no disk
|
||||
if disk is None:
|
||||
raise typer.BadParameter("No disk specified")
|
||||
|
||||
create_img(
|
||||
hostname = hostname,
|
||||
password = password,
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
import ipaddress
|
||||
import json
|
||||
from pathlib import Path
|
||||
from typing import Annotated
|
||||
from typing import Annotated, Optional, Union
|
||||
|
||||
import typer
|
||||
|
||||
from .config import config
|
||||
from .autoignition import json_to_img
|
||||
from .cli import cli_spinner
|
||||
from .config import config
|
||||
from .debug import debug_guard
|
||||
from .utils import ensure_build_dir
|
||||
|
||||
|
||||
type IPAddress = ipaddress.IPv4Address | ipaddress.IPv6Address
|
||||
# When PEP695 is supported this line should be:
|
||||
# type IPAddress = ipaddress.IPv4Address | ipaddress.IPv6Address
|
||||
IPAddress = Union[ipaddress.IPv4Address, ipaddress.IPv6Address]
|
||||
|
||||
|
||||
def load_template() -> dict:
|
||||
@@ -99,7 +100,7 @@ def create_img(
|
||||
),
|
||||
] = "node",
|
||||
password: Annotated[
|
||||
str,
|
||||
Optional[str],
|
||||
typer.Option(
|
||||
"--password",
|
||||
"-p",
|
||||
@@ -110,7 +111,7 @@ def create_img(
|
||||
),
|
||||
] = None,
|
||||
switch_ip: Annotated[
|
||||
IPAddress,
|
||||
Optional[IPAddress],
|
||||
typer.Option(
|
||||
"--switch-ip",
|
||||
"-ip",
|
||||
@@ -131,7 +132,7 @@ def create_img(
|
||||
),
|
||||
] = 4789,
|
||||
swarm_token: Annotated[
|
||||
str,
|
||||
Optional[str],
|
||||
typer.Option(
|
||||
"--swarm-token",
|
||||
"-t",
|
||||
@@ -194,10 +195,13 @@ def create_img(
|
||||
}
|
||||
)
|
||||
|
||||
# Guards against the user not specifying a password
|
||||
if password is None:
|
||||
raise typer.BadParameter("Password must be specified")
|
||||
|
||||
# Create ignition configuration
|
||||
ignition_config = load_template()
|
||||
ignition_config = apply_ignition_settings(
|
||||
ignition_config,
|
||||
load_template(),
|
||||
hostname,
|
||||
password,
|
||||
swarm_config,
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
from typing import Any, Dict
|
||||
|
||||
import typer
|
||||
|
||||
from .config import config
|
||||
from .autoignition import json_to_img
|
||||
from .config import config
|
||||
from .create_disk import create_ignition_disk
|
||||
from .create_img import create_img
|
||||
|
||||
|
||||
cmd_params = {
|
||||
cmd_params: Dict[Any, Any] = {
|
||||
"no_args_is_help": True,
|
||||
}
|
||||
|
||||
@@ -15,9 +17,19 @@ app = typer.Typer(
|
||||
**cmd_params,
|
||||
)
|
||||
|
||||
app.command(**cmd_params)(create_img)
|
||||
app.command(**cmd_params)(create_ignition_disk)
|
||||
app.command(**cmd_params)(json_to_img)
|
||||
# Register commands
|
||||
app.command(
|
||||
help = str(create_ignition_disk.__doc__).split("Args:")[0].strip(),
|
||||
**cmd_params
|
||||
)(create_ignition_disk)
|
||||
app.command(
|
||||
help = str(create_img.__doc__).split("Args:")[0].strip(),
|
||||
**cmd_params
|
||||
)(create_img)
|
||||
app.command(
|
||||
help = str(json_to_img.__doc__).split("Args:")[0].strip(),
|
||||
**cmd_params
|
||||
)(json_to_img)
|
||||
|
||||
if __name__ == "__main__":
|
||||
config.update_config("cli")
|
||||
|
||||
Reference in New Issue
Block a user