mirror of
https://github.com/yavook/kiwi-scp.git
synced 2024-11-22 12:53:00 +00:00
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
|
# system
|
||||||
import logging
|
import logging
|
||||||
|
import subprocess
|
||||||
|
|
||||||
# local
|
# local
|
||||||
from . import subcommands
|
from . import subcommands
|
||||||
|
from .subcommands.utils.executable import Executable
|
||||||
from .parser import Parser
|
from .parser import Parser
|
||||||
|
|
||||||
|
|
||||||
|
@ -15,6 +17,16 @@ class Runner:
|
||||||
__commands = []
|
__commands = []
|
||||||
|
|
||||||
def __init__(self):
|
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
|
# setup all subcommands
|
||||||
for className in subcommands.__all__:
|
for className in subcommands.__all__:
|
||||||
cmd = getattr(subcommands, className)
|
cmd = getattr(subcommands, className)
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
# local
|
# local
|
||||||
from ._subcommand import ServiceCommand
|
from ._subcommand import ServiceCommand
|
||||||
from .utils.dockercommand import DockerCommand
|
|
||||||
|
|
||||||
|
|
||||||
class BuildCommand(ServiceCommand):
|
class BuildCommand(ServiceCommand):
|
||||||
|
@ -14,7 +13,6 @@ class BuildCommand(ServiceCommand):
|
||||||
)
|
)
|
||||||
|
|
||||||
def _run_services(self, runner, args, project, services):
|
def _run_services(self, runner, args, project, services):
|
||||||
DockerCommand('docker-compose').run(project, [
|
project.compose_run(['build', '--pull', *services])
|
||||||
'build', '--pull', *services
|
|
||||||
])
|
|
||||||
return True
|
return True
|
||||||
|
|
|
@ -3,7 +3,6 @@ import logging
|
||||||
|
|
||||||
# local
|
# local
|
||||||
from ._subcommand import ProjectCommand
|
from ._subcommand import ProjectCommand
|
||||||
from .utils.dockercommand import DockerCommand
|
|
||||||
|
|
||||||
|
|
||||||
class CmdCommand(ProjectCommand):
|
class CmdCommand(ProjectCommand):
|
||||||
|
@ -36,8 +35,6 @@ class CmdCommand(ProjectCommand):
|
||||||
logging.debug(f"Updated args: {args}")
|
logging.debug(f"Updated args: {args}")
|
||||||
|
|
||||||
# run with split compose_cmd argument
|
# run with split compose_cmd argument
|
||||||
DockerCommand('docker-compose').run(projects[0], [
|
projects[0].compose_run([args.compose_cmd, *args.compose_args])
|
||||||
args.compose_cmd, *args.compose_args
|
|
||||||
])
|
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
# local
|
# local
|
||||||
from ._subcommand import ServiceCommand
|
from ._subcommand import ServiceCommand
|
||||||
from .utils.dockercommand import DockerCommand
|
|
||||||
from .utils.misc import are_you_sure
|
from .utils.misc import are_you_sure
|
||||||
|
|
||||||
|
|
||||||
|
@ -27,16 +26,12 @@ class DownCommand(ServiceCommand):
|
||||||
|
|
||||||
def _run_projects(self, runner, args, projects):
|
def _run_projects(self, runner, args, projects):
|
||||||
for project in projects:
|
for project in projects:
|
||||||
DockerCommand('docker-compose').run(project, [
|
project.compose_run(['down'])
|
||||||
'down'
|
|
||||||
])
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def _run_services(self, runner, args, project, services):
|
def _run_services(self, runner, args, project, services):
|
||||||
DockerCommand('docker-compose').run(project, [
|
project.compose_run(['stop', *services])
|
||||||
'stop', *services
|
project.compose_run(['rm', '-f', *services])
|
||||||
])
|
|
||||||
DockerCommand('docker-compose').run(project, [
|
|
||||||
'rm', '-f', *services
|
|
||||||
])
|
|
||||||
return True
|
return True
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
# local
|
# local
|
||||||
from ._subcommand import ServiceCommand
|
from ._subcommand import ServiceCommand
|
||||||
from .utils.dockercommand import DockerCommand
|
|
||||||
|
|
||||||
|
|
||||||
class LogsCommand(ServiceCommand):
|
class LogsCommand(ServiceCommand):
|
||||||
|
@ -31,10 +30,11 @@ class LogsCommand(ServiceCommand):
|
||||||
if services:
|
if services:
|
||||||
compose_cmd = [*compose_cmd, *args.services]
|
compose_cmd = [*compose_cmd, *args.services]
|
||||||
|
|
||||||
# use 'less' viewer if output will be static
|
|
||||||
if args.follow:
|
if args.follow:
|
||||||
DockerCommand('docker-compose').run(project, compose_cmd)
|
project.compose_run(compose_cmd)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
DockerCommand('docker-compose').run_less(project, compose_cmd)
|
# use 'less' viewer if output is static
|
||||||
|
project.compose_run_less(compose_cmd)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
|
@ -4,7 +4,7 @@ import subprocess
|
||||||
|
|
||||||
# local
|
# local
|
||||||
from ._subcommand import SubCommand
|
from ._subcommand import SubCommand
|
||||||
from .utils.dockercommand import DockerCommand
|
from .utils.executable import Executable
|
||||||
from .utils.misc import are_you_sure
|
from .utils.misc import are_you_sure
|
||||||
|
|
||||||
# parent
|
# parent
|
||||||
|
@ -12,7 +12,7 @@ from ..config import LoadedConfig
|
||||||
|
|
||||||
|
|
||||||
def _find_net(net_name):
|
def _find_net(net_name):
|
||||||
ps = DockerCommand('docker').run(None, [
|
ps = Executable('docker').run([
|
||||||
'network', 'ls', '--filter', f"name={net_name}", '--format', '{{.Name}}'
|
'network', 'ls', '--filter', f"name={net_name}", '--format', '{{.Name}}'
|
||||||
], stdout=subprocess.PIPE)
|
], stdout=subprocess.PIPE)
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ class NetUpCommand(SubCommand):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
try:
|
try:
|
||||||
DockerCommand('docker').run(None, [
|
Executable('docker').run([
|
||||||
'network', 'create',
|
'network', 'create',
|
||||||
'--driver', 'bridge',
|
'--driver', 'bridge',
|
||||||
'--internal',
|
'--internal',
|
||||||
|
@ -77,7 +77,7 @@ class NetDownCommand(SubCommand):
|
||||||
try:
|
try:
|
||||||
if are_you_sure("This will bring down this instance's hub network!"):
|
if are_you_sure("This will bring down this instance's hub network!"):
|
||||||
if runner.run('down'):
|
if runner.run('down'):
|
||||||
DockerCommand('docker').run(None, [
|
Executable('docker').run([
|
||||||
'network', 'rm', net_name
|
'network', 'rm', net_name
|
||||||
], check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
], check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
# local
|
# local
|
||||||
from ._subcommand import ServiceCommand
|
from ._subcommand import ServiceCommand
|
||||||
from .utils.dockercommand import DockerCommand
|
|
||||||
|
|
||||||
|
|
||||||
class PullCommand(ServiceCommand):
|
class PullCommand(ServiceCommand):
|
||||||
|
@ -14,7 +13,6 @@ class PullCommand(ServiceCommand):
|
||||||
)
|
)
|
||||||
|
|
||||||
def _run_services(self, runner, args, project, services):
|
def _run_services(self, runner, args, project, services):
|
||||||
DockerCommand('docker-compose').run(project, [
|
project.compose_run(['pull', '--ignore-pull-failures', *services])
|
||||||
'pull', '--ignore-pull-failures', *services
|
|
||||||
])
|
|
||||||
return True
|
return True
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
# local
|
# local
|
||||||
from ._subcommand import ServiceCommand
|
from ._subcommand import ServiceCommand
|
||||||
from .utils.dockercommand import DockerCommand
|
|
||||||
|
|
||||||
|
|
||||||
class PushCommand(ServiceCommand):
|
class PushCommand(ServiceCommand):
|
||||||
|
@ -14,7 +13,6 @@ class PushCommand(ServiceCommand):
|
||||||
)
|
)
|
||||||
|
|
||||||
def _run_services(self, runner, args, project, services):
|
def _run_services(self, runner, args, project, services):
|
||||||
DockerCommand('docker-compose').run(project, [
|
project.compose_run(['push', *services])
|
||||||
'push', *services
|
|
||||||
])
|
|
||||||
return True
|
return True
|
||||||
|
|
|
@ -4,7 +4,6 @@ import subprocess
|
||||||
|
|
||||||
# local
|
# local
|
||||||
from ._subcommand import ServiceCommand
|
from ._subcommand import ServiceCommand
|
||||||
from .utils.dockercommand import DockerCommand
|
|
||||||
|
|
||||||
# parent
|
# parent
|
||||||
from ..config import LoadedConfig
|
from ..config import LoadedConfig
|
||||||
|
@ -18,9 +17,10 @@ def _service_has_executable(project, service, exe_name):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# test if desired shell exists
|
# test if desired shell exists
|
||||||
DockerCommand('docker-compose').run(project, [
|
project.compose_run(
|
||||||
'exec', service, '/bin/sh', '-c', f"which {exe_name}"
|
['exec', service, '/bin/sh', '-c', f"which {exe_name}"],
|
||||||
], check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL
|
||||||
|
)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
except subprocess.CalledProcessError as e:
|
except subprocess.CalledProcessError as e:
|
||||||
|
@ -92,9 +92,7 @@ class ShCommand(ServiceCommand):
|
||||||
|
|
||||||
if shell is not None:
|
if shell is not None:
|
||||||
# spawn shell
|
# spawn shell
|
||||||
DockerCommand('docker-compose').run(project, [
|
project.compose_run(['exec', service, shell])
|
||||||
'exec', service, shell
|
|
||||||
])
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
# local
|
# local
|
||||||
from ._subcommand import ServiceCommand
|
from ._subcommand import ServiceCommand
|
||||||
from .utils.dockercommand import DockerCommand
|
|
||||||
|
|
||||||
|
|
||||||
class UpCommand(ServiceCommand):
|
class UpCommand(ServiceCommand):
|
||||||
|
@ -21,9 +20,7 @@ class UpCommand(ServiceCommand):
|
||||||
|
|
||||||
def _run_services(self, runner, args, project, services):
|
def _run_services(self, runner, args, project, services):
|
||||||
if runner.run('net-up'):
|
if runner.run('net-up'):
|
||||||
DockerCommand('docker-compose').run(project, [
|
project.compose_run(['up', '-d', *services])
|
||||||
'up', '-d', *services
|
|
||||||
])
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
return False
|
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 logging
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
from .executable import Executable
|
||||||
|
|
||||||
from ..._constants import CONF_DIRECTORY_NAME
|
from ..._constants import CONF_DIRECTORY_NAME
|
||||||
from ...config import LoadedConfig
|
from ...config import LoadedConfig
|
||||||
|
|
||||||
|
@ -63,6 +65,41 @@ class Project:
|
||||||
def has_configs(self):
|
def has_configs(self):
|
||||||
return os.path.isdir(self.conf_dir_name())
|
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):
|
def enable(self):
|
||||||
if self.is_disabled():
|
if self.is_disabled():
|
||||||
logging.info(f"Enabling project '{self.get_name()}'")
|
logging.info(f"Enabling project '{self.get_name()}'")
|
||||||
|
|
|
@ -4,7 +4,7 @@ import os
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
# local
|
# local
|
||||||
from .dockercommand import DockerCommand
|
from .executable import Executable
|
||||||
|
|
||||||
# parent
|
# parent
|
||||||
from ..._constants import IMAGES_DIRECTORY_NAME, LOCAL_IMAGES_NAME, DEFAULT_IMAGE_NAME
|
from ..._constants import IMAGES_DIRECTORY_NAME, LOCAL_IMAGES_NAME, DEFAULT_IMAGE_NAME
|
||||||
|
@ -38,7 +38,7 @@ class Rootkit:
|
||||||
self.__image_tag = image_tag
|
self.__image_tag = image_tag
|
||||||
|
|
||||||
def __exists(self):
|
def __exists(self):
|
||||||
ps = DockerCommand('docker').run(None, [
|
ps = Executable('docker').run([
|
||||||
'images',
|
'images',
|
||||||
'--filter', f"reference={_image_name(self.__image_tag)}",
|
'--filter', f"reference={_image_name(self.__image_tag)}",
|
||||||
'--format', '{{.Repository}}:{{.Tag}}'
|
'--format', '{{.Repository}}:{{.Tag}}'
|
||||||
|
@ -52,13 +52,13 @@ class Rootkit:
|
||||||
else:
|
else:
|
||||||
if self.__image_tag is None:
|
if self.__image_tag is None:
|
||||||
logging.info(f"Pulling image {_image_name(self.__image_tag)}")
|
logging.info(f"Pulling image {_image_name(self.__image_tag)}")
|
||||||
DockerCommand('docker').run(None, [
|
Executable('docker').run([
|
||||||
'pull', _image_name(self.__image_tag)
|
'pull', _image_name(self.__image_tag)
|
||||||
], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
logging.info(f"Building image {_image_name(self.__image_tag)}")
|
logging.info(f"Building image {_image_name(self.__image_tag)}")
|
||||||
DockerCommand('docker').run(None, [
|
Executable('docker').run([
|
||||||
'build',
|
'build',
|
||||||
'-t', _image_name(self.__image_tag),
|
'-t', _image_name(self.__image_tag),
|
||||||
'-f', f"{IMAGES_DIRECTORY_NAME}/{self.__image_tag}.Dockerfile",
|
'-f', f"{IMAGES_DIRECTORY_NAME}/{self.__image_tag}.Dockerfile",
|
||||||
|
@ -67,7 +67,7 @@ class Rootkit:
|
||||||
|
|
||||||
def run(self, process_args, **kwargs):
|
def run(self, process_args, **kwargs):
|
||||||
self.__build_image()
|
self.__build_image()
|
||||||
DockerCommand('docker').run(None, [
|
Executable('docker').run([
|
||||||
'run', '--rm',
|
'run', '--rm',
|
||||||
'-v', '/:/mnt',
|
'-v', '/:/mnt',
|
||||||
'-u', 'root',
|
'-u', 'root',
|
||||||
|
|
Loading…
Reference in a new issue