Call compose from Project objects
This commit is contained in:
parent
4290ed3743
commit
1f1f3b27b2
13 changed files with 80 additions and 117 deletions
|
@ -1,8 +1,10 @@
|
|||
# system
|
||||
import logging
|
||||
import subprocess
|
||||
|
||||
# local
|
||||
from . import subcommands
|
||||
from .subcommands.utils.executable import Executable
|
||||
from .parser import Parser
|
||||
|
||||
|
||||
|
@ -15,6 +17,16 @@ class Runner:
|
|||
__commands = []
|
||||
|
||||
def __init__(self):
|
||||
# probe for Docker access
|
||||
try:
|
||||
Executable('docker').run(
|
||||
['ps'],
|
||||
check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL
|
||||
)
|
||||
|
||||
except subprocess.CalledProcessError:
|
||||
raise PermissionError("Cannot access docker, please get into the docker group or run as root!")
|
||||
|
||||
# setup all subcommands
|
||||
for className in subcommands.__all__:
|
||||
cmd = getattr(subcommands, className)
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
# local
|
||||
from ._subcommand import ServiceCommand
|
||||
from .utils.dockercommand import DockerCommand
|
||||
|
||||
|
||||
class BuildCommand(ServiceCommand):
|
||||
|
@ -14,7 +13,6 @@ class BuildCommand(ServiceCommand):
|
|||
)
|
||||
|
||||
def _run_services(self, runner, args, project, services):
|
||||
DockerCommand('docker-compose').run(project, [
|
||||
'build', '--pull', *services
|
||||
])
|
||||
project.compose_run(['build', '--pull', *services])
|
||||
|
||||
return True
|
||||
|
|
|
@ -3,7 +3,6 @@ import logging
|
|||
|
||||
# local
|
||||
from ._subcommand import ProjectCommand
|
||||
from .utils.dockercommand import DockerCommand
|
||||
|
||||
|
||||
class CmdCommand(ProjectCommand):
|
||||
|
@ -36,8 +35,6 @@ class CmdCommand(ProjectCommand):
|
|||
logging.debug(f"Updated args: {args}")
|
||||
|
||||
# run with split compose_cmd argument
|
||||
DockerCommand('docker-compose').run(projects[0], [
|
||||
args.compose_cmd, *args.compose_args
|
||||
])
|
||||
projects[0].compose_run([args.compose_cmd, *args.compose_args])
|
||||
|
||||
return True
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
# local
|
||||
from ._subcommand import ServiceCommand
|
||||
from .utils.dockercommand import DockerCommand
|
||||
from .utils.misc import are_you_sure
|
||||
|
||||
|
||||
|
@ -27,16 +26,12 @@ class DownCommand(ServiceCommand):
|
|||
|
||||
def _run_projects(self, runner, args, projects):
|
||||
for project in projects:
|
||||
DockerCommand('docker-compose').run(project, [
|
||||
'down'
|
||||
])
|
||||
project.compose_run(['down'])
|
||||
|
||||
return True
|
||||
|
||||
def _run_services(self, runner, args, project, services):
|
||||
DockerCommand('docker-compose').run(project, [
|
||||
'stop', *services
|
||||
])
|
||||
DockerCommand('docker-compose').run(project, [
|
||||
'rm', '-f', *services
|
||||
])
|
||||
project.compose_run(['stop', *services])
|
||||
project.compose_run(['rm', '-f', *services])
|
||||
|
||||
return True
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
# local
|
||||
from ._subcommand import ServiceCommand
|
||||
from .utils.dockercommand import DockerCommand
|
||||
|
||||
|
||||
class LogsCommand(ServiceCommand):
|
||||
|
@ -31,10 +30,11 @@ class LogsCommand(ServiceCommand):
|
|||
if services:
|
||||
compose_cmd = [*compose_cmd, *args.services]
|
||||
|
||||
# use 'less' viewer if output will be static
|
||||
if args.follow:
|
||||
DockerCommand('docker-compose').run(project, compose_cmd)
|
||||
project.compose_run(compose_cmd)
|
||||
|
||||
else:
|
||||
DockerCommand('docker-compose').run_less(project, compose_cmd)
|
||||
# use 'less' viewer if output is static
|
||||
project.compose_run_less(compose_cmd)
|
||||
|
||||
return True
|
||||
|
|
|
@ -4,7 +4,7 @@ import subprocess
|
|||
|
||||
# local
|
||||
from ._subcommand import SubCommand
|
||||
from .utils.dockercommand import DockerCommand
|
||||
from .utils.executable import Executable
|
||||
from .utils.misc import are_you_sure
|
||||
|
||||
# parent
|
||||
|
@ -12,7 +12,7 @@ from ..config import LoadedConfig
|
|||
|
||||
|
||||
def _find_net(net_name):
|
||||
ps = DockerCommand('docker').run(None, [
|
||||
ps = Executable('docker').run([
|
||||
'network', 'ls', '--filter', f"name={net_name}", '--format', '{{.Name}}'
|
||||
], stdout=subprocess.PIPE)
|
||||
|
||||
|
@ -41,7 +41,7 @@ class NetUpCommand(SubCommand):
|
|||
return True
|
||||
|
||||
try:
|
||||
DockerCommand('docker').run(None, [
|
||||
Executable('docker').run([
|
||||
'network', 'create',
|
||||
'--driver', 'bridge',
|
||||
'--internal',
|
||||
|
@ -77,7 +77,7 @@ class NetDownCommand(SubCommand):
|
|||
try:
|
||||
if are_you_sure("This will bring down this instance's hub network!"):
|
||||
if runner.run('down'):
|
||||
DockerCommand('docker').run(None, [
|
||||
Executable('docker').run([
|
||||
'network', 'rm', net_name
|
||||
], check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
# local
|
||||
from ._subcommand import ServiceCommand
|
||||
from .utils.dockercommand import DockerCommand
|
||||
|
||||
|
||||
class PullCommand(ServiceCommand):
|
||||
|
@ -14,7 +13,6 @@ class PullCommand(ServiceCommand):
|
|||
)
|
||||
|
||||
def _run_services(self, runner, args, project, services):
|
||||
DockerCommand('docker-compose').run(project, [
|
||||
'pull', '--ignore-pull-failures', *services
|
||||
])
|
||||
project.compose_run(['pull', '--ignore-pull-failures', *services])
|
||||
|
||||
return True
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
# local
|
||||
from ._subcommand import ServiceCommand
|
||||
from .utils.dockercommand import DockerCommand
|
||||
|
||||
|
||||
class PushCommand(ServiceCommand):
|
||||
|
@ -14,7 +13,6 @@ class PushCommand(ServiceCommand):
|
|||
)
|
||||
|
||||
def _run_services(self, runner, args, project, services):
|
||||
DockerCommand('docker-compose').run(project, [
|
||||
'push', *services
|
||||
])
|
||||
project.compose_run(['push', *services])
|
||||
|
||||
return True
|
||||
|
|
|
@ -4,7 +4,6 @@ import subprocess
|
|||
|
||||
# local
|
||||
from ._subcommand import ServiceCommand
|
||||
from .utils.dockercommand import DockerCommand
|
||||
|
||||
# parent
|
||||
from ..config import LoadedConfig
|
||||
|
@ -18,9 +17,10 @@ def _service_has_executable(project, service, exe_name):
|
|||
|
||||
try:
|
||||
# test if desired shell exists
|
||||
DockerCommand('docker-compose').run(project, [
|
||||
'exec', service, '/bin/sh', '-c', f"which {exe_name}"
|
||||
], check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||
project.compose_run(
|
||||
['exec', service, '/bin/sh', '-c', f"which {exe_name}"],
|
||||
check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL
|
||||
)
|
||||
return True
|
||||
|
||||
except subprocess.CalledProcessError as e:
|
||||
|
@ -92,9 +92,7 @@ class ShCommand(ServiceCommand):
|
|||
|
||||
if shell is not None:
|
||||
# spawn shell
|
||||
DockerCommand('docker-compose').run(project, [
|
||||
'exec', service, shell
|
||||
])
|
||||
project.compose_run(['exec', service, shell])
|
||||
return True
|
||||
|
||||
return False
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
# local
|
||||
from ._subcommand import ServiceCommand
|
||||
from .utils.dockercommand import DockerCommand
|
||||
|
||||
|
||||
class UpCommand(ServiceCommand):
|
||||
|
@ -21,9 +20,7 @@ class UpCommand(ServiceCommand):
|
|||
|
||||
def _run_services(self, runner, args, project, services):
|
||||
if runner.run('net-up'):
|
||||
DockerCommand('docker-compose').run(project, [
|
||||
'up', '-d', *services
|
||||
])
|
||||
project.compose_run(['up', '-d', *services])
|
||||
return True
|
||||
|
||||
return False
|
||||
|
|
|
@ -1,67 +0,0 @@
|
|||
# system
|
||||
import logging
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
# local
|
||||
from .executable import Executable
|
||||
|
||||
# parent
|
||||
from ..._constants import CONF_DIRECTORY_NAME
|
||||
from ...config import LoadedConfig
|
||||
|
||||
|
||||
def _update_kwargs(project, **kwargs):
|
||||
# enabled project given: command affects a project in this instance
|
||||
if project is not None and project.is_enabled():
|
||||
config = LoadedConfig.get()
|
||||
|
||||
# execute command in project directory
|
||||
kwargs['cwd'] = project.dir_name()
|
||||
|
||||
# ensure there is an environment
|
||||
if 'env' not in kwargs:
|
||||
kwargs['env'] = {}
|
||||
|
||||
# create environment variables for docker commands
|
||||
kwargs['env'].update({
|
||||
'COMPOSE_PROJECT_NAME': project.get_name(),
|
||||
'KIWI_HUB_NAME': config['network:name'],
|
||||
'CONFDIR': os.path.join(config['runtime:storage'], CONF_DIRECTORY_NAME),
|
||||
'TARGETDIR': project.target_dir_name()
|
||||
})
|
||||
|
||||
logging.debug(f"kwargs updated: {kwargs}")
|
||||
|
||||
return kwargs
|
||||
|
||||
|
||||
class DockerCommand(Executable):
|
||||
__has_tried = False
|
||||
|
||||
def __init__(self, exe_name):
|
||||
super().__init__(exe_name)
|
||||
|
||||
if not DockerCommand.__has_tried:
|
||||
try:
|
||||
Executable('docker').run(
|
||||
['ps'],
|
||||
check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL
|
||||
)
|
||||
DockerCommand.__has_tried = True
|
||||
|
||||
except subprocess.CalledProcessError:
|
||||
raise PermissionError("Cannot access docker, please get into the docker group or run as root!")
|
||||
|
||||
def run(self, project, process_args, **kwargs):
|
||||
# equivalent to 'super().run' but agnostic of nested class construct
|
||||
return super().__getattr__("run")(
|
||||
process_args,
|
||||
**_update_kwargs(project, **kwargs)
|
||||
)
|
||||
|
||||
def run_less(self, project, process_args, **kwargs):
|
||||
return super().__getattr__("run_less")(
|
||||
process_args,
|
||||
**_update_kwargs(project, **kwargs)
|
||||
)
|
|
@ -1,6 +1,8 @@
|
|||
import logging
|
||||
import os
|
||||
|
||||
from .executable import Executable
|
||||
|
||||
from ..._constants import CONF_DIRECTORY_NAME
|
||||
from ...config import LoadedConfig
|
||||
|
||||
|
@ -63,6 +65,41 @@ class Project:
|
|||
def has_configs(self):
|
||||
return os.path.isdir(self.conf_dir_name())
|
||||
|
||||
def __update_kwargs(self, kwargs):
|
||||
if not self.is_enabled():
|
||||
# cannot compose in a disabled project
|
||||
logging.warning(f"Project '{self.get_name()}' is not enabled!")
|
||||
return False
|
||||
|
||||
config = LoadedConfig.get()
|
||||
|
||||
# execute command in project directory
|
||||
kwargs['cwd'] = self.dir_name()
|
||||
|
||||
# ensure there is an environment
|
||||
if 'env' not in kwargs:
|
||||
kwargs['env'] = {}
|
||||
|
||||
# create environment variables for docker commands
|
||||
kwargs['env'].update({
|
||||
'COMPOSE_PROJECT_NAME': self.get_name(),
|
||||
'KIWI_HUB_NAME': config['network:name'],
|
||||
'CONFDIR': os.path.join(config['runtime:storage'], CONF_DIRECTORY_NAME),
|
||||
'TARGETDIR': self.target_dir_name()
|
||||
})
|
||||
|
||||
logging.debug(f"kwargs updated: {kwargs}")
|
||||
|
||||
return True
|
||||
|
||||
def compose_run(self, compose_args, **kwargs):
|
||||
if self.__update_kwargs(kwargs):
|
||||
Executable('docker-compose').run(compose_args, **kwargs)
|
||||
|
||||
def compose_run_less(self, compose_args, **kwargs):
|
||||
if self.__update_kwargs(kwargs):
|
||||
Executable('docker-compose').run_less(compose_args, **kwargs)
|
||||
|
||||
def enable(self):
|
||||
if self.is_disabled():
|
||||
logging.info(f"Enabling project '{self.get_name()}'")
|
||||
|
|
|
@ -4,7 +4,7 @@ import os
|
|||
import subprocess
|
||||
|
||||
# local
|
||||
from .dockercommand import DockerCommand
|
||||
from .executable import Executable
|
||||
|
||||
# parent
|
||||
from ..._constants import IMAGES_DIRECTORY_NAME, LOCAL_IMAGES_NAME, DEFAULT_IMAGE_NAME
|
||||
|
@ -38,7 +38,7 @@ class Rootkit:
|
|||
self.__image_tag = image_tag
|
||||
|
||||
def __exists(self):
|
||||
ps = DockerCommand('docker').run(None, [
|
||||
ps = Executable('docker').run([
|
||||
'images',
|
||||
'--filter', f"reference={_image_name(self.__image_tag)}",
|
||||
'--format', '{{.Repository}}:{{.Tag}}'
|
||||
|
@ -52,13 +52,13 @@ class Rootkit:
|
|||
else:
|
||||
if self.__image_tag is None:
|
||||
logging.info(f"Pulling image {_image_name(self.__image_tag)}")
|
||||
DockerCommand('docker').run(None, [
|
||||
Executable('docker').run([
|
||||
'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(None, [
|
||||
Executable('docker').run([
|
||||
'build',
|
||||
'-t', _image_name(self.__image_tag),
|
||||
'-f', f"{IMAGES_DIRECTORY_NAME}/{self.__image_tag}.Dockerfile",
|
||||
|
@ -67,7 +67,7 @@ class Rootkit:
|
|||
|
||||
def run(self, process_args, **kwargs):
|
||||
self.__build_image()
|
||||
DockerCommand('docker').run(None, [
|
||||
Executable('docker').run([
|
||||
'run', '--rm',
|
||||
'-v', '/:/mnt',
|
||||
'-u', 'root',
|
||||
|
|
Loading…
Reference in a new issue