wrapper/: introduce Wrapper protocol
This commit is contained in:
parent
3fbda2e089
commit
14a2d0ae12
3 changed files with 37 additions and 12 deletions
|
@ -1,13 +1,13 @@
|
||||||
import os
|
|
||||||
import click
|
import click
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from config import config
|
from config import config
|
||||||
from utils import programs_available
|
from utils import programs_available
|
||||||
from .docker import DockerWrapper
|
from .docker import DockerWrapper
|
||||||
|
from .wrapper import Wrapper
|
||||||
|
|
||||||
wrapper_impls = {
|
wrapper_impls: dict[str, Wrapper] = {
|
||||||
'docker': DockerWrapper,
|
'docker': DockerWrapper(),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -15,15 +15,18 @@ def get_wrapper_type(wrapper_type: str = None):
|
||||||
return wrapper_type or config.file['wrapper']['type']
|
return wrapper_type or config.file['wrapper']['type']
|
||||||
|
|
||||||
|
|
||||||
|
def get_wrapper_impl(wrapper_type: str = None) -> Wrapper:
|
||||||
|
return wrapper_impls[get_wrapper_type(wrapper_type)]
|
||||||
|
|
||||||
|
|
||||||
def wrap(wrapper_type: str = None):
|
def wrap(wrapper_type: str = None):
|
||||||
wrapper_type = get_wrapper_type(wrapper_type)
|
wrapper_type = get_wrapper_type(wrapper_type)
|
||||||
if wrapper_type != 'none':
|
if wrapper_type != 'none':
|
||||||
wrapper_impls[wrapper_type]().wrap()
|
get_wrapper_impl(wrapper_type).wrap()
|
||||||
|
|
||||||
|
|
||||||
def is_wrapped(wrapper_type: str = None):
|
def is_wrapped(wrapper_type: str = None):
|
||||||
wrapper_type = get_wrapper_type(wrapper_type)
|
return get_wrapper_impl(wrapper_type).is_wrapped()
|
||||||
return os.getenv('KUPFERBOOTSTRAP_WRAPPED') == wrapper_type.capitalize()
|
|
||||||
|
|
||||||
|
|
||||||
def enforce_wrap(no_wrapper=False):
|
def enforce_wrap(no_wrapper=False):
|
||||||
|
|
|
@ -19,7 +19,7 @@ def docker_volumes_args(volume_mappings: dict[str, str]) -> list[str]:
|
||||||
|
|
||||||
|
|
||||||
class DockerWrapper(BaseWrapper):
|
class DockerWrapper(BaseWrapper):
|
||||||
type = 'docker'
|
type: str = 'docker'
|
||||||
|
|
||||||
def wrap(self):
|
def wrap(self):
|
||||||
script_path = config.runtime['script_source_dir']
|
script_path = config.runtime['script_source_dir']
|
||||||
|
|
|
@ -3,15 +3,33 @@ import os
|
||||||
import uuid
|
import uuid
|
||||||
import pathlib
|
import pathlib
|
||||||
|
|
||||||
|
from typing import Protocol
|
||||||
|
|
||||||
from config import config, dump_file as dump_config_file
|
from config import config, dump_file as dump_config_file
|
||||||
from constants import CHROOT_PATHS
|
from constants import CHROOT_PATHS
|
||||||
|
|
||||||
|
|
||||||
class BaseWrapper:
|
class Wrapper(Protocol):
|
||||||
id = None
|
"""Wrappers wrap kupferbootstrap in some form of isolation from the host OS, i.e. docker or chroots"""
|
||||||
identifier = None
|
|
||||||
type = None
|
def wrap(self):
|
||||||
wrapped_config_path = None
|
"""Instructs the wrapper to reexecute kupferbootstrap in a wrapped environment"""
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
"""Instructs the wrapper to stop the wrapped instance and clean up"""
|
||||||
|
|
||||||
|
def is_wrapped(self) -> bool:
|
||||||
|
"""
|
||||||
|
Queries the wrapper whether it believes we're executing wrapped by it currently.
|
||||||
|
Checks `env[KUPFERBOOTSTRAP_WRAPPED] == self.type.capitalize()` by default.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class BaseWrapper(Wrapper):
|
||||||
|
id: str
|
||||||
|
identifier: str
|
||||||
|
type: str
|
||||||
|
wrapped_config_path: str
|
||||||
|
|
||||||
def __init__(self, random_id: str = None, name: str = None):
|
def __init__(self, random_id: str = None, name: str = None):
|
||||||
self.uuid = str(random_id or uuid.uuid4())
|
self.uuid = str(random_id or uuid.uuid4())
|
||||||
|
@ -49,6 +67,7 @@ class BaseWrapper:
|
||||||
) -> str:
|
) -> str:
|
||||||
wrapped_config = f'{target_path.rstrip("/")}/{self.identifier}_wrapped.toml'
|
wrapped_config = f'{target_path.rstrip("/")}/{self.identifier}_wrapped.toml'
|
||||||
|
|
||||||
|
# FIXME: these at_exit hooks should go and be called from somewhere better suited
|
||||||
def at_exit():
|
def at_exit():
|
||||||
self.stop()
|
self.stop()
|
||||||
os.remove(wrapped_config)
|
os.remove(wrapped_config)
|
||||||
|
@ -73,6 +92,9 @@ class BaseWrapper:
|
||||||
def stop(self):
|
def stop(self):
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
def is_wrapped(self):
|
||||||
|
return os.getenv('KUPFERBOOTSTRAP_WRAPPED') == self.type.capitalize()
|
||||||
|
|
||||||
def get_bind_mounts_default(self, wrapped_config_path: str = None, ssh_dir: str = None, target_home: str = '/root'):
|
def get_bind_mounts_default(self, wrapped_config_path: str = None, ssh_dir: str = None, target_home: str = '/root'):
|
||||||
wrapped_config_path = wrapped_config_path or self.wrapped_config_path
|
wrapped_config_path = wrapped_config_path or self.wrapped_config_path
|
||||||
ssh_dir = ssh_dir or os.path.join(pathlib.Path.home(), '.ssh')
|
ssh_dir = ssh_dir or os.path.join(pathlib.Path.home(), '.ssh')
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue