From 5cb597305f07e03f348e2f257debd6093d8c15a7 Mon Sep 17 00:00:00 2001 From: Ewgenij Katchko Date: Thu, 25 Jul 2019 19:12:20 +0200 Subject: [PATCH 1/7] refactor(playbook): code for generic playbook runs --- .../VirtualMachineHandler.py | 47 ++-- .../VirtualMachineService-remote | 4 +- .../VirtualMachineService.py | 222 ++++++++++-------- .../ancon/BiocondaPlaybook.py | 77 ------ VirtualMachineService/ancon/Playbook.py | 120 ++++++++++ .../ancon/playbooks/bioconda.yml | 63 ++--- .../{variables.yml => bioconda_vars_file.yml} | 5 +- .../ancon/playbooks/change_key.yml | 6 + .../ancon/playbooks/change_key_vars_file.yml | 2 + .../ancon/playbooks/generic_playbook.yml | 6 + VirtualMachineService/ttypes.py | 76 ++++++ portal_client.thrift | 12 +- 12 files changed, 391 insertions(+), 249 deletions(-) delete mode 100644 VirtualMachineService/ancon/BiocondaPlaybook.py create mode 100644 VirtualMachineService/ancon/Playbook.py rename VirtualMachineService/ancon/playbooks/{variables.yml => bioconda_vars_file.yml} (89%) create mode 100644 VirtualMachineService/ancon/playbooks/change_key.yml create mode 100644 VirtualMachineService/ancon/playbooks/change_key_vars_file.yml create mode 100644 VirtualMachineService/ancon/playbooks/generic_playbook.yml diff --git a/VirtualMachineService/VirtualMachineHandler.py b/VirtualMachineService/VirtualMachineHandler.py index 67c61364..bc277585 100644 --- a/VirtualMachineService/VirtualMachineHandler.py +++ b/VirtualMachineService/VirtualMachineHandler.py @@ -15,7 +15,7 @@ from ttypes import ressourceException from ttypes import Flavor, Image, VM, PlaybookResult from constants import VERSION - from ancon.BiocondaPlaybook import BiocondaPlaybook + from ancon.Playbook import Playbook except Exception: from .VirtualMachineService import Iface @@ -28,7 +28,7 @@ from .ttypes import ressourceException from .ttypes import Flavor, Image, VM, PlaybookResult from .constants import VERSION - from .ancon.BiocondaPlaybook import BiocondaPlaybook + from .ancon.Playbook import Playbook from openstack import connection from deprecated import deprecated @@ -56,9 +56,9 @@ class VirtualMachineHandler(Iface): global osi_key_dict BUILD = "BUILD" ACTIVE = "ACTIVE" - PREPARE_BIOCONDA_BUILD = "PREPARE_BIOCONDA_BUILD" - BUILD_BIOCONDA = "BUILD_BIOCONDA" - BIOCONDA_FAILED = "BIOCONDA_FAILED" + PREPARE_PLAYBOOK_BUILD = "PREPARE_PLAYBOOK_BUILD" + BUILD_PLAYBOOK = "BUILD_PLAYBOOK" + PLAYBOOK_FAILED = "PLAYBOOK_FAILED" def create_connection(self): """ @@ -633,35 +633,34 @@ def start_server_with_custom_key(self, flavor, image, servername, elixir_id, dis openstack_id = server.to_dict()["id"] global osi_key_dict osi_key_dict[openstack_id] = dict(key=private_key, name=servername, - status=self.PREPARE_BIOCONDA_BUILD) + status=self.PREPARE_PLAYBOOK_BUILD) return {"openstackid": openstack_id, "volumeId": volume_id, 'private_key': private_key} except Exception as e: self.delete_keypair(key_name=servername) self.logger.exception("Start Server {1} error:{0}".format(e, servername)) return {} - def create_and_deploy_playbook(self, private_key, play_source, openstack_id): - self.logger.info(msg="Starting Bioconda Playbook for (openstack_id): {0} with packages {1}" - .format(openstack_id, play_source)) + def create_and_deploy_playbook(self, public_key, playbooks_information, openstack_id): + self.logger.info(msg="Starting Playbook for (openstack_id): {0}" + .format(openstack_id)) # get ip and port for inventory fields = self.get_ip_ports(openstack_id=openstack_id) global osi_key_dict global active_playbooks key_name = osi_key_dict[openstack_id]['name'] - playbook = BiocondaPlaybook(fields["IP"], fields["PORT"], play_source, - osi_key_dict[openstack_id]["key"], private_key) + playbook = Playbook(fields["IP"], + fields["PORT"], + playbooks_information, + osi_key_dict[openstack_id]["key"], + public_key, + self.logger) active_playbooks[openstack_id] = playbook - osi_key_dict[openstack_id]["status"] = self.BUILD_BIOCONDA + osi_key_dict[openstack_id]["status"] = self.BUILD_PLAYBOOK status, stdout, stderr = playbook.run_it() self.delete_keypair(key_name=key_name) if status != 0: - # self.logger.exception(msg="Bioconda playbook for {0} encountered an error with status code {1}. The messages are:" - # "stdout: {2}" - # "stderr: {3}".format(openstack_id, status, stdout, stderr)) - osi_key_dict[openstack_id]["status"] = self.BIOCONDA_FAILED + osi_key_dict[openstack_id]["status"] = self.PLAYBOOK_FAILED else: - # self.logger.info("Finished Bioconda Playbook for (openstack_id): {0} with status code: {1}" - # .format(openstack_id, status)) osi_key_dict[openstack_id]["status"] = self.ACTIVE return status @@ -783,14 +782,14 @@ def check_server_status(self, openstack_id, diskspace, volume_id): return server if openstack_id in osi_key_dict: - if osi_key_dict[openstack_id]["status"] == self.PREPARE_BIOCONDA_BUILD: - server.status = self.PREPARE_BIOCONDA_BUILD + if osi_key_dict[openstack_id]["status"] == self.PREPARE_PLAYBOOK_BUILD: + server.status = self.PREPARE_PLAYBOOK_BUILD return server - elif osi_key_dict[openstack_id]["status"] == self.BUILD_BIOCONDA: - server.status = self.BUILD_BIOCONDA + elif osi_key_dict[openstack_id]["status"] == self.BUILD_PLAYBOOK: + server.status = self.BUILD_PLAYBOOK return server - elif osi_key_dict[openstack_id]["status"] == self.BIOCONDA_FAILED: - server.status = self.BIOCONDA_FAILED + elif osi_key_dict[openstack_id]["status"] == self.PLAYBOOK_FAILED: + server.status = self.PLAYBOOK_FAILED return server else: return server diff --git a/VirtualMachineService/VirtualMachineService-remote b/VirtualMachineService/VirtualMachineService-remote index b61dc4e2..5b23e73e 100755 --- a/VirtualMachineService/VirtualMachineService-remote +++ b/VirtualMachineService/VirtualMachineService-remote @@ -38,7 +38,7 @@ if len(sys.argv) <= 1 or sys.argv[1] == '--help': print(' bool create_connection(string username, string password, string auth_url, string user_domain_name, string project_domain_name)') print(' start_server(string flavor, string image, string public_key, string servername, string elixir_id, string diskspace, string volumename)') print(' start_server_with_custom_key(string flavor, string image, string servername, string elixir_id, string diskspace, string volumename)') - print(' int create_and_deploy_playbook(string private_key, string play_source, string openstack_id)') + print(' int create_and_deploy_playbook(string public_key, playbooks_information, string openstack_id)') print(' PlaybookResult get_playbook_logs(string openstack_id)') print(' bool add_security_group_to_server(bool http, bool https, bool udp, string server_id)') print(' VM get_server(string openstack_id)') @@ -221,7 +221,7 @@ elif cmd == 'create_and_deploy_playbook': if len(args) != 3: print('create_and_deploy_playbook requires 3 args') sys.exit(1) - pp.pprint(client.create_and_deploy_playbook(args[0], args[1], args[2],)) + pp.pprint(client.create_and_deploy_playbook(args[0], eval(args[1]), args[2],)) elif cmd == 'get_playbook_logs': if len(args) != 1: diff --git a/VirtualMachineService/VirtualMachineService.py b/VirtualMachineService/VirtualMachineService.py index 0a6ac6d6..023f261e 100644 --- a/VirtualMachineService/VirtualMachineService.py +++ b/VirtualMachineService/VirtualMachineService.py @@ -179,13 +179,13 @@ def start_server_with_custom_key(self, flavor, image, servername, elixir_id, dis """ pass - def create_and_deploy_playbook(self, private_key, play_source, openstack_id): + def create_and_deploy_playbook(self, public_key, playbooks_information, openstack_id): """ Create and deploy an anaconda ansible playbook Parameters: - - private_key - - play_source + - public_key + - playbooks_information - openstack_id """ @@ -928,24 +928,24 @@ def recv_start_server_with_custom_key(self): raise result.o raise TApplicationException(TApplicationException.MISSING_RESULT, "start_server_with_custom_key failed: unknown result") - def create_and_deploy_playbook(self, private_key, play_source, openstack_id): + def create_and_deploy_playbook(self, public_key, playbooks_information, openstack_id): """ Create and deploy an anaconda ansible playbook Parameters: - - private_key - - play_source + - public_key + - playbooks_information - openstack_id """ - self.send_create_and_deploy_playbook(private_key, play_source, openstack_id) + self.send_create_and_deploy_playbook(public_key, playbooks_information, openstack_id) return self.recv_create_and_deploy_playbook() - def send_create_and_deploy_playbook(self, private_key, play_source, openstack_id): + def send_create_and_deploy_playbook(self, public_key, playbooks_information, openstack_id): self._oprot.writeMessageBegin('create_and_deploy_playbook', TMessageType.CALL, self._seqid) args = create_and_deploy_playbook_args() - args.private_key = private_key - args.play_source = play_source + args.public_key = public_key + args.playbooks_information = playbooks_information args.openstack_id = openstack_id args.write(self._oprot) self._oprot.writeMessageEnd() @@ -1983,7 +1983,7 @@ def process_create_and_deploy_playbook(self, seqid, iprot, oprot): iprot.readMessageEnd() result = create_and_deploy_playbook_result() try: - result.success = self._handler.create_and_deploy_playbook(args.private_key, args.play_source, args.openstack_id) + result.success = self._handler.create_and_deploy_playbook(args.public_key, args.playbooks_information, args.openstack_id) msg_type = TMessageType.REPLY except TTransport.TTransportException: raise @@ -2837,11 +2837,11 @@ def read(self, iprot): if fid == 0: if ftype == TType.MAP: self.success = {} - (_ktype24, _vtype25, _size23) = iprot.readMapBegin() - for _i27 in range(_size23): - _key28 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() - _val29 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() - self.success[_key28] = _val29 + (_ktype33, _vtype34, _size32) = iprot.readMapBegin() + for _i36 in range(_size32): + _key37 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + _val38 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + self.success[_key37] = _val38 iprot.readMapEnd() else: iprot.skip(ftype) @@ -2858,9 +2858,9 @@ def write(self, oprot): if self.success is not None: oprot.writeFieldBegin('success', TType.MAP, 0) oprot.writeMapBegin(TType.STRING, TType.STRING, len(self.success)) - for kiter30, viter31 in self.success.items(): - oprot.writeString(kiter30.encode('utf-8') if sys.version_info[0] == 2 else kiter30) - oprot.writeString(viter31.encode('utf-8') if sys.version_info[0] == 2 else viter31) + for kiter39, viter40 in self.success.items(): + oprot.writeString(kiter39.encode('utf-8') if sys.version_info[0] == 2 else kiter39) + oprot.writeString(viter40.encode('utf-8') if sys.version_info[0] == 2 else viter40) oprot.writeMapEnd() oprot.writeFieldEnd() oprot.writeFieldStop() @@ -2951,11 +2951,11 @@ def read(self, iprot): if fid == 0: if ftype == TType.LIST: self.success = [] - (_etype35, _size32) = iprot.readListBegin() - for _i36 in range(_size32): - _elem37 = Flavor() - _elem37.read(iprot) - self.success.append(_elem37) + (_etype44, _size41) = iprot.readListBegin() + for _i45 in range(_size41): + _elem46 = Flavor() + _elem46.read(iprot) + self.success.append(_elem46) iprot.readListEnd() else: iprot.skip(ftype) @@ -2972,8 +2972,8 @@ def write(self, oprot): if self.success is not None: oprot.writeFieldBegin('success', TType.LIST, 0) oprot.writeListBegin(TType.STRUCT, len(self.success)) - for iter38 in self.success: - iter38.write(oprot) + for iter47 in self.success: + iter47.write(oprot) oprot.writeListEnd() oprot.writeFieldEnd() oprot.writeFieldStop() @@ -3064,11 +3064,11 @@ def read(self, iprot): if fid == 0: if ftype == TType.LIST: self.success = [] - (_etype42, _size39) = iprot.readListBegin() - for _i43 in range(_size39): - _elem44 = Image() - _elem44.read(iprot) - self.success.append(_elem44) + (_etype51, _size48) = iprot.readListBegin() + for _i52 in range(_size48): + _elem53 = Image() + _elem53.read(iprot) + self.success.append(_elem53) iprot.readListEnd() else: iprot.skip(ftype) @@ -3085,8 +3085,8 @@ def write(self, oprot): if self.success is not None: oprot.writeFieldBegin('success', TType.LIST, 0) oprot.writeListBegin(TType.STRUCT, len(self.success)) - for iter45 in self.success: - iter45.write(oprot) + for iter54 in self.success: + iter54.write(oprot) oprot.writeListEnd() oprot.writeFieldEnd() oprot.writeFieldStop() @@ -3401,11 +3401,11 @@ def read(self, iprot): elif fid == 2: if ftype == TType.MAP: self.metadata = {} - (_ktype47, _vtype48, _size46) = iprot.readMapBegin() - for _i50 in range(_size46): - _key51 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() - _val52 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() - self.metadata[_key51] = _val52 + (_ktype56, _vtype57, _size55) = iprot.readMapBegin() + for _i59 in range(_size55): + _key60 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + _val61 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + self.metadata[_key60] = _val61 iprot.readMapEnd() else: iprot.skip(ftype) @@ -3426,9 +3426,9 @@ def write(self, oprot): if self.metadata is not None: oprot.writeFieldBegin('metadata', TType.MAP, 2) oprot.writeMapBegin(TType.STRING, TType.STRING, len(self.metadata)) - for kiter53, viter54 in self.metadata.items(): - oprot.writeString(kiter53.encode('utf-8') if sys.version_info[0] == 2 else kiter53) - oprot.writeString(viter54.encode('utf-8') if sys.version_info[0] == 2 else viter54) + for kiter62, viter63 in self.metadata.items(): + oprot.writeString(kiter62.encode('utf-8') if sys.version_info[0] == 2 else kiter62) + oprot.writeString(viter63.encode('utf-8') if sys.version_info[0] == 2 else viter63) oprot.writeMapEnd() oprot.writeFieldEnd() oprot.writeFieldStop() @@ -3480,11 +3480,11 @@ def read(self, iprot): if fid == 0: if ftype == TType.MAP: self.success = {} - (_ktype56, _vtype57, _size55) = iprot.readMapBegin() - for _i59 in range(_size55): - _key60 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() - _val61 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() - self.success[_key60] = _val61 + (_ktype65, _vtype66, _size64) = iprot.readMapBegin() + for _i68 in range(_size64): + _key69 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + _val70 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + self.success[_key69] = _val70 iprot.readMapEnd() else: iprot.skip(ftype) @@ -3507,9 +3507,9 @@ def write(self, oprot): if self.success is not None: oprot.writeFieldBegin('success', TType.MAP, 0) oprot.writeMapBegin(TType.STRING, TType.STRING, len(self.success)) - for kiter62, viter63 in self.success.items(): - oprot.writeString(kiter62.encode('utf-8') if sys.version_info[0] == 2 else kiter62) - oprot.writeString(viter63.encode('utf-8') if sys.version_info[0] == 2 else viter63) + for kiter71, viter72 in self.success.items(): + oprot.writeString(kiter71.encode('utf-8') if sys.version_info[0] == 2 else kiter71) + oprot.writeString(viter72.encode('utf-8') if sys.version_info[0] == 2 else viter72) oprot.writeMapEnd() oprot.writeFieldEnd() if self.e is not None: @@ -3569,10 +3569,10 @@ def read(self, iprot): elif fid == 2: if ftype == TType.SET: self.keys = set() - (_etype67, _size64) = iprot.readSetBegin() - for _i68 in range(_size64): - _elem69 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() - self.keys.add(_elem69) + (_etype76, _size73) = iprot.readSetBegin() + for _i77 in range(_size73): + _elem78 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + self.keys.add(_elem78) iprot.readSetEnd() else: iprot.skip(ftype) @@ -3593,8 +3593,8 @@ def write(self, oprot): if self.keys is not None: oprot.writeFieldBegin('keys', TType.SET, 2) oprot.writeSetBegin(TType.STRING, len(self.keys)) - for iter70 in self.keys: - oprot.writeString(iter70.encode('utf-8') if sys.version_info[0] == 2 else iter70) + for iter79 in self.keys: + oprot.writeString(iter79.encode('utf-8') if sys.version_info[0] == 2 else iter79) oprot.writeSetEnd() oprot.writeFieldEnd() oprot.writeFieldStop() @@ -3646,10 +3646,10 @@ def read(self, iprot): if fid == 0: if ftype == TType.SET: self.success = set() - (_etype74, _size71) = iprot.readSetBegin() - for _i75 in range(_size71): - _elem76 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() - self.success.add(_elem76) + (_etype83, _size80) = iprot.readSetBegin() + for _i84 in range(_size80): + _elem85 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + self.success.add(_elem85) iprot.readSetEnd() else: iprot.skip(ftype) @@ -3672,8 +3672,8 @@ def write(self, oprot): if self.success is not None: oprot.writeFieldBegin('success', TType.SET, 0) oprot.writeSetBegin(TType.STRING, len(self.success)) - for iter77 in self.success: - oprot.writeString(iter77.encode('utf-8') if sys.version_info[0] == 2 else iter77) + for iter86 in self.success: + oprot.writeString(iter86.encode('utf-8') if sys.version_info[0] == 2 else iter86) oprot.writeSetEnd() oprot.writeFieldEnd() if self.e is not None: @@ -4223,11 +4223,11 @@ def read(self, iprot): if fid == 0: if ftype == TType.MAP: self.success = {} - (_ktype79, _vtype80, _size78) = iprot.readMapBegin() - for _i82 in range(_size78): - _key83 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() - _val84 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() - self.success[_key83] = _val84 + (_ktype88, _vtype89, _size87) = iprot.readMapBegin() + for _i91 in range(_size87): + _key92 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + _val93 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + self.success[_key92] = _val93 iprot.readMapEnd() else: iprot.skip(ftype) @@ -4286,9 +4286,9 @@ def write(self, oprot): if self.success is not None: oprot.writeFieldBegin('success', TType.MAP, 0) oprot.writeMapBegin(TType.STRING, TType.STRING, len(self.success)) - for kiter85, viter86 in self.success.items(): - oprot.writeString(kiter85.encode('utf-8') if sys.version_info[0] == 2 else kiter85) - oprot.writeString(viter86.encode('utf-8') if sys.version_info[0] == 2 else viter86) + for kiter94, viter95 in self.success.items(): + oprot.writeString(kiter94.encode('utf-8') if sys.version_info[0] == 2 else kiter94) + oprot.writeString(viter95.encode('utf-8') if sys.version_info[0] == 2 else viter95) oprot.writeMapEnd() oprot.writeFieldEnd() if self.e is not None: @@ -4507,11 +4507,11 @@ def read(self, iprot): if fid == 0: if ftype == TType.MAP: self.success = {} - (_ktype88, _vtype89, _size87) = iprot.readMapBegin() - for _i91 in range(_size87): - _key92 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() - _val93 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() - self.success[_key92] = _val93 + (_ktype97, _vtype98, _size96) = iprot.readMapBegin() + for _i100 in range(_size96): + _key101 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + _val102 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + self.success[_key101] = _val102 iprot.readMapEnd() else: iprot.skip(ftype) @@ -4570,9 +4570,9 @@ def write(self, oprot): if self.success is not None: oprot.writeFieldBegin('success', TType.MAP, 0) oprot.writeMapBegin(TType.STRING, TType.STRING, len(self.success)) - for kiter94, viter95 in self.success.items(): - oprot.writeString(kiter94.encode('utf-8') if sys.version_info[0] == 2 else kiter94) - oprot.writeString(viter95.encode('utf-8') if sys.version_info[0] == 2 else viter95) + for kiter103, viter104 in self.success.items(): + oprot.writeString(kiter103.encode('utf-8') if sys.version_info[0] == 2 else kiter103) + oprot.writeString(viter104.encode('utf-8') if sys.version_info[0] == 2 else viter104) oprot.writeMapEnd() oprot.writeFieldEnd() if self.e is not None: @@ -4635,16 +4635,16 @@ def __ne__(self, other): class create_and_deploy_playbook_args(object): """ Attributes: - - private_key - - play_source + - public_key + - playbooks_information - openstack_id """ - def __init__(self, private_key=None, play_source=None, openstack_id=None,): - self.private_key = private_key - self.play_source = play_source + def __init__(self, public_key=None, playbooks_information=None, openstack_id=None,): + self.public_key = public_key + self.playbooks_information = playbooks_information self.openstack_id = openstack_id def read(self, iprot): @@ -4658,12 +4658,24 @@ def read(self, iprot): break if fid == 1: if ftype == TType.STRING: - self.private_key = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + self.public_key = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() else: iprot.skip(ftype) elif fid == 2: - if ftype == TType.STRING: - self.play_source = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + if ftype == TType.MAP: + self.playbooks_information = {} + (_ktype106, _vtype107, _size105) = iprot.readMapBegin() + for _i109 in range(_size105): + _key110 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + _val111 = {} + (_ktype113, _vtype114, _size112) = iprot.readMapBegin() + for _i116 in range(_size112): + _key117 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + _val118 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + _val111[_key117] = _val118 + iprot.readMapEnd() + self.playbooks_information[_key110] = _val111 + iprot.readMapEnd() else: iprot.skip(ftype) elif fid == 3: @@ -4681,13 +4693,21 @@ def write(self, oprot): oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec])) return oprot.writeStructBegin('create_and_deploy_playbook_args') - if self.private_key is not None: - oprot.writeFieldBegin('private_key', TType.STRING, 1) - oprot.writeString(self.private_key.encode('utf-8') if sys.version_info[0] == 2 else self.private_key) + if self.public_key is not None: + oprot.writeFieldBegin('public_key', TType.STRING, 1) + oprot.writeString(self.public_key.encode('utf-8') if sys.version_info[0] == 2 else self.public_key) oprot.writeFieldEnd() - if self.play_source is not None: - oprot.writeFieldBegin('play_source', TType.STRING, 2) - oprot.writeString(self.play_source.encode('utf-8') if sys.version_info[0] == 2 else self.play_source) + if self.playbooks_information is not None: + oprot.writeFieldBegin('playbooks_information', TType.MAP, 2) + oprot.writeMapBegin(TType.STRING, TType.MAP, len(self.playbooks_information)) + for kiter119, viter120 in self.playbooks_information.items(): + oprot.writeString(kiter119.encode('utf-8') if sys.version_info[0] == 2 else kiter119) + oprot.writeMapBegin(TType.STRING, TType.STRING, len(viter120)) + for kiter121, viter122 in viter120.items(): + oprot.writeString(kiter121.encode('utf-8') if sys.version_info[0] == 2 else kiter121) + oprot.writeString(viter122.encode('utf-8') if sys.version_info[0] == 2 else viter122) + oprot.writeMapEnd() + oprot.writeMapEnd() oprot.writeFieldEnd() if self.openstack_id is not None: oprot.writeFieldBegin('openstack_id', TType.STRING, 3) @@ -4712,8 +4732,8 @@ def __ne__(self, other): all_structs.append(create_and_deploy_playbook_args) create_and_deploy_playbook_args.thrift_spec = ( None, # 0 - (1, TType.STRING, 'private_key', 'UTF8', None, ), # 1 - (2, TType.STRING, 'play_source', 'UTF8', None, ), # 2 + (1, TType.STRING, 'public_key', 'UTF8', None, ), # 1 + (2, TType.MAP, 'playbooks_information', (TType.STRING, 'UTF8', TType.MAP, (TType.STRING, 'UTF8', TType.STRING, 'UTF8', False), False), None, ), # 2 (3, TType.STRING, 'openstack_id', 'UTF8', None, ), # 3 ) @@ -5611,11 +5631,11 @@ def read(self, iprot): if fid == 0: if ftype == TType.MAP: self.success = {} - (_ktype97, _vtype98, _size96) = iprot.readMapBegin() - for _i100 in range(_size96): - _key101 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() - _val102 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() - self.success[_key101] = _val102 + (_ktype124, _vtype125, _size123) = iprot.readMapBegin() + for _i127 in range(_size123): + _key128 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + _val129 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + self.success[_key128] = _val129 iprot.readMapEnd() else: iprot.skip(ftype) @@ -5632,9 +5652,9 @@ def write(self, oprot): if self.success is not None: oprot.writeFieldBegin('success', TType.MAP, 0) oprot.writeMapBegin(TType.STRING, TType.STRING, len(self.success)) - for kiter103, viter104 in self.success.items(): - oprot.writeString(kiter103.encode('utf-8') if sys.version_info[0] == 2 else kiter103) - oprot.writeString(viter104.encode('utf-8') if sys.version_info[0] == 2 else viter104) + for kiter130, viter131 in self.success.items(): + oprot.writeString(kiter130.encode('utf-8') if sys.version_info[0] == 2 else kiter130) + oprot.writeString(viter131.encode('utf-8') if sys.version_info[0] == 2 else viter131) oprot.writeMapEnd() oprot.writeFieldEnd() oprot.writeFieldStop() diff --git a/VirtualMachineService/ancon/BiocondaPlaybook.py b/VirtualMachineService/ancon/BiocondaPlaybook.py deleted file mode 100644 index 160c46a5..00000000 --- a/VirtualMachineService/ancon/BiocondaPlaybook.py +++ /dev/null @@ -1,77 +0,0 @@ -import logging -import shlex -import shutil -import sys -from tempfile import NamedTemporaryFile, TemporaryDirectory -import ruamel.yaml -import subprocess - - -class BiocondaPlaybook(object): - - def __init__(self, ip, port, play_source, osi_private_key, public_key): - self.status = -1 - self.stdout = '' - self.stderr = '' - # directories and files - self.ancon_dir = "/code/VirtualMachineService/ancon" - self.playbooks_dir = self.ancon_dir + "/playbooks" - self.directory = TemporaryDirectory(dir=self.ancon_dir) - #self.log_file = NamedTemporaryFile(mode='w+', delete=False, dir=self.directory.name) - shutil.copy(self.playbooks_dir+"/bioconda.yml", self.directory.name) - shutil.copy(self.playbooks_dir+"/variables.yml", self.directory.name) - self.ip = ip - self.port = port - self.private_key = NamedTemporaryFile(mode="w+", dir=self.directory.name, delete=False) - self.private_key.write(osi_private_key) - self.private_key.close() - - # logging - #self.logger = logging.getLogger(__name__) - #self.logger.setLevel(logging.DEBUG) - # create file handler which logs even debug messages - #self.fh = logging.FileHandler(self.log_file.name) - #self.fh.setLevel(logging.DEBUG) - # create formatter and add it to the handlers - #self.formatter = logging.Formatter( - # "%(asctime)s - %(name)s - %(levelname)s - %(message)s" - #) - #self.fh.setFormatter(self.formatter) - # add the handlers to the logger - #self.logger.addHandler(self.fh) - - # create inventory and add the to-be-installed tools to the variables.yml - self.inventory = NamedTemporaryFile(mode="w+", dir=self.directory.name, delete=False) - inventory_string = "[vm]\n" + self.ip + ":" + self.port + " ansible_user=ubuntu " \ - "ansible_ssh_private_key_file=" + self.private_key.name - self.inventory.write(inventory_string) - self.inventory.close() - - # load variables.yml and change some of its content - yaml_exec = ruamel.yaml.YAML() - with open(self.directory.name + "/variables.yml", mode='r') as variables: - data = yaml_exec.load(variables) - data["tools"]["string_line"] = play_source.strip('\"') - data["tools"]["public_key"] = public_key.strip('\"') - data["tools"]["timeout_length"] = str(len(play_source.split()) * 5) + "m" - with open(self.directory.name + "/variables.yml", mode='w') as variables: - yaml_exec.dump(data, variables) - - def run_it(self): - command_string = "/usr/local/bin/ansible-playbook -v -i {0} {1}/bioconda.yml"\ - .format(self.inventory.name, self.directory.name) - command_string = shlex.split(command_string) - process = subprocess.run(command_string, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) - # self.logger.log(level=20, msg=process.stdout) - self.stdout = process.stdout - if len(process.stderr) > 0: - self.stderr = process.stderr - # self.logger.log(level=50, msg=process.stderr) - self.status = process.returncode - return process.returncode, process.stdout, process.stderr - - def get_logs(self): - return self.status, self.stdout, self.stderr - - def cleanup(self): - self.directory.cleanup() diff --git a/VirtualMachineService/ancon/Playbook.py b/VirtualMachineService/ancon/Playbook.py new file mode 100644 index 00000000..f7fd1bbd --- /dev/null +++ b/VirtualMachineService/ancon/Playbook.py @@ -0,0 +1,120 @@ +import logging +import shlex +import shutil +from tempfile import NamedTemporaryFile, TemporaryDirectory +import ruamel.yaml +import subprocess + +BIOCONDA = "bioconda" + + +class Playbook(object): + + def __init__(self, ip, port, playbooks_information, osi_private_key, public_key, logger): + self.yaml_exec = ruamel.yaml.YAML() + self.vars_files = [] + self.tasks = [] + self.logger = logger + # init return logs + self.status = -1 + self.stdout = '' + self.stderr = '' + # init temporary directories and mandatory generic files + self.ancon_dir = "/code/VirtualMachineService/ancon" # path to this directory + self.playbooks_dir = self.ancon_dir + "/playbooks" # path to source playbooks + self.directory = TemporaryDirectory(dir=self.ancon_dir) + self.private_key = NamedTemporaryFile(mode="w+", dir=self.directory.name, delete=False) + self.private_key.write(osi_private_key) + self.private_key.close() + + # create the custom playbook and save its name + self.playbook_exec_name = "generic_playbook.yml" + self.copy_playbooks_and_init(playbooks_information, public_key) + + # create inventory + self.inventory = NamedTemporaryFile(mode="w+", dir=self.directory.name, delete=False) + inventory_string = "[vm]\n" + ip + ":" + port + " ansible_user=ubuntu " \ + "ansible_ssh_private_key_file=" + self.private_key.name + self.inventory.write(inventory_string) + self.inventory.close() + + def copy_playbooks_and_init(self, playbooks_information, public_key): + self.logger.info(type(playbooks_information)) + self.logger.info(playbooks_information) + for k, v in playbooks_information.items(): + self.copy_and_init(k, v) + + # init yml to change public keys as last task + shutil.copy(self.playbooks_dir + "/change_key.yml", self.directory.name) + shutil.copy(self.playbooks_dir + "/change_key_vars_file.yml", self.directory.name) + with open(self.directory.name + "/change_key_vars_file.yml", mode='r') as key_file: + data_ck = self.yaml_exec.load(key_file) + data_ck["change_key_vars"]["key"] = public_key.strip('\"') + with open(self.directory.name + "/change_key_vars_file.yml", mode='w') as key_file: + self.yaml_exec.dump(data_ck, key_file) + self.add_to_playbook_lists("change_key") + + # write all vars_files and tasks in generic_playbook + shutil.copy(self.playbooks_dir + "/" + self.playbook_exec_name, self.directory.name) + with open(self.directory.name + "/" + self.playbook_exec_name, mode='r') as generic_playbook: + data_gp = self.yaml_exec.load(generic_playbook) + data_gp[0]["vars_files"] = self.vars_files + data_gp[0]["tasks"] = self.tasks + with open(self.directory.name + "/" + self.playbook_exec_name, mode='w') as generic_playbook: + self.yaml_exec.dump(data_gp, generic_playbook) + + def copy_and_init(self, playbook_name, playbook_vars): + + def load_vars(): + if playbook_name == BIOCONDA: + for k, v in playbook_vars.items(): + if k == "string_line": + data[playbook_name + "_tools"][k] = v.strip('\"') + data[playbook_name + "_tools"]["timeout_length"] = str(len(v.split()) * 5) + "m" + + playbook_yml = "/{0}.yml".format(playbook_name) + playbook_var_yml = "/{0}_vars_file.yml".format(playbook_name) + try: + shutil.copy(self.playbooks_dir + playbook_yml, + self.directory.name) + try: + shutil.copy(self.playbooks_dir + playbook_var_yml, + self.directory.name) + with open(self.directory.name + playbook_var_yml, mode='r') as variables: + data = self.yaml_exec.load(variables) + load_vars() + with open(self.directory.name + playbook_var_yml, mode='w') as variables: + self.yaml_exec.dump(data, variables) + self.add_to_playbook_lists(playbook_name) + except shutil.Error as e: + self.logger.exception(e) + self.add_tasks_only(playbook_name) + except shutil.Error as e: + self.logger.exception(e) + + def add_to_playbook_lists(self, playbook_name): + self.vars_files.append(playbook_name + "_vars_file.yml") + self.tasks.append(dict(name="Running {0} tasks".format(playbook_name), import_tasks=playbook_name+".yml")) + + def add_tasks_only(self, playbook_name): + self.tasks.append(dict(name="Running {0} tasks".format(playbook_name), import_tasks=playbook_name+".yml")) + + def run_it(self): + command_string = "/usr/local/bin/ansible-playbook -v -i {0} {1}/{2}"\ + .format(self.inventory.name, self.directory.name, self.playbook_exec_name) + command_string = shlex.split(command_string) + process = subprocess.run(command_string, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + universal_newlines=True) + self.stdout = process.stdout + if len(process.stderr) > 0: + self.stderr = process.stderr + self.status = process.returncode + return process.returncode, process.stdout, process.stderr + + def get_logs(self): + return self.status, self.stdout, self.stderr + + def cleanup(self): + self.directory.cleanup() diff --git a/VirtualMachineService/ancon/playbooks/bioconda.yml b/VirtualMachineService/ancon/playbooks/bioconda.yml index 18980f86..1ce3734c 100644 --- a/VirtualMachineService/ancon/playbooks/bioconda.yml +++ b/VirtualMachineService/ancon/playbooks/bioconda.yml @@ -1,43 +1,28 @@ -- name: Install miniconda3 and the chosen packages - hosts: all - connection: paramiko_ssh - gather_facts: yes - vars_files: - - variables.yml - tasks: +- name: Download miniconda install script + get_url: + args: + url: "{{ bioconda_folders.conda_installer_url }}" + dest: "{{ bioconda_folders.install_script }}" + mode: 0755 + timeout: 180 - - name: Download miniconda install script - get_url: - args: - url: "{{ folders.conda_installer_url }}" - dest: "{{ folders.install_script }}" - mode: 0755 - timeout: 180 +- name: Install miniconda + shell: "timeout 3m {{ bioconda_folders.install_script }} -b" + args: + executable: /bin/bash + creates: "{{ bioconda_folders.conda_dir }}" - - name: Install miniconda - shell: "timeout 3m {{ folders.install_script }} -b" - args: - executable: /bin/bash - creates: "{{ folders.conda_dir }}" +- name: Add channels + shell: "timeout 2m bash -c 'source {{ bioconda_folders.conda_dir }}/bin/activate && conda config --add channels default && conda config --add channels bioconda && conda config --add channels conda-forge'" + args: + executable: /bin/bash - - name: Add channels - shell: "timeout 2m bash -c 'source {{ folders.conda_dir }}/bin/activate && conda config --add channels default && conda config --add channels bioconda && conda config --add channels conda-forge'" - args: - executable: /bin/bash +- name: Create environment + shell: "timeout 2m bash -c 'source {{ bioconda_folders.conda_dir }}/bin/activate && conda create --yes -n {{ bioconda_tools.env }}'" + args: + executable: /bin/bash - - name: Create environment - shell: "timeout 2m bash -c 'source {{ folders.conda_dir }}/bin/activate && conda create --yes -n {{ tools.env }}'" - args: - executable: /bin/bash - - - name: Install chosen packages - shell: "timeout {{ tools.timeout_length }} bash -c 'source {{ folders.conda_dir }}/bin/activate && conda activate {{ tools.env }} && conda install --yes {{ tools.string_line }}'" - args: - executable: /bin/bash - - - name: Set user public Key and remove created public Key - authorized_key: - user: ubuntu - key: '{{ tools.public_key }}' - state: present - exclusive: True +- name: Install chosen packages + shell: "timeout {{ bioconda_tools.timeout_length }} bash -c 'source {{ bioconda_folders.conda_dir }}/bin/activate && conda activate {{ bioconda_tools.env }} && conda install --yes {{ bioconda_tools.string_line }}'" + args: + executable: /bin/bash diff --git a/VirtualMachineService/ancon/playbooks/variables.yml b/VirtualMachineService/ancon/playbooks/bioconda_vars_file.yml similarity index 89% rename from VirtualMachineService/ancon/playbooks/variables.yml rename to VirtualMachineService/ancon/playbooks/bioconda_vars_file.yml index 08928163..12ec9ce4 100644 --- a/VirtualMachineService/ancon/playbooks/variables.yml +++ b/VirtualMachineService/ancon/playbooks/bioconda_vars_file.yml @@ -1,10 +1,9 @@ -tools: +bioconda_tools: string_line: "" env: "denbi" - public_key: "" timeout_length: "5m" -folders: +bioconda_folders: install_script: "/home/{{ ansible_user_id }}/install_miniconda3.sh" conda_dir: "/home/{{ ansible_user_id }}/miniconda3" conda_installer_url: "https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh" diff --git a/VirtualMachineService/ancon/playbooks/change_key.yml b/VirtualMachineService/ancon/playbooks/change_key.yml new file mode 100644 index 00000000..bafbd0a9 --- /dev/null +++ b/VirtualMachineService/ancon/playbooks/change_key.yml @@ -0,0 +1,6 @@ +- name: Set user public Key and remove created public Key + authorized_key: + user: ubuntu + key: "{{ change_key_vars.key }}" + state: present + exclusive: True diff --git a/VirtualMachineService/ancon/playbooks/change_key_vars_file.yml b/VirtualMachineService/ancon/playbooks/change_key_vars_file.yml new file mode 100644 index 00000000..68e0b3cd --- /dev/null +++ b/VirtualMachineService/ancon/playbooks/change_key_vars_file.yml @@ -0,0 +1,2 @@ +change_key_vars: + key: diff --git a/VirtualMachineService/ancon/playbooks/generic_playbook.yml b/VirtualMachineService/ancon/playbooks/generic_playbook.yml new file mode 100644 index 00000000..bea7831f --- /dev/null +++ b/VirtualMachineService/ancon/playbooks/generic_playbook.yml @@ -0,0 +1,6 @@ +- name: Setting up your virtual machine + hosts: all + connection: paramiko_ssh + gather_facts: yes + vars_files: + tasks: diff --git a/VirtualMachineService/ttypes.py b/VirtualMachineService/ttypes.py index 398bda72..e6046a17 100644 --- a/VirtualMachineService/ttypes.py +++ b/VirtualMachineService/ttypes.py @@ -634,6 +634,77 @@ def __ne__(self, other): return not (self == other) +class PlaybookVars(object): + """ + This struct contains a mapping of variable keys to their content. This struct should be mapped by a playbook name. + + Attributes: + - needed_variables: The mapping of variable key to variable content + + """ + + + def __init__(self, needed_variables=None,): + self.needed_variables = needed_variables + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, [self.__class__, self.thrift_spec]) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.MAP: + self.needed_variables = {} + (_ktype24, _vtype25, _size23) = iprot.readMapBegin() + for _i27 in range(_size23): + _key28 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + _val29 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + self.needed_variables[_key28] = _val29 + iprot.readMapEnd() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec])) + return + oprot.writeStructBegin('PlaybookVars') + if self.needed_variables is not None: + oprot.writeFieldBegin('needed_variables', TType.MAP, 1) + oprot.writeMapBegin(TType.STRING, TType.STRING, len(self.needed_variables)) + for kiter30, viter31 in self.needed_variables.items(): + oprot.writeString(kiter30.encode('utf-8') if sys.version_info[0] == 2 else kiter30) + oprot.writeString(viter31.encode('utf-8') if sys.version_info[0] == 2 else viter31) + oprot.writeMapEnd() + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + if self.needed_variables is None: + raise TProtocolException(message='Required field needed_variables is unset!') + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + class otherException(TException): """ Attributes: @@ -1162,6 +1233,11 @@ def __ne__(self, other): (2, TType.STRING, 'stdout', 'UTF8', None, ), # 2 (3, TType.STRING, 'stderr', 'UTF8', None, ), # 3 ) +all_structs.append(PlaybookVars) +PlaybookVars.thrift_spec = ( + None, # 0 + (1, TType.MAP, 'needed_variables', (TType.STRING, 'UTF8', TType.STRING, 'UTF8', False), None, ), # 1 +) all_structs.append(otherException) otherException.thrift_spec = ( None, # 0 diff --git a/portal_client.thrift b/portal_client.thrift index 09edaeff..7939a5a4 100644 --- a/portal_client.thrift +++ b/portal_client.thrift @@ -125,7 +125,13 @@ struct PlaybookResult { 3: required string stderr } - +/** + * This struct contains a mapping of variable keys to their content. This struct should be mapped by a playbook name. + */ +struct PlaybookVars { + /**The mapping of variable key to variable content*/ + 1: required map needed_variables +} @@ -339,8 +345,8 @@ service VirtualMachineService { /** Create and deploy an anaconda ansible playbook*/ int create_and_deploy_playbook( - 1:string private_key, - 2:string play_source, + 1:string public_key, + 2:map> playbooks_information 3:string openstack_id ) From 939f321893746772aab1fa32b8e75adabecc407b Mon Sep 17 00:00:00 2001 From: Ewgenij Katchko Date: Mon, 29 Jul 2019 16:21:48 +0200 Subject: [PATCH 2/7] refactor(playbook): delete logging of playbook-information --- VirtualMachineService/ancon/Playbook.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/VirtualMachineService/ancon/Playbook.py b/VirtualMachineService/ancon/Playbook.py index f7fd1bbd..ffba6312 100644 --- a/VirtualMachineService/ancon/Playbook.py +++ b/VirtualMachineService/ancon/Playbook.py @@ -1,4 +1,3 @@ -import logging import shlex import shutil from tempfile import NamedTemporaryFile, TemporaryDirectory @@ -39,8 +38,6 @@ def __init__(self, ip, port, playbooks_information, osi_private_key, public_key, self.inventory.close() def copy_playbooks_and_init(self, playbooks_information, public_key): - self.logger.info(type(playbooks_information)) - self.logger.info(playbooks_information) for k, v in playbooks_information.items(): self.copy_and_init(k, v) From 58c970689d045acd735160675ab5589e56076eb2 Mon Sep 17 00:00:00 2001 From: Ewgenij Katchko Date: Tue, 30 Jul 2019 16:21:50 +0200 Subject: [PATCH 3/7] fix(playbook): try except for _vars_file.yml --- VirtualMachineService/ancon/Playbook.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/VirtualMachineService/ancon/Playbook.py b/VirtualMachineService/ancon/Playbook.py index ffba6312..be449f58 100644 --- a/VirtualMachineService/ancon/Playbook.py +++ b/VirtualMachineService/ancon/Playbook.py @@ -5,6 +5,8 @@ import subprocess BIOCONDA = "bioconda" +THEIA = "theia" +RSTUDIO = "rstudio" class Playbook(object): @@ -68,6 +70,13 @@ def load_vars(): if k == "string_line": data[playbook_name + "_tools"][k] = v.strip('\"') data[playbook_name + "_tools"]["timeout_length"] = str(len(v.split()) * 5) + "m" + if playbook_name == THEIA: + for k, v in playbook_vars.items(): + if k == "version": + data[playbook_name + "_vars"][k] = v + if playbook_name == RSTUDIO: + for k, v in playbook_vars.items(): + pass playbook_yml = "/{0}.yml".format(playbook_name) playbook_var_yml = "/{0}_vars_file.yml".format(playbook_name) @@ -86,8 +95,13 @@ def load_vars(): except shutil.Error as e: self.logger.exception(e) self.add_tasks_only(playbook_name) + except IOError as e: + self.logger.exception(e) + self.add_tasks_only(playbook_name) except shutil.Error as e: self.logger.exception(e) + except IOError as e: + self.logger.exception(e) def add_to_playbook_lists(self, playbook_name): self.vars_files.append(playbook_name + "_vars_file.yml") From 5ad588c070093fe2eedaa5d680f169d1d1b23bc3 Mon Sep 17 00:00:00 2001 From: eKatchko <47833533+eKatchko@users.noreply.github.com> Date: Thu, 1 Aug 2019 15:47:54 +0200 Subject: [PATCH 4/7] Refactor/generic playbook (#119) * refactor(playbook): code for generic playbook runs * fix(playbook): try except for _vars_file.yml --- .../VirtualMachineHandler.py | 47 ++-- .../VirtualMachineService-remote | 4 +- .../VirtualMachineService.py | 222 ++++++++++-------- .../ancon/BiocondaPlaybook.py | 77 ------ VirtualMachineService/ancon/Playbook.py | 131 +++++++++++ .../ancon/playbooks/bioconda.yml | 63 ++--- .../{variables.yml => bioconda_vars_file.yml} | 5 +- .../ancon/playbooks/change_key.yml | 6 + .../ancon/playbooks/change_key_vars_file.yml | 2 + .../ancon/playbooks/generic_playbook.yml | 6 + VirtualMachineService/ttypes.py | 76 ++++++ portal_client.thrift | 12 +- 12 files changed, 402 insertions(+), 249 deletions(-) delete mode 100644 VirtualMachineService/ancon/BiocondaPlaybook.py create mode 100644 VirtualMachineService/ancon/Playbook.py rename VirtualMachineService/ancon/playbooks/{variables.yml => bioconda_vars_file.yml} (89%) create mode 100644 VirtualMachineService/ancon/playbooks/change_key.yml create mode 100644 VirtualMachineService/ancon/playbooks/change_key_vars_file.yml create mode 100644 VirtualMachineService/ancon/playbooks/generic_playbook.yml diff --git a/VirtualMachineService/VirtualMachineHandler.py b/VirtualMachineService/VirtualMachineHandler.py index 67c61364..bc277585 100644 --- a/VirtualMachineService/VirtualMachineHandler.py +++ b/VirtualMachineService/VirtualMachineHandler.py @@ -15,7 +15,7 @@ from ttypes import ressourceException from ttypes import Flavor, Image, VM, PlaybookResult from constants import VERSION - from ancon.BiocondaPlaybook import BiocondaPlaybook + from ancon.Playbook import Playbook except Exception: from .VirtualMachineService import Iface @@ -28,7 +28,7 @@ from .ttypes import ressourceException from .ttypes import Flavor, Image, VM, PlaybookResult from .constants import VERSION - from .ancon.BiocondaPlaybook import BiocondaPlaybook + from .ancon.Playbook import Playbook from openstack import connection from deprecated import deprecated @@ -56,9 +56,9 @@ class VirtualMachineHandler(Iface): global osi_key_dict BUILD = "BUILD" ACTIVE = "ACTIVE" - PREPARE_BIOCONDA_BUILD = "PREPARE_BIOCONDA_BUILD" - BUILD_BIOCONDA = "BUILD_BIOCONDA" - BIOCONDA_FAILED = "BIOCONDA_FAILED" + PREPARE_PLAYBOOK_BUILD = "PREPARE_PLAYBOOK_BUILD" + BUILD_PLAYBOOK = "BUILD_PLAYBOOK" + PLAYBOOK_FAILED = "PLAYBOOK_FAILED" def create_connection(self): """ @@ -633,35 +633,34 @@ def start_server_with_custom_key(self, flavor, image, servername, elixir_id, dis openstack_id = server.to_dict()["id"] global osi_key_dict osi_key_dict[openstack_id] = dict(key=private_key, name=servername, - status=self.PREPARE_BIOCONDA_BUILD) + status=self.PREPARE_PLAYBOOK_BUILD) return {"openstackid": openstack_id, "volumeId": volume_id, 'private_key': private_key} except Exception as e: self.delete_keypair(key_name=servername) self.logger.exception("Start Server {1} error:{0}".format(e, servername)) return {} - def create_and_deploy_playbook(self, private_key, play_source, openstack_id): - self.logger.info(msg="Starting Bioconda Playbook for (openstack_id): {0} with packages {1}" - .format(openstack_id, play_source)) + def create_and_deploy_playbook(self, public_key, playbooks_information, openstack_id): + self.logger.info(msg="Starting Playbook for (openstack_id): {0}" + .format(openstack_id)) # get ip and port for inventory fields = self.get_ip_ports(openstack_id=openstack_id) global osi_key_dict global active_playbooks key_name = osi_key_dict[openstack_id]['name'] - playbook = BiocondaPlaybook(fields["IP"], fields["PORT"], play_source, - osi_key_dict[openstack_id]["key"], private_key) + playbook = Playbook(fields["IP"], + fields["PORT"], + playbooks_information, + osi_key_dict[openstack_id]["key"], + public_key, + self.logger) active_playbooks[openstack_id] = playbook - osi_key_dict[openstack_id]["status"] = self.BUILD_BIOCONDA + osi_key_dict[openstack_id]["status"] = self.BUILD_PLAYBOOK status, stdout, stderr = playbook.run_it() self.delete_keypair(key_name=key_name) if status != 0: - # self.logger.exception(msg="Bioconda playbook for {0} encountered an error with status code {1}. The messages are:" - # "stdout: {2}" - # "stderr: {3}".format(openstack_id, status, stdout, stderr)) - osi_key_dict[openstack_id]["status"] = self.BIOCONDA_FAILED + osi_key_dict[openstack_id]["status"] = self.PLAYBOOK_FAILED else: - # self.logger.info("Finished Bioconda Playbook for (openstack_id): {0} with status code: {1}" - # .format(openstack_id, status)) osi_key_dict[openstack_id]["status"] = self.ACTIVE return status @@ -783,14 +782,14 @@ def check_server_status(self, openstack_id, diskspace, volume_id): return server if openstack_id in osi_key_dict: - if osi_key_dict[openstack_id]["status"] == self.PREPARE_BIOCONDA_BUILD: - server.status = self.PREPARE_BIOCONDA_BUILD + if osi_key_dict[openstack_id]["status"] == self.PREPARE_PLAYBOOK_BUILD: + server.status = self.PREPARE_PLAYBOOK_BUILD return server - elif osi_key_dict[openstack_id]["status"] == self.BUILD_BIOCONDA: - server.status = self.BUILD_BIOCONDA + elif osi_key_dict[openstack_id]["status"] == self.BUILD_PLAYBOOK: + server.status = self.BUILD_PLAYBOOK return server - elif osi_key_dict[openstack_id]["status"] == self.BIOCONDA_FAILED: - server.status = self.BIOCONDA_FAILED + elif osi_key_dict[openstack_id]["status"] == self.PLAYBOOK_FAILED: + server.status = self.PLAYBOOK_FAILED return server else: return server diff --git a/VirtualMachineService/VirtualMachineService-remote b/VirtualMachineService/VirtualMachineService-remote index b61dc4e2..5b23e73e 100755 --- a/VirtualMachineService/VirtualMachineService-remote +++ b/VirtualMachineService/VirtualMachineService-remote @@ -38,7 +38,7 @@ if len(sys.argv) <= 1 or sys.argv[1] == '--help': print(' bool create_connection(string username, string password, string auth_url, string user_domain_name, string project_domain_name)') print(' start_server(string flavor, string image, string public_key, string servername, string elixir_id, string diskspace, string volumename)') print(' start_server_with_custom_key(string flavor, string image, string servername, string elixir_id, string diskspace, string volumename)') - print(' int create_and_deploy_playbook(string private_key, string play_source, string openstack_id)') + print(' int create_and_deploy_playbook(string public_key, playbooks_information, string openstack_id)') print(' PlaybookResult get_playbook_logs(string openstack_id)') print(' bool add_security_group_to_server(bool http, bool https, bool udp, string server_id)') print(' VM get_server(string openstack_id)') @@ -221,7 +221,7 @@ elif cmd == 'create_and_deploy_playbook': if len(args) != 3: print('create_and_deploy_playbook requires 3 args') sys.exit(1) - pp.pprint(client.create_and_deploy_playbook(args[0], args[1], args[2],)) + pp.pprint(client.create_and_deploy_playbook(args[0], eval(args[1]), args[2],)) elif cmd == 'get_playbook_logs': if len(args) != 1: diff --git a/VirtualMachineService/VirtualMachineService.py b/VirtualMachineService/VirtualMachineService.py index 0a6ac6d6..023f261e 100644 --- a/VirtualMachineService/VirtualMachineService.py +++ b/VirtualMachineService/VirtualMachineService.py @@ -179,13 +179,13 @@ def start_server_with_custom_key(self, flavor, image, servername, elixir_id, dis """ pass - def create_and_deploy_playbook(self, private_key, play_source, openstack_id): + def create_and_deploy_playbook(self, public_key, playbooks_information, openstack_id): """ Create and deploy an anaconda ansible playbook Parameters: - - private_key - - play_source + - public_key + - playbooks_information - openstack_id """ @@ -928,24 +928,24 @@ def recv_start_server_with_custom_key(self): raise result.o raise TApplicationException(TApplicationException.MISSING_RESULT, "start_server_with_custom_key failed: unknown result") - def create_and_deploy_playbook(self, private_key, play_source, openstack_id): + def create_and_deploy_playbook(self, public_key, playbooks_information, openstack_id): """ Create and deploy an anaconda ansible playbook Parameters: - - private_key - - play_source + - public_key + - playbooks_information - openstack_id """ - self.send_create_and_deploy_playbook(private_key, play_source, openstack_id) + self.send_create_and_deploy_playbook(public_key, playbooks_information, openstack_id) return self.recv_create_and_deploy_playbook() - def send_create_and_deploy_playbook(self, private_key, play_source, openstack_id): + def send_create_and_deploy_playbook(self, public_key, playbooks_information, openstack_id): self._oprot.writeMessageBegin('create_and_deploy_playbook', TMessageType.CALL, self._seqid) args = create_and_deploy_playbook_args() - args.private_key = private_key - args.play_source = play_source + args.public_key = public_key + args.playbooks_information = playbooks_information args.openstack_id = openstack_id args.write(self._oprot) self._oprot.writeMessageEnd() @@ -1983,7 +1983,7 @@ def process_create_and_deploy_playbook(self, seqid, iprot, oprot): iprot.readMessageEnd() result = create_and_deploy_playbook_result() try: - result.success = self._handler.create_and_deploy_playbook(args.private_key, args.play_source, args.openstack_id) + result.success = self._handler.create_and_deploy_playbook(args.public_key, args.playbooks_information, args.openstack_id) msg_type = TMessageType.REPLY except TTransport.TTransportException: raise @@ -2837,11 +2837,11 @@ def read(self, iprot): if fid == 0: if ftype == TType.MAP: self.success = {} - (_ktype24, _vtype25, _size23) = iprot.readMapBegin() - for _i27 in range(_size23): - _key28 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() - _val29 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() - self.success[_key28] = _val29 + (_ktype33, _vtype34, _size32) = iprot.readMapBegin() + for _i36 in range(_size32): + _key37 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + _val38 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + self.success[_key37] = _val38 iprot.readMapEnd() else: iprot.skip(ftype) @@ -2858,9 +2858,9 @@ def write(self, oprot): if self.success is not None: oprot.writeFieldBegin('success', TType.MAP, 0) oprot.writeMapBegin(TType.STRING, TType.STRING, len(self.success)) - for kiter30, viter31 in self.success.items(): - oprot.writeString(kiter30.encode('utf-8') if sys.version_info[0] == 2 else kiter30) - oprot.writeString(viter31.encode('utf-8') if sys.version_info[0] == 2 else viter31) + for kiter39, viter40 in self.success.items(): + oprot.writeString(kiter39.encode('utf-8') if sys.version_info[0] == 2 else kiter39) + oprot.writeString(viter40.encode('utf-8') if sys.version_info[0] == 2 else viter40) oprot.writeMapEnd() oprot.writeFieldEnd() oprot.writeFieldStop() @@ -2951,11 +2951,11 @@ def read(self, iprot): if fid == 0: if ftype == TType.LIST: self.success = [] - (_etype35, _size32) = iprot.readListBegin() - for _i36 in range(_size32): - _elem37 = Flavor() - _elem37.read(iprot) - self.success.append(_elem37) + (_etype44, _size41) = iprot.readListBegin() + for _i45 in range(_size41): + _elem46 = Flavor() + _elem46.read(iprot) + self.success.append(_elem46) iprot.readListEnd() else: iprot.skip(ftype) @@ -2972,8 +2972,8 @@ def write(self, oprot): if self.success is not None: oprot.writeFieldBegin('success', TType.LIST, 0) oprot.writeListBegin(TType.STRUCT, len(self.success)) - for iter38 in self.success: - iter38.write(oprot) + for iter47 in self.success: + iter47.write(oprot) oprot.writeListEnd() oprot.writeFieldEnd() oprot.writeFieldStop() @@ -3064,11 +3064,11 @@ def read(self, iprot): if fid == 0: if ftype == TType.LIST: self.success = [] - (_etype42, _size39) = iprot.readListBegin() - for _i43 in range(_size39): - _elem44 = Image() - _elem44.read(iprot) - self.success.append(_elem44) + (_etype51, _size48) = iprot.readListBegin() + for _i52 in range(_size48): + _elem53 = Image() + _elem53.read(iprot) + self.success.append(_elem53) iprot.readListEnd() else: iprot.skip(ftype) @@ -3085,8 +3085,8 @@ def write(self, oprot): if self.success is not None: oprot.writeFieldBegin('success', TType.LIST, 0) oprot.writeListBegin(TType.STRUCT, len(self.success)) - for iter45 in self.success: - iter45.write(oprot) + for iter54 in self.success: + iter54.write(oprot) oprot.writeListEnd() oprot.writeFieldEnd() oprot.writeFieldStop() @@ -3401,11 +3401,11 @@ def read(self, iprot): elif fid == 2: if ftype == TType.MAP: self.metadata = {} - (_ktype47, _vtype48, _size46) = iprot.readMapBegin() - for _i50 in range(_size46): - _key51 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() - _val52 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() - self.metadata[_key51] = _val52 + (_ktype56, _vtype57, _size55) = iprot.readMapBegin() + for _i59 in range(_size55): + _key60 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + _val61 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + self.metadata[_key60] = _val61 iprot.readMapEnd() else: iprot.skip(ftype) @@ -3426,9 +3426,9 @@ def write(self, oprot): if self.metadata is not None: oprot.writeFieldBegin('metadata', TType.MAP, 2) oprot.writeMapBegin(TType.STRING, TType.STRING, len(self.metadata)) - for kiter53, viter54 in self.metadata.items(): - oprot.writeString(kiter53.encode('utf-8') if sys.version_info[0] == 2 else kiter53) - oprot.writeString(viter54.encode('utf-8') if sys.version_info[0] == 2 else viter54) + for kiter62, viter63 in self.metadata.items(): + oprot.writeString(kiter62.encode('utf-8') if sys.version_info[0] == 2 else kiter62) + oprot.writeString(viter63.encode('utf-8') if sys.version_info[0] == 2 else viter63) oprot.writeMapEnd() oprot.writeFieldEnd() oprot.writeFieldStop() @@ -3480,11 +3480,11 @@ def read(self, iprot): if fid == 0: if ftype == TType.MAP: self.success = {} - (_ktype56, _vtype57, _size55) = iprot.readMapBegin() - for _i59 in range(_size55): - _key60 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() - _val61 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() - self.success[_key60] = _val61 + (_ktype65, _vtype66, _size64) = iprot.readMapBegin() + for _i68 in range(_size64): + _key69 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + _val70 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + self.success[_key69] = _val70 iprot.readMapEnd() else: iprot.skip(ftype) @@ -3507,9 +3507,9 @@ def write(self, oprot): if self.success is not None: oprot.writeFieldBegin('success', TType.MAP, 0) oprot.writeMapBegin(TType.STRING, TType.STRING, len(self.success)) - for kiter62, viter63 in self.success.items(): - oprot.writeString(kiter62.encode('utf-8') if sys.version_info[0] == 2 else kiter62) - oprot.writeString(viter63.encode('utf-8') if sys.version_info[0] == 2 else viter63) + for kiter71, viter72 in self.success.items(): + oprot.writeString(kiter71.encode('utf-8') if sys.version_info[0] == 2 else kiter71) + oprot.writeString(viter72.encode('utf-8') if sys.version_info[0] == 2 else viter72) oprot.writeMapEnd() oprot.writeFieldEnd() if self.e is not None: @@ -3569,10 +3569,10 @@ def read(self, iprot): elif fid == 2: if ftype == TType.SET: self.keys = set() - (_etype67, _size64) = iprot.readSetBegin() - for _i68 in range(_size64): - _elem69 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() - self.keys.add(_elem69) + (_etype76, _size73) = iprot.readSetBegin() + for _i77 in range(_size73): + _elem78 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + self.keys.add(_elem78) iprot.readSetEnd() else: iprot.skip(ftype) @@ -3593,8 +3593,8 @@ def write(self, oprot): if self.keys is not None: oprot.writeFieldBegin('keys', TType.SET, 2) oprot.writeSetBegin(TType.STRING, len(self.keys)) - for iter70 in self.keys: - oprot.writeString(iter70.encode('utf-8') if sys.version_info[0] == 2 else iter70) + for iter79 in self.keys: + oprot.writeString(iter79.encode('utf-8') if sys.version_info[0] == 2 else iter79) oprot.writeSetEnd() oprot.writeFieldEnd() oprot.writeFieldStop() @@ -3646,10 +3646,10 @@ def read(self, iprot): if fid == 0: if ftype == TType.SET: self.success = set() - (_etype74, _size71) = iprot.readSetBegin() - for _i75 in range(_size71): - _elem76 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() - self.success.add(_elem76) + (_etype83, _size80) = iprot.readSetBegin() + for _i84 in range(_size80): + _elem85 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + self.success.add(_elem85) iprot.readSetEnd() else: iprot.skip(ftype) @@ -3672,8 +3672,8 @@ def write(self, oprot): if self.success is not None: oprot.writeFieldBegin('success', TType.SET, 0) oprot.writeSetBegin(TType.STRING, len(self.success)) - for iter77 in self.success: - oprot.writeString(iter77.encode('utf-8') if sys.version_info[0] == 2 else iter77) + for iter86 in self.success: + oprot.writeString(iter86.encode('utf-8') if sys.version_info[0] == 2 else iter86) oprot.writeSetEnd() oprot.writeFieldEnd() if self.e is not None: @@ -4223,11 +4223,11 @@ def read(self, iprot): if fid == 0: if ftype == TType.MAP: self.success = {} - (_ktype79, _vtype80, _size78) = iprot.readMapBegin() - for _i82 in range(_size78): - _key83 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() - _val84 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() - self.success[_key83] = _val84 + (_ktype88, _vtype89, _size87) = iprot.readMapBegin() + for _i91 in range(_size87): + _key92 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + _val93 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + self.success[_key92] = _val93 iprot.readMapEnd() else: iprot.skip(ftype) @@ -4286,9 +4286,9 @@ def write(self, oprot): if self.success is not None: oprot.writeFieldBegin('success', TType.MAP, 0) oprot.writeMapBegin(TType.STRING, TType.STRING, len(self.success)) - for kiter85, viter86 in self.success.items(): - oprot.writeString(kiter85.encode('utf-8') if sys.version_info[0] == 2 else kiter85) - oprot.writeString(viter86.encode('utf-8') if sys.version_info[0] == 2 else viter86) + for kiter94, viter95 in self.success.items(): + oprot.writeString(kiter94.encode('utf-8') if sys.version_info[0] == 2 else kiter94) + oprot.writeString(viter95.encode('utf-8') if sys.version_info[0] == 2 else viter95) oprot.writeMapEnd() oprot.writeFieldEnd() if self.e is not None: @@ -4507,11 +4507,11 @@ def read(self, iprot): if fid == 0: if ftype == TType.MAP: self.success = {} - (_ktype88, _vtype89, _size87) = iprot.readMapBegin() - for _i91 in range(_size87): - _key92 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() - _val93 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() - self.success[_key92] = _val93 + (_ktype97, _vtype98, _size96) = iprot.readMapBegin() + for _i100 in range(_size96): + _key101 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + _val102 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + self.success[_key101] = _val102 iprot.readMapEnd() else: iprot.skip(ftype) @@ -4570,9 +4570,9 @@ def write(self, oprot): if self.success is not None: oprot.writeFieldBegin('success', TType.MAP, 0) oprot.writeMapBegin(TType.STRING, TType.STRING, len(self.success)) - for kiter94, viter95 in self.success.items(): - oprot.writeString(kiter94.encode('utf-8') if sys.version_info[0] == 2 else kiter94) - oprot.writeString(viter95.encode('utf-8') if sys.version_info[0] == 2 else viter95) + for kiter103, viter104 in self.success.items(): + oprot.writeString(kiter103.encode('utf-8') if sys.version_info[0] == 2 else kiter103) + oprot.writeString(viter104.encode('utf-8') if sys.version_info[0] == 2 else viter104) oprot.writeMapEnd() oprot.writeFieldEnd() if self.e is not None: @@ -4635,16 +4635,16 @@ def __ne__(self, other): class create_and_deploy_playbook_args(object): """ Attributes: - - private_key - - play_source + - public_key + - playbooks_information - openstack_id """ - def __init__(self, private_key=None, play_source=None, openstack_id=None,): - self.private_key = private_key - self.play_source = play_source + def __init__(self, public_key=None, playbooks_information=None, openstack_id=None,): + self.public_key = public_key + self.playbooks_information = playbooks_information self.openstack_id = openstack_id def read(self, iprot): @@ -4658,12 +4658,24 @@ def read(self, iprot): break if fid == 1: if ftype == TType.STRING: - self.private_key = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + self.public_key = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() else: iprot.skip(ftype) elif fid == 2: - if ftype == TType.STRING: - self.play_source = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + if ftype == TType.MAP: + self.playbooks_information = {} + (_ktype106, _vtype107, _size105) = iprot.readMapBegin() + for _i109 in range(_size105): + _key110 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + _val111 = {} + (_ktype113, _vtype114, _size112) = iprot.readMapBegin() + for _i116 in range(_size112): + _key117 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + _val118 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + _val111[_key117] = _val118 + iprot.readMapEnd() + self.playbooks_information[_key110] = _val111 + iprot.readMapEnd() else: iprot.skip(ftype) elif fid == 3: @@ -4681,13 +4693,21 @@ def write(self, oprot): oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec])) return oprot.writeStructBegin('create_and_deploy_playbook_args') - if self.private_key is not None: - oprot.writeFieldBegin('private_key', TType.STRING, 1) - oprot.writeString(self.private_key.encode('utf-8') if sys.version_info[0] == 2 else self.private_key) + if self.public_key is not None: + oprot.writeFieldBegin('public_key', TType.STRING, 1) + oprot.writeString(self.public_key.encode('utf-8') if sys.version_info[0] == 2 else self.public_key) oprot.writeFieldEnd() - if self.play_source is not None: - oprot.writeFieldBegin('play_source', TType.STRING, 2) - oprot.writeString(self.play_source.encode('utf-8') if sys.version_info[0] == 2 else self.play_source) + if self.playbooks_information is not None: + oprot.writeFieldBegin('playbooks_information', TType.MAP, 2) + oprot.writeMapBegin(TType.STRING, TType.MAP, len(self.playbooks_information)) + for kiter119, viter120 in self.playbooks_information.items(): + oprot.writeString(kiter119.encode('utf-8') if sys.version_info[0] == 2 else kiter119) + oprot.writeMapBegin(TType.STRING, TType.STRING, len(viter120)) + for kiter121, viter122 in viter120.items(): + oprot.writeString(kiter121.encode('utf-8') if sys.version_info[0] == 2 else kiter121) + oprot.writeString(viter122.encode('utf-8') if sys.version_info[0] == 2 else viter122) + oprot.writeMapEnd() + oprot.writeMapEnd() oprot.writeFieldEnd() if self.openstack_id is not None: oprot.writeFieldBegin('openstack_id', TType.STRING, 3) @@ -4712,8 +4732,8 @@ def __ne__(self, other): all_structs.append(create_and_deploy_playbook_args) create_and_deploy_playbook_args.thrift_spec = ( None, # 0 - (1, TType.STRING, 'private_key', 'UTF8', None, ), # 1 - (2, TType.STRING, 'play_source', 'UTF8', None, ), # 2 + (1, TType.STRING, 'public_key', 'UTF8', None, ), # 1 + (2, TType.MAP, 'playbooks_information', (TType.STRING, 'UTF8', TType.MAP, (TType.STRING, 'UTF8', TType.STRING, 'UTF8', False), False), None, ), # 2 (3, TType.STRING, 'openstack_id', 'UTF8', None, ), # 3 ) @@ -5611,11 +5631,11 @@ def read(self, iprot): if fid == 0: if ftype == TType.MAP: self.success = {} - (_ktype97, _vtype98, _size96) = iprot.readMapBegin() - for _i100 in range(_size96): - _key101 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() - _val102 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() - self.success[_key101] = _val102 + (_ktype124, _vtype125, _size123) = iprot.readMapBegin() + for _i127 in range(_size123): + _key128 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + _val129 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + self.success[_key128] = _val129 iprot.readMapEnd() else: iprot.skip(ftype) @@ -5632,9 +5652,9 @@ def write(self, oprot): if self.success is not None: oprot.writeFieldBegin('success', TType.MAP, 0) oprot.writeMapBegin(TType.STRING, TType.STRING, len(self.success)) - for kiter103, viter104 in self.success.items(): - oprot.writeString(kiter103.encode('utf-8') if sys.version_info[0] == 2 else kiter103) - oprot.writeString(viter104.encode('utf-8') if sys.version_info[0] == 2 else viter104) + for kiter130, viter131 in self.success.items(): + oprot.writeString(kiter130.encode('utf-8') if sys.version_info[0] == 2 else kiter130) + oprot.writeString(viter131.encode('utf-8') if sys.version_info[0] == 2 else viter131) oprot.writeMapEnd() oprot.writeFieldEnd() oprot.writeFieldStop() diff --git a/VirtualMachineService/ancon/BiocondaPlaybook.py b/VirtualMachineService/ancon/BiocondaPlaybook.py deleted file mode 100644 index 160c46a5..00000000 --- a/VirtualMachineService/ancon/BiocondaPlaybook.py +++ /dev/null @@ -1,77 +0,0 @@ -import logging -import shlex -import shutil -import sys -from tempfile import NamedTemporaryFile, TemporaryDirectory -import ruamel.yaml -import subprocess - - -class BiocondaPlaybook(object): - - def __init__(self, ip, port, play_source, osi_private_key, public_key): - self.status = -1 - self.stdout = '' - self.stderr = '' - # directories and files - self.ancon_dir = "/code/VirtualMachineService/ancon" - self.playbooks_dir = self.ancon_dir + "/playbooks" - self.directory = TemporaryDirectory(dir=self.ancon_dir) - #self.log_file = NamedTemporaryFile(mode='w+', delete=False, dir=self.directory.name) - shutil.copy(self.playbooks_dir+"/bioconda.yml", self.directory.name) - shutil.copy(self.playbooks_dir+"/variables.yml", self.directory.name) - self.ip = ip - self.port = port - self.private_key = NamedTemporaryFile(mode="w+", dir=self.directory.name, delete=False) - self.private_key.write(osi_private_key) - self.private_key.close() - - # logging - #self.logger = logging.getLogger(__name__) - #self.logger.setLevel(logging.DEBUG) - # create file handler which logs even debug messages - #self.fh = logging.FileHandler(self.log_file.name) - #self.fh.setLevel(logging.DEBUG) - # create formatter and add it to the handlers - #self.formatter = logging.Formatter( - # "%(asctime)s - %(name)s - %(levelname)s - %(message)s" - #) - #self.fh.setFormatter(self.formatter) - # add the handlers to the logger - #self.logger.addHandler(self.fh) - - # create inventory and add the to-be-installed tools to the variables.yml - self.inventory = NamedTemporaryFile(mode="w+", dir=self.directory.name, delete=False) - inventory_string = "[vm]\n" + self.ip + ":" + self.port + " ansible_user=ubuntu " \ - "ansible_ssh_private_key_file=" + self.private_key.name - self.inventory.write(inventory_string) - self.inventory.close() - - # load variables.yml and change some of its content - yaml_exec = ruamel.yaml.YAML() - with open(self.directory.name + "/variables.yml", mode='r') as variables: - data = yaml_exec.load(variables) - data["tools"]["string_line"] = play_source.strip('\"') - data["tools"]["public_key"] = public_key.strip('\"') - data["tools"]["timeout_length"] = str(len(play_source.split()) * 5) + "m" - with open(self.directory.name + "/variables.yml", mode='w') as variables: - yaml_exec.dump(data, variables) - - def run_it(self): - command_string = "/usr/local/bin/ansible-playbook -v -i {0} {1}/bioconda.yml"\ - .format(self.inventory.name, self.directory.name) - command_string = shlex.split(command_string) - process = subprocess.run(command_string, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) - # self.logger.log(level=20, msg=process.stdout) - self.stdout = process.stdout - if len(process.stderr) > 0: - self.stderr = process.stderr - # self.logger.log(level=50, msg=process.stderr) - self.status = process.returncode - return process.returncode, process.stdout, process.stderr - - def get_logs(self): - return self.status, self.stdout, self.stderr - - def cleanup(self): - self.directory.cleanup() diff --git a/VirtualMachineService/ancon/Playbook.py b/VirtualMachineService/ancon/Playbook.py new file mode 100644 index 00000000..be449f58 --- /dev/null +++ b/VirtualMachineService/ancon/Playbook.py @@ -0,0 +1,131 @@ +import shlex +import shutil +from tempfile import NamedTemporaryFile, TemporaryDirectory +import ruamel.yaml +import subprocess + +BIOCONDA = "bioconda" +THEIA = "theia" +RSTUDIO = "rstudio" + + +class Playbook(object): + + def __init__(self, ip, port, playbooks_information, osi_private_key, public_key, logger): + self.yaml_exec = ruamel.yaml.YAML() + self.vars_files = [] + self.tasks = [] + self.logger = logger + # init return logs + self.status = -1 + self.stdout = '' + self.stderr = '' + # init temporary directories and mandatory generic files + self.ancon_dir = "/code/VirtualMachineService/ancon" # path to this directory + self.playbooks_dir = self.ancon_dir + "/playbooks" # path to source playbooks + self.directory = TemporaryDirectory(dir=self.ancon_dir) + self.private_key = NamedTemporaryFile(mode="w+", dir=self.directory.name, delete=False) + self.private_key.write(osi_private_key) + self.private_key.close() + + # create the custom playbook and save its name + self.playbook_exec_name = "generic_playbook.yml" + self.copy_playbooks_and_init(playbooks_information, public_key) + + # create inventory + self.inventory = NamedTemporaryFile(mode="w+", dir=self.directory.name, delete=False) + inventory_string = "[vm]\n" + ip + ":" + port + " ansible_user=ubuntu " \ + "ansible_ssh_private_key_file=" + self.private_key.name + self.inventory.write(inventory_string) + self.inventory.close() + + def copy_playbooks_and_init(self, playbooks_information, public_key): + for k, v in playbooks_information.items(): + self.copy_and_init(k, v) + + # init yml to change public keys as last task + shutil.copy(self.playbooks_dir + "/change_key.yml", self.directory.name) + shutil.copy(self.playbooks_dir + "/change_key_vars_file.yml", self.directory.name) + with open(self.directory.name + "/change_key_vars_file.yml", mode='r') as key_file: + data_ck = self.yaml_exec.load(key_file) + data_ck["change_key_vars"]["key"] = public_key.strip('\"') + with open(self.directory.name + "/change_key_vars_file.yml", mode='w') as key_file: + self.yaml_exec.dump(data_ck, key_file) + self.add_to_playbook_lists("change_key") + + # write all vars_files and tasks in generic_playbook + shutil.copy(self.playbooks_dir + "/" + self.playbook_exec_name, self.directory.name) + with open(self.directory.name + "/" + self.playbook_exec_name, mode='r') as generic_playbook: + data_gp = self.yaml_exec.load(generic_playbook) + data_gp[0]["vars_files"] = self.vars_files + data_gp[0]["tasks"] = self.tasks + with open(self.directory.name + "/" + self.playbook_exec_name, mode='w') as generic_playbook: + self.yaml_exec.dump(data_gp, generic_playbook) + + def copy_and_init(self, playbook_name, playbook_vars): + + def load_vars(): + if playbook_name == BIOCONDA: + for k, v in playbook_vars.items(): + if k == "string_line": + data[playbook_name + "_tools"][k] = v.strip('\"') + data[playbook_name + "_tools"]["timeout_length"] = str(len(v.split()) * 5) + "m" + if playbook_name == THEIA: + for k, v in playbook_vars.items(): + if k == "version": + data[playbook_name + "_vars"][k] = v + if playbook_name == RSTUDIO: + for k, v in playbook_vars.items(): + pass + + playbook_yml = "/{0}.yml".format(playbook_name) + playbook_var_yml = "/{0}_vars_file.yml".format(playbook_name) + try: + shutil.copy(self.playbooks_dir + playbook_yml, + self.directory.name) + try: + shutil.copy(self.playbooks_dir + playbook_var_yml, + self.directory.name) + with open(self.directory.name + playbook_var_yml, mode='r') as variables: + data = self.yaml_exec.load(variables) + load_vars() + with open(self.directory.name + playbook_var_yml, mode='w') as variables: + self.yaml_exec.dump(data, variables) + self.add_to_playbook_lists(playbook_name) + except shutil.Error as e: + self.logger.exception(e) + self.add_tasks_only(playbook_name) + except IOError as e: + self.logger.exception(e) + self.add_tasks_only(playbook_name) + except shutil.Error as e: + self.logger.exception(e) + except IOError as e: + self.logger.exception(e) + + def add_to_playbook_lists(self, playbook_name): + self.vars_files.append(playbook_name + "_vars_file.yml") + self.tasks.append(dict(name="Running {0} tasks".format(playbook_name), import_tasks=playbook_name+".yml")) + + def add_tasks_only(self, playbook_name): + self.tasks.append(dict(name="Running {0} tasks".format(playbook_name), import_tasks=playbook_name+".yml")) + + def run_it(self): + command_string = "/usr/local/bin/ansible-playbook -v -i {0} {1}/{2}"\ + .format(self.inventory.name, self.directory.name, self.playbook_exec_name) + command_string = shlex.split(command_string) + process = subprocess.run(command_string, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + universal_newlines=True) + self.stdout = process.stdout + if len(process.stderr) > 0: + self.stderr = process.stderr + self.status = process.returncode + return process.returncode, process.stdout, process.stderr + + def get_logs(self): + return self.status, self.stdout, self.stderr + + def cleanup(self): + self.directory.cleanup() diff --git a/VirtualMachineService/ancon/playbooks/bioconda.yml b/VirtualMachineService/ancon/playbooks/bioconda.yml index 18980f86..1ce3734c 100644 --- a/VirtualMachineService/ancon/playbooks/bioconda.yml +++ b/VirtualMachineService/ancon/playbooks/bioconda.yml @@ -1,43 +1,28 @@ -- name: Install miniconda3 and the chosen packages - hosts: all - connection: paramiko_ssh - gather_facts: yes - vars_files: - - variables.yml - tasks: +- name: Download miniconda install script + get_url: + args: + url: "{{ bioconda_folders.conda_installer_url }}" + dest: "{{ bioconda_folders.install_script }}" + mode: 0755 + timeout: 180 - - name: Download miniconda install script - get_url: - args: - url: "{{ folders.conda_installer_url }}" - dest: "{{ folders.install_script }}" - mode: 0755 - timeout: 180 +- name: Install miniconda + shell: "timeout 3m {{ bioconda_folders.install_script }} -b" + args: + executable: /bin/bash + creates: "{{ bioconda_folders.conda_dir }}" - - name: Install miniconda - shell: "timeout 3m {{ folders.install_script }} -b" - args: - executable: /bin/bash - creates: "{{ folders.conda_dir }}" +- name: Add channels + shell: "timeout 2m bash -c 'source {{ bioconda_folders.conda_dir }}/bin/activate && conda config --add channels default && conda config --add channels bioconda && conda config --add channels conda-forge'" + args: + executable: /bin/bash - - name: Add channels - shell: "timeout 2m bash -c 'source {{ folders.conda_dir }}/bin/activate && conda config --add channels default && conda config --add channels bioconda && conda config --add channels conda-forge'" - args: - executable: /bin/bash +- name: Create environment + shell: "timeout 2m bash -c 'source {{ bioconda_folders.conda_dir }}/bin/activate && conda create --yes -n {{ bioconda_tools.env }}'" + args: + executable: /bin/bash - - name: Create environment - shell: "timeout 2m bash -c 'source {{ folders.conda_dir }}/bin/activate && conda create --yes -n {{ tools.env }}'" - args: - executable: /bin/bash - - - name: Install chosen packages - shell: "timeout {{ tools.timeout_length }} bash -c 'source {{ folders.conda_dir }}/bin/activate && conda activate {{ tools.env }} && conda install --yes {{ tools.string_line }}'" - args: - executable: /bin/bash - - - name: Set user public Key and remove created public Key - authorized_key: - user: ubuntu - key: '{{ tools.public_key }}' - state: present - exclusive: True +- name: Install chosen packages + shell: "timeout {{ bioconda_tools.timeout_length }} bash -c 'source {{ bioconda_folders.conda_dir }}/bin/activate && conda activate {{ bioconda_tools.env }} && conda install --yes {{ bioconda_tools.string_line }}'" + args: + executable: /bin/bash diff --git a/VirtualMachineService/ancon/playbooks/variables.yml b/VirtualMachineService/ancon/playbooks/bioconda_vars_file.yml similarity index 89% rename from VirtualMachineService/ancon/playbooks/variables.yml rename to VirtualMachineService/ancon/playbooks/bioconda_vars_file.yml index 08928163..12ec9ce4 100644 --- a/VirtualMachineService/ancon/playbooks/variables.yml +++ b/VirtualMachineService/ancon/playbooks/bioconda_vars_file.yml @@ -1,10 +1,9 @@ -tools: +bioconda_tools: string_line: "" env: "denbi" - public_key: "" timeout_length: "5m" -folders: +bioconda_folders: install_script: "/home/{{ ansible_user_id }}/install_miniconda3.sh" conda_dir: "/home/{{ ansible_user_id }}/miniconda3" conda_installer_url: "https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh" diff --git a/VirtualMachineService/ancon/playbooks/change_key.yml b/VirtualMachineService/ancon/playbooks/change_key.yml new file mode 100644 index 00000000..bafbd0a9 --- /dev/null +++ b/VirtualMachineService/ancon/playbooks/change_key.yml @@ -0,0 +1,6 @@ +- name: Set user public Key and remove created public Key + authorized_key: + user: ubuntu + key: "{{ change_key_vars.key }}" + state: present + exclusive: True diff --git a/VirtualMachineService/ancon/playbooks/change_key_vars_file.yml b/VirtualMachineService/ancon/playbooks/change_key_vars_file.yml new file mode 100644 index 00000000..68e0b3cd --- /dev/null +++ b/VirtualMachineService/ancon/playbooks/change_key_vars_file.yml @@ -0,0 +1,2 @@ +change_key_vars: + key: diff --git a/VirtualMachineService/ancon/playbooks/generic_playbook.yml b/VirtualMachineService/ancon/playbooks/generic_playbook.yml new file mode 100644 index 00000000..bea7831f --- /dev/null +++ b/VirtualMachineService/ancon/playbooks/generic_playbook.yml @@ -0,0 +1,6 @@ +- name: Setting up your virtual machine + hosts: all + connection: paramiko_ssh + gather_facts: yes + vars_files: + tasks: diff --git a/VirtualMachineService/ttypes.py b/VirtualMachineService/ttypes.py index 398bda72..e6046a17 100644 --- a/VirtualMachineService/ttypes.py +++ b/VirtualMachineService/ttypes.py @@ -634,6 +634,77 @@ def __ne__(self, other): return not (self == other) +class PlaybookVars(object): + """ + This struct contains a mapping of variable keys to their content. This struct should be mapped by a playbook name. + + Attributes: + - needed_variables: The mapping of variable key to variable content + + """ + + + def __init__(self, needed_variables=None,): + self.needed_variables = needed_variables + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, [self.__class__, self.thrift_spec]) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.MAP: + self.needed_variables = {} + (_ktype24, _vtype25, _size23) = iprot.readMapBegin() + for _i27 in range(_size23): + _key28 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + _val29 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + self.needed_variables[_key28] = _val29 + iprot.readMapEnd() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec])) + return + oprot.writeStructBegin('PlaybookVars') + if self.needed_variables is not None: + oprot.writeFieldBegin('needed_variables', TType.MAP, 1) + oprot.writeMapBegin(TType.STRING, TType.STRING, len(self.needed_variables)) + for kiter30, viter31 in self.needed_variables.items(): + oprot.writeString(kiter30.encode('utf-8') if sys.version_info[0] == 2 else kiter30) + oprot.writeString(viter31.encode('utf-8') if sys.version_info[0] == 2 else viter31) + oprot.writeMapEnd() + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + if self.needed_variables is None: + raise TProtocolException(message='Required field needed_variables is unset!') + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + class otherException(TException): """ Attributes: @@ -1162,6 +1233,11 @@ def __ne__(self, other): (2, TType.STRING, 'stdout', 'UTF8', None, ), # 2 (3, TType.STRING, 'stderr', 'UTF8', None, ), # 3 ) +all_structs.append(PlaybookVars) +PlaybookVars.thrift_spec = ( + None, # 0 + (1, TType.MAP, 'needed_variables', (TType.STRING, 'UTF8', TType.STRING, 'UTF8', False), None, ), # 1 +) all_structs.append(otherException) otherException.thrift_spec = ( None, # 0 diff --git a/portal_client.thrift b/portal_client.thrift index 09edaeff..7939a5a4 100644 --- a/portal_client.thrift +++ b/portal_client.thrift @@ -125,7 +125,13 @@ struct PlaybookResult { 3: required string stderr } - +/** + * This struct contains a mapping of variable keys to their content. This struct should be mapped by a playbook name. + */ +struct PlaybookVars { + /**The mapping of variable key to variable content*/ + 1: required map needed_variables +} @@ -339,8 +345,8 @@ service VirtualMachineService { /** Create and deploy an anaconda ansible playbook*/ int create_and_deploy_playbook( - 1:string private_key, - 2:string play_source, + 1:string public_key, + 2:map> playbooks_information 3:string openstack_id ) From 3b435835cc079ccbadb45562aa80df275e24873b Mon Sep 17 00:00:00 2001 From: David Weinholz Date: Tue, 6 Aug 2019 16:31:44 +0200 Subject: [PATCH 5/7] fix(Virtualmachine):not timeout when stopping or resuming vm --- VirtualMachineService/VirtualMachineHandler.py | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/VirtualMachineService/VirtualMachineHandler.py b/VirtualMachineService/VirtualMachineHandler.py index bc277585..a7a4a06b 100644 --- a/VirtualMachineService/VirtualMachineHandler.py +++ b/VirtualMachineService/VirtualMachineHandler.py @@ -1146,14 +1146,8 @@ def stop_server(self, openstack_id): if server.status == "ACTIVE": self.conn.compute.suspend_server(server) - server = self.conn.compute.get_server(server) - while server.status != "SUSPENDED": - server = self.conn.compute.get_server(server) - time.sleep(3) - return True else: - return False except Exception as e: self.logger.exception("Stop Server {0} error:".format(openstack_id, e)) @@ -1199,10 +1193,6 @@ def resume_server(self, openstack_id): if server.status == "SUSPENDED": self.conn.compute.resume_server(server) - while server.status != "ACTIVE": - server = self.conn.compute.get_server(server) - time.sleep(3) - return True else: From 085f7f7411d62f8fe48a8b37010429121d42eabe Mon Sep 17 00:00:00 2001 From: Ewgenij Katchko Date: Thu, 8 Aug 2019 00:45:48 +0200 Subject: [PATCH 6/7] fix(vm): stops instead of suspending --- VirtualMachineService/VirtualMachineHandler.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/VirtualMachineService/VirtualMachineHandler.py b/VirtualMachineService/VirtualMachineHandler.py index bc277585..1ad400f0 100644 --- a/VirtualMachineService/VirtualMachineHandler.py +++ b/VirtualMachineService/VirtualMachineHandler.py @@ -1051,8 +1051,8 @@ def delete_server(self, openstack_id): self.logger.exception("Instance {0} not found".format(openstack_id)) raise serverNotFoundException - if server.status == "SUSPENDED": - self.conn.compute.resume_server(server) + if server.status == "SHUTOFF": + self.conn.compute.start_server(server) server = self.conn.compute.get_server(server) self.conn.compute.wait_for_server(server=server, status='ACTIVE') self.logger.info(server) @@ -1145,9 +1145,9 @@ def stop_server(self, openstack_id): raise serverNotFoundException if server.status == "ACTIVE": - self.conn.compute.suspend_server(server) + self.conn.compute.stop_server(server) server = self.conn.compute.get_server(server) - while server.status != "SUSPENDED": + while server.status != "SHUTOFF": server = self.conn.compute.get_server(server) time.sleep(3) @@ -1197,8 +1197,8 @@ def resume_server(self, openstack_id): self.logger.exception("Instance {0} not found".format(openstack_id)) raise serverNotFoundException - if server.status == "SUSPENDED": - self.conn.compute.resume_server(server) + if server.status == "SHUTOFF": + self.conn.compute.start_server(server) while server.status != "ACTIVE": server = self.conn.compute.get_server(server) time.sleep(3) From 102ad3bca52642503b9688f6ba746ccc2d165a59 Mon Sep 17 00:00:00 2001 From: David Weinholz Date: Thu, 8 Aug 2019 13:03:19 +0200 Subject: [PATCH 7/7] updated changelog --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a5b3fb9..7baf2b4d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +## (2019-08-08) + + +#### Bug Fixes + +* **Virtualmachine:** not timeout when stopping or resuming vm ([3b435835](3b435835)) +* **playbook:** try except for _vars_file.yml ([58c97068](58c97068)) +* **vm:** stops instead of suspending ([085f7f74](085f7f74)) + ## (2019-07-10)