Getting on par with docker-compose

This commit is contained in:
jpic 2020-08-02 20:10:52 +02:00
parent bc7cb9c355
commit c38ad7e089
4 changed files with 110 additions and 5 deletions

View File

@ -7,7 +7,7 @@ setup(
setup_requires='setupmeta',
extras_require=dict(
cli=[
'cli2>=2.2.2',
'cli2>=2.3.0',
],
test=[
'pytest',

View File

@ -1,6 +1,7 @@
import copy
import os
from .podman import Podman
from .image import Image
@ -12,6 +13,7 @@ class Container:
self.image = Image(self.image)
self.volumes = volumes or {}
self.env = env or {}
prefix = os.getcwd().split('/')[-1]
repo = self.image.repository.replace('/', '-')
if prefix == repo:
@ -19,8 +21,39 @@ class Container:
else:
self.name = '-'.join([prefix, repo])
self.pod = None
@property
def full_name(self):
if self.pod:
return '-'.join([self.pod.name, self.name])
return self.name
async def up(self, target, *args):
"""Start the container foreground"""
podman = Podman(target)
if self.pod:
pod = None
for _ in await podman.pod.ps():
if _['Name'] == self.pod.name:
pod = _
break
if not pod:
await podman.pod.create('--name', self.pod.name)
args = list(args) + ['--pod', self.pod.name]
# skip if already up
for result in await podman.ps('-a'):
for name in result['Names']:
if name == self.full_name:
if result['State'] == 'running':
target.output.info(f'{self.full_name} already running')
return
elif result['State'] == 'exited':
target.output.info(f'{self.full_name} starting')
await target.exec('podman', 'start', self.full_name)
return
cmd = [
'podman',
'run',
@ -34,7 +67,7 @@ class Container:
cmd += [
'--name',
self.name,
self.full_name,
str(self.image),
]
await target.exec(*cmd)
@ -45,11 +78,15 @@ class Container:
async def stop(self, target):
"""Start the container"""
await target.exec('podman', 'stop', self.name)
await target.exec('podman', 'stop', self.full_name)
async def logs(self, target):
"""Start the container"""
await target.exec('podman', 'logs', self.full_name)
async def down(self, target):
"""Start the container"""
await target.exec('podman', 'rm', '-f', self.name, raises=False)
await target.exec('podman', 'rm', '-f', self.full_name, raises=False)
async def apply(self, target):
"""Start the container"""

View File

@ -1,13 +1,21 @@
import cli2
import json
import os
from shlax.targets.base import Target
from shlax.actions.parallel import Parallel
from .podman import Podman
class Pod:
"""Help text"""
def __init__(self, **containers):
self.containers = containers
for name, container in self.containers.items():
container.pod = self
container.name = name
self.name = os.getcwd().split('/')[-1]
async def _call(self, target, method, *names):
methods = [
@ -19,8 +27,50 @@ class Pod:
async def build(self, target, *names):
"""Build container images"""
if not Proc.test or os.getuid() == 0:
os.execvp('buildah', ['buildah', 'unshare'] + sys.argv)
else:
await self._call(target, 'build', *names)
async def down(self, target, *names):
"""Delete container images"""
await self._call(target, 'down', *names)
async def start(self, target, *names):
"""Start container images"""
await self._call(target, 'start', *names)
async def logs(self, target, *names):
"""Start container images"""
await self._call(target, 'logs', *names)
async def ps(self, target):
"""Show containers and volumes"""
containers = []
names = []
for container in await Podman(target).ps('-a'):
for name in container['Names']:
if name.startswith(self.name + '-'):
container['Name'] = name
containers.append(container)
names.append(name)
for name, container in self.containers.items():
full_name = '-'.join([self.name, container.name])
if full_name in names:
continue
containers.append(dict(
Name=full_name,
State='not created',
))
cli2.Table(
['Name', 'State'],
*[
(container['Name'], container['State'])
for container in containers
]
).print()
def __str__(self):
return f'Pod({self.name})'

18
shlax/podman.py Normal file
View File

@ -0,0 +1,18 @@
import json
class Podman(list):
def __init__(self, target, *args):
self.target = target
super().__init__(args or ['podman'])
def __getattr__(self, command):
if command.startswith('_'):
return super().__getattr__(command)
return Podman(self.target, *self + [command])
async def __call__(self, *args, **kwargs):
cmd = self + list(args) + [f'--{k}={v}' for k, v in kwargs.items()]
if 'ps' in cmd:
cmd += ['--format=json']
return (await self.target.exec(*cmd, quiet=True)).json