conf-copy implemented

This commit is contained in:
Jörn-Michael Miehe 2022-01-27 17:57:15 +01:00
parent cbe4e422e0
commit a35ba188b0
7 changed files with 93 additions and 46 deletions

View file

@ -1,9 +1,5 @@
import os import os
RESERVED_PROJECT_NAMES = [
'config'
]
############# #############
# REGEX PARTS # REGEX PARTS
@ -40,6 +36,11 @@ CONF_DIRECTORY_NAME = 'config'
# location for auxiliary Dockerfiles # location for auxiliary Dockerfiles
IMAGES_DIRECTORY_NAME = f"{KIWI_ROOT}/data/images" IMAGES_DIRECTORY_NAME = f"{KIWI_ROOT}/data/images"
# prohibited project names
RESERVED_PROJECT_NAMES = [
CONFIG_DIRECTORY_NAME,
]
#################### ####################
# DOCKER IMAGE NAMES # DOCKER IMAGE NAMES

View file

@ -53,15 +53,12 @@ class UpdateCommand(KiwiCommand):
): ):
return return
# services.copy_configs()
# return
ctx = get_current_context() ctx = get_current_context()
assert isinstance(BuildCommand, click.Command) assert isinstance(BuildCommand, click.Command)
ctx.forward(BuildCommand) ctx.forward(BuildCommand)
assert isinstance(PullCommand, click.Command) assert isinstance(PullCommand, click.Command)
ctx.forward(PullCommand) ctx.forward(PullCommand)
# TODO conf-copy services.copy_configs()
assert isinstance(DownCommand, click.Command) assert isinstance(DownCommand, click.Command)
ctx.forward(DownCommand) ctx.forward(DownCommand)
assert isinstance(UpCommand, click.Command) assert isinstance(UpCommand, click.Command)

View file

@ -3,7 +3,7 @@ from typing import Generator, Dict, Sequence
import attr import attr
from ._constants import KIWI_CONF_NAME from ._constants import KIWI_CONF_NAME, CONFIG_DIRECTORY_NAME
from .config import KiwiConfig from .config import KiwiConfig
from .project import Project from .project import Project
@ -22,6 +22,14 @@ class Instance:
with open(self.directory.joinpath(KIWI_CONF_NAME), "w") as file: with open(self.directory.joinpath(KIWI_CONF_NAME), "w") as file:
config.dump_kiwi_yml(file) config.dump_kiwi_yml(file)
@property
def config_directory(self):
return self.directory.joinpath(CONFIG_DIRECTORY_NAME)
@property
def storage_config_directory(self):
return self.config.storage.directory.joinpath(CONFIG_DIRECTORY_NAME)
@property @property
def projects(self) -> Generator[Project, None, None]: def projects(self) -> Generator[Project, None, None]:
for project in self.config.projects: for project in self.config.projects:

View file

@ -5,7 +5,7 @@ from typing import TYPE_CHECKING, Optional, Dict, Any
import attr import attr
from ruamel.yaml import CommentedMap from ruamel.yaml import CommentedMap
from ._constants import COMPOSE_FILE_NAME, CONF_DIRECTORY_NAME from ._constants import COMPOSE_FILE_NAME, CONFIG_DIRECTORY_NAME
from .config import ProjectConfig from .config import ProjectConfig
from .service import Service from .service import Service
from .services import Services from .services import Services
@ -40,7 +40,7 @@ class Project:
project_name: str = self.name project_name: str = self.name
kiwi_hub_name: str = self.parent_instance.config.network.name kiwi_hub_name: str = self.parent_instance.config.network.name
target_root_dir: Path = self.parent_instance.config.storage.directory target_root_dir: Path = self.parent_instance.config.storage.directory
conf_dir: Path = target_root_dir.joinpath(CONF_DIRECTORY_NAME) conf_dir: Path = target_root_dir.joinpath(CONFIG_DIRECTORY_NAME)
target_dir: Path = target_root_dir.joinpath(project_name) target_dir: Path = target_root_dir.joinpath(project_name)
result: Dict[str, Any] = { result: Dict[str, Any] = {

View file

@ -2,7 +2,7 @@ import functools
import logging import logging
import subprocess import subprocess
from pathlib import Path from pathlib import Path
from typing import Optional, TypeVar, Union, List from typing import Optional, TypeVar, Union, Sequence, Any
import attr import attr
@ -11,18 +11,7 @@ from .executable import DOCKER_EXE
_logger = logging.getLogger(__name__) _logger = logging.getLogger(__name__)
PSL = TypeVar("PSL", Union[Path, str], List[Union[Path, str]]) ROOTKIT_PREFIX = Path("/mnt")
def prefix_path(path: PSL, prefix: Path = Path("/mnt")) -> PSL:
if isinstance(path, Path):
return prefix.joinpath(path.absolute())
if isinstance(path, str):
return prefix_path(Path(path), prefix)
elif isinstance(path, list):
return [prefix_path(prefix, p) for p in path]
@attr.s @attr.s
@ -68,11 +57,38 @@ class Rootkit:
], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) ], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
def run(self, process_args, **kwargs) -> Optional[subprocess.CompletedProcess]: def run(self, process_args, **kwargs) -> Optional[subprocess.CompletedProcess]:
any_sequence = TypeVar("any_sequence", Union[str, Path, Any], Sequence[Union[str, Path, Any]])
def parse_args(argument: any_sequence) -> any_sequence:
if isinstance(argument, str):
return argument
elif isinstance(argument, Path):
if argument.is_absolute():
argument = argument.relative_to("/")
return str(ROOTKIT_PREFIX.joinpath(argument))
elif not isinstance(argument, Sequence):
return str(argument)
else:
parsed = [parse_args(path) for path in argument]
flat = []
for item in parsed:
if not isinstance(item, list):
flat.append(item)
else:
flat.extend(item)
return flat
self.__build_image() self.__build_image()
return DOCKER_EXE.run([ return DOCKER_EXE.run([
'run', '--rm', "run", "--rm",
'-v', '/:/mnt', "-v", f"/:{ROOTKIT_PREFIX!s}",
'-u', 'root', "-u", "root",
Rootkit.__image_name(self.image_tag), Rootkit.__image_name(self.image_tag),
*process_args *parse_args(process_args)
], **kwargs) ], **kwargs)

