alshabib | c61999a | 2016-10-27 16:44:27 -0700 | [diff] [blame] | 1 | from consul.twisted import Consul |
alshabib | c67ee3a | 2016-10-25 23:24:03 -0700 | [diff] [blame] | 2 | from structlog import get_logger |
| 3 | from twisted.internet import reactor |
alshabib | c61999a | 2016-10-27 16:44:27 -0700 | [diff] [blame] | 4 | from twisted.internet.defer import returnValue |
alshabib | c67ee3a | 2016-10-25 23:24:03 -0700 | [diff] [blame] | 5 | |
alshabib | c61999a | 2016-10-27 16:44:27 -0700 | [diff] [blame] | 6 | from common.utils.dockerhelpers import create_container_network, start_container, create_host_config |
alshabib | c67ee3a | 2016-10-25 23:24:03 -0700 | [diff] [blame] | 7 | |
| 8 | containers = { |
| 9 | 'chameleon' : { |
alshabib | c61999a | 2016-10-27 16:44:27 -0700 | [diff] [blame] | 10 | 'image' : 'cord/chameleon', |
alshabib | c67ee3a | 2016-10-25 23:24:03 -0700 | [diff] [blame] | 11 | 'command' : [ "/chameleon/main.py", |
| 12 | "-v", |
| 13 | "--consul=consul:8500", |
| 14 | "--fluentd=fluentd:24224", |
| 15 | "--rest-port=8881", |
| 16 | "--grpc-endpoint=@voltha-grpc", |
| 17 | "--instance-id-is-container-name", |
| 18 | "-v"], |
| 19 | 'ports' : [ 8881 ], |
| 20 | 'depends_on' : [ "consul", "voltha" ], |
alshabib | c61999a | 2016-10-27 16:44:27 -0700 | [diff] [blame] | 21 | 'links' : { "consul" : "consul", "fluentd" : "fluentd" }, |
alshabib | c67ee3a | 2016-10-25 23:24:03 -0700 | [diff] [blame] | 22 | 'environment' : ["SERVICE_8881_NAME=chamleon-rest"], |
alshabib | c61999a | 2016-10-27 16:44:27 -0700 | [diff] [blame] | 23 | 'volumes' : { '/var/run/docker.sock' : '/tmp/docker.sock' } |
alshabib | c67ee3a | 2016-10-25 23:24:03 -0700 | [diff] [blame] | 24 | } |
| 25 | } |
| 26 | |
| 27 | class ConsulManager(object): |
| 28 | |
| 29 | log = get_logger() |
| 30 | |
| 31 | def __init__(self, arg): |
| 32 | self.log.info('Initializing consul manager') |
| 33 | self.running = False |
| 34 | self.index = 0 |
| 35 | (host, port) = arg.split(':') |
alshabib | c61999a | 2016-10-27 16:44:27 -0700 | [diff] [blame] | 36 | self.conn = Consul(host=host, port=port) |
alshabib | c67ee3a | 2016-10-25 23:24:03 -0700 | [diff] [blame] | 37 | |
alshabib | c67ee3a | 2016-10-25 23:24:03 -0700 | [diff] [blame] | 38 | def run(self): |
| 39 | if self.running: |
| 40 | return |
| 41 | self.running = True |
| 42 | |
| 43 | self.log.info('Running consul manager') |
| 44 | |
alshabib | c61999a | 2016-10-27 16:44:27 -0700 | [diff] [blame] | 45 | reactor.callLater(0, self.provision_voltha_instances, None) |
alshabib | c67ee3a | 2016-10-25 23:24:03 -0700 | [diff] [blame] | 46 | |
| 47 | reactor.addSystemEventTrigger('before', 'shutdown', self.shutdown) |
| 48 | returnValue(self) |
| 49 | |
alshabib | c61999a | 2016-10-27 16:44:27 -0700 | [diff] [blame] | 50 | |
alshabib | c67ee3a | 2016-10-25 23:24:03 -0700 | [diff] [blame] | 51 | def shutdown(self): |
| 52 | self.log.info('Shutting down consul manager') |
| 53 | self.running = False |
| 54 | |
alshabib | c67ee3a | 2016-10-25 23:24:03 -0700 | [diff] [blame] | 55 | |
alshabib | c61999a | 2016-10-27 16:44:27 -0700 | [diff] [blame] | 56 | def provision_voltha_instances(self, _): |
| 57 | if not self.running: |
| 58 | return |
| 59 | # maintain index such that callbacks only happen is something has changed |
| 60 | # timeout is default to 5m |
| 61 | deferred = self.conn.catalog.service(wait='5s', service='voltha-grpc', |
| 62 | index=self.index) |
| 63 | deferred.addCallbacks(self.provision, self.fail) |
| 64 | deferred.addBoth(self.provision_voltha_instances) |
| 65 | |
| 66 | def provision(self, result): |
| 67 | (self.index, data) = result |
| 68 | self.log.info('PROVISIONING {}'.format(data)) |
alshabib | c67ee3a | 2016-10-25 23:24:03 -0700 | [diff] [blame] | 69 | for item in data: |
alshabib | c61999a | 2016-10-27 16:44:27 -0700 | [diff] [blame] | 70 | (service, id) = item['ServiceID'].split(':')[1].split('_')[1:3] |
| 71 | self.log.info('got {} {}'.format(service, id)) |
| 72 | self.podProvisioned(service, id, item['ServiceTags']) |
| 73 | |
| 74 | def fail(self, err): |
| 75 | self.log.info('Failure %s'.format(err)) |
| 76 | |
| 77 | def start_containers(self, result, service, id, tags): |
| 78 | self.log.info("wtf : {}".format(result)) |
| 79 | (_, done) = result |
| 80 | self.log.info("result : {}, {}".format(done, type(done))) |
| 81 | if done: |
| 82 | return |
| 83 | self.log.info('provisioning voltha instance {}, with tags {}'.format(id, tags)) |
| 84 | for tag in tags: |
| 85 | if tag in containers: |
| 86 | netcfg = self.create_network(id, tag) |
| 87 | if self.create_container(id, tag, netcfg): |
| 88 | self.markProvisioned(service, id) |
alshabib | c67ee3a | 2016-10-25 23:24:03 -0700 | [diff] [blame] | 89 | |
| 90 | |
| 91 | def create_network(self, id, tag): |
| 92 | return create_container_network('podder_%s_%s' % (tag, id), |
| 93 | containers[tag]['links']) |
| 94 | |
| 95 | def create_container(self, id, tag, netcfg): |
| 96 | args = {} |
alshabib | c61999a | 2016-10-27 16:44:27 -0700 | [diff] [blame] | 97 | args['image'] = containers[tag]['image'] |
alshabib | c67ee3a | 2016-10-25 23:24:03 -0700 | [diff] [blame] | 98 | args['networking_config'] = netcfg |
alshabib | c61999a | 2016-10-27 16:44:27 -0700 | [diff] [blame] | 99 | args['command'] = containers[tag]['command'] |
| 100 | args['ports'] = containers[tag]['ports'] |
| 101 | args['environment'] = containers[tag]['environment'] |
| 102 | args['volumes'] = containers[tag]['volumes'].keys() |
| 103 | args['host_config'] = create_host_config(containers[tag]['volumes'], |
| 104 | containers[tag]['ports']) |
| 105 | args['name'] = 'podder_%s_%s' % (tag, id) |
| 106 | start_container(args) |
| 107 | #TODO check container is running |
| 108 | |
| 109 | return True |
| 110 | |
| 111 | def podProvisioned(self, service, id, tags): |
| 112 | d = self.conn.kv.get('podder/%s/%s/state' % (service, id)) |
| 113 | d.addCallback(self.start_containers, service, id, tags) |
| 114 | d.addErrback(lambda err: self.log.info("FAIL {}".format(err))) |
| 115 | |
| 116 | def markProvisioned(self, service, id): |
| 117 | self.conn.kv.put('podder/%s/%s/state' % (service, id), "started") |