forked from abulte/docker-dbaas
-
Notifications
You must be signed in to change notification settings - Fork 0
/
docker_lib.py
135 lines (118 loc) · 4.13 KB
/
docker_lib.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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright 2013 Alexandre Bulté <alexandre[at]bulte[dot]net>
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
import datetime
import dateutil.parser
from docker import Client
from yapsy.PluginManager import PluginManager
from webapp import app, query_db, get_db
from requests.exceptions import HTTPError
# import logging
# logging.basicConfig(level=logging.DEBUG)
## PLUGINS
# Load the plugins from the plugin directory.
manager = PluginManager()
manager.setPluginPlaces(["plugins"])
manager.collectPlugins()
def getPluginNames():
return [plugin.name for plugin in manager.getAllPlugins()]
def _getAdapter(ttype):
adapter = manager.getPluginByName(ttype)
if adapter is None:
raise Exception('Unsupported database type: %s' % ttype)
else:
return adapter.plugin_object
## END PLUGINS
def dc():
return Client(base_url=app.config.get('BASE_URL'), version='1.3')
def _format_container(raw):
# app.logger.debug(raw)
adapter = _getAdapter(raw['type'])
port = adapter.PORT
running = raw['State']['Running']
c_id = raw['ID'][:12]
if not running:
return {'id': c_id, 'running': False}
else:
start = raw['State']['StartedAt']
start = dateutil.parser.parse(start)
up_for = datetime.datetime.now(start.tzinfo) - start
status = 'Up %s day(s) %s hour(s)' % (up_for.days, up_for.seconds / 3600)
return {
'id': c_id,
'running': True,
'ip': raw['NetworkSettings']['IPAddress'],
'db_port': raw['NetworkSettings']['PortMapping']['Tcp'].get('%s' % port, None),
'created': raw['Created'],
'status': status
}
def _get_container_from_db(c_id):
cdb = query_db('select * from databases where docker_id = ?', args=[c_id], one=True)
if cdb is None:
raise Exception('No container by id %s' % c_id)
return cdb
def stop_container(c_id):
dc().stop(c_id)
return True
def start_container(c_id):
dc().start(c_id)
return True
def remove_container(c_id):
with app.app_context():
get_db().execute('delete from databases where docker_id = ?', [c_id])
get_db().commit()
try:
dc().remove_container(c_id)
except RuntimeError:
pass
return True
def inspect_container(container_id):
raw = dc().inspect_container(container_id)
cdb = _get_container_from_db(container_id)
raw['type'] = cdb['type']
return _format_container(raw)
def get_containers(details=False):
cs = []
with app.app_context():
for c in query_db('select * from databases'):
cs.append({'id': c['docker_id'], 'name': c['name'], 'type': c['type']})
if not details:
return cs
else:
detail_containers = []
for c in cs:
# app.logger.debug(c)
try:
details = inspect_container(c['id'])
except HTTPError:
details = {}
details['id'] = c['id']
c['name'] = 'Not found'
c['type'] = ''
details['name'] = c['name']
details['type'] = c['type']
detail_containers.append(details)
return detail_containers
def create_container(dbtype, name, mem_limit, pm):
adapter = _getAdapter(dbtype)
container = adapter.create_container(mem_limit=int(mem_limit)*1024*1024, pm=pm)
with app.app_context():
get_db().execute('insert into databases (docker_id, name, memory_limit, port_mapping, type) \
values (?, ?, ?, ?, ?)', [container['Id'], name, mem_limit, pm, dbtype])
get_db().commit()
start_container(container['Id'])
return container
def test_container(c_id):
with app.app_context():
cdb = _get_container_from_db(c_id)
adapter = _getAdapter(cdb['type'])
info = inspect_container(c_id)
if not info:
raise Exception('No container by id')
elif not info['running']:
return False
return adapter.test_container(info)