mirror of
https://github.com/containers/podman-compose.git
synced 2024-12-28 17:49:07 +01:00
new switches: --dry-run, --no-cleanup, --podman-path
Small refactoring and three new switches: `--dry-run` for debugging (doesn't execute podman), `--no-cleanup` doesn't stop & remove containers on a fresh run, `--podman-path` allows the user to point to podman binary if not in $PATH
This commit is contained in:
parent
f6f711a82a
commit
bbc62e34b0
@ -1,6 +1,5 @@
|
|||||||
#! /usr/bin/env python
|
#! /usr/bin/env python
|
||||||
|
|
||||||
|
|
||||||
# https://docs.docker.com/compose/compose-file/#service-configuration-reference
|
# https://docs.docker.com/compose/compose-file/#service-configuration-reference
|
||||||
# https://docs.docker.com/samples/
|
# https://docs.docker.com/samples/
|
||||||
# https://docs.docker.com/compose/gettingstarted/
|
# https://docs.docker.com/compose/gettingstarted/
|
||||||
@ -9,7 +8,6 @@
|
|||||||
|
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import argparse
|
import argparse
|
||||||
import subprocess
|
import subprocess
|
||||||
@ -60,6 +58,7 @@ def norm_as_dict(src):
|
|||||||
raise ValueError("dictionary or iterable is expected")
|
raise ValueError("dictionary or iterable is expected")
|
||||||
return dst
|
return dst
|
||||||
|
|
||||||
|
|
||||||
# transformation helpers
|
# transformation helpers
|
||||||
|
|
||||||
def adj_hosts(services, cnt, dst = "127.0.0.1"):
|
def adj_hosts(services, cnt, dst = "127.0.0.1"):
|
||||||
@ -81,8 +80,6 @@ def adj_hosts(services, cnt, dst="127.0.0.1"):
|
|||||||
extra_hosts.append("{}:{}".format(alias, dst))
|
extra_hosts.append("{}:{}".format(alias, dst))
|
||||||
cnt["extra_hosts"] = extra_hosts
|
cnt["extra_hosts"] = extra_hosts
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def move_list(dst, containers, key):
|
def move_list(dst, containers, key):
|
||||||
"""
|
"""
|
||||||
move key (like port forwarding) from containers to dst (a pod or a infra container)
|
move key (like port forwarding) from containers to dst (a pod or a infra container)
|
||||||
@ -188,27 +185,28 @@ def tr_1podfw(project_name, services, given_containers):
|
|||||||
move_port_fw(pod, containers)
|
move_port_fw(pod, containers)
|
||||||
return pods, containers
|
return pods, containers
|
||||||
|
|
||||||
def down(project_name, dirname, pods, containers):
|
def down(project_name, dirname, pods, containers, dry_run, podman_path):
|
||||||
for cnt in containers:
|
for cnt in containers:
|
||||||
cmd="""podman stop -t=1 '{name}'""".format(**cnt)
|
cmd = """{} stop -t=1 '{name}'""".format(podman_path, **cnt)
|
||||||
print(cmd)
|
print(cmd)
|
||||||
subprocess.Popen(cmd, shell=True).wait()
|
if dry_run == False: subprocess.Popen(cmd, shell = True).wait()
|
||||||
for cnt in containers:
|
for cnt in containers:
|
||||||
cmd="""podman rm '{name}'""".format(**cnt)
|
cmd = """{} rm '{name}'""".format(podman_path, **cnt)
|
||||||
print(cmd)
|
print(cmd)
|
||||||
subprocess.Popen(cmd, shell=True).wait()
|
if dry_run == False: subprocess.Popen(cmd, shell = True).wait()
|
||||||
for pod in pods:
|
for pod in pods:
|
||||||
cmd="""podman pod rm '{name}'""".format(**pod)
|
cmd = """{} pod rm '{name}'""".format(podman_path, **pod)
|
||||||
print(cmd)
|
print(cmd)
|
||||||
subprocess.Popen(cmd, shell=True).wait()
|
if dry_run == False: subprocess.Popen(cmd, shell = True).wait()
|
||||||
|
|
||||||
def container_to_args(cnt, dirname):
|
def container_to_args(cnt, dirname, podman_path):
|
||||||
pod = cnt.get('pod') or ''
|
pod = cnt.get('pod') or ''
|
||||||
args = [
|
args = [
|
||||||
'podman', 'run',
|
podman_path, 'run',
|
||||||
'--name={}'.format(cnt.get('name')),
|
'--name={}'.format(cnt.get('name')),
|
||||||
'-d'
|
'-d'
|
||||||
]
|
]
|
||||||
|
|
||||||
if pod:
|
if pod:
|
||||||
args.append('--pod={}'.format(pod))
|
args.append('--pod={}'.format(pod))
|
||||||
if cnt.get('read_only'):
|
if cnt.get('read_only'):
|
||||||
@ -287,13 +285,15 @@ def flat_deps(services, container_by_name):
|
|||||||
for name, cnt in container_by_name.items():
|
for name, cnt in container_by_name.items():
|
||||||
rec_deps(services, container_by_name, cnt, cnt.get('_service'))
|
rec_deps(services, container_by_name, cnt, cnt.get('_service'))
|
||||||
|
|
||||||
def up(project_name, dirname, pods, containers):
|
def up(project_name, dirname, pods, containers, no_cleanup, dry_run, podman_path):
|
||||||
os.chdir(dirname)
|
if dry_run == False: os.chdir(dirname)
|
||||||
|
|
||||||
# no need remove them if they have same hash label
|
# no need remove them if they have same hash label
|
||||||
down(project_name, dirname, pods, containers)
|
if no_cleanup == False: down(project_name, dirname, pods, containers, dry_run, podman_path)
|
||||||
|
|
||||||
for pod in pods:
|
for pod in pods:
|
||||||
args = [
|
args = [
|
||||||
"podman", "pod", "create",
|
podman_path, "pod", "create",
|
||||||
"--name={}".format(pod["name"]),
|
"--name={}".format(pod["name"]),
|
||||||
"--share", "net",
|
"--share", "net",
|
||||||
]
|
]
|
||||||
@ -301,27 +301,41 @@ def up(project_name, dirname, pods, containers):
|
|||||||
for i in ports:
|
for i in ports:
|
||||||
args.extend(['-p', i])
|
args.extend(['-p', i])
|
||||||
print(" ".join(args))
|
print(" ".join(args))
|
||||||
|
|
||||||
|
if dry_run == False:
|
||||||
p = subprocess.Popen(args)
|
p = subprocess.Popen(args)
|
||||||
print(p.wait())
|
print(p.wait())
|
||||||
#print(opts)
|
|
||||||
for cnt in containers:
|
for cnt in containers:
|
||||||
# TODO: -e , --add-host, -v, --read-only
|
# TODO: -e , --add-host, -v, --read-only
|
||||||
args = container_to_args(cnt, dirname)
|
args = container_to_args(cnt, dirname, podman_path)
|
||||||
print(" ".join(args))
|
print(" ".join(args))
|
||||||
p=subprocess.Popen(args)
|
## print("""podman run -d --pod='{pod}' --name='{name}' '{image}'""".format(**cnt))
|
||||||
print(p.wait())
|
if dry_run == False:
|
||||||
#print("""podman run -d --pod='{pod}' --name='{name}' '{image}'""".format(**cnt))
|
subprocess.Popen(args).wait()
|
||||||
# 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)
|
# 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)
|
||||||
time.sleep(1)
|
if dry_run == False: time.sleep(1)
|
||||||
|
|
||||||
def main(command, filename, project_name, no_ansi, transform_policy, host_env=None):
|
def main(command, filename, project_name, no_ansi, no_cleanup, dry_run, transform_policy, podman_path, host_env = None):
|
||||||
filename = os.path.realpath(filename)
|
filename = os.path.realpath(filename)
|
||||||
dirname = os.path.dirname(filename)
|
dirname = os.path.dirname(filename)
|
||||||
dir_basename = os.path.basename(dirname)
|
dir_basename = os.path.basename(dirname)
|
||||||
if not project_name: project_name = dir_basename
|
|
||||||
|
if podman_path != 'podman':
|
||||||
|
if os.path.isfile(podman_path) and os.access(podman_path, os.X_OK):
|
||||||
|
podman_path = os.path.realpath(podman_path)
|
||||||
|
else:
|
||||||
|
# this also works if podman hasn't been installed now
|
||||||
|
if dry_run == False: raise IOError("Binary {} has not been found.".format(podman_path))
|
||||||
|
|
||||||
|
if not project_name:
|
||||||
|
project_name = dir_basename
|
||||||
with open(filename, 'r') as f:
|
with open(filename, 'r') as f:
|
||||||
compose = yaml.safe_load(f)
|
compose = yaml.safe_load(f)
|
||||||
print(json.dumps(compose, indent=2))
|
|
||||||
|
# debug mode
|
||||||
|
#print(json.dumps(compose, indent = 2))
|
||||||
|
|
||||||
ver = compose.get('version')
|
ver = compose.get('version')
|
||||||
services = compose.get('services')
|
services = compose.get('services')
|
||||||
podman_compose_labels = [
|
podman_compose_labels = [
|
||||||
@ -367,37 +381,44 @@ def main(command, filename, project_name, no_ansi, transform_policy, host_env=No
|
|||||||
pods, containers = tr(project_name, container_names_by_service, given_containers)
|
pods, containers = tr(project_name, container_names_by_service, given_containers)
|
||||||
cmd = command[0]
|
cmd = command[0]
|
||||||
if cmd == "up":
|
if cmd == "up":
|
||||||
up(project_name, dirname, pods, containers)
|
up(project_name, dirname, pods, containers, no_cleanup, dry_run, podman_path)
|
||||||
elif cmd == "down":
|
elif cmd == "down":
|
||||||
down(project_name, dirname, pods, containers)
|
down(project_name, dirname, pods, containers, dry_run, podman_path)
|
||||||
else:
|
else:
|
||||||
raise NotImplementedError("command {} is not implemented".format(cmd))
|
raise NotImplementedError("command {} is not implemented".format(cmd))
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
parser.add_argument('command', metavar = 'command',
|
parser.add_argument('command', metavar = 'command',
|
||||||
help = 'command to run',
|
help = 'command to run',
|
||||||
choices = ['up', 'down'], nargs = 1, default = "up")
|
choices = ['up', 'down'], nargs = 1, default = "up")
|
||||||
|
|
||||||
parser.add_argument("-f", "--file",
|
parser.add_argument("-f", "--file",
|
||||||
help = "Specify an alternate compose file (default: docker-compose.yml)",
|
help = "Specify an alternate compose file (default: docker-compose.yml)",
|
||||||
type=str, default='docker-compose.yml')
|
type = str, default = "docker-compose.yml")
|
||||||
parser.add_argument("-p", "--project-name",
|
parser.add_argument("-p", "--project-name",
|
||||||
help = "Specify an alternate project name (default: directory name)",
|
help = "Specify an alternate project name (default: directory name)",
|
||||||
type = str, default = None)
|
type = str, default = None)
|
||||||
|
parser.add_argument("--podman-path",
|
||||||
|
help = "Specify an alternate path to podman (default: use location in $PATH variable)",
|
||||||
|
type = str, default = "podman")
|
||||||
parser.add_argument("--no-ansi",
|
parser.add_argument("--no-ansi",
|
||||||
help = "Do not print ANSI control characters", action = 'store_true')
|
help = "Do not print ANSI control characters", action = 'store_true')
|
||||||
|
parser.add_argument("--no-cleanup",
|
||||||
|
help = "Do not stop and remove existing pod & containers", action = 'store_true')
|
||||||
|
parser.add_argument("--dry-run",
|
||||||
|
help = "No action; perform a simulation of commands", action = 'store_true')
|
||||||
parser.add_argument("-t", "--transform_policy",
|
parser.add_argument("-t", "--transform_policy",
|
||||||
help = "how to translate docker compose to podman [1pod|hostnet|accurate]",
|
help = "how to translate docker compose to podman [1pod|hostnet|accurate]",
|
||||||
choices = ['1pod', '1podfw', 'hostnet', 'cntnet', 'publishall', 'identity'], default = '1podfw')
|
choices = ['1pod', '1podfw', 'hostnet', 'cntnet', 'publishall', 'identity'], default = '1podfw')
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
main (
|
main (
|
||||||
command = args.command,
|
command = args.command,
|
||||||
filename = args.file,
|
filename = args.file,
|
||||||
project_name = args.project_name,
|
project_name = args.project_name,
|
||||||
no_ansi = args.no_ansi,
|
no_ansi = args.no_ansi,
|
||||||
transform_policy=args.transform_policy)
|
no_cleanup = args.no_cleanup,
|
||||||
|
dry_run = args.dry_run,
|
||||||
|
transform_policy = args.transform_policy,
|
||||||
|
podman_path = args.podman_path
|
||||||
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user