You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
pyentrypoint/pyentrypoint/command.py

123 lines
4.0 KiB
Python

"Command object"
import os
from fnmatch import fnmatch
from .logs import Logs
from .runner import Runner
class Command(object):
"""This object handle command in dockerfile"""
def __init__(self, command, config, args):
self.config = config
self.args = args
self.command = command
self.env = os.environ
self.log = Logs().log
self.log.debug('Handled command is: {cmd}'.format(cmd=self.command))
self.log.debug('Arguments are: "{args}"'.format(
args='" "'.join(self.args)
))
self.runner = Runner(config=self.config,
cmds=self.config.post_run_commands)
def _rm_dockerenv(self):
"""Delete '/.dockerenv' and '/.dockerinit' files"""
files = ['/.dockerenv', '/.dockerinit']
for f in files:
if os.path.isfile(f):
self.log.debug('Removing {file} file'.format(file=f))
os.unlink(f)
def _clean_links_env(self):
# TODO: that Looks too much complicated
all_link_names = []
def is_link_env(env, links):
for link in links:
patterns = [
'{}_NAME'.format(link.upper()),
'{}_PORT_*'.format(link.upper()),
'{}_ENV_*'.format(link.upper()),
]
for patt in patterns:
if fnmatch(env, patt):
return True
return False
for link in self.config.links.all:
all_link_names.extend(link.names)
self.env = {env: val for env, val in os.environ.items()
if not is_link_env(env, all_link_names)}
def _clean_secret_env(self):
to_del = []
for key in self.env:
for item in self.config.secret_env:
if fnmatch(key, item):
self.log.debug("Secret env '{item}' match '{key}'".format(
item=item,
key=key,
))
to_del.append(key)
for item in to_del:
if item in self.env:
del(self.env[item])
@property
def is_handled(self):
if self.config.commands and self.args:
return [
p for p in self.config.commands if fnmatch(self.args[0], p)
]
subcom = self.config.subcommands
if not self.args or self.args[0] == self.command or \
[p for p in subcom if fnmatch(self.args[0], p)]:
self.log.debug("Command is handled")
return True
self.log.debug("Command is not handled")
return False
def _exec(self):
self.log.debug('Now running: "{args}"'.format(
args='" "'.join(self.args)
))
if not self.args[0]:
raise Exception('Nothing to run')
os.execvpe(self.args[0], self.args, self.env)
def _run_reloader(self):
if self.config.reload:
self.log.debug('Launching reloader process')
self.config.reload.run_in_process()
def _run_post_commands(self):
if self.config.post_run_commands:
self.log.debug('Running post run commands')
self.runner.run_in_process()
def run(self):
if not self.is_handled:
self._exec()
if self.config.remove_dockerenv:
self._rm_dockerenv()
if os.getuid() == 0:
os.setgid(self.config.group)
os.setuid(self.config.user)
self.log.debug('Set uid {uid} and gid {gid}'.format(
uid=self.config.user,
gid=self.config.group,
))
if self.config.clean_env:
self._clean_links_env()
self._clean_secret_env()
subcom = self.config.subcommands
if not self.args or \
[p for p in subcom if fnmatch(self.args[0], p)]:
self.args.insert(0, self.command)
self._run_reloader()
self._run_post_commands()
self._exec()