2021-08-04 18:36:37 +02:00
|
|
|
import atexit
|
|
|
|
import os
|
|
|
|
import subprocess
|
|
|
|
import sys
|
2021-08-17 20:42:17 +02:00
|
|
|
import uuid
|
2021-09-12 06:10:15 +02:00
|
|
|
import click
|
|
|
|
import logging
|
2021-09-13 15:44:44 +02:00
|
|
|
from config import config, dump_file as dump_config_file
|
|
|
|
|
|
|
|
DOCKER_PATHS = {
|
|
|
|
'chroots': '/chroot',
|
|
|
|
'jumpdrive': '/var/cache/jumpdrive',
|
|
|
|
'pacman': '/var/cache/pacman/pkg',
|
|
|
|
}
|
2021-08-04 18:36:37 +02:00
|
|
|
|
2021-09-12 06:10:15 +02:00
|
|
|
|
|
|
|
def wrap_docker():
|
2021-09-13 15:44:44 +02:00
|
|
|
|
|
|
|
def _docker_volumes(volume_mappings: dict[str, str]) -> list[str]:
|
|
|
|
result = []
|
|
|
|
for source, destination in volume_mappings.items():
|
|
|
|
result += ['-v', f'{source}:{destination}:z']
|
|
|
|
return result
|
|
|
|
|
2021-08-04 18:36:37 +02:00
|
|
|
script_path = os.path.dirname(os.path.abspath(__file__))
|
|
|
|
with open(os.path.join(script_path, 'version.txt')) as version_file:
|
|
|
|
version = version_file.read().replace('\n', '')
|
2021-08-08 18:16:39 +02:00
|
|
|
tag = f'registry.gitlab.com/kupfer/kupferbootstrap:{version}'
|
2021-08-04 18:36:37 +02:00
|
|
|
if version == 'dev':
|
2021-09-12 06:10:15 +02:00
|
|
|
logging.info(f'Building docker image "{tag}"')
|
|
|
|
cmd = [
|
|
|
|
'docker',
|
|
|
|
'build',
|
|
|
|
'.',
|
|
|
|
'-t',
|
|
|
|
tag,
|
|
|
|
] + (['-q'] if not config.runtime['verbose'] else [])
|
|
|
|
result = subprocess.run(cmd, cwd=script_path, capture_output=True)
|
2021-08-04 18:36:37 +02:00
|
|
|
if result.returncode != 0:
|
2021-09-12 06:10:15 +02:00
|
|
|
logging.fatal('Failed to build docker image:\n' + result.stderr.decode())
|
2021-08-04 18:36:37 +02:00
|
|
|
exit(1)
|
|
|
|
else:
|
|
|
|
# Check if the image for the version already exists
|
2021-08-08 18:32:42 +02:00
|
|
|
result = subprocess.run(
|
|
|
|
[
|
|
|
|
'docker',
|
|
|
|
'images',
|
|
|
|
'-q',
|
|
|
|
tag,
|
|
|
|
],
|
|
|
|
capture_output=True,
|
|
|
|
)
|
2021-08-04 18:36:37 +02:00
|
|
|
if result.stdout == b'':
|
2021-09-12 06:10:15 +02:00
|
|
|
logging.info(f'Pulling kupferbootstrap docker image version \'{version}\'')
|
2021-08-08 18:32:42 +02:00
|
|
|
subprocess.run([
|
|
|
|
'docker',
|
|
|
|
'pull',
|
|
|
|
tag,
|
|
|
|
])
|
2021-08-17 20:42:17 +02:00
|
|
|
container_name = f'kupferbootstrap-{str(uuid.uuid4())}'
|
2021-09-13 15:44:44 +02:00
|
|
|
wrapped_config = f'/tmp/kupfer/{container_name}_wrapped.toml'
|
2021-08-04 18:36:37 +02:00
|
|
|
|
|
|
|
def at_exit():
|
2021-08-08 18:32:42 +02:00
|
|
|
subprocess.run(
|
|
|
|
[
|
|
|
|
'docker',
|
|
|
|
'kill',
|
2021-08-17 20:42:17 +02:00
|
|
|
container_name,
|
2021-08-08 18:32:42 +02:00
|
|
|
],
|
|
|
|
stdout=subprocess.DEVNULL,
|
|
|
|
stderr=subprocess.DEVNULL,
|
|
|
|
)
|
2021-09-13 15:44:44 +02:00
|
|
|
os.remove(wrapped_config)
|
2021-08-08 18:32:42 +02:00
|
|
|
|
2021-08-04 18:36:37 +02:00
|
|
|
atexit.register(at_exit)
|
|
|
|
|
2021-09-13 15:44:44 +02:00
|
|
|
dump_config_file(file_path=wrapped_config, config=(config.file | {'paths': DOCKER_PATHS}))
|
|
|
|
volumes = {
|
|
|
|
'/dev': '/dev',
|
|
|
|
os.getcwd(): '/src',
|
|
|
|
wrapped_config: '/root/.config/kupfer/kupferbootstrap.toml',
|
|
|
|
}
|
|
|
|
volumes |= dict({(config.file['paths'][vol_name], vol_dest) for vol_name, vol_dest in DOCKER_PATHS.items()})
|
|
|
|
if os.getenv('KUPFERBOOTSTRAP_PREBUILTS'):
|
|
|
|
volumes |= {os.getenv("KUPFERBOOTSTRAP_PREBUILTS"): '/prebuilts'}
|
2021-09-12 06:10:15 +02:00
|
|
|
cmd = [
|
2021-08-08 18:32:42 +02:00
|
|
|
'docker',
|
|
|
|
'run',
|
|
|
|
'--name',
|
2021-08-17 20:42:17 +02:00
|
|
|
container_name,
|
2021-08-08 18:32:42 +02:00
|
|
|
'--rm',
|
|
|
|
'--interactive',
|
|
|
|
'--tty',
|
|
|
|
'--privileged',
|
2021-09-13 15:44:44 +02:00
|
|
|
] + _docker_volumes(volumes) + [tag, 'kupferbootstrap'] + sys.argv[1:]
|
2021-09-12 06:10:15 +02:00
|
|
|
logging.debug('Wrapping in docker:' + repr(cmd))
|
|
|
|
result = subprocess.run(cmd)
|
2021-08-17 20:42:17 +02:00
|
|
|
|
|
|
|
exit(result.returncode)
|
2021-09-12 06:10:15 +02:00
|
|
|
|
|
|
|
|
|
|
|
def enforce_wrap(no_wrapper=False):
|
|
|
|
if os.getenv('KUPFERBOOTSTRAP_DOCKER') != '1' and not no_wrapper:
|
|
|
|
wrap_docker()
|
|
|
|
|
|
|
|
|
|
|
|
nowrapper_option = click.option(
|
|
|
|
'--no-wrapper',
|
|
|
|
'no_wrapper',
|
|
|
|
is_flag=True,
|
|
|
|
default=False,
|
|
|
|
help='Disable the docker wrapper. Defaults to autodetection.',
|
|
|
|
)
|