View file

@ -25,10 +25,6 @@ class Service:
_RE_CONFIGDIR = re.compile(r"^\s*\$(?:CONFIGDIR|{CONFIGDIR})/+(.*)$", flags=re.UNICODE) _RE_CONFIGDIR = re.compile(r"^\s*\$(?:CONFIGDIR|{CONFIGDIR})/+(.*)$", flags=re.UNICODE)
@property
def parent_instance(self) -> "Instance":
return self.parent_project.parent_instance
@property @property
def configs(self) -> Generator[Path, None, None]: def configs(self) -> Generator[Path, None, None]:
if "volumes" not in self.content: if "volumes" not in self.content:

View file

@ -1,12 +1,14 @@
import subprocess
from pathlib import Path from pathlib import Path
from typing import List, Generator, Optional, TYPE_CHECKING from typing import List, Generator, Optional, TYPE_CHECKING, TypeVar, Union
import attr import attr
from .rootkit import Rootkit
from .yaml import YAML from .yaml import YAML
if TYPE_CHECKING: if TYPE_CHECKING:
from .instance import Instance from .project import Project
from .service import Service from .service import Service
@ -19,33 +21,60 @@ class Services:
"services": { "services": {
service.name: service.content service.name: service.content
for service in self.content for service in self.content
} },
"configs": [
str(config)
for config in self.configs
],
}).strip() }).strip()
def __bool__(self) -> bool: def __bool__(self) -> bool:
return bool(self.content) return bool(self.content)
@property @property
def parent_instance(self) -> Optional["Instance"]: def parent_project(self) -> Optional["Project"]:
if not self: if not self:
return return
return self.content[0].parent_instance return self.content[0].parent_project
@property @property
def configs(self) -> Generator[Path, None, None]: def configs(self) -> Generator[Path, None, None]:
for service in self.content: for service in self.content:
yield from service.configs yield from service.configs
# def copy_configs(self) -> None: def copy_configs(self) -> None:
# instance = self.parent_instance path_str_list = TypeVar("path_str_list", Union[Path, str], List[Union[Path, str]])
#
# if instance is None: def prefix_path(path: path_str_list, prefix: Path) -> path_str_list:
# return if isinstance(path, Path):
# return prefix.absolute().joinpath(path)
# print(list(self.configs))
# elif isinstance(path, str):
# # Rootkit("rsync"). return prefix_path(Path(path), prefix)
elif isinstance(path, list):
return [prefix_path(p, prefix) for p in path]
project = self.parent_project
if project is None:
return
instance = project.parent_instance
cfgs = list(self.configs)
local_cfgs = prefix_path(cfgs, instance.config_directory)
storage_cfgs = prefix_path(cfgs, instance.storage_config_directory)
storage_dirs = [path.parent for path in storage_cfgs]
Rootkit("rsync").run([
"mkdir", "-p", storage_dirs
], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
Rootkit("rsync").run([
"rsync", "-rpt", list(zip(local_cfgs, storage_cfgs))
], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
@property @property
def names(self) -> Generator[str, None, None]: def names(self) -> Generator[str, None, None]: