mirror of
https://github.com/Red5d/docker-autocompose
synced 2026-01-17 14:08:02 +00:00
Compare commits
17 Commits
1.1
...
e19c4654af
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e19c4654af | ||
|
|
d6dddedb3d | ||
|
|
0dfdac353f | ||
|
|
a8f00e0deb | ||
|
|
adf98bb062 | ||
|
|
1af6b49233 | ||
|
|
40aaf8e82c | ||
|
|
63810906f9 | ||
|
|
e32c9d4275 | ||
|
|
caa747b605 | ||
|
|
d783902265 | ||
|
|
e6badd31c3 | ||
|
|
3f756235b2 | ||
|
|
b9c096dd94 | ||
|
|
e7dbe41f23 | ||
|
|
d976d520b4 | ||
|
|
ec211717ed |
@@ -43,3 +43,6 @@ Use the new image to generate a docker-compose file from a running container or
|
||||
|
||||
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock ghcr.io/red5d/docker-autocompose <container-name-or-id> <additional-names-or-ids>...
|
||||
|
||||
To print out all containers in a docker-compose format:
|
||||
|
||||
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock ghcr.io/red5d/docker-autocompose $(docker ps -aq)
|
||||
|
||||
@@ -1,19 +1,32 @@
|
||||
#! /usr/bin/env python
|
||||
|
||||
import datetime
|
||||
import sys, argparse, pyaml, docker
|
||||
from collections import OrderedDict
|
||||
|
||||
|
||||
def list_container_names():
|
||||
c = docker.from_env()
|
||||
return [container.name for container in c.containers.list(all=True)]
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description='Generate docker-compose yaml definition from running container.')
|
||||
parser.add_argument('-a', '--all', action='store_true', help='Include all active containers')
|
||||
parser.add_argument('-v', '--version', type=int, default=3, help='Compose file version (1 or 3)')
|
||||
parser.add_argument('cnames', nargs='*', type=str, help='The name of the container to process.')
|
||||
args = parser.parse_args()
|
||||
|
||||
container_names = args.cnames
|
||||
if args.all:
|
||||
container_names.extend(list_container_names())
|
||||
|
||||
struct = {}
|
||||
networks = []
|
||||
for cname in args.cnames:
|
||||
cfile, networks = generate(cname)
|
||||
networks = {}
|
||||
for cname in container_names:
|
||||
cfile, c_networks = generate(cname)
|
||||
|
||||
struct.update(cfile)
|
||||
networks.update(c_networks)
|
||||
|
||||
render(struct, args, networks)
|
||||
|
||||
@@ -24,7 +37,21 @@ def render(struct, args, networks):
|
||||
pyaml.p(OrderedDict(struct))
|
||||
else:
|
||||
pyaml.p(OrderedDict({'version': '"3"', 'services': struct, 'networks': networks}))
|
||||
|
||||
|
||||
|
||||
def is_date_or_time(s: str):
|
||||
for parse_func in [datetime.date.fromisoformat, datetime.datetime.fromisoformat]:
|
||||
try:
|
||||
parse_func(s.rstrip('Z'))
|
||||
return True
|
||||
except ValueError:
|
||||
pass
|
||||
return False
|
||||
|
||||
|
||||
def fix_label(label: str):
|
||||
return f"'{label}'" if is_date_or_time(label) else label
|
||||
|
||||
|
||||
def generate(cname):
|
||||
c = docker.from_env()
|
||||
@@ -32,7 +59,7 @@ def generate(cname):
|
||||
try:
|
||||
cid = [x.short_id for x in c.containers.list(all=True) if cname == x.name or x.short_id in cname][0]
|
||||
except IndexError:
|
||||
print("That container is not available.")
|
||||
print("That container is not available.", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
cattrs = c.containers.get(cid).attrs
|
||||
@@ -55,7 +82,7 @@ def generate(cname):
|
||||
'environment': cattrs['Config']['Env'],
|
||||
'extra_hosts': cattrs['HostConfig']['ExtraHosts'],
|
||||
'image': cattrs['Config']['Image'],
|
||||
'labels': cattrs['Config']['Labels'],
|
||||
'labels': {label: fix_label(value) for label, value in cattrs['Config']['Labels'].items()},
|
||||
'links': cattrs['HostConfig']['Links'],
|
||||
#'log_driver': cattrs['HostConfig']['LogConfig']['Type'],
|
||||
#'log_opt': cattrs['HostConfig']['LogConfig']['Config'],
|
||||
@@ -91,15 +118,16 @@ def generate(cname):
|
||||
networklist = c.networks.list()
|
||||
for network in networklist:
|
||||
if network.attrs['Name'] in values['networks']:
|
||||
networks[network.attrs['Name']] = {'external': (not network.attrs['Internal'])}
|
||||
networks[network.attrs['Name']] = {'external': (not network.attrs['Internal']),
|
||||
'name': network.attrs['Name']}
|
||||
|
||||
# Check for command and add it if present.
|
||||
if cattrs['Config']['Cmd'] != None:
|
||||
values['command'] = " ".join(cattrs['Config']['Cmd']),
|
||||
if cattrs['Config']['Cmd'] is not None:
|
||||
values['command'] = cattrs['Config']['Cmd']
|
||||
|
||||
# Check for exposed/bound ports and add them if needed.
|
||||
try:
|
||||
expose_value = list(cattrs['Config']['ExposedPorts'].keys())
|
||||
expose_value = list(cattrs['Config']['ExposedPorts'].keys())
|
||||
ports_value = [cattrs['HostConfig']['PortBindings'][key][0]['HostIp']+':'+cattrs['HostConfig']['PortBindings'][key][0]['HostPort']+':'+key for key in cattrs['HostConfig']['PortBindings']]
|
||||
|
||||
# If bound ports found, don't use the 'expose' value.
|
||||
|
||||
Reference in New Issue
Block a user