Add up command, allow fine grain debug output

This commit is contained in:
jpic 2020-02-12 13:19:44 +01:00
parent 409b625309
commit 2e9a23eb5a
6 changed files with 118 additions and 46 deletions

View File

@ -40,7 +40,11 @@ class ConsoleScript(cli2.ConsoleScript):
for name, script in self.podfile.pod.scripts.items():
cb = self.podfile.pod.script(name)
cb.__doc__ = inspect.getdoc(script) or script.doc
self[name] = cli2.Callable(name, cb)
self[name] = cli2.Callable(
name,
cb,
options=script.options,
)
return super().__call__(*args, **kwargs)
def call(self, command):

View File

@ -4,16 +4,48 @@ import os
from .build import Build
from .container import Container
from .exceptions import WrongResult
from .script import Script
from .visitable import Visitable
class Up(Script):
async def run(self, *args, **kwargs):
for key, value in kwargs.items():
setattr(self, key, value)
pod = kwargs.get('pod')
try:
pod.info = (await self.exec(
'podman', 'pod', 'inspect', pod.name
)).json
print(f'Pod {pod.name} ready')
except WrongResult:
print(f'Pod {pod.name} creating')
await self.exec(
'podman', 'pod', 'create', '--name', self.pod.name,
)
print(f'Pod {pod.name} created')
pod.info = (await self.exec(
'podman', 'pod', 'inspect', pod.name
)).json
return await super().run(*args, **kwargs)
class Pod(Visitable):
default_scripts = dict(
build=Build(),
run=Script('run', 'Run a container command'),
up=Up('up', 'Start the stack'),
test=Script('test', 'Run tests inside containers'),
)
@property
def name(self):
return os.getenv('POD', os.getcwd().split('/')[-1])
@property
def containers(self):
return [i for i in self.visitors if type(i) == Container]
@ -22,20 +54,6 @@ class Pod(Visitable):
async def cb(*args, **kwargs):
asyncio.events.get_event_loop()
script = copy.deepcopy(self.scripts[name])
if args:
containers = [c for c in self.containers if c.name in args]
else:
containers = self.containers
procs = []
for container in containers:
procs.append(script(
container,
*args,
container=container,
pod=self,
**kwargs,
))
return await asyncio.gather(*procs)
kwargs['pod'] = self
return await script.run(*args, **kwargs)
return cb

View File

@ -1,4 +1,5 @@
import importlib
import os
from .container import Container
from .pod import Pod
@ -8,9 +9,14 @@ class Podfile:
def __init__(self, pods, containers):
self.pods = pods
self.containers = containers
if not self.pods:
self.pods['pod'] = Pod(*containers.values())
for pod in self.pods.values():
for container in pod.containers:
container.pod = pod
@property
def pod(self):
return self.pods['pod']

View File

@ -20,12 +20,16 @@ class PrefixStreamProtocol(asyncio.subprocess.SubprocessStreamProtocol):
super().__init__(*args, **kwargs)
def pipe_data_received(self, fd, data):
if fd in (1, 2):
from .console_script import console_script
debug = console_script.parser.options.get('debug', False)
if (debug is True or 'out' in str(debug)) and fd in (1, 2):
for line in data.split(b'\n'):
if not line:
continue
sys.stdout.buffer.write(
self.prefix.encode('utf8') + b' | ' + line + b'\n'
if self.prefix else line + b'\n'
)
sys.stdout.flush()
super().pipe_data_received(fd, data)
@ -38,26 +42,6 @@ def protocol_factory(prefix):
loop=asyncio.events.get_event_loop()
)
return _p
'''
async def proc(args, prefix=None, wait=True, raises=True):
loop = asyncio.events.get_event_loop()
transport, protocol = await loop.subprocess_exec(
protocol_factory(prefix), *args)
proc = asyncio.subprocess.Process(transport, protocol, loop)
if wait:
stdout, stderr = await proc.communicate()
log['result'] = await proc.wait()
if raises and log['result']:
raise WrongResult()
if wait:
return log
return proc
'''
class Proc:
@ -92,7 +76,13 @@ class Proc:
if self.called:
raise Exception('Already called: ' + self.cmd)
from .console_script import console_script
debug = console_script.parser.options.get('debug', False)
if debug is True or 'proc' in str(debug):
if self.prefix:
print(f'{self.prefix} | + {self.cmd}')
else:
print(f'+ {self.cmd}')
loop = asyncio.events.get_event_loop()
transport, protocol = await loop.subprocess_exec(
@ -121,3 +111,8 @@ class Proc:
if self.raises and self.proc.returncode:
raise WrongResult()
return self
@property
def json(self):
import json
return json.loads(self.out)

View File

@ -1,15 +1,30 @@
import asyncio
import cli2
import textwrap
from .proc import Proc
class Script:
options = [
cli2.Option(
'debug',
alias='d',
color=cli2.GREEN,
help='''
Display debug output.
Supports values: proc,out,visit
'''
),
]
def __init__(self, name=None, doc=None):
self.name = name or type(self).__name__.lower()
self.doc = doc or 'Custom script'
async def exec(self, *args, **kwargs):
"""Execute a command on the host."""
if getattr(self, 'container', None):
kwargs.setdefault('prefix', self.container.name)
proc = await Proc(*args, **kwargs)()
if kwargs.get('wait', True):
@ -17,6 +32,9 @@ class Script:
return proc
async def __call__(self, visitable, *args, **kwargs):
from .console_script import console_script
debug = console_script.parser.options.get('debug', False)
for key, value in kwargs.items():
setattr(self, key, value)
@ -36,10 +54,10 @@ class Script:
if not hasattr(visitor, method):
continue
if debug is True or 'visit' in str(debug):
print(
visitable.name + ' | ',
type(visitor).__name__,
method,
'.'.join([type(visitor).__name__, method]),
' '.join(f'{k}={v}' for k, v in visitor.__dict__.items())
)
result = getattr(visitor, method)(self)
@ -49,3 +67,22 @@ class Script:
except Exception as e:
await clean()
raise
async def run(self, *args, **kwargs):
pod = kwargs.get('pod')
if args:
containers = [c for c in pod.containers if c.name in args]
else:
containers = pod.containers
procs = []
for container in containers:
procs.append(self(
container,
*args,
container=container,
**kwargs,
))
return await asyncio.gather(*procs)

View File

@ -1,6 +1,8 @@
import os
import subprocess
from ..exceptions import WrongResult
CI_VARS = (
# gitlab
'CI_COMMIT_SHORT_SHA',
@ -85,3 +87,13 @@ class Commit:
'--name', script.container.name,
':'.join((self.repo, self.tags[0])),
)
async def up(self, script):
name = '-'.join([script.pod.name, script.container.name])
try:
await script.exec('podman', 'inspect', name)
except WrongResult:
await script.exec(
'podman', 'run', '-d', '--name', name,
':'.join((self.repo, self.tags[0])),
)