kupferbootstrap/wrapper/__init__.py

87 lines
2.7 KiB
Python
Raw Normal View History

import click
import logging
from typing import Optional, Sequence, Union
2022-08-20 03:44:15 +02:00
from config.state import config
2022-08-20 03:44:15 +02:00
from constants import Arch
from utils import programs_available
from .docker import DockerWrapper
2022-02-17 16:25:31 +01:00
from .wrapper import Wrapper
2022-02-17 16:25:31 +01:00
wrapper_impls: dict[str, Wrapper] = {
'docker': DockerWrapper(),
}
2021-08-04 18:36:37 +02:00
2021-08-08 18:32:42 +02:00
def get_wrapper_type(wrapper_type: Optional[str] = None) -> str:
return wrapper_type or config.file.wrapper.type
2021-08-04 18:36:37 +02:00
def get_wrapper_impl(wrapper_type: Optional[str] = None) -> Wrapper:
2022-02-17 16:25:31 +01:00
return wrapper_impls[get_wrapper_type(wrapper_type)]
def wrap(wrapper_type: Optional[str] = None):
wrapper_type = get_wrapper_type(wrapper_type)
if wrapper_type != 'none':
2022-02-17 16:25:31 +01:00
get_wrapper_impl(wrapper_type).wrap()
def is_wrapped(wrapper_type: Optional[str] = None) -> bool:
wrapper_type = get_wrapper_type(wrapper_type)
return wrapper_type != 'none' and get_wrapper_impl(wrapper_type).is_wrapped()
def needs_wrap(wrapper_type: Optional[str] = None) -> bool:
wrapper_type = wrapper_type or get_wrapper_type()
return wrapper_type != 'none' and not is_wrapped(wrapper_type) and not config.runtime.no_wrap
def enforce_wrap(no_wrapper=False):
wrapper_type = get_wrapper_type()
if needs_wrap(wrapper_type) and not no_wrapper:
logging.info(f'Wrapping in {wrapper_type}')
wrap()
2022-08-20 03:44:15 +02:00
def check_programs_wrap(programs: Union[str, Sequence[str]]):
if not programs_available(programs):
2022-08-20 03:44:15 +02:00
logging.debug(f"Wrapping because one of {[programs] if isinstance(programs, str) else programs} isn't available.")
enforce_wrap()
def wrap_if_foreign_arch(arch: Arch):
if arch != config.runtime.arch:
enforce_wrap()
2023-03-13 05:54:10 +01:00
def execute_without_exit(f, argv_override: Optional[list[str]], *args, **kwargs):
"""If no wrap is needed, executes and returns f(*args, **kwargs).
If a wrap is determined to be necessary, force a wrap with argv_override applied.
If a wrap was forced, None is returned.
WARNING: No protection against f() returning None is taken."""
if not needs_wrap():
return f(*args, **kwargs)
assert get_wrapper_type() != 'none', "needs_wrap() should've returned False"
w = get_wrapper_impl()
w_cmd = w.argv_override
# we need to avoid throwing and catching SystemExit due to FDs getting closed otherwise
w_should_exit = w.should_exit
w.argv_override = argv_override
w.should_exit = False
w.wrap()
w.argv_override = w_cmd
w.should_exit = w_should_exit
return None
nowrapper_option = click.option(
2022-08-27 04:59:18 +02:00
'-w/-W',
'--force-wrapper/--no-wrapper',
'wrapper_override',
is_flag=True,
2022-08-27 04:59:18 +02:00
default=None,
help='Force or disable the docker wrapper. Defaults to autodetection.',
)