Rootkit implementation for copyconf (and other commands as root)
This commit is contained in:
parent
9907e72244
commit
366ed9b4fe
2 changed files with 108 additions and 30 deletions
|
@ -10,6 +10,7 @@ from .._constants import KIWI_ROOT
|
||||||
from ._subcommand import SubCommand
|
from ._subcommand import SubCommand
|
||||||
from .utils.dockercommand import DockerCommand
|
from .utils.dockercommand import DockerCommand
|
||||||
from .utils.project import list_projects, get_project_dir
|
from .utils.project import list_projects, get_project_dir
|
||||||
|
from .utils.rootkit import Rootkit, prefix_path
|
||||||
|
|
||||||
|
|
||||||
def _add_prefix(prefix, path):
|
def _add_prefix(prefix, path):
|
||||||
|
@ -27,43 +28,21 @@ class CopyConfCommand(SubCommand):
|
||||||
)
|
)
|
||||||
|
|
||||||
def run(self, runner, config, args):
|
def run(self, runner, config, args):
|
||||||
logging.info("Building image kiwi-config/auxiliary:rsync")
|
conf_dirs = []
|
||||||
DockerCommand('docker').run(
|
|
||||||
config, args,
|
|
||||||
[
|
|
||||||
'build',
|
|
||||||
'-t', 'kiwi-config/auxiliary:rsync',
|
|
||||||
'-f', f"{KIWI_ROOT}/images/rsync.Dockerfile",
|
|
||||||
f"{KIWI_ROOT}/images"
|
|
||||||
],
|
|
||||||
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL
|
|
||||||
)
|
|
||||||
|
|
||||||
conf_sources = []
|
|
||||||
|
|
||||||
for project_name in list_projects(config):
|
for project_name in list_projects(config):
|
||||||
project_conf = f"{get_project_dir(config, project_name)}/conf"
|
project_conf = f"{get_project_dir(config, project_name)}/conf"
|
||||||
|
|
||||||
if os.path.isdir(project_conf):
|
if os.path.isdir(project_conf):
|
||||||
conf_sources.append(project_conf)
|
conf_dirs.append(project_conf)
|
||||||
|
|
||||||
if conf_sources:
|
if conf_dirs:
|
||||||
print(f"Syncing {conf_sources} to '{config['runtime:storage']}'")
|
# add target directory
|
||||||
conf_sources = [f"'{_add_prefix('/mnt', src)}'" for src in conf_sources]
|
conf_dirs.append(config['runtime:storage'])
|
||||||
conf_sources = ' '.join(conf_sources)
|
logging.info(f"Sync directories: {conf_dirs}")
|
||||||
|
|
||||||
conf_target = f"'{_add_prefix('/mnt', config['runtime:storage'])}'"
|
Rootkit('rsync').run(
|
||||||
logging.debug(f"Config sources {conf_sources}, Config target {conf_target}")
|
config, args, ['rsync', '-r', *prefix_path(conf_dirs)],
|
||||||
|
|
||||||
DockerCommand('docker').run(
|
|
||||||
config, args,
|
|
||||||
[
|
|
||||||
'run', '--rm',
|
|
||||||
'-v', '/:/mnt',
|
|
||||||
'-u', 'root',
|
|
||||||
'kiwi-config/auxiliary:rsync',
|
|
||||||
'ash', '-c', f"rsync -r {conf_sources} {conf_target}"
|
|
||||||
],
|
|
||||||
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL
|
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
99
src/kiwi/subcommands/utils/rootkit.py
Normal file
99
src/kiwi/subcommands/utils/rootkit.py
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
# system
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
# parent
|
||||||
|
from ..._constants import KIWI_ROOT
|
||||||
|
|
||||||
|
# local
|
||||||
|
from .dockercommand import DockerCommand
|
||||||
|
|
||||||
|
|
||||||
|
def _prefix_path(prefix, path):
|
||||||
|
abs_path = os.path.abspath(path)
|
||||||
|
return os.path.realpath(prefix + '/' + abs_path)
|
||||||
|
|
||||||
|
|
||||||
|
def prefix_path(path):
|
||||||
|
if isinstance(path, str):
|
||||||
|
return _prefix_path('/mnt/', path)
|
||||||
|
elif isinstance(path, list):
|
||||||
|
return [_prefix_path('/mnt/', p) for p in path]
|
||||||
|
|
||||||
|
|
||||||
|
def _image_name(image_tag):
|
||||||
|
if image_tag is not None:
|
||||||
|
return f"kiwi-config/auxiliary:{image_tag}"
|
||||||
|
else:
|
||||||
|
return "alpine:latest"
|
||||||
|
|
||||||
|
|
||||||
|
class Rootkit:
|
||||||
|
class __Rootkit:
|
||||||
|
__image_tag = None
|
||||||
|
|
||||||
|
def __init__(self, image_tag=None):
|
||||||
|
self.__image_tag = image_tag
|
||||||
|
|
||||||
|
def __exists(self, config, args):
|
||||||
|
ps = DockerCommand('docker').run(
|
||||||
|
config, args, [
|
||||||
|
'images',
|
||||||
|
'--filter', f"reference={_image_name(self.__image_tag)}",
|
||||||
|
'--format', '{{.Repository}}:{{.Tag}}'
|
||||||
|
],
|
||||||
|
stdout=subprocess.PIPE
|
||||||
|
)
|
||||||
|
|
||||||
|
return str(ps.stdout, 'utf-8').strip() == _image_name(self.__image_tag)
|
||||||
|
|
||||||
|
def __build_image(self, config, args):
|
||||||
|
if self.__exists(config, args):
|
||||||
|
logging.info(f"Using image {_image_name(self.__image_tag)}")
|
||||||
|
else:
|
||||||
|
if self.__image_tag is None:
|
||||||
|
logging.info(f"Pulling image {_image_name(self.__image_tag)}")
|
||||||
|
DockerCommand('docker').run(
|
||||||
|
config, args, ['pull', _image_name(self.__image_tag)],
|
||||||
|
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL
|
||||||
|
)
|
||||||
|
|
||||||
|
else:
|
||||||
|
logging.info(f"Building image {_image_name(self.__image_tag)}")
|
||||||
|
DockerCommand('docker').run(
|
||||||
|
config, args,
|
||||||
|
[
|
||||||
|
'build',
|
||||||
|
'-t', _image_name(self.__image_tag),
|
||||||
|
'-f', f"{KIWI_ROOT}/images/{self.__image_tag}.Dockerfile",
|
||||||
|
f"{KIWI_ROOT}/images"
|
||||||
|
],
|
||||||
|
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL
|
||||||
|
)
|
||||||
|
|
||||||
|
def run(self, config, args, process_args, **kwargs):
|
||||||
|
self.__build_image(config, args)
|
||||||
|
DockerCommand('docker').run(
|
||||||
|
config, args,
|
||||||
|
[
|
||||||
|
'run', '--rm',
|
||||||
|
'-v', '/:/mnt',
|
||||||
|
'-u', 'root',
|
||||||
|
_image_name(self.__image_tag),
|
||||||
|
*process_args
|
||||||
|
],
|
||||||
|
**kwargs
|
||||||
|
)
|
||||||
|
|
||||||
|
__image_tag = None
|
||||||
|
__instances = {}
|
||||||
|
|
||||||
|
def __init__(self, image_tag=None):
|
||||||
|
self.__image_tag = image_tag
|
||||||
|
|
||||||
|
if _image_name(self.__image_tag) not in Rootkit.__instances:
|
||||||
|
Rootkit.__instances[_image_name(self.__image_tag)] = Rootkit.__Rootkit(image_tag)
|
||||||
|
|
||||||
|
def __getattr__(self, item):
|
||||||
|
return getattr(self.__instances[_image_name(self.__image_tag)], item)
|
Loading…
Reference in a new issue