-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbuild_running_containers.py
85 lines (72 loc) · 2.72 KB
/
build_running_containers.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#!/usr/bin/python
"""
Build script of creating docker-compose.yml
Extract info running containers, and
generates compose yaml (services against each containers)
Note: link containers not supported yet!
"""
import yaml
import docker
import subprocess
import json
from aws_ecr import *
from terraform_create import *
def build_from_running_containers(ids=None, account_id=None, build_image=False):
client = docker.from_env()
if ids==None:
containers = client.containers.list()
else:
# containers from given ids
containers = client.containers.list(filters={'status': 'running', 'id': ids})
template = {'services': {}, 'version': '3'}
for c in containers:
service = {}
# image info
image = c.attrs['Config']['Image']
#tag = c.attrs['Config']['Labels']
# correction
service['image'] = str(image)
#if tag:
# service['image'] = (str(image) + ":" + str(tag))
#else:
# service['image'] = (str(image))
# mount volume info
# TODO: multiple mounts
if len(c.attrs['Mounts']):
dest_volume = c.attrs['Mounts'][0]['Destination']
source_volume = c.attrs['Mounts'][0]['Source']
service['volumes'] = [str(source_volume) + ":" + str(dest_volume)]
# port mapping info ( handle tcp port only yet)
# default port will be zero, if some container working as client,
# and didn't host any service, then we didn't need port
innerport = '0'
urls = c.attrs['NetworkSettings']['Ports']
for url in urls:
innerport = url.split('/')[0]
if urls[url]: # TCP ports
outerport = urls[url][0]['HostPort']
service['ports'] = [str(innerport)+':'+str(outerport)]
# service name info
# default service name is same as image name, if netstat is not present in container
service_name = str(image)
pid=c.attrs['State']['Pid']
netstat_command=['pkexec', 'nsenter', '-t', str(pid), '-n', 'netstat', '-tulpn']
netstat_output=subprocess.check_output(netstat_command)
for row in netstat_output.split(b'\n'):
if str.encode(innerport) in row:
if row.split()[0] == b'tcp':
service_name = row.split()[6].split('/')[1]
# append service
template['services'][service_name] = service
if account_id:
# build image with same tag as container and push to ECR
image_name = image.split(':')[0]
tag = image.split(':')[1]
build_and_ecr_push(tag, account_id, image_name, build_image)
# create task defination with port mapping and mount volume in terraform dir
create_task_definition(service_name, account_id, service)
# create variables.tf in terraform dir with app name
create_variables(image_name, outerport, 'ecs_app_cluster')
#print yaml.dump(template, default_flow_style=False)
with open('docker-compose.yml', 'w') as outfile:
yaml.dump(template, outfile, default_flow_style=False)