forked from extern/podman-compose
FIXES #380: output to stderr
This commit is contained in:
parent
30051c2f5b
commit
7ad377557d
@ -7,8 +7,6 @@
|
||||
# https://docs.docker.com/compose/django/
|
||||
# https://docs.docker.com/compose/wordpress/
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import sys
|
||||
import os
|
||||
import argparse
|
||||
@ -37,13 +35,8 @@ from dotenv import dotenv_values
|
||||
|
||||
__version__ = '1.0.3'
|
||||
|
||||
PY3 = sys.version_info[0] == 3
|
||||
if PY3:
|
||||
basestring = str
|
||||
|
||||
# helper functions
|
||||
|
||||
is_str = lambda s: isinstance(s, basestring)
|
||||
is_str = lambda s: isinstance(s, str)
|
||||
is_dict = lambda d: isinstance(d, dict)
|
||||
is_list = lambda l: not is_str(l) and not is_dict(l) and hasattr(l, "__iter__")
|
||||
# identity filter
|
||||
@ -67,6 +60,11 @@ def try_float(i, fallback=None):
|
||||
pass
|
||||
return fallback
|
||||
|
||||
def log(*msgs, sep=" ", end="\n"):
|
||||
line = (sep.join(["{}".format(msg) for msg in msgs]))+end
|
||||
sys.stderr.write(line)
|
||||
sys.stderr.flush()
|
||||
|
||||
dir_re = re.compile("^[~/\.]")
|
||||
propagation_re = re.compile("^(?:z|Z|O|U|r?shared|r?slave|r?private|r?unbindable|r?bind|(?:no)?(?:exec|dev|suid))$")
|
||||
norm_re = re.compile('[^-_a-z0-9]')
|
||||
@ -290,7 +288,7 @@ def assert_volume(compose, mount_dict):
|
||||
if mount_dict["type"] != "volume" or not vol or vol.get("external", None) or not vol.get("name", None): return
|
||||
proj_name = compose.project_name
|
||||
vol_name = vol["name"]
|
||||
print("podman volume inspect {vol_name} || podman volume create {vol_name}".format(vol_name=vol_name))
|
||||
log("podman volume inspect {vol_name} || podman volume create {vol_name}".format(vol_name=vol_name))
|
||||
# TODO: might move to using "volume list"
|
||||
# podman volume list --format '{{.Name}}\t{{.MountPoint}}' -f 'label=io.podman.compose.project=HERE'
|
||||
try: out = compose.podman.output([], "volume", ["inspect", vol_name]).decode('utf-8')
|
||||
@ -449,7 +447,7 @@ def get_secret_args(compose, cnt, secret):
|
||||
'--volume', '{}:{}:ro,rprivate,rbind'.format(source_file, dest_file)
|
||||
]
|
||||
if uid or gid or mode:
|
||||
print(
|
||||
log(
|
||||
'WARNING: Service "{}" uses secret "{}" with uid, gid, or mode.'
|
||||
.format(cnt['_service'], target if target else secret_name)
|
||||
+ ' These fields are not supported by this implementation of the Compose file'
|
||||
@ -478,7 +476,7 @@ def get_secret_args(compose, cnt, secret):
|
||||
elif target and target != secret_name:
|
||||
raise ValueError(err_str.format(target, secret_name))
|
||||
elif target:
|
||||
print('WARNING: Service "{}" uses target: "{}" for secret: "{}".'
|
||||
log('WARNING: Service "{}" uses target: "{}" for secret: "{}".'
|
||||
.format(cnt['_service'], target, secret_name)
|
||||
+ ' That is un-supported and a no-op and is ignored.')
|
||||
return [ '--secret', '{}{}'.format(secret_name, secret_opts) ]
|
||||
@ -816,7 +814,7 @@ class Podman:
|
||||
cmd_args = cmd_args or []
|
||||
xargs = self.compose.get_podman_args(cmd) if cmd else []
|
||||
cmd_ls = [self.podman_path, *podman_args, cmd] + xargs + cmd_args
|
||||
print(cmd_ls)
|
||||
log(cmd_ls)
|
||||
return subprocess.check_output(cmd_ls)
|
||||
|
||||
def run(self, podman_args, cmd='', cmd_args=None, wait=True, sleep=1, obj=None):
|
||||
@ -825,14 +823,14 @@ class Podman:
|
||||
cmd_args = list(map(str, cmd_args or []))
|
||||
xargs = self.compose.get_podman_args(cmd) if cmd else []
|
||||
cmd_ls = [self.podman_path, *podman_args, cmd] + xargs + cmd_args
|
||||
print(" ".join([str(i) for i in cmd_ls]))
|
||||
log(" ".join([str(i) for i in cmd_ls]))
|
||||
if self.dry_run:
|
||||
return None
|
||||
# subprocess.Popen(args, bufsize = 0, executable = None, stdin = None, stdout = None, stderr = None, preexec_fn = None, close_fds = False, shell = False, cwd = None, env = None, universal_newlines = False, startupinfo = None, creationflags = 0)
|
||||
p = subprocess.Popen(cmd_ls)
|
||||
if wait:
|
||||
exit_code = p.wait()
|
||||
print("exit code:", exit_code)
|
||||
log("exit code:", exit_code)
|
||||
if obj is not None:
|
||||
obj.exit_code = exit_code
|
||||
|
||||
@ -1016,7 +1014,7 @@ class PodmanCompose:
|
||||
if not self.podman_version:
|
||||
sys.stderr.write("it seems that you do not have `podman` installed\n")
|
||||
exit(1)
|
||||
print("using podman version: "+self.podman_version)
|
||||
log("using podman version: "+self.podman_version)
|
||||
cmd_name = args.command
|
||||
if (cmd_name != "version"):
|
||||
self._parse_compose_file()
|
||||
@ -1036,12 +1034,12 @@ class PodmanCompose:
|
||||
args.file = list(filter(os.path.exists, default_ls))
|
||||
files = args.file
|
||||
if not files:
|
||||
print("no compose.yaml, docker-compose.yml or container-compose.yml file found, pass files with -f")
|
||||
log("no compose.yaml, docker-compose.yml or container-compose.yml file found, pass files with -f")
|
||||
exit(-1)
|
||||
ex = map(os.path.exists, files)
|
||||
missing = [ fn0 for ex0, fn0 in zip(ex, files) if not ex0 ]
|
||||
if missing:
|
||||
print("missing files: ", missing)
|
||||
log("missing files: ", missing)
|
||||
exit(1)
|
||||
# make absolute
|
||||
relative_files = files
|
||||
@ -1081,22 +1079,22 @@ class PodmanCompose:
|
||||
for filename in files:
|
||||
with open(filename, 'r') as f:
|
||||
content = yaml.safe_load(f)
|
||||
#print(filename, json.dumps(content, indent = 2))
|
||||
#log(filename, json.dumps(content, indent = 2))
|
||||
if not isinstance(content, dict):
|
||||
sys.stderr.write("Compose file does not contain a top level object: %s\n"%filename)
|
||||
exit(1)
|
||||
content = normalize(content)
|
||||
#print(filename, json.dumps(content, indent = 2))
|
||||
#log(filename, json.dumps(content, indent = 2))
|
||||
content = rec_subs(content, self.environ)
|
||||
rec_merge(compose, content)
|
||||
# debug mode
|
||||
if len(files)>1:
|
||||
print(" ** merged:\n", json.dumps(compose, indent = 2))
|
||||
log(" ** merged:\n", json.dumps(compose, indent = 2))
|
||||
ver = compose.get('version', None)
|
||||
services = compose.get('services', None)
|
||||
if services is None:
|
||||
services = {}
|
||||
print("WARNING: No services defined")
|
||||
log("WARNING: No services defined")
|
||||
|
||||
# NOTE: maybe add "extends.service" to _deps at this stage
|
||||
flat_deps(services, with_extends=True)
|
||||
@ -1157,7 +1155,7 @@ class PodmanCompose:
|
||||
else:
|
||||
name = name0
|
||||
container_names_by_service[service_name].append(name)
|
||||
# print(service_name,service_desc)
|
||||
# log(service_name,service_desc)
|
||||
cnt = dict(name=name, num=num,
|
||||
service_name=service_name, **service_desc)
|
||||
if 'image' not in cnt:
|
||||
@ -1178,10 +1176,10 @@ class PodmanCompose:
|
||||
given_containers.append(cnt)
|
||||
self.container_names_by_service = container_names_by_service
|
||||
container_by_name = dict([(c["name"], c) for c in given_containers])
|
||||
#print("deps:", [(c["name"], c["_deps"]) for c in given_containers])
|
||||
#log("deps:", [(c["name"], c["_deps"]) for c in given_containers])
|
||||
given_containers = list(container_by_name.values())
|
||||
given_containers.sort(key=lambda c: len(c.get('_deps', None) or []))
|
||||
#print("sorted:", [c["name"] for c in given_containers])
|
||||
#log("sorted:", [c["name"] for c in given_containers])
|
||||
pods, containers = tr_identity(project_name, given_containers)
|
||||
self.pods = pods
|
||||
self.containers = containers
|
||||
@ -1271,7 +1269,7 @@ class cmd_parse:
|
||||
|
||||
@cmd_run(podman_compose, 'version', 'show version')
|
||||
def compose_version(compose, args):
|
||||
print("podman-composer version ", __version__)
|
||||
log("podman-composer version ", __version__)
|
||||
compose.podman.run(["--version"], "", [], sleep=0)
|
||||
|
||||
def is_local(container: dict) -> bool:
|
||||
@ -1376,7 +1374,7 @@ def up_specific(compose, args):
|
||||
for service in args.services:
|
||||
deps.extend([])
|
||||
# args.always_recreate_deps
|
||||
print("services", args.services)
|
||||
log("services", args.services)
|
||||
raise NotImplementedError("starting specific services is not yet implemented")
|
||||
|
||||
def get_excluded(compose, args):
|
||||
@ -1386,7 +1384,7 @@ def get_excluded(compose, args):
|
||||
for service in args.services:
|
||||
excluded-= compose.services[service]['_deps']
|
||||
excluded.discard(service)
|
||||
print("** excluding: ", excluded)
|
||||
log("** excluding: ", excluded)
|
||||
return excluded
|
||||
|
||||
@cmd_run(podman_compose, 'up', 'Create and start the entire stack or some of its services')
|
||||
@ -1410,7 +1408,7 @@ def compose_up(compose, args):
|
||||
create_pods(compose, args)
|
||||
for cnt in compose.containers:
|
||||
if cnt["_service"] in excluded:
|
||||
print("** skipping: ", cnt['name'])
|
||||
log("** skipping: ", cnt['name'])
|
||||
continue
|
||||
podman_args = container_to_args(compose, cnt, detached=args.detach)
|
||||
subproc = compose.podman.run([], podman_command, podman_args)
|
||||
@ -1428,7 +1426,7 @@ def compose_up(compose, args):
|
||||
threads = []
|
||||
for cnt in compose.containers:
|
||||
if cnt["_service"] in excluded:
|
||||
print("** skipping: ", cnt['name'])
|
||||
log("** skipping: ", cnt['name'])
|
||||
continue
|
||||
# TODO: remove sleep from podman.run
|
||||
obj = compose if exit_code_from == cnt['_service'] else None
|
||||
@ -1483,7 +1481,7 @@ def compose_down(compose, args):
|
||||
for cnt in containers:
|
||||
if cnt["_service"] not in excluded: continue
|
||||
vol_names_to_keep.update(get_volume_names(compose, cnt))
|
||||
print("keep", vol_names_to_keep)
|
||||
log("keep", vol_names_to_keep)
|
||||
volume_names = [vol["Name"] for vol in compose.podman.volume_inspect_proj()]
|
||||
for volume_name in volume_names:
|
||||
if volume_name in vol_names_to_keep: continue
|
||||
|
Loading…
Reference in New Issue
Block a user