kiwi-scp/kiwi_scp/instance.py

109 lines
3.2 KiB
Python
Raw Permalink Normal View History

2022-02-21 15:42:12 +00:00
import logging
import subprocess
2021-10-22 15:50:26 +00:00
from pathlib import Path
2021-12-02 18:32:38 +00:00
from typing import Generator, Dict, Sequence
2021-10-22 15:50:26 +00:00
import attr
2022-01-27 16:57:15 +00:00
from ._constants import KIWI_CONF_NAME, CONFIG_DIRECTORY_NAME
2021-12-02 16:08:14 +00:00
from .config import KiwiConfig
2022-02-21 15:42:12 +00:00
from .executable import DOCKER_EXE
2021-12-02 16:08:14 +00:00
from .project import Project
2021-11-03 15:32:01 +00:00
2022-02-21 15:42:12 +00:00
_logger = logging.getLogger(__name__)
2021-11-03 15:32:01 +00:00
@attr.s
2021-11-03 15:32:01 +00:00
class Instance:
directory: Path = attr.ib(default=Path('.'))
@property
def config(self) -> KiwiConfig:
"""shorthand: get the current configuration"""
return KiwiConfig.from_directory(self.directory)
2022-01-20 09:20:57 +00:00
def save_config(self, config: KiwiConfig) -> None:
with open(self.directory.joinpath(KIWI_CONF_NAME), "w") as file:
config.dump_kiwi_yml(file)
2022-01-27 16:57:15 +00:00
@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)
2022-02-21 15:42:12 +00:00
@staticmethod
def __find_net(net_name):
ps = DOCKER_EXE.run([
"network", "ls", "--filter", f"name={net_name}", "--format", "{{.Name}}"
], stdout=subprocess.PIPE)
net_found = str(ps.stdout, 'utf-8').strip()
return net_found == net_name
def create_net(self):
net_name = self.config.network.name
net_cidr = str(self.config.network.cidr)
if self.__find_net(net_name):
_logger.info(f"Network '{net_name}' already exists")
return
try:
DOCKER_EXE.run([
"network", "create",
"--driver", "bridge",
"--internal",
"--subnet", net_cidr,
net_name
], check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
_logger.info(f"Network '{net_name}' created")
except subprocess.CalledProcessError:
_logger.error(f"Error creating network '{net_name}'")
def remove_net(self):
net_name = self.config.network.name
if not self.__find_net(net_name):
_logger.info(f"Network '{net_name}' does not exist")
return
try:
DOCKER_EXE.run([
"network", "rm",
net_name
], check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
_logger.info(f"Network '{net_name}' removed")
except subprocess.CalledProcessError:
_logger.error(f"Error removing network '{net_name}'")
@property
def projects(self) -> Generator[Project, None, None]:
2021-12-02 01:38:29 +00:00
for project in self.config.projects:
yield Project(
directory=self.directory.joinpath(project.name),
2022-01-27 14:26:10 +00:00
parent_instance=self,
)
2021-12-02 18:32:38 +00:00
def get_projects(self, project_names: Sequence[str]) -> Dict[str, Project]:
existing_projects = {
project.name: project
for project in self.projects
if project.name in project_names
}
nonexistent_projects = {
name: None
for name in project_names
if name not in existing_projects
}
return {
**existing_projects,
**nonexistent_projects
}