implement detach, and make attach the default

This commit is contained in:
Muayyad Alsadi 2019-08-17 23:39:42 +03:00
parent d53ad3217e
commit 35219c84b9

View File

@ -18,6 +18,8 @@ import re
import hashlib import hashlib
import random import random
from threading import Thread
try: try:
from shlex import quote as cmd_quote from shlex import quote as cmd_quote
except ImportError: except ImportError:
@ -413,12 +415,13 @@ def mount_desc_to_args(compose, mount_desc, srv_name, cnt_name):
def container_to_args(compose, cnt, detached=True): def container_to_args(compose, cnt, detached=True, podman_command='run'):
# TODO: double check -e , --add-host, -v, --read-only
dirname = compose.dirname dirname = compose.dirname
shared_vols = compose.shared_vols shared_vols = compose.shared_vols
pod = cnt.get('pod') or '' pod = cnt.get('pod') or ''
podman_args = [ podman_args = [
'run', podman_command,
'--name={}'.format(cnt.get('name')), '--name={}'.format(cnt.get('name')),
] ]
@ -810,32 +813,37 @@ def compose_push(compose, args):
if services and cnt['_service'] not in services: continue if services and cnt['_service'] not in services: continue
compose.podman.run(["push", cnt["image"]], sleep=0) compose.podman.run(["push", cnt["image"]], sleep=0)
def build_one(compose, args, cnt):
if 'build' not in cnt: return
if getattr(args, 'if_not_exists'):
try: img_id = compose.podman.output(['inspect', '-t', 'image', '-f', '{{.Id}}', cnt["image"]])
except subprocess.CalledProcessError: img_id = None
if img_id: return
build_desc = cnt['build']
if not hasattr(build_desc, 'items'):
build_desc = dict(context=build_desc)
ctx = build_desc.get('context', '.')
dockerfile = os.path.join(ctx, build_desc.get("dockerfile", "Dockerfile"))
if not os.path.exists(dockerfile):
dockerfile = os.path.join(ctx, build_desc.get("dockerfile", "dockerfile"))
if not os.path.exists(dockerfile):
raise OSError("Dockerfile not found in "+ctx)
build_args = [
"build", "-t", cnt["image"],
"-f", dockerfile
]
if getattr(args, 'pull_always'): build_args.append("--pull-always")
elif getattr(args, 'pull'): build_args.append("--pull")
args_list = norm_as_list(build_desc.get('args', {}))
for build_arg in args_list:
build_args.extend(("--build-arg", build_arg,))
build_args.append(ctx)
compose.podman.run(build_args, sleep=0)
@cmd_run(podman_compose, 'build', 'build stack images') @cmd_run(podman_compose, 'build', 'build stack images')
def compose_build(compose, args): def compose_build(compose, args):
podman_args = []
if args.pull_always: podman_args.append("--pull-always")
elif args.pull: podman_args.append("--pull")
for cnt in compose.containers: for cnt in compose.containers:
if 'build' not in cnt: continue build_one(compose, args, cnt)
build_desc = cnt['build']
if not hasattr(build_desc, 'items'):
build_desc = dict(context=build_desc)
ctx = build_desc.get('context', '.')
dockerfile = os.path.join(ctx, build_desc.get("dockerfile", "Dockerfile"))
if not os.path.exists(dockerfile):
dockerfile = os.path.join(ctx, build_desc.get("dockerfile", "dockerfile"))
if not os.path.exists(dockerfile):
raise OSError("Dockerfile not found in "+ctx)
build_args = [
"build", "-t", cnt["image"],
"-f", dockerfile
]
build_args.extend(podman_args)
args_list = norm_as_list(build_desc.get('args', {}))
for build_arg in args_list:
build_args.extend(("--build-arg", build_arg,))
build_args.append(ctx)
compose.podman.run(build_args, sleep=0)
def create_pods(compose, args): def create_pods(compose, args):
for pod in compose.pods: for pod in compose.pods:
@ -849,24 +857,59 @@ def create_pods(compose, args):
podman_args.extend(['-p', i]) podman_args.extend(['-p', i])
compose.podman.run(podman_args) compose.podman.run(podman_args)
def up_specific(compose, args):
deps = []
if not args.no_deps:
for service in args.services:
deps.extend([])
# args.always_recreate_deps
print("services", args.services)
raise NotImplementedError("starting specific services is not yet implemented")
@cmd_run(podman_compose, 'up', 'Create and start the entire stack or some of its services') @cmd_run(podman_compose, 'up', 'Create and start the entire stack or some of its services')
def compose_up(compose, args): def compose_up(compose, args):
if args.services:
return up_specific(compose, args)
if not args.no_build:
# `podman build` does not cache, so don't always build
build_args = argparse.Namespace(
if_not_exists=(not args.build),
**args.__dict__,
)
compose.commands['build'](compose, build_args)
shared_vols = compose.shared_vols shared_vols = compose.shared_vols
# NOTE: podman does not cache, so don't always build # TODO: implement check hash label for change
# TODO: if build and the following command fails "podman inspect -t image <image_name>" then run build if args.force_recreate:
# no need remove them if they have same hash label
if compose.global_args.no_cleanup == False:
compose.commands['down'](compose, args) compose.commands['down'](compose, args)
# args.no_recreate disables check for changes (which is not implemented)
podman_command = 'run' if args.detach and not args.no_start else 'create'
create_pods(compose, args) create_pods(compose, args)
for cnt in compose.containers: for cnt in compose.containers:
# TODO: -e , --add-host, -v, --read-only podman_args = container_to_args(compose, cnt,
podman_args = container_to_args(compose, cnt) detached=args.detach, podman_command=podman_command)
compose.podman.run(podman_args) compose.podman.run(podman_args)
if args.no_start or args.detach: return
# TODO: colors if sys.stdout.isatty()
threads = []
for cnt in compose.containers:
# TODO: remove sleep from podman.run
thread = Thread(target=compose.podman.run, args=[['start', '-a', cnt['name']]], daemon=True)
thread.start()
threads.append(thread)
time.sleep(1)
while True:
for thread in threads:
thread.join(timeout=1.0)
if thread.is_alive(): continue
if args.abort_on_container_exit:
exit(-1)
@cmd_run(podman_compose, 'down', 'tear down entire stack') @cmd_run(podman_compose, 'down', 'tear down entire stack')
def compose_down(compose, args): def compose_down(compose, args):