conf-copy implemented
This commit is contained in:
parent
cbe4e422e0
commit
a35ba188b0
7 changed files with 93 additions and 46 deletions
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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] = {
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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]:
|
||||||
|
|
Loading…
Reference in a new issue