Getting on par with docker-compose
This commit is contained in:
parent
bc7cb9c355
commit
c38ad7e089
2
setup.py
2
setup.py
@ -7,7 +7,7 @@ setup(
|
|||||||
setup_requires='setupmeta',
|
setup_requires='setupmeta',
|
||||||
extras_require=dict(
|
extras_require=dict(
|
||||||
cli=[
|
cli=[
|
||||||
'cli2>=2.2.2',
|
'cli2>=2.3.0',
|
||||||
],
|
],
|
||||||
test=[
|
test=[
|
||||||
'pytest',
|
'pytest',
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import copy
|
import copy
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
from .podman import Podman
|
||||||
from .image import Image
|
from .image import Image
|
||||||
|
|
||||||
|
|
||||||
@ -12,6 +13,7 @@ class Container:
|
|||||||
self.image = Image(self.image)
|
self.image = Image(self.image)
|
||||||
self.volumes = volumes or {}
|
self.volumes = volumes or {}
|
||||||
self.env = env or {}
|
self.env = env or {}
|
||||||
|
|
||||||
prefix = os.getcwd().split('/')[-1]
|
prefix = os.getcwd().split('/')[-1]
|
||||||
repo = self.image.repository.replace('/', '-')
|
repo = self.image.repository.replace('/', '-')
|
||||||
if prefix == repo:
|
if prefix == repo:
|
||||||
@ -19,8 +21,39 @@ class Container:
|
|||||||
else:
|
else:
|
||||||
self.name = '-'.join([prefix, repo])
|
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):
|
async def up(self, target, *args):
|
||||||
"""Start the container foreground"""
|
"""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 = [
|
cmd = [
|
||||||
'podman',
|
'podman',
|
||||||
'run',
|
'run',
|
||||||
@ -34,7 +67,7 @@ class Container:
|
|||||||
|
|
||||||
cmd += [
|
cmd += [
|
||||||
'--name',
|
'--name',
|
||||||
self.name,
|
self.full_name,
|
||||||
str(self.image),
|
str(self.image),
|
||||||
]
|
]
|
||||||
await target.exec(*cmd)
|
await target.exec(*cmd)
|
||||||
@ -45,11 +78,15 @@ class Container:
|
|||||||
|
|
||||||
async def stop(self, target):
|
async def stop(self, target):
|
||||||
"""Start the container"""
|
"""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):
|
async def down(self, target):
|
||||||
"""Start the container"""
|
"""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):
|
async def apply(self, target):
|
||||||
"""Start the container"""
|
"""Start the container"""
|
||||||
|
|||||||
52
shlax/pod.py
52
shlax/pod.py
@ -1,13 +1,21 @@
|
|||||||
import cli2
|
import cli2
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
|
||||||
from shlax.targets.base import Target
|
from shlax.targets.base import Target
|
||||||
from shlax.actions.parallel import Parallel
|
from shlax.actions.parallel import Parallel
|
||||||
|
|
||||||
|
from .podman import Podman
|
||||||
|
|
||||||
|
|
||||||
class Pod:
|
class Pod:
|
||||||
"""Help text"""
|
"""Help text"""
|
||||||
def __init__(self, **containers):
|
def __init__(self, **containers):
|
||||||
self.containers = 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):
|
async def _call(self, target, method, *names):
|
||||||
methods = [
|
methods = [
|
||||||
@ -19,8 +27,50 @@ class Pod:
|
|||||||
|
|
||||||
async def build(self, target, *names):
|
async def build(self, target, *names):
|
||||||
"""Build container images"""
|
"""Build container images"""
|
||||||
await self._call(target, 'build', *names)
|
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):
|
async def start(self, target, *names):
|
||||||
"""Start container images"""
|
"""Start container images"""
|
||||||
await self._call(target, 'start', *names)
|
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
18
shlax/podman.py
Normal 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
|
||||||
Loading…
x
Reference in New Issue
Block a user