class HAProxy: def __init__(self, etcd_url='127.0.0.1', etcd_port=2379): self.etcd_conn = Etcd(etcd_url, etcd_port) self.key = '/fc-haproxy/' self.key_http = {'80': 'app-http', '443': 'app-https'} self.appHTTP = 'app-http' self.appHTTPS = 'app-https' self.app_protocol_http = ['http', 'https'] self.ports_http = ['80', '443'] self.hostname = socket.gethostname() def generate_conf(self, application_name, container_name, ports_container, protocol, address_container, dns=None): logging.info( 'Generate conf to haproxy with application: %s, container: %s' % (application_name, container_name)) if not application_name: raise Exception("Name of application is required") if not container_name: raise Exception("Name of container is required") if not ports_container: raise Exception("Ports of container is required") if not protocol: raise Exception("Protocol of container is required") if not address_container: raise Exception("Address of container is required") keys_ports = ports_container.keys() for key in keys_ports: if str(key) in self.ports_http: etcd_key = self.key + self.key_http[str(key)] try: values = self._http_and_https( etcd_key=etcd_key, application_name=str(application_name), container_name=str(container_name), address_container=address_container, dns=str(dns), ports_container=ports_container[key]) self.etcd_conn.write(etcd_key, json.dumps(values)) except Exception as e: raise Exception(e) keys_ports.remove(key) if len(keys_ports) > 0: try: values = self._tcp_and_udp(application_name=application_name, keys_ports=keys_ports, container_name=container_name, address_container=address_container, dns=dns, protocol=protocol, ports_container=ports_container) self.etcd_conn.write(self.key + application_name, json.dumps(values)) except Exception as e: raise Exception(e) def _tcp_and_udp(self, application_name, keys_ports, container_name, address_container, dns, protocol, ports_container): key_exists = self.etcd_conn.key_exists(self.key + application_name) if key_exists: try: values = ast.literal_eval( self.etcd_conn.read(self.key + application_name)) for key in keys_ports: for host in values['hosts']: if 'portSRC' in host and host['portSRC'] == key: for dst in ports_container[key]: host['containers'].append({ 'name': container_name, 'address': address_container + ':' + dst, 'minion': self.hostname }) except Exception as e: raise Exception(e) else: values = {'hosts': [], 'dns': dns} for key in keys_ports: containers = [] for dst in ports_container[key]: containers.append({ 'name': container_name, 'address': address_container + ':' + dst, 'minion': self.hostname }) values['hosts'].append({ 'protocol': protocol[str(key)], 'portSRC': key, 'containers': containers }) return values def _http_and_https(self, etcd_key, application_name, container_name, address_container, dns, ports_container): key_exists = self.etcd_conn.key_exists(etcd_key) if key_exists: try: contains = False values = ast.literal_eval(self.etcd_conn.read(etcd_key)) for host in values['hosts']: if 'name' in host and host['name'] == application_name: contains = True for dst in ports_container: host['containers'].append({ 'name': container_name, 'address': address_container + ':' + dst, 'minion': self.hostname }) if contains == False: containers = [] for dst in ports_container: containers.append({ 'name': container_name, 'address': address_container + ':' + dst, 'minion': self.hostname }) values['hosts'].append({ 'name': application_name, 'containers': containers, 'dns': dns }) except Exception as e: raise Exception(e) else: values = {'hosts': []} containers = [] for dst in ports_container: containers.append({ 'name': container_name, 'address': address_container + ':' + dst, 'minion': self.hostname }) values['hosts'].append({ 'name': application_name, 'containers': containers, 'dns': dns, 'minion': self.hostname }) return values def remove_container(self, application_name, container_name, protocol): if not application_name: raise Exception("Name of application is required") if not container_name: raise Exception("Name of container is required") keys_protocol = protocol.keys() keys_etcd = [] for key in keys_protocol: if str(key) in self.ports_http: if self.etcd_conn.key_exists(self.key + self.key_http[str(key)]) == False: raise Exception("Key %s not exists in system haproxy" % self.key_http[str(key)]) keys_etcd.append(self.key + self.key_http[str(key)]) keys_protocol.remove(key) if len(keys_protocol) > 0: if self.etcd_conn.key_exists(self.key + application_name) == False: raise Exception( "Key of application %s not exists in system haproxy" % application_name) keys_etcd.append(self.key + application_name) for key in keys_etcd: try: values = ast.literal_eval(self.etcd_conn.read(key)) if 'hosts' in values: for host in values['hosts']: if 'containers' in host: containers = host['containers'] for idx, container in enumerate(containers): if container['name'] == container_name: containers = containers[:idx] + containers[ idx + 1:] host['containers'] = containers self.etcd_conn.write(key, json.dumps(values)) except Exception as e: raise Exception(e)
class Zeus(sleekxmpp.ClientXMPP): def __init__(self, jid, password, etcd_url): sleekxmpp.ClientXMPP.__init__(self, jid, password) self.minions = [] self.jid_minions = [] self.minions_pods = {} self.chat_minions = 'minions' self.etcd_url = etcd_url self.etcd_port = 2379 self.containers_per_minion = {} self.path_images = os.environ['path_images'] self.add_event_handler("session_start", self.start) self.add_event_handler("message", self.message) self.add_event_handler("name_pods", self._handler_deploy) self.etcd_conn = Etcd(self.etcd_url, self.etcd_port) self.docker_commands = DockerCommands(etcd_url=self.etcd_url, etcd_port=self.etcd_port) self.haproxy = HAProxy(etcd_url=self.etcd_url, etcd_port=self.etcd_port) def start(self, event): self.send_presence() self.get_roster() global form self.room = '*****@*****.**' self.nick = self.boundjid.user rooms = self.plugin['xep_0030'].get_items(jid='conference.localhost') for room in rooms['disco_items']: if room['jid'] != self.room: self.plugin['xep_0045'].joinMUC(room['jid'], self.nick) self.add_event_handler("muc::%s::got_online" % room['jid'], self.muc_online) self.add_event_handler("muc::%s::got_offline" % room['jid'], self.muc_offline) logging.info("Chat room %s success!" % room['jid']) try: room_exist = self.plugin['xep_0030'].get_info(jid=self.room) except IqError as e: if e.condition == 'item-not-found': self.plugin['xep_0045'].joinMUC(self.room, self.nick, wait=True) form = self.plugin['xep_0045'].getRoomConfig(self.room) form.set_values({ 'muc#roomconfig_persistentroom': 1, 'muc#roomconfig_passwordprotectedroom': 0, 'muc#roomconfig_publicroom': 1, 'muc#roomconfig_roomdesc': 'TESTE!' }) try: self.plugin['xep_0045'].configureRoom(self.room, form=form) logging.info("Chat room %s success created!" % self.room) except IqError as e: logging.error("Could not create chat room: %s" % e.iq['error']['text']) self.disconnect() else: logging.error("Could not create chat room: %s" % e.iq['error']['text']) self.disconnect() else: self.plugin['xep_0045'].joinMUC(self.room, self.nick) logging.info("Chat room %s success created!" % self.room) self.add_event_handler("muc::%s::got_online" % self.room, self.muc_online) self.add_event_handler("muc::%s::got_offline" % self.room, self.muc_offline) def message(self, msg): logging.info('Chat Message: %s' % msg['body']) if msg['type'] in ('chat', 'normal'): option = msg['body'].split()[0] if option == "help": self.help(msg) elif option == "deploy": thread_deploy = threading.Thread(target=self.first_deploy, args=[msg]) thread_deploy.daemon = True thread_deploy.start() elif option == "append": thread_append = threading.Thread(target=self.append_containers, args=[msg]) thread_append.daemon = True thread_append.start() elif option == "create_room": self.create_room(msg) elif option == "container-die": thread_container_die = threading.Thread( target=self.container_die, args=[msg]) thread_container_die.daemon = True thread_container_die.start() elif option == "stop" or option == "start" or option == "pause" or option == "resume": body = msg['body'].split(' ') try: print("PORRA") self.action_container(action=option, container=body[1]) response = 'Success ' + option + ' ' + body[1] except Exception as e: response = unicode(e) self.send_message(mto=msg['from'], mbody=response, mtype='chat') else: print(option) self.send_message(mto=msg['from'], mbody='Invalid Option', mtype='chat') if msg['type'] in ('groupchat', 'normal'): print(msg['body']) def help(self, msg): custom_msg = self.Message() custom_msg[ 'body'] = 'Here's my .plan for today: 1. Add the following examples to XEP-0071: - ordered and unordered lists - more styles (e.g., indentation) 2. Kick back and relax' custom_msg['html'][ 'body'] = '<p>Here's my .plan for today:</p><ol><li>Add the following examples to XEP-0071:<ul><li>ordered and unordered lists</li><li>more styles (e.g., indentation)</li></ul></li><li>Kick back and relax</li></ol>' self.send_message(mto=msg['from'], mbody=custom_msg['body'], mhtml=custom_msg['html'], mtype='chat') def _handler_deploy(self, iq): logging.info('Receive iq request from: %s, iq: %s, args: %s' % (iq['from'], iq['id'], iq['docker'])) if 'master-first-deploy' in iq['id']: args = iq['docker'] try: response = self._deploy_application(args=args, iq_response=iq['id'], ifrom=iq['from']) except Exception as e: self.plugin['docker'].response_master_deploy( iq_response=iq['id'], ito=iq['from'], ifrom=self.boundjid, success=False, error=unicode(e)) if 'master-append-deploy' in iq['id']: args = iq['docker'] try: reponse = self._append_containers(args=args, iq_response=iq['id'], ifrom=iq['from']) except Exception as e: self.plugin['docker'].response_master_append_deploy( iq_response=iq['id'], ito=iq['from'], ifrom=self.boundjid, success=False, error=unicode(e)) def _deploy_application(self, args, iq_response, ifrom): logging.info('Start Deploy Application %s' % (args['application_name'])) if len(self.minions) == 0: raise Exception('Not have hosts to start the deploy') image = '{0}_app-{1}/image:v1'.format(args['customer'], args['application_name']) ports_and_protocols = args['ports'].strip().split(',') protocol = {} ports = [] for x in ports_and_protocols: pp = x.split('/') ports.append(pp[0]) protocol[pp[0]] = pp[1] values_application = { 'cpus': args['cpus'], 'memory': args['memory'], 'ports_dst': ports, 'protocol': protocol, 'image': image, 'total_containers': args['total_containers'], 'dns': args['dns'] } if 'args' in args: values_application['args'] = args['args'] key_application = '/{0}/{1}'.format(args['customer'], args['application_name']) image_name = '{0}_app-{1}'.format(args['customer'], args['application_name']) try: self.etcd_conn.write(key_application, values_application) except Exception as e: raise Exception(e) # try: # self._create_room(args['application_name']) # except Exception as e: # raise Exception(e) try: self._request_deploy_minion( args=args, image_name=image_name, iq_response=iq_response, ifrom=ifrom, key_application=key_application, total_containers=args['total_containers'], first=True) except Exception as e: raise Exception(e) def _append_deploy_application(self, args, iq_response, ifrom): logging.info('Start Append Deploy Application %s' % (args['application_name'])) if len(self.minions) == 0: raise Exception('Not have hosts to start the deploy') key_application = '/{0}/{1}'.format(args['customer'], args['application_name']) try: values_application = ast.literal_eval( self.etcd_conn.read(key_application)) except Exception as e: raise Exception(e) total_containers = values_application['total_containers'] + args[ 'total_containers'] start_count = values_application['total_containers'] + 1 try: self._request_deploy_minion( args=args, image_name=values_application['image'], iq_response=iq_response, ifrom=ifrom, key_application=key_application, total_containers=args['total_containers'], start_count=start_count) except Exception as e: raise Exception(e) values_application['total_containers'] = total_containers try: self.etcd_conn.write(key_application, values_application) except Exception as e: raise Exception(e) def _request_deploy_minion(self, args, image_name, iq_response, ifrom, key_application, total_containers, first=False, start_count=1): if len(self.minions) == 1: if first: try: self._generate_image(path=args['path'], image_name=image_name, key_application=key_application, ito=self.jid_minions[0]) except Exception as e: raise Exception(e) for count in range(int(total_containers)): container_name = '{0}_app-{1}-{2}'.format( args['customer'], args['application_name'], str(start_count)) start_count += 1 thread_deploy_minion = threading.Thread( target=self._requet_deploy_to_minion, args=[ self.jid_minions[0], args['application_name'], key_application, container_name, ifrom ]) thread_deploy_minion.daemon = True thread_deploy_minion.start() else: minions_containers = self._pods_containers(int(total_containers)) iterator = start_count keys_minions = minions_containers.keys() if first: try: self._generate_image(path=args['path'], image_name=image_name, key_application=key_application, ito=keys_minions[0]) except Exception as e: raise Exception(e) for minion in keys_minions[1:]: try: path = '{0}{1}.tar.gz'.format(self.path_images, image_name) self._load_image(path=path, ito=minion) except Exception as e: raise Exception(e) def start_deploy(self, minion, total_containers, iterator, key_application, application_name, customer, ifrom): for count in range(total_containers): container_name = '{0}_app-{1}-{2}'.format( customer, application_name, str(iterator)) iterator += 1 thread_deploy_minion = threading.Thread( target=self._requet_deploy_to_minion, args=[ minion, application_name, key_application, container_name, ifrom ]) thread_deploy_minion.daemon = True thread_deploy_minion.start() for minion in keys_minions: thread_start_deploy = threading.Thread( target=start_deploy, args=[ self, minion, minions_containers[minion], iterator, key_application, args['application_name'], args['customer'], ifrom ]) thread_start_deploy.daemon = True thread_start_deploy.start() iterator += minions_containers[minion] # def _first_deploy(self, args, iq_response, ifrom): # logging.info('Start First Deploy') # if len(self.minions) == 0: # raise Exception('Not have hosts to start the deploy') # image = args['customer'] + '_app-' + args['name'] + '/image:v1' # values_etcd = {'cpus': args['cpus'], 'memory': args['memory'], 'ports_dst': args['ports'].strip( # ).split(','), 'image': image, 'total': args['total']} # key_application = '/' + args['customer'] + '/' + args['name'] # etcd_conn = Etcd(self.etcd_url, self.etcd_port) # try: # etcd_conn.write(key_application, values_etcd) # except Exception as e: # raise Exception(e) # try: # self._create_room(args['name']) # except Exception as e: # raise Exception(e) # try: # self._send_deploy_minion(args=args, image=image, iq_response=iq_response, # ifrom=ifrom, key_application=key_application, first=True) # except Exception as e: # raise Exception(e) def _deploy_container_die(self, application_name, container_name, minion, key_application): logging.info('Movie containers die in minion ' % (container_name)) try: values_application = ast.literal_eval( self.etcd_conn.read(key_application)) except Exception as e: raise Exception(e) minions_containers = self._pods_containers(1) keys_minions = minions_containers.keys() try: self.plugin['docker'].request_minion_deploy( application_name=application_name, container_name=container_name, key_application=key_application, ito=keys_minions[0], ifrom=self.boundjid, timeout=120) self.containers_per_minion[keys_minions[0]].append(container_name) except IqError as e: raise Exception(e.iq['error']['text']) except IqTimeout as t: raise Exception('Timout request') #if len(keys_minions) == 1 and keys_minions[0] == minion: # raise Exception('Note have hosts avaliable to depoloy container') def _deploy_minion_die(self, containers): logging.info('Deploy containers %s die' % (containers)) minions_containers = self._pods_containers(len(containers)) keys_minions = minions_containers.keys() minion_iterator = 0 count_containers = 1 for idx, container_name in enumerate(containers): cn = container_name.split('_app-') customer = cn[0] application_name = '-'.join(cn[1].split('-')[:-1]) key_application = '/{0}/{1}'.format(customer, application_name) if count_containers > minions_containers[ keys_minions[minion_iterator]]: minion_iterator += 1 count_containers = 1 try: values_application = ast.literal_eval( self.etcd_conn.read(key_application)) except Exception as e: raise Exception(e) try: self.haproxy.remove_container( application_name=str(application_name), container_name=str(container_name), protocol=ast.literal_eval( str(values_application['protocol']))) self.plugin['docker'].request_minion_deploy( application_name=application_name, container_name=container_name, key_application=key_application, ito=keys_minions[minion_iterator], ifrom=self.boundjid, timeout=120) count_containers += 1 containers = containers[:idx] + containers[idx + 1:] self.containers_per_minion = containers except IqError as e: raise Exception(e.iq['error']['text']) except IqTimeout as t: raise Exception('Timeout request deploy container %s' % (container_name)) containers = None def _append_containers(self, args, iq_response, ifrom): print(args) # def _send_deploy_minion(self, args, image, iq_response, ifrom, key_application, first): # if len(self.minions) == 1: # if first: # try: # self._generate_image( # path=args['path'], image_name=image, key_application=key_application, ito=self.jid_minions[0]) # except Exception as e: # raise Exception(e) # # for number in range(int(args['total'])): # application_name = args['customer'] + \ # '_app-' + args['name'] + '-' + str(number) # # thread_deploy_minion = threading.Thread(target=self._requet_deploy_to_minion, args=[ # self.jid_minions[0], args['name'], key_application, application_name, ifrom]) # thread_deploy_minion.daemon = True # thread_deploy_minion.start() # else: # minions_containers = self._pods_containers(int(args['total'])) # iterator = 0 # keys_minions = minions_containers.keys() # # if first: # try: # self._generate_image( # path=args['path'], image_name=args['name'], key_application=key_application, ito=self.keys_minions[0]) # except Exception as e: # raise Exception(e) # # for minion in keys_minions[1:]: # try: # self._load_image( # path=self.path_images + args['name'] + '.tar.gz', ito=minion) # except Exception as e: # raise Exception(e) # # def start_deploy(self, minion, number, iterator, key_application, name, ifrom): # for n in range(number): # application_name = name + '-' + str(iterator) # iterator += 1 # # thread_deploy_minion = threading.Thread(target=self._requet_deploy_to_minion, args=[ # minion, name, key_application, application_name, ifrom]) # thread_deploy_minion.daemon = True # thread_deploy_minion.start() # # for minion in keys_minions: # thread_start_deploy = threading.Thread(target=start_deploy, args=[ # self, minion, minions_containers[minion], iterator, key_application, args['name'], ifrom]) # thread_start_deploy.daemon = True # thread_start_deploy.start() def get_number_containers(self, to): try: response = self.plugin['docker'].request_total_pods( ito=to, ifrom=self.boundjid) return response['docker']['total'] except IqError as e: raise Exception(e.iq['error']['text']) except IqTimeout as t: raise Exception(t) def _handler_send_message(self, mto, body): self.send_message(mto=mto, mbody=body, mtype='chat') def action_container(self, action, container): for minion in self.jid_minions: try: containers = self.plugin['docker'].request_get_name_pods( ito=minion, ifrom=self.boundjid) if container in containers['docker']['name']: self.plugin['docker'].request_action_container( container=container, action=action, ito=minion, ifrom=self.boundjid) return True except IqError as e: raise Exception(e.iq['error']['text']) except IqTimeout as t: raise Exception(t) raise Exception("Container " + container + " is not exists") def first_deploy(self, msg): options = msg['body'].split() try: application_name, customer, values = self._get_start_infos(options) except Exception as e: self._handler_send_message(msg['from'], unicode(e)) return values['application_name'] = application_name values['customer'] = customer values['path'] = '/root/python-xmpp/go/hello_world/hello_world' #values['dns'] = 'lucas.com.br' print(application_name, customer, values) try: self._deploy_application(args=values, iq_response=None, ifrom=msg['from']) except IqError as e: self._handler_send_message(msg['from'], unicode(e.iq['error']['text'])) except IqTimeout as t: self._handler_send_message(msg['from'], unicode(t)) # logging.info('Start First Deploy') # # if len(self.minions) == 0: # self._handler_send_message( # msg['from'], "Not have hosts to start the deploy") # return # # try: # hostname, customer, pods, values_etcd = self._get_start_infos( # msg['body'].split('%')) # except Exception as e: # self._handler_send_message(msg['from'], unicode(e)) # # self._pods_containers(pods) # # etcd_conn = Etcd(self.etcd_url, self.etcd_port) # endpoint = '/' + customer + '/' + hostname # # try: # etcd_conn.write(endpoint, values_etcd) # except Exception as e: # self._handler_send_message(msg['from'], unicode(e)) # # try: # self._create_room(hostname) # except Exception as e: # self._handler_send_message(msg['from'], unicode(e)) # # if len(self.minions) == 1: # try: # self._generate_image(path='/root/python-xmpp/go/hello_world/hello_world', # image_name=customer + '_app-' + hostname, key_application=endpoint, ito=self.jid_minions[0]) # except Exception as e: # self._handler_send_message(msg['from'], unicode(e)) # # for number in range(pods): # application_name = customer + '_app-' + \ # hostname + "-" + str(number) # # thread_deploy_minion = threading.Thread(target=self._requet_deploy_to_minion, args=[ # self.jid_minions[0], hostname, endpoint, application_name, msg['from']]) # thread_deploy_minion.daemon = True # thread_deploy_minion.start() # else: # def start_deploy(self, key, number, iterator, endpoint, hostname, ifrom, customer): # for n in range(number): # application_name = customer + '_app-' + \ # hostname + "-" + str(iterator) # iterator += 1 # # thread_deploy_minion = threading.Thread(target=self._requet_deploy_to_minion, # args=[key, hostname, endpoint, application_name, ifrom]) # thread_deploy_minion.daemon = True # thread_deploy_minion.start() # # minions_pods = self._pods_containers(pods) # iterator = 0 # keys = minions_pods.keys() # # try: # self._generate_image( # path='/root/python-xmpp/go/hello_world/hello_world', image_name=customer + '_app-' + hostname, key_application=endpoint, ito=keys[0]) # except Exception as e: # self._handler_send_message(msg['from'], unicode(e)) # # print(keys[1:]) # for key in keys[1:]: # try: # self._load_image( # path=self.path_images + customer + '_app-' + hostname + '.tar.gz', ito=key) # except Exception as e: # self._handler_send_message(msg['from'], unicode(e)) # # for key in keys: # thread_start_deploy = threading.Thread(target=start_deploy, # args=[self, key, minions_pods[key], iterator, endpoint, hostname, msg['from'], customer]) # thread_start_deploy.daemon = True # thread_start_deploy.start() # # iterator += minions_pods[key] def container_die(self, msg): options = msg['body'].split() containers = self.containers_per_minion[options[3]] for idx, container in enumerate( self.containers_per_minion[options[3]]): if container == options[2]: containers = containers[:idx] + containers[idx + 1:] self.containers_per_minion[options[3]] = containers try: self._deploy_container_die(application_name=options[1], container_name=options[2], minion=options[3], key_application=options[4]) except Exception as e: logging.error('Error to create container die: %s' % unicode(e)) def append_containers(self, msg): options = msg['body'].split() args = {} for op in options: if "--name" in op: args['application_name'] = op.replace("--name=", "").strip() if "--customer" in op: args['customer'] = op.replace("--customer=", "").strip() if "--total" in op: args['total_containers'] = int( op.replace("--total=", "").strip()) if 'customer' not in args: self._handler_send_message(msg['from'], 'Customer is required') return if 'application_name' not in args: self._handler_send_message(msg['from'], 'Name of application is required') return if 'total_containers' not in args: self._handler_send_message(msg['from'], 'Total of containers is required') return try: self._append_deploy_application(args=args, iq_response=None, ifrom=msg['from']) except IqError as e: self._handler_send_message(msg['from'], unicode(e.iq['error']['text'])) except IqTimeout as t: self._handler_send_message(msg['from'], unicode(t)) # options = msg['body'].split('%') # # if len(self.minions) == 0: # self._handler_send_message( # msg['from'], "Not have hosts to start the deploy") # return # # for option in options: # if 'customer' in option: # customer = option.replace('customer=', '').strip() # if 'name' in option: # name = option.replace('name=', '').strip() # if 'number' in option: # number_containers = option.replace('number=', '').strip() # # etcd_conn = Etcd(self.etcd_url, self.etcd_port) # key_customer = '/' + customer + '/' + name # # if etcd_conn.key_exists(key_customer) is False: # self._handler_send_message( # msg['from'], 'Application "' + name + '" is not exists') # return # # try: # values = ast.literal_eval(etcd_conn.read(key_customer)) # except Exception as e: # self._handler_send_message(msg['from'], unicode(e)) # return # # iterator = values['pods'] + 1 # # values['pods'] = values['pods'] + int(number_containers) # # try: # etcd_conn.update(key_customer, values) # except Exception as e: # self._handler_send_message(msg['from'], unicode(e)) # return # # if len(self.minions) == 1: # for number in range(int(number_containers)): # application_name = name + '-' + str(iterator) # iterator += 1 # # thread_deploy_append_minion = threading.Thread(target=self._requet_deploy_to_minion, args=[ # self.jid_minions[0], name, key_customer, application_name, msg['from']]) # thread_deploy_append_minion.daemon = True # thread_deploy_append_minion.start() # else: # def start_deploy(self, key, number, iterator, endpoint, hostname, ifrom): # for n in range(number): # application_name = hostname + "-" + str(iterator) # iterator += 1 # # thread_deploy_append_minion = threading.Thread(target=self._requet_deploy_to_minion, args=[ # key, hostname, endpoint, application_name, ifrom]) # thread_deploy_append_minion.daemon = True # thread_deploy_append_minion.start() # # minions_pods = self._pods_containers(int(number_containers)) # keys = minions_pods.keys() # # for key in keys: # thread_start_deploy = threading.Thread(target=start_deploy, args=[ # self, key, minions_pods[key], iterator, key_customer, name, msg['from']]) # thread_start_deploy.daemon = True # thread_start_deploy.start() # # iterator += minions_pods[key] def _generate_image(self, path, image_name, key_application, ito): print(path, image_name, key_application, ito) try: self.plugin['docker'].request_generate_image(path=path, name=image_name, key=key_application, ito=ito, ifrom=self.boundjid) except IqError as e: raise Exception(e.iq['error']['text']) except IqTimeout as t: raise Exception("timeout generate image") def _load_image(self, path, ito): try: self.plugin['docker'].request_load_image(path=path, ito=ito, ifrom=self.boundjid) except IqError as e: raise Exception(e.iq['error']['text']) except IqTimeout as t: raise Exception("timeout load image") def _requet_deploy_to_minion(self, ito, application_name, key_application, container_name, ifrom): try: self.plugin['docker'].request_minion_deploy( application_name=application_name, container_name=container_name, key_application=key_application, ito=ito, ifrom=self.boundjid, timeout=120) # self.plugin['docker'].request_first_deploy(ito=ito, # ifrom=self.boundjid, # name=application_name, # key=key_application, # user=container_name) print(ito) print(self.containers_per_minion) if not bool(self.containers_per_minion): self.containers_per_minion[ito] = [container_name] else: self.containers_per_minion[ito].append(container_name) self._handler_send_message( ifrom, 'success deploy container ' + container_name) except IqError as e: self._handler_send_message(ifrom, e.iq['error']['text']) except IqTimeout as t: self._handler_send_message(ifrom, 'timeout container ' + container_name) def _pods_containers(self, pods): minions_pods = {} list_pods = [] minions_count = {} idx = 0 check_iquals = True for minion in self.jid_minions: try: response = self.plugin['docker'].request_total_pods( ito=minion, ifrom=self.boundjid) if len(response['docker']['total'].strip()) > 0: total = int(response['docker']['total']) list_pods.append(total) else: list_pods.append(0) if not minions_count: minions_count[idx] = {'total': total, 'minion': minion} else: for count in minions_count.keys(): if minions_count[count][ 'total'] == total or minions_count[count][ 'total'] < total: minions_count[idx] = { 'total': total, 'minion': minion } else: minions_count[idx] = minions_count[count] minions_count[count] = { 'total': total, 'minion': minion } idx += 1 except IqError as e: raise Exception(e.iq['error']['text']) except IqTimeout as t: raise Exception(t) if len(list_pods) > 1: check_iquals = all(list_pods[:1] == elem for elem in list_pods) total_minions = len(self.jid_minions) if pods == 1: if check_iquals: minions_pods[self.jid_minions[0]] = pods else: minions_pods[minions_count[0]['minion']] = pods else: if check_iquals: for minion in self.jid_minions: minions_pods[minion] = pods / total_minions if pods % total_minions != 0: minions_pods[self.jid_minions[0]] += pods % total_minions else: for count in range(pods): if count > 0 and minions_count[0]['total'] > minions_count[ 1]['total']: for idx in minions_count.keys(): x = idx + 1 if x < len(minions_count.keys()) and minions_count[ idx]['total'] > minions_count[x]['total']: total = minions_count[x]['total'] minion = minions_count[x]['minion'] minions_count[x] = { 'minion': minions_count[idx]['minion'], 'total': minions_count[idx]['total'] } minions_count[idx] = { 'minion': minion, 'total': total } if minions_count[0]['minion'] not in minions_pods: minions_pods[minions_count[0]['minion']] = 1 else: minions_pods[minions_count[0]['minion']] += 1 minions_count[0]['total'] += 1 return minions_pods def _get_start_infos(self, values): options = {'total_containers': 1} application_name = None customer = None for value in values: if "--cpus" in value: options['cpus'] = value.replace("--cpus=", "").strip() if "--memory" in value: options['memory'] = value.replace("--memory=", "").strip() if "--args" in value: dic = {} args = value.strip().replace("--args[", "").replace("]", "").split(',') for arg in args: x = arg.replace('"', '').split(':') dic[x[0]] = x[1] options['args'] = dic if "--name" in value: application_name = value.replace("--name=", "").strip() if "--customer" in value: customer = value.replace("--customer=", "").strip() if "--total" in value: total_containers = int(value.replace("--total=", "").strip()) options['total_containers'] = total_containers if "--ports" in value: options['ports'] = value.strip().replace("--ports=", "") if "--dns" in value: options['dns'] = value.strip().replace("--dns=", "") return application_name, customer, options def create_room(self, msg): args = msg['body'].split() self._create_room(args[1]) def _create_room(self, name): self.room = name + '@conference.localhost' try: room_exist = self.plugin['xep_0030'].get_info(jid=self.room) except IqError as e: if e.condition == 'item-not-found': self.plugin['xep_0045'].joinMUC(self.room, self.nick, wait=True) form = self.plugin['xep_0045'].getRoomConfig(self.room) form.set_values({ 'muc#roomconfig_persistentroom': 1, 'muc#roomconfig_passwordprotectedroom': 0, 'muc#roomconfig_publicroom': 1, 'muc#roomconfig_roomdesc': 'TESTE!', 'muc#roomconfig_roomname': self.room }) try: self.plugin['xep_0045'].configureRoom(self.room, form=form) logging.info("Chat room %s success created!" % self.room) except IqError as e: logging.error("Could not create chat room: %s" % e.iq['error']['text']) else: logging.error("Could not create chat room: %s" % e.iq['error']['text']) else: self.plugin['xep_0045'].joinMUC(self.room, self.nick) logging.info("Chat room %s success created!" % self.room) self.add_event_handler("muc::%s::got_online" % self.room, self.muc_online) self.add_event_handler("muc::%s::got_offline" % self.room, self.muc_offline) def muc_online(self, presence): if len(presence['muc']['nick'].strip()) > 0: if presence['muc']['nick'] != self.nick: if presence['from'].bare.split('@')[0] == self.chat_minions: self.minions.append(presence['muc']['nick']) self.jid_minions.append(presence['muc']['jid']) try: containers = self.plugin[ 'docker'].request_containers_minion( ito=presence['muc']['jid'], ifrom=self.boundjid) if containers['docker']['message']: self.containers_per_minion[ presence['muc']['jid']] = containers['docker'][ 'message'].split(',') except IqError as e: logging.error("Could not get names of containers: %s" % e.iq['error']['text']) except IqTimeout as t: logging.error( "Timeout to get names of containers: %s" % t) self.send_message( mto=presence['from'].bare, mbody="Ola Trouxa, %s %s" % (presence['muc']['role'], presence['muc']['nick']), mtype='groupchat') print(self.containers_per_minion) def muc_offline(self, presence): if presence['muc']['nick'] != self.nick: if presence['muc']['nick'] in self.minions: minion = presence['muc']['jid'] logging.info('Minion Down %s' % (minion)) self.minions.remove(presence['muc']['nick']) self.jid_minions.remove(presence['muc']['jid']) #del[presence['muc']['jid']] print(self.containers_per_minion) print(self.containers_per_minion[presence['muc']['jid']]) thread_minion_die = threading.Thread( target=self._deploy_minion_die, args=[self.containers_per_minion[presence['muc']['jid']]]) thread_minion_die.daemon = True thread_minion_die.start() else: print("Application Down") print(presence['muc']['nick'])
sys.exit('host of xmpp is not informed') if 'jid' not in envs: sys.exit('jid is not informed') if 'etcd_url' in envs: etcd_envs['etcd_url'] = os.environ['etcd_url'] if 'etcd_port' in envs: etcd_envs['etcd_port'] = os.environ['etcd_port'] etcd_connection = Etcd(etcd_envs['etcd_url'], etcd_envs['etcd_port']) try: values_etcd = ast.literal_eval( etcd_connection.read(os.environ['etcd_endpoint'])) except Exception as e: sys.exit(unicode(e)) password = crypt.decrypt_data(values_etcd['password'], 'id_rsa') endpoint = os.environ['etcd_endpoint'].split('/') xmpp = ClientDocker(os.environ['jid'], password, endpoint[len(endpoint) - 1]) xmpp.register_plugin('xep_0030') #Service Discovery xmpp.register_plugin('xep_0004') xmpp.register_plugin('xep_0059') xmpp.register_plugin('xep_0060') xmpp.register_plugin('xep_0199') xmpp.register_plugin('xep_0066') xmpp.register_plugin('xep_0045')