2020-08-17 15:56:29 +00:00
|
|
|
# system
|
|
|
|
import logging
|
|
|
|
import os
|
|
|
|
import subprocess
|
|
|
|
|
|
|
|
# local
|
|
|
|
from .dockercommand import DockerCommand
|
|
|
|
|
2020-08-18 10:28:59 +00:00
|
|
|
# parent
|
|
|
|
from ..._constants import IMAGES_DIRECTORY_NAME, LOCAL_IMAGES_NAME, DEFAULT_IMAGE_NAME
|
|
|
|
|
2020-08-17 15:56:29 +00:00
|
|
|
|
|
|
|
def _prefix_path(prefix, path):
|
|
|
|
if isinstance(path, str):
|
2020-08-18 10:24:55 +00:00
|
|
|
abs_path = os.path.abspath(path)
|
|
|
|
return os.path.realpath(f"{prefix}/{abs_path}")
|
2020-08-19 14:10:56 +00:00
|
|
|
|
2020-08-17 15:56:29 +00:00
|
|
|
elif isinstance(path, list):
|
2020-08-18 10:24:55 +00:00
|
|
|
return [_prefix_path(prefix, p) for p in path]
|
|
|
|
|
|
|
|
|
2020-08-18 10:28:59 +00:00
|
|
|
def prefix_path_mnt(path):
|
2020-08-18 10:24:55 +00:00
|
|
|
return _prefix_path('/mnt/', path)
|
2020-08-17 15:56:29 +00:00
|
|
|
|
|
|
|
|
|
|
|
def _image_name(image_tag):
|
|
|
|
if image_tag is not None:
|
2020-08-18 10:24:55 +00:00
|
|
|
return f"{LOCAL_IMAGES_NAME}:{image_tag}"
|
2020-08-17 15:56:29 +00:00
|
|
|
else:
|
2020-08-18 10:24:55 +00:00
|
|
|
return DEFAULT_IMAGE_NAME
|
2020-08-17 15:56:29 +00:00
|
|
|
|
|
|
|
|
|
|
|
class Rootkit:
|
|
|
|
class __Rootkit:
|
|
|
|
__image_tag = None
|
|
|
|
|
|
|
|
def __init__(self, image_tag=None):
|
|
|
|
self.__image_tag = image_tag
|
|
|
|
|
2020-08-19 14:10:56 +00:00
|
|
|
def __exists(self):
|
|
|
|
ps = DockerCommand('docker').run(None, [
|
|
|
|
'images',
|
|
|
|
'--filter', f"reference={_image_name(self.__image_tag)}",
|
|
|
|
'--format', '{{.Repository}}:{{.Tag}}'
|
|
|
|
], stdout=subprocess.PIPE)
|
2020-08-17 15:56:29 +00:00
|
|
|
|
|
|
|
return str(ps.stdout, 'utf-8').strip() == _image_name(self.__image_tag)
|
|
|
|
|
2020-08-19 14:10:56 +00:00
|
|
|
def __build_image(self):
|
|
|
|
if self.__exists():
|
2020-08-17 15:56:29 +00:00
|
|
|
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)}")
|
2020-08-19 14:10:56 +00:00
|
|
|
DockerCommand('docker').run(None, [
|
|
|
|
'pull', _image_name(self.__image_tag)
|
|
|
|
], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
2020-08-17 15:56:29 +00:00
|
|
|
|
|
|
|
else:
|
|
|
|
logging.info(f"Building image {_image_name(self.__image_tag)}")
|
2020-08-19 14:10:56 +00:00
|
|
|
DockerCommand('docker').run(None, [
|
|
|
|
'build',
|
|
|
|
'-t', _image_name(self.__image_tag),
|
|
|
|
'-f', f"{IMAGES_DIRECTORY_NAME}/{self.__image_tag}.Dockerfile",
|
|
|
|
f"{IMAGES_DIRECTORY_NAME}"
|
|
|
|
], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
|
|
|
|
|
|
|
def run(self, process_args, **kwargs):
|
|
|
|
self.__build_image()
|
|
|
|
DockerCommand('docker').run(None, [
|
|
|
|
'run', '--rm',
|
|
|
|
'-v', '/:/mnt',
|
|
|
|
'-u', 'root',
|
|
|
|
_image_name(self.__image_tag),
|
|
|
|
*process_args
|
|
|
|
], **kwargs)
|
2020-08-17 15:56:29 +00:00
|
|
|
|
|
|
|
__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)
|