Split instance.py
This commit is contained in:
parent
00bb2adee4
commit
1d5c4ccbee
16 changed files with 178 additions and 141 deletions
|
@ -7,7 +7,9 @@ from typing import List, Iterable, Type, Optional, TypeVar
|
|||
|
||||
import click
|
||||
|
||||
from ..instance import Instance, Project, Services
|
||||
from ..instance import Instance
|
||||
from ..project import Project
|
||||
from ..services import Services
|
||||
from ..wstring import WParagraph, WAlignment
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
|
|
@ -3,7 +3,8 @@ from typing import List
|
|||
from .cli import KiwiCommand, KiwiCommandType
|
||||
from .decorators import kiwi_command
|
||||
from ..executable import COMPOSE_EXE
|
||||
from ..instance import Instance, Project
|
||||
from ..instance import Instance
|
||||
from ..project import Project
|
||||
|
||||
|
||||
@kiwi_command(
|
||||
|
|
|
@ -5,7 +5,8 @@ import click
|
|||
from .cli import KiwiCommand, KiwiCommandType
|
||||
from .decorators import kiwi_command
|
||||
from ..executable import COMPOSE_EXE
|
||||
from ..instance import Instance, Project
|
||||
from ..instance import Instance
|
||||
from ..project import Project
|
||||
|
||||
|
||||
@click.argument(
|
||||
|
|
|
@ -3,7 +3,8 @@ import click
|
|||
from .cli import KiwiCommand, KiwiCommandType
|
||||
from .decorators import kiwi_command
|
||||
from .._constants import KIWI_CONF_NAME
|
||||
from ..instance import Instance, Project
|
||||
from ..instance import Instance
|
||||
from ..project import Project
|
||||
|
||||
|
||||
@click.option(
|
||||
|
|
|
@ -5,7 +5,9 @@ import click
|
|||
from .cli import KiwiCommand, KiwiCommandType
|
||||
from .decorators import kiwi_command
|
||||
from ..executable import COMPOSE_EXE
|
||||
from ..instance import Instance, Project, Services
|
||||
from ..instance import Instance
|
||||
from ..project import Project
|
||||
from ..services import Services
|
||||
|
||||
|
||||
@click.option(
|
||||
|
|
|
@ -3,7 +3,8 @@ import click
|
|||
from .cli import KiwiCommand, KiwiCommandType
|
||||
from .decorators import kiwi_command
|
||||
from .._constants import KIWI_CONF_NAME
|
||||
from ..instance import Instance, Project
|
||||
from ..instance import Instance
|
||||
from ..project import Project
|
||||
|
||||
|
||||
@click.option(
|
||||
|
|
|
@ -4,7 +4,8 @@ import click
|
|||
|
||||
from .cli import KiwiCommandType, KiwiCommand
|
||||
from .decorators import kiwi_command
|
||||
from ..instance import Instance, Project
|
||||
from ..instance import Instance
|
||||
from ..project import Project
|
||||
|
||||
|
||||
@click.option(
|
||||
|
|
|
@ -5,7 +5,9 @@ import click
|
|||
from .cli import KiwiCommand, KiwiCommandType
|
||||
from .decorators import kiwi_command
|
||||
from ..executable import COMPOSE_EXE
|
||||
from ..instance import Instance, Project, Services
|
||||
from ..instance import Instance
|
||||
from ..project import Project
|
||||
from ..services import Services
|
||||
|
||||
|
||||
@click.option(
|
||||
|
|
|
@ -5,7 +5,9 @@ import click
|
|||
from .cli import KiwiCommand, KiwiCommandType
|
||||
from .decorators import kiwi_command
|
||||
from ..executable import COMPOSE_EXE
|
||||
from ..instance import Instance, Project, Services
|
||||
from ..instance import Instance
|
||||
from ..project import Project
|
||||
from ..services import Services
|
||||
|
||||
|
||||
@kiwi_command(short_help="Bring up kiwi services")
|
||||
|
|
|
@ -1,136 +1,10 @@
|
|||
import functools
|
||||
import re
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
from typing import Generator, List, Optional, Dict, Any
|
||||
from typing import Generator
|
||||
|
||||
import attr
|
||||
from ruamel.yaml.comments import CommentedMap
|
||||
|
||||
from ._constants import COMPOSE_FILE_NAME, CONF_DIRECTORY_NAME
|
||||
from .config import KiwiConfig, ProjectConfig
|
||||
from .executable import COMPOSE_EXE
|
||||
from .yaml import YAML
|
||||
|
||||
|
||||
@attr.s
|
||||
class Service:
|
||||
name: str = attr.ib()
|
||||
content: CommentedMap = attr.ib()
|
||||
parent: "Project" = attr.ib()
|
||||
|
||||
_RE_CONFDIR = re.compile(r"^\s*\$(?:CONFDIR|{CONFDIR})/+(.*)$", flags=re.UNICODE)
|
||||
|
||||
@property
|
||||
def configs(self) -> Generator[Path, None, None]:
|
||||
if "volumes" not in self.content:
|
||||
return
|
||||
|
||||
for volume in self.content["volumes"]:
|
||||
host_part = volume.split(":")[0]
|
||||
cd_match = Service._RE_CONFDIR.match(host_part)
|
||||
|
||||
if cd_match:
|
||||
yield Path(cd_match.group(1))
|
||||
|
||||
def has_executable(self, exe_name: str) -> bool:
|
||||
try:
|
||||
# test if desired executable exists
|
||||
COMPOSE_EXE.run(
|
||||
["exec", "-T", self.name, "/bin/sh", "-c", f"command -v {exe_name}"],
|
||||
check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL,
|
||||
**self.parent.process_kwargs,
|
||||
)
|
||||
return True
|
||||
|
||||
except subprocess.CalledProcessError:
|
||||
return False
|
||||
|
||||
|
||||
@attr.s
|
||||
class Services:
|
||||
content: List[Service] = attr.ib()
|
||||
|
||||
def __str__(self) -> str:
|
||||
return YAML().dump({
|
||||
"services": {
|
||||
service.name: service.content
|
||||
for service in self.content
|
||||
}
|
||||
}).strip()
|
||||
|
||||
def __bool__(self) -> bool:
|
||||
return bool(self.content)
|
||||
|
||||
@property
|
||||
def names(self) -> Generator[str, None, None]:
|
||||
return (
|
||||
service.name
|
||||
for service in self.content
|
||||
)
|
||||
|
||||
def filter_existing(self, service_names: List[str]) -> "Services":
|
||||
return Services([
|
||||
service
|
||||
for service in self.content
|
||||
if service.name in service_names
|
||||
])
|
||||
|
||||
|
||||
@attr.s
|
||||
class Project:
|
||||
directory: Path = attr.ib()
|
||||
parent: "Instance" = attr.ib()
|
||||
|
||||
@staticmethod
|
||||
@functools.lru_cache(maxsize=10)
|
||||
def _parse_compose_file(directory: Path) -> CommentedMap:
|
||||
with open(directory.joinpath(COMPOSE_FILE_NAME), "r") as cf:
|
||||
return YAML().load(cf)
|
||||
|
||||
@property
|
||||
def name(self) -> str:
|
||||
return self.directory.name
|
||||
|
||||
@property
|
||||
def config(self) -> Optional[ProjectConfig]:
|
||||
return self.parent.config.get_project_config(self.name)
|
||||
|
||||
@property
|
||||
def process_kwargs(self) -> Dict[str, Any]:
|
||||
directory: Path = self.directory
|
||||
project_name: str = self.name
|
||||
kiwi_hub_name: str = self.parent.config.network.name
|
||||
target_root_dir: Path = self.parent.config.storage.directory
|
||||
conf_dir: Path = target_root_dir.joinpath(CONF_DIRECTORY_NAME)
|
||||
target_dir: Path = target_root_dir.joinpath(project_name)
|
||||
|
||||
result: Dict[str, Any] = {
|
||||
"cwd": str(directory),
|
||||
"env": {
|
||||
"COMPOSE_PROJECT_NAME": project_name,
|
||||
"KIWI_HUB_NAME": kiwi_hub_name,
|
||||
"TARGETROOT": str(target_root_dir),
|
||||
"CONFDIR": str(conf_dir),
|
||||
"TARGETDIR": str(target_dir),
|
||||
},
|
||||
}
|
||||
|
||||
result["env"].update(self.parent.config.environment)
|
||||
|
||||
return result
|
||||
|
||||
@property
|
||||
def services(self) -> Services:
|
||||
yml = Project._parse_compose_file(self.directory)
|
||||
|
||||
return Services([
|
||||
Service(
|
||||
name=name,
|
||||
content=content,
|
||||
parent=self,
|
||||
) for name, content in yml["services"].items()
|
||||
])
|
||||
from .config import KiwiConfig
|
||||
from .project import Project
|
||||
|
||||
|
||||
@attr.s
|
||||
|
|
69
kiwi_scp/project.py
Normal file
69
kiwi_scp/project.py
Normal file
|
@ -0,0 +1,69 @@
|
|||
import functools
|
||||
from pathlib import Path
|
||||
from typing import Optional, Dict, Any
|
||||
|
||||
import attr
|
||||
from ruamel.yaml import CommentedMap
|
||||
|
||||
from ._constants import COMPOSE_FILE_NAME, CONF_DIRECTORY_NAME
|
||||
from .config import ProjectConfig
|
||||
from .instance import Instance
|
||||
from .service import Service
|
||||
from .services import Services
|
||||
from .yaml import YAML
|
||||
|
||||
|
||||
@attr.s
|
||||
class Project:
|
||||
directory: Path = attr.ib()
|
||||
parent: "Instance" = attr.ib()
|
||||
|
||||
@staticmethod
|
||||
@functools.lru_cache(maxsize=10)
|
||||
def _parse_compose_file(directory: Path) -> CommentedMap:
|
||||
with open(directory.joinpath(COMPOSE_FILE_NAME), "r") as cf:
|
||||
return YAML().load(cf)
|
||||
|
||||
@property
|
||||
def name(self) -> str:
|
||||
return self.directory.name
|
||||
|
||||
@property
|
||||
def config(self) -> Optional[ProjectConfig]:
|
||||
return self.parent.config.get_project_config(self.name)
|
||||
|
||||
@property
|
||||
def process_kwargs(self) -> Dict[str, Any]:
|
||||
directory: Path = self.directory
|
||||
project_name: str = self.name
|
||||
kiwi_hub_name: str = self.parent.config.network.name
|
||||
target_root_dir: Path = self.parent.config.storage.directory
|
||||
conf_dir: Path = target_root_dir.joinpath(CONF_DIRECTORY_NAME)
|
||||
target_dir: Path = target_root_dir.joinpath(project_name)
|
||||
|
||||
result: Dict[str, Any] = {
|
||||
"cwd": str(directory),
|
||||
"env": {
|
||||
"COMPOSE_PROJECT_NAME": project_name,
|
||||
"KIWI_HUB_NAME": kiwi_hub_name,
|
||||
"TARGETROOT": str(target_root_dir),
|
||||
"CONFDIR": str(conf_dir),
|
||||
"TARGETDIR": str(target_dir),
|
||||
},
|
||||
}
|
||||
|
||||
result["env"].update(self.parent.config.environment)
|
||||
|
||||
return result
|
||||
|
||||
@property
|
||||
def services(self) -> Services:
|
||||
yml = Project._parse_compose_file(self.directory)
|
||||
|
||||
return Services([
|
||||
Service(
|
||||
name=name,
|
||||
content=content,
|
||||
parent=self,
|
||||
) for name, content in yml["services"].items()
|
||||
])
|
44
kiwi_scp/service.py
Normal file
44
kiwi_scp/service.py
Normal file
|
@ -0,0 +1,44 @@
|
|||
import re
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
from typing import Generator
|
||||
|
||||
import attr
|
||||
from ruamel.yaml import CommentedMap
|
||||
|
||||
from .executable import COMPOSE_EXE
|
||||
from .project import Project
|
||||
|
||||
|
||||
@attr.s
|
||||
class Service:
|
||||
name: str = attr.ib()
|
||||
content: CommentedMap = attr.ib()
|
||||
parent: "Project" = attr.ib()
|
||||
|
||||
_RE_CONFDIR = re.compile(r"^\s*\$(?:CONFDIR|{CONFDIR})/+(.*)$", flags=re.UNICODE)
|
||||
|
||||
@property
|
||||
def configs(self) -> Generator[Path, None, None]:
|
||||
if "volumes" not in self.content:
|
||||
return
|
||||
|
||||
for volume in self.content["volumes"]:
|
||||
host_part = volume.split(":")[0]
|
||||
cd_match = Service._RE_CONFDIR.match(host_part)
|
||||
|
||||
if cd_match:
|
||||
yield Path(cd_match.group(1))
|
||||
|
||||
def has_executable(self, exe_name: str) -> bool:
|
||||
try:
|
||||
# test if desired executable exists
|
||||
COMPOSE_EXE.run(
|
||||
["exec", "-T", self.name, "/bin/sh", "-c", f"command -v {exe_name}"],
|
||||
check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL,
|
||||
**self.parent.process_kwargs,
|
||||
)
|
||||
return True
|
||||
|
||||
except subprocess.CalledProcessError:
|
||||
return False
|
36
kiwi_scp/services.py
Normal file
36
kiwi_scp/services.py
Normal file
|
@ -0,0 +1,36 @@
|
|||
from typing import List, Generator
|
||||
|
||||
import attr
|
||||
|
||||
from kiwi_scp.service import Service
|
||||
from kiwi_scp.yaml import YAML
|
||||
|
||||
|
||||
@attr.s
|
||||
class Services:
|
||||
content: List[Service] = attr.ib()
|
||||
|
||||
def __str__(self) -> str:
|
||||
return YAML().dump({
|
||||
"services": {
|
||||
service.name: service.content
|
||||
for service in self.content
|
||||
}
|
||||
}).strip()
|
||||
|
||||
def __bool__(self) -> bool:
|
||||
return bool(self.content)
|
||||
|
||||
@property
|
||||
def names(self) -> Generator[str, None, None]:
|
||||
return (
|
||||
service.name
|
||||
for service in self.content
|
||||
)
|
||||
|
||||
def filter_existing(self, service_names: List[str]) -> "Services":
|
||||
return Services([
|
||||
service
|
||||
for service in self.content
|
||||
if service.name in service_names
|
||||
])
|
|
@ -4,7 +4,7 @@ import pytest
|
|||
|
||||
from kiwi_scp._constants import COMPOSE_FILE_NAME
|
||||
from kiwi_scp.config import KiwiConfig
|
||||
from kiwi_scp.instance import Project
|
||||
from kiwi_scp.project import Project
|
||||
|
||||
|
||||
class TestDefault:
|
||||
|
|
|
@ -2,7 +2,7 @@ from pathlib import Path
|
|||
|
||||
from ruamel.yaml import CommentedMap
|
||||
|
||||
from kiwi_scp.instance import Service
|
||||
from kiwi_scp.service import Service
|
||||
|
||||
|
||||
class TestDefault:
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
from ruamel.yaml import CommentedMap
|
||||
|
||||
from kiwi_scp.instance import Service, Services
|
||||
from kiwi_scp.services import Services
|
||||
from kiwi_scp.service import Service
|
||||
|
||||
|
||||
class TestServices:
|
||||
|
|
Loading…
Reference in a new issue