diff --git a/IM/ConfManager.py b/IM/ConfManager.py index a67a6e50c..4e1607d58 100644 --- a/IM/ConfManager.py +++ b/IM/ConfManager.py @@ -54,8 +54,6 @@ class ConfManager(threading.Thread): Class to manage the contextualization steps """ - logger = logging.getLogger('ConfManager') - """ Logger object """ MASTER_YAML = "conf-ansible.yml" """ The file with the ansible steps to configure the master node """ SECOND_STEP_YAML = 'conf-ansible-s2.yml' @@ -70,6 +68,7 @@ def __init__(self, inf, auth, max_ctxt_time=1e9): self.max_ctxt_time = max_ctxt_time self._stop_thread = False self.ansible_process = None + self.logger = logging.getLogger('ConfManager') def check_running_pids(self, vms_configuring): """ @@ -86,13 +85,10 @@ def check_running_pids(self, vms_configuring): if step not in res: res[step] = [] res[step].append(vm) - ConfManager.logger.debug("Inf ID: " + str(self.inf.id) + - ": Ansible process to configure " + str( - vm.im_id) + " with PID " + vm.ctxt_pid + " is still running.") + self.log_debug("Ansible process to configure " + str(vm.im_id) + + " with PID " + vm.ctxt_pid + " is still running.") else: - ConfManager.logger.debug( - "Inf ID: " + str(self.inf.id) + ": Configuration process in VM: " + - str(vm.im_id) + " finished.") + self.log_debug("Configuration process in VM: " + str(vm.im_id) + " finished.") # Force to save the data to store the log data () IM.InfrastructureList.InfrastructureList.save_data(self.inf.id) else: @@ -101,16 +97,13 @@ def check_running_pids(self, vms_configuring): if step not in res: res[step] = [] res[step].append(vm) - ConfManager.logger.debug("Inf ID: " + str(self.inf.id) + - ": Configuration process of master node: " + - str(vm.get_ctxt_process_names()) + " is still running.") + self.log_debug("Configuration process of master node: " + + str(vm.get_ctxt_process_names()) + " is still running.") else: if vm.configured: - ConfManager.logger.debug("Inf ID: " + str(self.inf.id) + - ": Configuration process of master node successfully finished.") + self.log_debug("Configuration process of master node successfully finished.") else: - ConfManager.logger.debug( - "Inf ID: " + str(self.inf.id) + ": Configuration process of master node failed.") + self.log_debug("Configuration process of master node failed.") # Force to save the data to store the log data IM.InfrastructureList.InfrastructureList.save_data(self.inf.id) @@ -120,11 +113,9 @@ def stop(self): self._stop_thread = True # put a task to assure to wake up the thread self.inf.add_ctxt_tasks([(-10, 0, None, None)]) - ConfManager.logger.debug( - "Inf ID: " + str(self.inf.id) + ": Stop Configuration thread.") + self.log_debug("Stop Configuration thread.") if self.ansible_process and self.ansible_process.is_alive(): - ConfManager.logger.debug( - "Inf ID: " + str(self.inf.id) + ": Stopping pending Ansible process.") + self.log_debug("Stopping pending Ansible process.") self.ansible_process.terminate() def check_vm_ips(self, timeout=Config.WAIT_RUNNING_VM_TIMEOUT): @@ -148,8 +139,8 @@ def check_vm_ips(self, timeout=Config.WAIT_RUNNING_VM_TIMEOUT): # If the VM is not in a "running" state, ignore it if vm.state in VirtualMachine.NOT_RUNNING_STATES: - ConfManager.logger.warn("Inf ID: " + str(self.inf.id) + ": The VM ID: " + str( - vm.id) + " is not running, do not wait it to have an IP.") + self.log_warn("The VM ID: " + str(vm.id) + + " is not running, do not wait it to have an IP.") continue if vm.hasPublicNet(): @@ -164,8 +155,7 @@ def check_vm_ips(self, timeout=Config.WAIT_RUNNING_VM_TIMEOUT): break if not success: - ConfManager.logger.warn( - "Inf ID: " + str(self.inf.id) + ": Error waiting all the VMs to have a correct IP") + self.log_warn("Error waiting all the VMs to have a correct IP") wait += Config.CONFMAMAGER_CHECK_STATE_INTERVAL time.sleep(Config.CONFMAMAGER_CHECK_STATE_INTERVAL) else: @@ -178,26 +168,22 @@ def kill_ctxt_processes(self): Kill all the ctxt processes """ for vm in self.inf.get_vm_list(): - ConfManager.logger.debug( - "Inf ID: " + str(self.inf.id) + ": Killing ctxt processes.") + self.log_debug("Killing ctxt processes.") vm.kill_check_ctxt_process() def run(self): - ConfManager.logger.debug( - "Inf ID: " + str(self.inf.id) + ": Starting the ConfManager Thread") + self.log_debug("Starting the ConfManager Thread") last_step = None vms_configuring = {} while not self._stop_thread: if self.init_time + self.max_ctxt_time < time.time(): - ConfManager.logger.debug( - "Inf ID: " + str(self.inf.id) + ": Max contextualization time passed. Exit thread.") + self.log_debug("Max contextualization time passed. Exit thread.") # Kill the ansible processes self.kill_ctxt_processes() if self.ansible_process and self.ansible_process.is_alive(): - ConfManager.logger.debug( - "Inf ID: " + str(self.inf.id) + ": Stopping pending Ansible process.") + self.log_debug("Stopping pending Ansible process.") self.ansible_process.terminate() return @@ -213,15 +199,14 @@ def run(self): # stop the thread if the stop method has been called if self._stop_thread: - ConfManager.logger.debug( - "Inf ID: " + str(self.inf.id) + ": Exit Configuration thread.") + self.log_debug("Exit Configuration thread.") return # if this task is from a next step if last_step is not None and last_step < step: if vm.is_configured() is False: - ConfManager.logger.debug("Inf ID: " + str(self.inf.id) + ": Configuration process of step " + str( - last_step) + " failed, ignoring tasks of later steps.") + self.log_debug("Configuration process of step " + str(last_step) + + " failed, ignoring tasks of later steps.") else: # Add the task again to the queue only if the last step was # OK @@ -229,28 +214,25 @@ def run(self): # If there are any process running of last step, wait if last_step in vms_configuring and len(vms_configuring[last_step]) > 0: - ConfManager.logger.debug("Inf ID: " + str(self.inf.id) + ": Waiting processes of step " + - str(last_step) + " to finish.") + self.log_debug("Waiting processes of step " + str(last_step) + " to finish.") time.sleep(Config.CONFMAMAGER_CHECK_STATE_INTERVAL) else: # if not, update the step, to go ahead with the new # step - ConfManager.logger.debug("Inf ID: " + str(self.inf.id) + ": Step " + str( - last_step) + " finished. Go to step: " + str(step)) + self.log_debug("Step " + str(last_step) + " finished. Go to step: " + str(step)) last_step = step else: if isinstance(vm, VirtualMachine): if vm.destroy: - ConfManager.logger.warn("Inf ID: " + str(self.inf.id) + ": VM ID " + str( - vm.im_id) + " has been destroyed. Not launching new tasks for it.") + self.log_warn("VM ID " + str(vm.im_id) + + " has been destroyed. Not launching new tasks for it.") elif vm.is_configured() is False: - ConfManager.logger.debug("Inf ID: " + str(self.inf.id) + ": Configuration process of step " + - str(last_step) + " failed, ignoring tasks of later steps.") + self.log_debug("Configuration process of step " + + str(last_step) + " failed, ignoring tasks of later steps.") # Check that the VM has no other ansible process # running elif vm.ctxt_pid: - ConfManager.logger.debug("Inf ID: " + str(self.inf.id) + ": VM ID " + - str(vm.im_id) + " has running processes, wait.") + self.log_debug("VM ID " + str(vm.im_id) + " has running processes, wait.") # If there are, add the tasks again to the queue # Set the priority to a higher number to decrease the # priority enabling to select other items of the queue @@ -307,22 +289,19 @@ def launch_ctxt_agent(self, vm, tasks): ip = vm.getPrivateIP() if not ip: - ConfManager.logger.error("Inf ID: " + str(self.inf.id) + - ": VM with ID %s (%s) does not have an IP!!. " - "We cannot launch the ansible process!!" % (str(vm.im_id), vm.id)) + self.log_error("VM with ID %s (%s) does not have an IP!!. " + "We cannot launch the ansible process!!" % (str(vm.im_id), vm.id)) else: remote_dir = Config.REMOTE_CONF_DIR + "/" + \ str(self.inf.id) + "/" + ip + "_" + \ str(vm.getRemoteAccessPort()) tmp_dir = tempfile.mkdtemp() - ConfManager.logger.debug( - "Inf ID: " + str(self.inf.id) + ": Create the configuration file for the contextualization agent") + self.log_debug("Create the configuration file for the contextualization agent") conf_file = tmp_dir + "/config.cfg" self.create_vm_conf_file(conf_file, vm, tasks, remote_dir) - ConfManager.logger.debug( - "Inf ID: " + str(self.inf.id) + ": Copy the contextualization agent config file") + self.log_debug("Copy the contextualization agent config file") # Copy the contextualization agent config file ssh = vm.get_ssh_ansible_master() @@ -342,18 +321,15 @@ def launch_ctxt_agent(self, vm, tasks): " > " + remote_dir + "/stdout" + " 2> " + remote_dir + "/stderr < /dev/null & echo -n $!") - ConfManager.logger.debug("Inf ID: " + str(self.inf.id) + ": Ansible process to configure " + - str(vm.im_id) + " launched with pid: " + pid) + self.log_debug("Ansible process to configure " + str(vm.im_id) + " launched with pid: " + pid) vm.ctxt_pid = pid vm.launch_check_ctxt_process() else: - ConfManager.logger.warn("Inf ID: " + str(self.inf.id) + ": Ansible process to configure " + - str(vm.im_id) + " NOT launched") + self.log_warn("Ansible process to configure " + str(vm.im_id) + " NOT launched") except: pid = None - ConfManager.logger.exception("Inf ID: " + str(self.inf.id) + ": Error launching the ansible process " - "to configure VM with ID %s" % str(vm.im_id)) + self.log_exception("Error launching the ansible process to configure VM with ID %s" % str(vm.im_id)) finally: if tmp_dir: shutil.rmtree(tmp_dir, ignore_errors=True) @@ -371,8 +347,7 @@ def generate_inventory(self, tmp_dir): """ Generate the ansible inventory file """ - ConfManager.logger.debug( - "Inf ID: " + str(self.inf.id) + ": create the ansible configuration file") + self.log_debug("Create the ansible configuration file") res_filename = "hosts" ansible_file = tmp_dir + "/" + res_filename out = open(ansible_file, 'w') @@ -414,13 +389,13 @@ def generate_inventory(self, tmp_dir): ip = vm.getPrivateIP() if not ip: - ConfManager.logger.warn("Inf ID: " + str(self.inf.id) + ": The VM ID: " + str( - vm.id) + " does not have an IP. It will not be included in the inventory file.") + self.log_warn("The VM ID: " + str(vm.id) + + " does not have an IP. It will not be included in the inventory file.") continue if vm.state in VirtualMachine.NOT_RUNNING_STATES: - ConfManager.logger.warn("Inf ID: " + str(self.inf.id) + ": The VM ID: " + str( - vm.id) + " is not running. It will not be included in the inventory file.") + self.log_warn("The VM ID: " + str(vm.id) + + " is not running. It will not be included in the inventory file.") continue if vm.getOS().lower() == "windows": @@ -533,8 +508,8 @@ def generate_etc_hosts(self, tmp_dir): ip = vm.getPrivateIP() if not ip: - ConfManager.logger.warn("Inf ID: " + str(self.inf.id) + ": The VM ID: " + str( - vm.id) + " does not have an IP. It will not be included in the /etc/hosts file.") + self.log_warn("The VM ID: " + str(vm.id) + + " does not have an IP. It will not be included in the /etc/hosts file.") continue for i in range(vm.getNumNetworkIfaces()): @@ -544,12 +519,11 @@ def generate_etc_hosts(self, tmp_dir): hosts_out.write(vm.getIfaceIP( i) + " " + nodename + "." + nodedom + " " + nodename + "\r\n") else: - ConfManager.logger.warn("Inf ID: %s: Net interface %d request a name, " - "but it does not have an IP." % (self.inf.id, i)) + self.log_warn("Net interface %d request a name, but it does not have an IP." % i) for j in range(vm.getNumNetworkIfaces()): if vm.getIfaceIP(j): - ConfManager.logger.warn("Setting the IP of the iface %d." % j) + self.log_warn("Setting the IP of the iface %d." % j) hosts_out.write(vm.getIfaceIP( j) + " " + nodename + "." + nodedom + " " + nodename + "\r\n") break @@ -740,8 +714,7 @@ def configure_master(self): time.sleep(cont * 5) cont += 1 try: - ConfManager.logger.info( - "Inf ID: " + str(self.inf.id) + ": Start the contextualization process.") + self.log_info("Start the contextualization process.") if self.inf.radl.ansible_hosts: configured_ok = True @@ -759,17 +732,14 @@ def configure_master(self): configured_ok = self.configure_ansible(ssh, tmp_dir) if not configured_ok: - ConfManager.logger.error( - "Inf ID: " + str(self.inf.id) + ": Error in the ansible installation process") + self.log_error("Error in the ansible installation process") if not self.inf.ansible_configured: self.inf.ansible_configured = False else: - ConfManager.logger.info( - "Inf ID: " + str(self.inf.id) + ": Ansible installation finished successfully") + self.log_info("Ansible installation finished successfully") remote_dir = Config.REMOTE_CONF_DIR + "/" + str(self.inf.id) + "/" - ConfManager.logger.debug( - "Inf ID: " + str(self.inf.id) + ": Copy the contextualization agent files") + self.log_debug("Copy the contextualization agent files") files = [] files.append((Config.IM_PATH + "/SSH.py", remote_dir + "/IM/SSH.py")) files.append((Config.CONTEXTUALIZATION_DIR + "/ctxt_agent.py", remote_dir + "/ctxt_agent.py")) @@ -805,8 +775,7 @@ def configure_master(self): success = configured_ok except Exception as ex: - ConfManager.logger.exception( - "Inf ID: " + str(self.inf.id) + ": Error in the ansible installation process") + self.log_exception("Error in the ansible installation process") self.inf.add_cont_msg( "Error in the ansible installation process: " + str(ex)) if not self.inf.ansible_configured: @@ -833,8 +802,7 @@ def wait_master(self): - Wait it to boot and has the SSH port open """ if self.inf.radl.ansible_hosts: - ConfManager.logger.debug("Inf ID: " + str(self.inf.id) + - ": Usign ansible host: " + self.inf.radl.ansible_hosts[0].getHost()) + self.log_debug("Usign ansible host: " + self.inf.radl.ansible_hosts[0].getHost()) self.inf.set_configured(True) return True @@ -853,41 +821,38 @@ def wait_master(self): if not self.inf.vm_master: # If there are not a valid master VM, exit - ConfManager.logger.error("Inf ID: " + str(self.inf.id) + ": No correct Master VM found. Exit") + self.log_error("No correct Master VM found. Exit") self.inf.add_cont_msg("Contextualization Error: No correct Master VM found. Check if there a " "linux VM with Public IP and connected with the rest of VMs.") self.inf.set_configured(False) return - ConfManager.logger.info("Inf ID: " + str(self.inf.id) + ": Wait the master VM to be running") + self.log_info("Wait the master VM to be running") self.inf.add_cont_msg("Wait master VM to boot") all_running = self.wait_vm_running(self.inf.vm_master, Config.WAIT_RUNNING_VM_TIMEOUT, True) if not all_running: - ConfManager.logger.error("Inf ID: " + str(self.inf.id) + - ": Error Waiting the Master VM to boot, exit") + self.log_error("Error Waiting the Master VM to boot, exit") self.inf.add_cont_msg("Contextualization Error: Error Waiting the Master VM to boot") self.inf.set_configured(False) return # To avoid problems with the known hosts of previous calls if os.path.isfile(os.path.expanduser("~/.ssh/known_hosts")): - ConfManager.logger.debug("Remove " + os.path.expanduser("~/.ssh/known_hosts")) + self.log_debug("Remove " + os.path.expanduser("~/.ssh/known_hosts")) os.remove(os.path.expanduser("~/.ssh/known_hosts")) self.inf.add_cont_msg("Wait master VM to have the SSH active.") is_connected, msg = self.wait_vm_ssh_acccess(self.inf.vm_master, Config.WAIT_SSH_ACCCESS_TIMEOUT) if not is_connected: - ConfManager.logger.error("Inf ID: " + str(self.inf.id) + - ": Error Waiting the Master VM to have the SSH active, exit: " + - msg) + self.log_error("Error Waiting the Master VM to have the SSH active, exit: " + msg) self.inf.add_cont_msg("Contextualization Error: Error Waiting the Master VM to have the SSH" " active: " + msg) self.inf.set_configured(False) return - ConfManager.logger.info("Inf ID: " + str(self.inf.id) + ": VMs available.") + self.log_info("VMs available.") # Check and change if necessary the credentials of the master # vm @@ -901,8 +866,7 @@ def wait_master(self): self.inf.set_configured(True) except: - ConfManager.logger.exception( - "Inf ID: " + str(self.inf.id) + ": Error waiting the master VM to be running") + self.log_exception("Error waiting the master VM to be running") self.inf.set_configured(False) else: self.inf.set_configured(True) @@ -920,8 +884,7 @@ def generate_playbooks_and_hosts(self): # Get the groups for the different VM types vm_group = self.inf.get_vm_list_by_system_name() - ConfManager.logger.debug( - "Inf ID: " + str(self.inf.id) + ": Generating YAML, hosts and inventory files.") + self.log_debug("Generating YAML, hosts and inventory files.") # Create the other configure sections (it may be included in other # configure) filenames = [] @@ -973,8 +936,7 @@ def generate_playbooks_and_hosts(self): recipe_files.append((tmp_dir + "/" + f, remote_dir + "/" + f)) self.inf.add_cont_msg("Copying YAML, hosts and inventory files.") - ConfManager.logger.debug( - "Inf ID: " + str(self.inf.id) + ": Copying YAML files.") + self.log_debug("Copying YAML files.") if self.inf.radl.ansible_hosts: for ansible_host in self.inf.radl.ansible_hosts: (user, passwd, private_key) = ansible_host.getCredentialValues() @@ -990,8 +952,7 @@ def generate_playbooks_and_hosts(self): self.inf.set_configured(True) except Exception as ex: self.inf.set_configured(False) - ConfManager.logger.exception( - "Inf ID: " + str(self.inf.id) + ": Error generating playbooks.") + self.log_exception("Error generating playbooks.") self.inf.add_cont_msg("Error generating playbooks: " + str(ex)) finally: if tmp_dir: @@ -1005,13 +966,11 @@ def relaunch_vm(self, vm, failed_cloud=False): removed = IM.InfrastructureManager.InfrastructureManager.RemoveResource( self.inf.id, vm.im_id, self.auth) except: - ConfManager.logger.exception( - "Inf ID: " + str(self.inf.id) + ": Error removing a failed VM.") + self.log_exception("Error removing a failed VM.") removed = 0 if removed != 1: - ConfManager.logger.error( - "Inf ID: " + str(self.inf.id) + ": Error removing a failed VM. Not launching a new one.") + self.log_error("Error removing a failed VM. Not launching a new one.") return new_radl = "" @@ -1047,27 +1006,22 @@ def wait_vm_running(self, vm, timeout, relaunch=False): if vm.state == VirtualMachine.RUNNING: return True elif vm.state == VirtualMachine.FAILED: - ConfManager.logger.warn( - "Inf ID: " + str(self.inf.id) + ": VM " + str(vm.id) + " is FAILED") + self.log_warn("VM " + str(vm.id) + " is FAILED") if relaunch and retries < Config.MAX_VM_FAILS: - ConfManager.logger.info( - "Inf ID: " + str(self.inf.id) + ": Launching new VM") + self.log_info("Launching new VM") self.relaunch_vm(vm, True) # Set the wait counter to 0 wait = 0 retries += 1 else: - ConfManager.logger.error( - "Inf ID: " + str(self.inf.id) + ": Relaunch is not enabled. Exit") + self.log_error("Relaunch is not enabled. Exit") return False else: - ConfManager.logger.warn( - "Inf ID: " + str(self.inf.id) + ": VM deleted by the user, Exit") + self.log_warn("VM deleted by the user, Exit") return False - ConfManager.logger.debug( - "Inf ID: " + str(self.inf.id) + ": VM " + str(vm.id) + " is not running yet.") + self.log_debug("VM " + str(vm.id) + " is not running yet.") time.sleep(delay) wait += delay @@ -1083,19 +1037,16 @@ def wait_vm_running(self, vm, timeout, relaunch=False): if vm.state == VirtualMachine.RUNNING: return True else: - ConfManager.logger.warn( - "VM " + str(vm.id) + " timeout") + self.log_warn("VM " + str(vm.id) + " timeout") if relaunch: - ConfManager.logger.info("Launch a new VM") + self.log_info("Launch a new VM") self.relaunch_vm(vm) else: - ConfManager.logger.error( - "Relaunch is not available. Exit") + self.log_error("Relaunch is not available. Exit") return False else: - ConfManager.logger.warn( - "Inf ID: " + str(self.inf.id) + ": VM deleted by the user, Exit") + self.log_warn("VM deleted by the user, Exit") return False # Timeout, return False @@ -1123,36 +1074,33 @@ def wait_vm_ssh_acccess(self, vm, timeout): else: vm.update_status(self.auth) if vm.state == VirtualMachine.FAILED: - ConfManager.logger.debug("Inf ID: " + str(self.inf.id) + ": " + 'VM: ' + - str(vm.id) + " is in state Failed. Does not wait for SSH.") + self.log_debug('VM: ' + str(vm.id) + " is in state Failed. Does not wait for SSH.") return False, "VM Failure." ip = vm.getPublicIP() if ip is not None: ssh = vm.get_ssh() - ConfManager.logger.debug("Inf ID: " + str(self.inf.id) + ": " + 'SSH Connecting with: ' + - ip + ' to the VM: ' + str(vm.id)) + self.log_debug('SSH Connecting with: ' + ip + ' to the VM: ' + str(vm.id)) try: connected = ssh.test_connectivity(5) except AuthenticationException: - ConfManager.logger.warn("Error connecting with ip: " + ip + " incorrect credentials.") + self.log_warn("Error connecting with ip: " + ip + " incorrect credentials.") auth_errors += 1 if auth_errors >= auth_error_retries: - ConfManager.logger.error("Too many authentication errors") + self.log_error("Too many authentication errors") return False, "Error connecting with ip: " + ip + " incorrect credentials." if connected: - ConfManager.logger.debug("Inf ID: " + str(self.inf.id) + ": " + 'Works!') + self.log_debug('Works!') return True, "" else: - ConfManager.logger.debug("Inf ID: " + str(self.inf.id) + ": " + 'do not connect, wait ...') + self.log_debug('do not connect, wait ...') wait += delay time.sleep(delay) else: - ConfManager.logger.debug("Inf ID: " + str(self.inf.id) + ": " + 'VM ' + - str(vm.id) + ' with no IP') + self.log_debug('VM ' + str(vm.id) + ' with no IP') # Update the VM info and wait to have a valid public IP wait += delay time.sleep(delay) @@ -1193,7 +1141,7 @@ def change_master_credentials(self, ssh): # only change to the new password if there are a previous # passwd value if passwd and new_passwd: - ConfManager.logger.info("Changing password to master VM") + self.log_info("Changing password to master VM") (out, err, code) = ssh.execute('echo "' + passwd + '" | sudo -S bash -c \'echo "' + user + ':' + new_passwd + '" | /usr/sbin/chpasswd && echo "OK"\' 2> /dev/null') @@ -1202,13 +1150,13 @@ def change_master_credentials(self, ssh): change_creds = True ssh.password = new_passwd else: - ConfManager.logger.error("Error changing password to master VM. " + out + err) + self.log_error("Error changing password to master VM. " + out + err) if new_public_key and new_private_key: - ConfManager.logger.info("Changing public key to master VM") + self.log_info("Changing public key to master VM") (out, err, code) = ssh.execute_timeout('echo ' + new_public_key + ' >> .ssh/authorized_keys', 5) if code != 0: - ConfManager.logger.error("Error changing public key to master VM. " + out + err) + self.log_error("Error changing public key to master VM. " + out + err) else: change_creds = True ssh.private_key = new_private_key @@ -1216,7 +1164,7 @@ def change_master_credentials(self, ssh): if change_creds: self.inf.vm_master.info.systems[0].updateNewCredentialValues() except: - ConfManager.logger.exception("Error changing credentials to master VM.") + self.log_exception("Error changing credentials to master VM.") return change_creds @@ -1249,8 +1197,7 @@ def call_ansible(self, tmp_dir, inventory, playbook, ssh): os.symlink(os.path.abspath( Config.RECIPES_DIR + "/utils"), tmp_dir + "/utils") - ConfManager.logger.debug( - "Inf ID: " + str(self.inf.id) + ": " + 'Lanzamos ansible.') + self.log_debug('Launching Ansible process.') result = Queue() # store the process to terminate it later is Ansible does not finish correctly self.ansible_process = AnsibleThread(result, StringIO(), tmp_dir + "/" + playbook, None, 1, gen_pk_file, @@ -1260,37 +1207,44 @@ def call_ansible(self, tmp_dir, inventory, playbook, ssh): wait = 0 while self.ansible_process.is_alive(): if wait >= Config.ANSIBLE_INSTALL_TIMEOUT: - ConfManager.logger.error("Inf ID: " + str(self.inf.id) + ": " + - 'Timeout waiting Ansible process to finish') + self.log_error('Timeout waiting Ansible process to finish') try: # Try to assure that the are no ansible process running self.ansible_process.teminate() except: - ConfManager.logger.exception("Inf ID: " + str(self.inf.id) + ": " + - 'Problems terminating Ansible processes.') + self.log_exception('Problems terminating Ansible processes.') self.ansible_process = None return (False, "Timeout. Ansible process terminated.") else: - ConfManager.logger.debug("Inf ID: " + str(self.inf.id) + ": " + - 'Waiting Ansible process to finish ' - '(%d/%d).' % (wait, Config.ANSIBLE_INSTALL_TIMEOUT)) + self.log_debug('Waiting Ansible process to finish (%d/%d).' % (wait, Config.ANSIBLE_INSTALL_TIMEOUT)) time.sleep(Config.CHECK_CTXT_PROCESS_INTERVAL) wait += Config.CHECK_CTXT_PROCESS_INTERVAL + + self.log_debug('Ansible process finished.') + + try: + timeout = Config.ANSIBLE_INSTALL_TIMEOUT - wait + if timeout < Config.CHECK_CTXT_PROCESS_INTERVAL: + timeout = Config.CHECK_CTXT_PROCESS_INTERVAL + self.log_debug('Get the result with a timeout of %d seconds.' % timeout) + _, (return_code, _), output = result.get(timeout=timeout) + msg = output.getvalue() + except: + self.log_exception('Error getting ansible results.') + return_code = 1 + msg = "Error getting ansible results." + try: # Try to assure that the are no ansible process running self.ansible_process.teminate() except: - ConfManager.logger.exception("Inf ID: " + str(self.inf.id) + ": " + - 'Problems terminating Ansible processes.') - pass + self.log_exception('Problems terminating Ansible processes.') self.ansible_process = None - _, (return_code, _), output = result.get() - if return_code == 0: - return (True, output.getvalue()) + return (True, msg) else: - return (False, output.getvalue()) + return (False, msg) def add_ansible_header(self, host, os): """ @@ -1359,8 +1313,7 @@ def configure_ansible(self, ssh, tmp_dir): self.inf.add_cont_msg( "Creating and copying Ansible playbook files") - ConfManager.logger.debug("Inf ID: " + str(self.inf.id) + - ": Preparing Ansible playbook to copy Ansible modules: " + str(modules)) + self.log_debug("Preparing Ansible playbook to copy Ansible modules: " + str(modules)) ssh.sftp_mkdir(Config.REMOTE_CONF_DIR) ssh.sftp_mkdir(Config.REMOTE_CONF_DIR + "/" + str(self.inf.id) + "/") @@ -1368,8 +1321,7 @@ def configure_ansible(self, ssh, tmp_dir): for galaxy_name in modules: if galaxy_name: - ConfManager.logger.debug( - "Inf ID: " + str(self.inf.id) + ": Install " + galaxy_name + " with ansible-galaxy.") + self.log_debug("Install " + galaxy_name + " with ansible-galaxy.") self.inf.add_cont_msg( "Galaxy role " + galaxy_name + " detected setting to install.") @@ -1404,35 +1356,29 @@ def configure_ansible(self, ssh, tmp_dir): self.inf.add_cont_msg("Performing preliminary steps to configure Ansible.") - ConfManager.logger.debug( - "Inf ID: " + str(self.inf.id) + ": Remove requiretty in sshd config") + self.log_debug("Remove requiretty in sshd config") try: cmd = "sudo -S sed -i 's/.*requiretty$/#Defaults requiretty/' /etc/sudoers" if ssh.password: cmd = "echo '" + ssh.password + "' | " + cmd (stdout, stderr, _) = ssh.execute(cmd, 120) - ConfManager.logger.debug( - "Inf ID: " + str(self.inf.id) + ": " + stdout + stderr) + self.log_debug(stdout + "\n" + stderr) except: - ConfManager.logger.exception("Inf ID: " + str(self.inf.id) + ": Error remove requiretty. Ignoring.") + self.log_exception("Error removing requiretty. Ignoring.") self.inf.add_cont_msg("Configure Ansible in the master VM.") - ConfManager.logger.debug( - "Inf ID: " + str(self.inf.id) + ": Call Ansible to (re)configure in the master node") + self.log_debug("Call Ansible to (re)configure in the master node") (success, msg) = self.call_ansible( tmp_dir, "inventory.cfg", ConfManager.MASTER_YAML, ssh) if not success: - ConfManager.logger.error("Inf ID: " + str(self.inf.id) + - ": Error configuring master node: " + msg + "\n\n") + self.log_error("Error configuring master node: " + msg + "\n\n") self.inf.add_cont_msg("Error configuring the master VM: " + msg + " " + tmp_dir) else: - ConfManager.logger.debug("Inf ID: " + str(self.inf.id) + - ": Ansible successfully configured in the master VM:\n" + msg + "\n\n") + self.log_debug("Ansible successfully configured in the master VM:\n" + msg + "\n\n") self.inf.add_cont_msg("Ansible successfully configured in the master VM.") except Exception as ex: - ConfManager.logger.exception( - "Inf ID: " + str(self.inf.id) + ": Error configuring master node.") + self.log_exception("Error configuring master node.") self.inf.add_cont_msg("Error configuring master node: " + str(ex)) success = False @@ -1448,8 +1394,8 @@ def create_general_conf_file(self, conf_file, vm_list): conf_data['vms'] = [] for vm in vm_list: if vm.state in VirtualMachine.NOT_RUNNING_STATES: - ConfManager.logger.warn("Inf ID: " + str(self.inf.id) + ": The VM ID: " + str( - vm.id) + " is not running, do not include in the general conf file.") + self.log_warn("The VM ID: " + str(vm.id) + + " is not running, do not include in the general conf file.") else: vm_conf_data = {} vm_conf_data['id'] = vm.im_id @@ -1479,8 +1425,8 @@ def create_general_conf_file(self, conf_file, vm_list): if not vm_conf_data['ip']: # if the vm does not have an IP, do not iclude it to avoid # errors configurin gother VMs - ConfManager.logger.warn("Inf ID: " + str(self.inf.id) + ": The VM ID: " + str( - vm.id) + " does not have an IP, do not include in the general conf file.") + self.log_warn("The VM ID: " + str(vm.id) + + " does not have an IP, do not include in the general conf file.") else: conf_data['vms'].append(vm_conf_data) @@ -1510,13 +1456,11 @@ def create_vm_conf_file(self, conf_file, vm, tasks, remote_dir): conf_data['changed_pass'] = True conf_out = open(conf_file, 'w') - ConfManager.logger.debug( - "Ctxt agent vm configuration file: " + json.dumps(conf_data)) + self.log_debug("Ctxt agent vm configuration file: " + json.dumps(conf_data)) json.dump(conf_data, conf_out, indent=2) conf_out.close() - @staticmethod - def mergeYAML(yaml1, yaml2): + def mergeYAML(self, yaml1, yaml2): """ Merge two ansible yaml docs @@ -1531,16 +1475,14 @@ def mergeYAML(yaml1, yaml2): if not isinstance(yamlo1o, dict): yamlo1o = {} except Exception: - ConfManager.logger.exception( - "Error parsing YAML: " + yaml1 + "\n Ignore it") + self.log_exception("Error parsing YAML: " + yaml1 + "\n Ignore it") try: yamlo2s = yaml.load(yaml2) if not isinstance(yamlo2s, list) or any([not isinstance(d, dict) for d in yamlo2s]): yamlo2s = {} except Exception: - ConfManager.logger.exception( - "Error parsing YAML: " + yaml2 + "\n Ignore it") + self.log_exception("Error parsing YAML: " + yaml2 + "\n Ignore it") yamlo2s = {} if not yamlo2s and not yamlo1o: @@ -1571,3 +1513,22 @@ def mergeYAML(yaml1, yaml2): result.append(yamlo1) return yaml.dump(result, default_flow_style=False, explicit_start=True, width=256) + + def log_msg(self, level, msg, exc_info=0): + msg = "Inf ID: %s: %s" % (self.inf.id, msg) + self.logger.log(level, msg, exc_info=exc_info) + + def log_error(self, msg): + self.log_msg(logging.ERROR, msg) + + def log_debug(self, msg): + self.log_msg(logging.DEBUG, msg) + + def log_warn(self, msg): + self.log_msg(logging.WARNING, msg) + + def log_exception(self, msg): + self.log_msg(logging.ERROR, msg, exc_info=1) + + def log_info(self, msg): + self.log_msg(logging.INFO, msg) diff --git a/IM/InfrastructureInfo.py b/IM/InfrastructureInfo.py index 672f5d73e..181577ac5 100644 --- a/IM/InfrastructureInfo.py +++ b/IM/InfrastructureInfo.py @@ -165,13 +165,6 @@ def deserialize_auth(str_data): newinf.auth = Authentication.deserialize(dic['auth']) return newinf - def get_next_vm_id(self): - """Get the next vm id available.""" - with self._lock: - vmid = self.vm_id - self.vm_id += 1 - return vmid - def delete(self): """ Set this Inf as deleted @@ -206,6 +199,8 @@ def add_vm(self, vm): Add, and assigns a new VM ID to the infrastructure """ with self._lock: + # Set the ID of the pos in the list + vm.im_id = len(self.vm_list) self.vm_list.append(vm) def add_cont_msg(self, msg): diff --git a/IM/InfrastructureManager.py b/IM/InfrastructureManager.py index b2cdf1891..418dabb0d 100644 --- a/IM/InfrastructureManager.py +++ b/IM/InfrastructureManager.py @@ -151,141 +151,87 @@ def root(n): return deploy_groups @staticmethod - def _launch_vm(sel_inf, task, deploy_group, auth, deployed_vm, - cancel_deployment, exceptions, cloud_with_errors): - """ - Launch a VM in a cloud provider. - In case of failure it will try with the next provider defined (if any) - """ + def _launch_group(sel_inf, deploy_group, deploys_group_cloud_list, cloud_list, concrete_systems, + radl, auth, deployed_vm, cancel_deployment): + """Launch a group of deploys together.""" + + if not deploy_group: + InfrastructureManager.logger.warning("No VMs to deploy!") + return + if not deploys_group_cloud_list: + cancel_deployment.append(Exception("No cloud provider available")) + return all_ok = False - # Each task_cloud represents a task to launch the VM in a cloud provider - # if some fails we will try to use the next one - for task_cloud in task: - cloud, deploy, launch_radl, requested_radl, remain_vm, vm_type = task_cloud - - if id(deploy_group) in cloud_with_errors and cloud.cloud.id in cloud_with_errors[id(deploy_group)]: - InfrastructureManager.logger.debug("Cloud %s has failed for this deployment group. " - "Do not use it to launch other VMs of the same group") - continue + exceptions = [] + for cloud_id in deploys_group_cloud_list: + cloud = cloud_list[cloud_id] + all_ok = True + for deploy in deploy_group: + remain_vm, fail_cont = deploy.vm_number, 0 + while (remain_vm > 0 and fail_cont < Config.MAX_VM_FAILS and not cancel_deployment): + concrete_system = concrete_systems[cloud_id][deploy.id][0] + if not concrete_system: + InfrastructureManager.logger.error( + "Error, no concrete system to deploy: " + deploy.id + " in cloud: " + + cloud_id + ". Check if a correct image is being used") + exceptions.append("Error, no concrete system to deploy: " + deploy.id + + " in cloud: " + cloud_id + ". Check if a correct image is being used") + break - fail_cont = 0 - while (remain_vm > 0 and fail_cont < Config.MAX_VM_FAILS and not cancel_deployment): - InfrastructureManager.logger.debug("Launching %d VMs of type %s" % (remain_vm, vm_type)) - try: - launched_vms = cloud.cloud.getCloudConnector(sel_inf).launch( - sel_inf, launch_radl, requested_radl, remain_vm, auth) - except Exception as e: - InfrastructureManager.logger.exception("Error launching some of the VMs: %s" % e) - exceptions.append("Error launching the VMs of type %s to cloud ID %s" - " of type %s. Cloud Provider Error: %s" % (vm_type, - cloud.cloud.id, - cloud.cloud.type, e)) - launched_vms = [] - - all_ok = True - for success, launched_vm in launched_vms: - if success: - InfrastructureManager.logger.debug("VM successfully launched: %s" % str(launched_vm.id)) - deployed_vm.setdefault(deploy, []).append(launched_vm) - deploy.cloud_id = cloud.cloud.id - remain_vm -= 1 - else: - all_ok = False - InfrastructureManager.logger.warn("Error launching some of the VMs: %s" % str(launched_vm)) - exceptions.append("Error launching the VMs of type %s to cloud ID %s of type %s. %s" % ( - vm_type, cloud.cloud.id, cloud.cloud.type, str(launched_vm))) - if not isinstance(launched_vm, (str, unicode)): - cloud.finalize(launched_vm, auth) - - fail_cont += 1 - if remain_vm > 0 and fail_cont >= Config.MAX_VM_FAILS: - if id(deploy_group) not in cloud_with_errors: - cloud_with_errors[id(deploy_group)] = [] - cloud_with_errors[id(deploy_group)].append(cloud.cloud.id) - if cancel_deployment: - all_ok = False - break + (username, _, _, _) = concrete_system.getCredentialValues() + if not username: + raise IncorrectVMCrecentialsException( + "No username for deploy: " + deploy.id) + launch_radl = radl.clone() + launch_radl.systems = [concrete_system.clone()] + requested_radl = radl.clone() + requested_radl.systems = [radl.get_system_by_name(concrete_system.name)] + try: + InfrastructureManager.logger.debug( + "Launching %d VMs of type %s" % (remain_vm, concrete_system.name)) + launched_vms = cloud.cloud.getCloudConnector(sel_inf).launch( + sel_inf, launch_radl, requested_radl, remain_vm, auth) + except Exception as e: + InfrastructureManager.logger.exception("Error launching some of the VMs: %s" % e) + exceptions.append("Error launching the VMs of type %s to cloud ID %s" + " of type %s. Cloud Provider Error: %s" % (concrete_system.name, + cloud.cloud.id, + cloud.cloud.type, e)) + launched_vms = [] + for success, launched_vm in launched_vms: + if success: + InfrastructureManager.logger.debug( + "VM successfully launched: " + str(launched_vm.id)) + deployed_vm.setdefault( + deploy, []).append(launched_vm) + deploy.cloud_id = cloud_id + remain_vm -= 1 + else: + InfrastructureManager.logger.warn( + "Error launching some of the VMs: " + str(launched_vm)) + exceptions.append("Error launching the VMs of type %s to cloud ID %s of type %s. %s" % ( + concrete_system.name, cloud.cloud.id, cloud.cloud.type, str(launched_vm))) + if not isinstance(launched_vm, (str, unicode)): + cloud.finalize(launched_vm, auth) + fail_cont += 1 + if remain_vm > 0 or cancel_deployment: + all_ok = False + break if not all_ok: - # Something has failed, finalize the VMs created and try with other cloud provider (if avail) for deploy in deploy_group: for vm in deployed_vm.get(deploy, []): vm.finalize(auth) deployed_vm[deploy] = [] - else: - # All was OK so do not try with other cloud provider + if cancel_deployment or all_ok: break - if not all_ok and not cancel_deployment: msg = "" for i, e in enumerate(exceptions): - msg += "Attempt %d: %s\n" % (i + 1, str(e)) + msg += "Attempt " + str(i + 1) + ": " + str(e) + "\n" cancel_deployment.append( Exception("All machines could not be launched: \n%s" % msg)) - @staticmethod - def _launch_groups(sel_inf, deploy_groups, deploys_group_cloud_list_all, cloud_list, concrete_systems, - radl, auth, deployed_vm, cancel_deployment): - """Launch all groups of deploys together.""" - try: - tasks = [] - cloud_with_errors = {} - for deploy_group in deploy_groups: - deploys_group_cloud_list = deploys_group_cloud_list_all[id(deploy_group)] - if not deploy_group: - InfrastructureManager.logger.warning("No VMs to deploy!") - return - if not deploys_group_cloud_list: - cancel_deployment.append(Exception("No cloud provider available")) - return - exceptions = [] - for deploy in deploy_group: - task_cloud = [] - if deploy.vm_number > 0: - for cloud_id in deploys_group_cloud_list: - cloud = cloud_list[cloud_id] - concrete_system = concrete_systems[cloud_id][deploy.id][0] - if not concrete_system: - InfrastructureManager.logger.error( - "Error, no concrete system to deploy: " + deploy.id + " in cloud: " + - cloud_id + ". Check if a correct image is being used") - exceptions.append("Error, no concrete system to deploy: " + - deploy.id + ". Check if a correct image is being used.") - break - - (username, _, _, _) = concrete_system.getCredentialValues() - if not username: - raise IncorrectVMCrecentialsException("No username for deploy: " + deploy.id) - - launch_radl = radl.clone() - launch_radl.systems = [concrete_system.clone()] - requested_radl = radl.clone() - requested_radl.systems = [radl.get_system_by_name(concrete_system.name)] - task_cloud.append((cloud, deploy, launch_radl, requested_radl, - deploy.vm_number, concrete_system.name)) - else: - InfrastructureManager.logger.debug("deploy %s with 0 num. Ignoring." % deploy.id) - - if task_cloud: - tasks.append(task_cloud) - - if Config.MAX_SIMULTANEOUS_LAUNCHES > 1: - pool = ThreadPool(processes=Config.MAX_SIMULTANEOUS_LAUNCHES) - pool.map( - lambda task: InfrastructureManager._launch_vm(sel_inf, task, deploy_group, auth, - deployed_vm, cancel_deployment, exceptions, - cloud_with_errors), tasks) - pool.close() - else: - for task in tasks: - InfrastructureManager._launch_vm(sel_inf, task, deploy_group, auth, - deployed_vm, cancel_deployment, exceptions, - cloud_with_errors) - except Exception as e: - # Please, avoid exception to arrive to this level, because some virtual - # machine may lost. - cancel_deployment.append(e) - @staticmethod def get_infrastructure(inf_id, auth): """Return infrastructure info with some id if valid authorization provided.""" @@ -541,9 +487,13 @@ def AddResource(inf_id, radl_data, auth, context=True, failed_clouds=[]): # Sort by score the cloud providers # NOTE: consider fake deploys (vm_number == 0) deploys_group_cloud_list = {} + # reverse the list to use the reverse order in the sort function + # list of ordered clouds + + ordered_cloud_list = [c.id for c in CloudInfo.get_cloud_list(auth)] + ordered_cloud_list.reverse() for deploy_group in deploy_groups: - suggested_cloud_ids = list( - set([d.cloud_id for d in deploy_group if d.cloud_id])) + suggested_cloud_ids = list(set([d.cloud_id for d in deploy_group if d.cloud_id])) if len(suggested_cloud_ids) > 1: raise Exception("Two deployments that have to be launched in the same cloud provider " "are asked to be deployed in different cloud providers: %s" % deploy_group) @@ -568,22 +518,33 @@ def AddResource(inf_id, radl_data, auth, context=True, failed_clouds=[]): total += 1 scored_clouds.append((cloud_id, total)) - ordered_cloud_list = [c.id for c in CloudInfo.get_cloud_list(auth)] - # reverse the list to use the reverse order in the sort function - ordered_cloud_list.reverse() # Order the clouds first by the score and then using the cloud # order in the auth data - sorted_scored_clouds = sorted(scored_clouds, key=lambda x: ( - x[1], ordered_cloud_list.index(x[0])), reverse=True) - deploys_group_cloud_list[id(deploy_group)] = [ - c[0] for c in sorted_scored_clouds] + sorted_scored_clouds = sorted(scored_clouds, + key=lambda x: (x[1], ordered_cloud_list.index(x[0])), + reverse=True) + deploys_group_cloud_list[id(deploy_group)] = [c[0] for c in sorted_scored_clouds] # Launch every group in the same cloud provider deployed_vm = {} cancel_deployment = [] - InfrastructureManager._launch_groups(sel_inf, deploy_groups, deploys_group_cloud_list, - cloud_list, concrete_systems, radl, auth, - deployed_vm, cancel_deployment) + try: + if Config.MAX_SIMULTANEOUS_LAUNCHES > 1: + pool = ThreadPool(processes=Config.MAX_SIMULTANEOUS_LAUNCHES) + pool.map( + lambda ds: InfrastructureManager._launch_group(sel_inf, ds, deploys_group_cloud_list[id(ds)], + cloud_list, concrete_systems, radl, auth, + deployed_vm, cancel_deployment), deploy_groups) + pool.close() + else: + for ds in deploy_groups: + InfrastructureManager._launch_group(sel_inf, ds, deploys_group_cloud_list[id(ds)], + cloud_list, concrete_systems, radl, + auth, deployed_vm, cancel_deployment) + except Exception as e: + # Please, avoid exception to arrive to this level, because some virtual + # machine may lost. + cancel_deployment.append(e) # We make this to maintain the order of the VMs in the sel_inf.vm_list # according to the deploys shown in the RADL @@ -602,8 +563,7 @@ def AddResource(inf_id, radl_data, auth, context=True, failed_clouds=[]): msg = "" for e in cancel_deployment: msg += str(e) + "\n" - raise Exception( - "Some deploys did not proceed successfully: %s" % msg) + raise Exception("Some deploys did not proceed successfully: %s" % msg) for vm in new_vms: sel_inf.add_vm(vm) diff --git a/IM/VirtualMachine.py b/IM/VirtualMachine.py index bcbe09d6b..5dfdad430 100644 --- a/IM/VirtualMachine.py +++ b/IM/VirtualMachine.py @@ -62,10 +62,7 @@ def __init__(self, inf, cloud_id, cloud, info, requested_radl, cloud_connector=N """Infrastructure which this VM is part of""" self.id = cloud_id """The ID of the VM assigned by the cloud provider""" - if im_id is None: - self.im_id = inf.get_next_vm_id() - else: - self.im_id = im_id + self.im_id = im_id """The internal ID of the VM assigned by the IM""" self.cloud = cloud """CloudInfo object with the information about the cloud provider""" diff --git a/IM/connectors/Azure.py b/IM/connectors/Azure.py index 3335eefa4..376723950 100644 --- a/IM/connectors/Azure.py +++ b/IM/connectors/Azure.py @@ -14,7 +14,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import time +import uuid from IM.uriparse import uriparse from IM.VirtualMachine import VirtualMachine from .CloudConnector import CloudConnector @@ -342,7 +342,7 @@ def get_azure_vm_create_json(self, storage_account, vm_name, nics, radl, instanc system.updateNewCredentialValues() user_credentials = system.getCredentials() - os_disk_name = "osdisk-" + str(int(time.time() * 100)) + os_disk_name = "osdisk-" + str(uuid.uuid1()) return { 'location': location, @@ -474,18 +474,18 @@ def launch(self, inf, radl, requested_radl, num_vm, auth_data): res = [] i = 0 while i < num_vm: + group_name = None try: - # Create the VM to get the nodename - now = int(time.time() * 100) - vm = VirtualMachine(inf, None, self.cloud, radl, requested_radl, self) - group_name = "rg-%s-%d" % (inf.id, vm.im_id) - storage_account_name = "st%d%d" % (now, vm.im_id) + uid = str(uuid.uuid1()) + storage_account_name = "st-%s" % uid vm_name = radl.systems[0].getValue("instance_name") if vm_name: - vm_name = "%s%d" % (vm_name, now) + vm_name = "%s-%s" % (vm_name, uid) else: - vm_name = "userimage%d" % now + vm_name = "userimage-%s" % uid + + group_name = "rg-%s" % (vm_name) # Create resource group for the VM resource_client.resource_groups.create_or_update(group_name, {'location': location}) @@ -508,8 +508,7 @@ def launch(self, inf, radl, requested_radl, num_vm, auth_data): async_vm_creation = compute_client.virtual_machines.create_or_update(group_name, vm_name, vm_parameters) azure_vm = async_vm_creation.result() - # Set the cloud id to the VM - vm.id = group_name + '/' + vm_name + vm = VirtualMachine(inf, group_name + '/' + vm_name, self.cloud, radl, requested_radl, self) vm.info.systems[0].setValue('instance_id', group_name + '/' + vm_name) self.attach_data_disks(vm, storage_account_name, credentials, subscription_id, location) @@ -520,7 +519,8 @@ def launch(self, inf, radl, requested_radl, num_vm, auth_data): res.append((False, "Error creating the VM: " + str(ex))) # Delete Resource group and everything in it - resource_client.resource_groups.delete(group_name) + if group_name: + resource_client.resource_groups.delete(group_name) i += 1 diff --git a/IM/connectors/AzureClassic.py b/IM/connectors/AzureClassic.py index 061de021a..7e5d424e0 100644 --- a/IM/connectors/AzureClassic.py +++ b/IM/connectors/AzureClassic.py @@ -18,6 +18,7 @@ import requests import time import os +import uuid import tempfile from IM.xmlobject import XMLObject from IM.uriparse import uriparse @@ -318,7 +319,7 @@ def gen_data_disks(self, system, storage_account): disk_size = system.getFeature( "disk." + str(cont) + ".size").getValue('G') - disk_name = "datadisk-1-" + str(int(time.time() * 100)) + disk_name = "datadisk-1-" + str(uuid.uuid1()) disks += ''' @@ -436,7 +437,7 @@ def create_service(self, auth_data, region): """ Create a Azure Cloud Service and return the name """ - service_name = "IM-" + str(int(time.time() * 100)) + service_name = "IM-" + str(uuid.uuid1()) self.log_info("Create the service " + service_name + " in region: " + region) try: diff --git a/IM/connectors/Docker.py b/IM/connectors/Docker.py index 945b3928f..f68df3307 100644 --- a/IM/connectors/Docker.py +++ b/IM/connectors/Docker.py @@ -21,6 +21,7 @@ import socket import requests import random +import uuid from IM.uriparse import uriparse from IM.VirtualMachine import VirtualMachine from IM.config import Config @@ -183,7 +184,7 @@ def _generate_create_svc_request_data(self, image_name, outports, vm, ssh_port, if not name: name = "imsvc" - svc_data['Name'] = "%s-%d" % (name, int(time.time() * 100)) + svc_data['Name'] = "%s-%s" % (name, str(uuid.uuid1())) svc_data['TaskTemplate'] = {} svc_data['TaskTemplate']['ContainerSpec'] = {} svc_data['TaskTemplate']['ContainerSpec']['Image'] = image_name @@ -487,7 +488,7 @@ def _create_volumes(self, system, auth_data): # user device as volume name source = system.getValue("disk." + str(cont) + ".device") if not source: - source = "d-%d-%d" % (int(time.time() * 100), cont) + source = "d-%s-%d" % (str(uuid.uuid1()), cont) system.setValue("disk." + str(cont) + ".device", source) # if the name of the source starts with / we assume it is a bind, so do not create a volume diff --git a/IM/connectors/EC2.py b/IM/connectors/EC2.py index a69577c71..7c8bf3ccd 100644 --- a/IM/connectors/EC2.py +++ b/IM/connectors/EC2.py @@ -17,6 +17,7 @@ import time import base64 import os +import uuid try: import boto.ec2 @@ -401,7 +402,7 @@ def create_security_group(self, conn, inf, radl, vpc=None): def create_keypair(self, system, conn): # create the keypair - keypair_name = "im-" + str(int(time.time() * 100)) + keypair_name = "im-" + str(uuid.uuid1()) created = False try: diff --git a/IM/connectors/GCE.py b/IM/connectors/GCE.py index a26897030..094cac13a 100644 --- a/IM/connectors/GCE.py +++ b/IM/connectors/GCE.py @@ -15,6 +15,7 @@ # along with this program. If not, see . import time +import uuid import os try: @@ -426,10 +427,10 @@ def launch(self, inf, radl, requested_radl, num_vm, auth_data): res = [] if num_vm > 1: args['number'] = num_vm - args['base_name'] = "%s-%s" % (name.lower().replace("_", "-"), int(time.time() * 100)) + args['base_name'] = "%s-%s" % (name.lower().replace("_", "-"), str(uuid.uuid1())) nodes = driver.ex_create_multiple_nodes(**args) else: - args['name'] = "%s-%s" % (name.lower().replace("_", "-"), int(time.time() * 100)) + args['name'] = "%s-%s" % (name.lower().replace("_", "-"), str(uuid.uuid1())) nodes = [driver.create_node(**args)] for node in nodes: @@ -600,7 +601,7 @@ def attach_volumes(self, vm, node): "disk." + str(cont) + ".device") self.log_debug( "Creating a %d GB volume for the disk %d" % (int(disk_size), cont)) - volume_name = "im-%d" % int(time.time() * 100.0) + volume_name = "im-%s" % str(uuid.uuid1()) location = self.get_node_location(node) volume = node.driver.create_volume( diff --git a/IM/connectors/LibCloud.py b/IM/connectors/LibCloud.py index 0a28d1137..fdae04302 100644 --- a/IM/connectors/LibCloud.py +++ b/IM/connectors/LibCloud.py @@ -14,7 +14,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import time +import uuid try: from libcloud.compute.base import NodeImage, NodeAuthSSHKey @@ -224,7 +224,7 @@ def launch(self, inf, radl, requested_radl, num_vm, auth_data): args = {'size': instance_type, 'image': image, - 'name': "%s-%s" % (name, int(time.time() * 100))} + 'name': "%s-%s" % (name, str(uuid.uuid1()))} keypair = None public_key = system.getValue("disk.0.os.credentials.public_key") @@ -240,7 +240,7 @@ def launch(self, inf, radl, requested_radl, num_vm, auth_data): else: args["ex_keyname"] = keypair.name elif not system.getValue("disk.0.os.credentials.password"): - keypair_name = "im-%d" % int(time.time() * 100.0) + keypair_name = "im-%s" % str(uuid.uuid1()) keypair = driver.create_key_pair(keypair_name) system.setUserKeyCredentials( system.getCredentials().username, None, keypair.private_key) @@ -584,7 +584,7 @@ def attach_volumes(self, vm, node): if disk_device: disk_device = "/dev/" + disk_device self.log_debug("Creating a %d GB volume for the disk %d" % (int(disk_size), cont)) - volume_name = "im-%d" % int(time.time() * 100.0) + volume_name = "im-%s" % str(uuid.uuid1()) location = self.get_node_location(node) volume = node.driver.create_volume(int(disk_size), volume_name, location=location) diff --git a/contextualization/ctxt_agent.py b/contextualization/ctxt_agent.py index 03b7381c1..8edc8f0b2 100755 --- a/contextualization/ctxt_agent.py +++ b/contextualization/ctxt_agent.py @@ -184,7 +184,12 @@ def wait_thread(thread_data, output=None): """ thread, result = thread_data thread.join() - _, (return_code, hosts_with_errors), _ = result.get() + try: + _, (return_code, hosts_with_errors), _ = result.get(timeout=60) + except: + CtxtAgent.logger.exception('Error getting ansible results.') + return_code = -1 + hosts_with_errors = [] if output: if return_code == 0: diff --git a/doc/source/client.rst b/doc/source/client.rst index 1821541e7..537384175 100644 --- a/doc/source/client.rst +++ b/doc/source/client.rst @@ -165,9 +165,11 @@ keys are: used as the label in the *deploy* section in the RADL. * ``subscription_id`` indicates the subscription_id name associated to the credential. - This field is only used in the Azure and Azure Classic plugins. + This field is only used in the Azure and Azure Classic plugins. To create a user to use the Azure (ARM) + plugin check the documentation of the Azure python SDK: + `here `_ -OpenStack addicional fields +OpenStack additional fields ^^^^^^^^^^^^^^^^^^^^^^^^^^^ OpenStack has a set of additional fields to access a cloud site: diff --git a/test/unit/connectors/Azure.py b/test/unit/connectors/Azure.py index 23a5ac2fa..3afb1b8dd 100755 --- a/test/unit/connectors/Azure.py +++ b/test/unit/connectors/Azure.py @@ -202,8 +202,7 @@ def test_30_updateVMInfo(self, credentials, compute_client, network_client): azure_cloud = self.get_azure_cloud() inf = MagicMock() - inf.get_next_vm_id.return_value = 1 - vm = VirtualMachine(inf, "rg0/im0", azure_cloud.cloud, radl, radl, azure_cloud) + vm = VirtualMachine(inf, "rg0/im0", azure_cloud.cloud, radl, radl, azure_cloud, 1) instace_type = MagicMock() instace_type.name = "instance_type1" @@ -251,8 +250,7 @@ def test_40_stop(self, credentials, compute_client): azure_cloud = self.get_azure_cloud() inf = MagicMock() - inf.get_next_vm_id.return_value = 1 - vm = VirtualMachine(inf, "rg0/vm0", azure_cloud.cloud, "", "", azure_cloud) + vm = VirtualMachine(inf, "rg0/vm0", azure_cloud.cloud, "", "", azure_cloud, 1) success, _ = azure_cloud.stop(vm, auth) @@ -267,8 +265,7 @@ def test_50_start(self, credentials, compute_client): azure_cloud = self.get_azure_cloud() inf = MagicMock() - inf.get_next_vm_id.return_value = 1 - vm = VirtualMachine(inf, "rg0/vm0", azure_cloud.cloud, "", "", azure_cloud) + vm = VirtualMachine(inf, "rg0/vm0", azure_cloud.cloud, "", "", azure_cloud, 1) success, _ = azure_cloud.start(vm, auth) @@ -341,8 +338,7 @@ def test_55_alter(self, credentials, network_client, compute_client, storage_cli nclient.public_ip_addresses.get.return_value = pub_ip_res inf = MagicMock() - inf.get_next_vm_id.return_value = 1 - vm = VirtualMachine(inf, "rg0/vm0", azure_cloud.cloud, radl, radl, azure_cloud) + vm = VirtualMachine(inf, "rg0/vm0", azure_cloud.cloud, radl, radl, azure_cloud, 1) success, _ = azure_cloud.alterVM(vm, new_radl, auth) @@ -357,8 +353,7 @@ def test_60_finalize(self, credentials, resource_client): azure_cloud = self.get_azure_cloud() inf = MagicMock() - inf.get_next_vm_id.return_value = 1 - vm = VirtualMachine(inf, "rg0/vm0", azure_cloud.cloud, "", "", azure_cloud) + vm = VirtualMachine(inf, "rg0/vm0", azure_cloud.cloud, "", "", azure_cloud, 1) success, _ = azure_cloud.finalize(vm, auth) diff --git a/test/unit/connectors/AzureClassic.py b/test/unit/connectors/AzureClassic.py index b1aac934c..cbda40029 100644 --- a/test/unit/connectors/AzureClassic.py +++ b/test/unit/connectors/AzureClassic.py @@ -227,8 +227,7 @@ def test_30_updateVMInfo(self, requests): azure_cloud = self.get_azure_cloud() inf = MagicMock() - inf.get_next_vm_id.return_value = 1 - vm = VirtualMachine(inf, "1", azure_cloud.cloud, radl, radl, azure_cloud) + vm = VirtualMachine(inf, "1", azure_cloud.cloud, radl, radl, azure_cloud, 1) requests.side_effect = self.get_response @@ -245,8 +244,7 @@ def test_40_stop(self, sleep, requests): azure_cloud = self.get_azure_cloud() inf = MagicMock() - inf.get_next_vm_id.return_value = 1 - vm = VirtualMachine(inf, "1", azure_cloud.cloud, "", "", azure_cloud) + vm = VirtualMachine(inf, "1", azure_cloud.cloud, "", "", azure_cloud, 1) requests.side_effect = self.get_response @@ -263,8 +261,7 @@ def test_50_start(self, sleep, requests): azure_cloud = self.get_azure_cloud() inf = MagicMock() - inf.get_next_vm_id.return_value = 1 - vm = VirtualMachine(inf, "1", azure_cloud.cloud, "", "", azure_cloud) + vm = VirtualMachine(inf, "1", azure_cloud.cloud, "", "", azure_cloud, 1) requests.side_effect = self.get_response @@ -303,8 +300,7 @@ def test_55_alter(self, sleep, requests): azure_cloud = self.get_azure_cloud() inf = MagicMock() - inf.get_next_vm_id.return_value = 1 - vm = VirtualMachine(inf, "1", azure_cloud.cloud, radl, radl, azure_cloud) + vm = VirtualMachine(inf, "1", azure_cloud.cloud, radl, radl, azure_cloud, 1) requests.side_effect = self.get_response @@ -321,8 +317,7 @@ def test_60_finalize(self, sleep, requests): azure_cloud = self.get_azure_cloud() inf = MagicMock() - inf.get_next_vm_id.return_value = 1 - vm = VirtualMachine(inf, "1", azure_cloud.cloud, "", "", azure_cloud) + vm = VirtualMachine(inf, "1", azure_cloud.cloud, "", "", azure_cloud, 1) sleep.return_value = True requests.side_effect = self.get_response diff --git a/test/unit/connectors/Docker.py b/test/unit/connectors/Docker.py index 5ba874ecb..047e6b271 100755 --- a/test/unit/connectors/Docker.py +++ b/test/unit/connectors/Docker.py @@ -224,8 +224,7 @@ def test_30_updateVMInfo(self, requests): docker_cloud = self.get_docker_cloud() inf = MagicMock() - inf.get_next_vm_id.return_value = 1 - vm = VirtualMachine(inf, "1", docker_cloud.cloud, radl, radl, docker_cloud) + vm = VirtualMachine(inf, "1", docker_cloud.cloud, radl, radl, docker_cloud, 1) requests.side_effect = self.get_response @@ -249,8 +248,7 @@ def test_40_stop(self, requests): docker_cloud = self.get_docker_cloud() inf = MagicMock() - inf.get_next_vm_id.return_value = 1 - vm = VirtualMachine(inf, "1", docker_cloud.cloud, "", "", docker_cloud) + vm = VirtualMachine(inf, "1", docker_cloud.cloud, "", "", docker_cloud, 1) requests.side_effect = self.get_response @@ -265,8 +263,7 @@ def test_50_start(self, requests): docker_cloud = self.get_docker_cloud() inf = MagicMock() - inf.get_next_vm_id.return_value = 1 - vm = VirtualMachine(inf, "1", docker_cloud.cloud, "", "", docker_cloud) + vm = VirtualMachine(inf, "1", docker_cloud.cloud, "", "", docker_cloud, 1) requests.side_effect = self.get_response @@ -288,8 +285,7 @@ def test_60_finalize(self, requests): docker_cloud = self.get_docker_cloud() inf = MagicMock() - inf.get_next_vm_id.return_value = 1 - vm = VirtualMachine(inf, "1", docker_cloud.cloud, radl, radl, docker_cloud) + vm = VirtualMachine(inf, "1", docker_cloud.cloud, radl, radl, docker_cloud, 1) requests.side_effect = self.get_response diff --git a/test/unit/connectors/EC2.py b/test/unit/connectors/EC2.py index 9a54e85d0..bc01b5b1e 100755 --- a/test/unit/connectors/EC2.py +++ b/test/unit/connectors/EC2.py @@ -305,8 +305,7 @@ def test_30_updateVMInfo(self, get_connection): ec2_cloud = self.get_ec2_cloud() inf = MagicMock() - inf.get_next_vm_id.return_value = 1 - vm = VirtualMachine(inf, "us-east-1;id-1", ec2_cloud.cloud, radl, radl, ec2_cloud) + vm = VirtualMachine(inf, "us-east-1;id-1", ec2_cloud.cloud, radl, radl, ec2_cloud, 1) conn = MagicMock() get_connection.return_value = conn @@ -366,8 +365,7 @@ def test_30_updateVMInfo_spot(self, get_connection): ec2_cloud = self.get_ec2_cloud() inf = MagicMock() - inf.get_next_vm_id.return_value = 1 - vm = VirtualMachine(inf, "us-east-1;sid-1", ec2_cloud.cloud, radl, radl, ec2_cloud) + vm = VirtualMachine(inf, "us-east-1;sid-1", ec2_cloud.cloud, radl, radl, ec2_cloud, 1) conn = MagicMock() get_connection.return_value = conn @@ -411,8 +409,7 @@ def test_40_stop(self, get_connection): ec2_cloud = self.get_ec2_cloud() inf = MagicMock() - inf.get_next_vm_id.return_value = 1 - vm = VirtualMachine(inf, "us-east-1;id-1", ec2_cloud.cloud, "", "", ec2_cloud) + vm = VirtualMachine(inf, "us-east-1;id-1", ec2_cloud.cloud, "", "", ec2_cloud, 1) conn = MagicMock() get_connection.return_value = conn @@ -435,8 +432,7 @@ def test_50_start(self, get_connection): ec2_cloud = self.get_ec2_cloud() inf = MagicMock() - inf.get_next_vm_id.return_value = 1 - vm = VirtualMachine(inf, "us-east-1;id-1", ec2_cloud.cloud, "", "", ec2_cloud) + vm = VirtualMachine(inf, "us-east-1;id-1", ec2_cloud.cloud, "", "", ec2_cloud, 1) conn = MagicMock() get_connection.return_value = conn @@ -481,8 +477,7 @@ def test_55_alter(self, get_connection): ec2_cloud = self.get_ec2_cloud() inf = MagicMock() - inf.get_next_vm_id.return_value = 1 - vm = VirtualMachine(inf, "us-east-1;sid-1", ec2_cloud.cloud, radl, radl, ec2_cloud) + vm = VirtualMachine(inf, "us-east-1;sid-1", ec2_cloud.cloud, radl, radl, ec2_cloud, 1) conn = MagicMock() get_connection.return_value = conn @@ -527,8 +522,7 @@ def test_60_finalize(self, sleep, get_connection): inf = MagicMock() inf.id = "1" - inf.get_next_vm_id.return_value = 1 - vm = VirtualMachine(inf, "us-east-1;id-1", ec2_cloud.cloud, radl, radl, ec2_cloud) + vm = VirtualMachine(inf, "us-east-1;id-1", ec2_cloud.cloud, radl, radl, ec2_cloud, 1) vm.keypair_name = "key" conn = MagicMock() diff --git a/test/unit/connectors/Fogbow.py b/test/unit/connectors/Fogbow.py index ff9359b1e..b4491c039 100755 --- a/test/unit/connectors/Fogbow.py +++ b/test/unit/connectors/Fogbow.py @@ -191,8 +191,7 @@ def test_30_updateVMInfo(self, connection): fogbow_cloud = self.get_fogbow_cloud() inf = MagicMock() - inf.get_next_vm_id.return_value = 1 - vm = VirtualMachine(inf, "1", fogbow_cloud.cloud, radl, radl, fogbow_cloud) + vm = VirtualMachine(inf, "1", fogbow_cloud.cloud, radl, radl, fogbow_cloud, 1) conn = MagicMock() connection.return_value = conn @@ -211,8 +210,7 @@ def test_60_finalize(self, connection): fogbow_cloud = self.get_fogbow_cloud() inf = MagicMock() - inf.get_next_vm_id.return_value = 1 - vm = VirtualMachine(inf, "1", fogbow_cloud.cloud, "", "", fogbow_cloud) + vm = VirtualMachine(inf, "1", fogbow_cloud.cloud, "", "", fogbow_cloud, 1) conn = MagicMock() connection.return_value = conn diff --git a/test/unit/connectors/GCE.py b/test/unit/connectors/GCE.py index 572a9fe5a..eded9f884 100755 --- a/test/unit/connectors/GCE.py +++ b/test/unit/connectors/GCE.py @@ -206,8 +206,7 @@ def test_30_updateVMInfo(self, get_driver): gce_cloud = self.get_gce_cloud() inf = MagicMock() - inf.get_next_vm_id.return_value = 1 - vm = VirtualMachine(inf, "1", gce_cloud.cloud, radl, radl, gce_cloud) + vm = VirtualMachine(inf, "1", gce_cloud.cloud, radl, radl, gce_cloud, 1) driver = MagicMock() get_driver.return_value = driver @@ -243,8 +242,7 @@ def test_40_stop(self, get_driver): gce_cloud = self.get_gce_cloud() inf = MagicMock() - inf.get_next_vm_id.return_value = 1 - vm = VirtualMachine(inf, "1", gce_cloud.cloud, "", "", gce_cloud) + vm = VirtualMachine(inf, "1", gce_cloud.cloud, "", "", gce_cloud, 1) driver = MagicMock() get_driver.return_value = driver @@ -264,8 +262,7 @@ def test_50_start(self, get_driver): gce_cloud = self.get_gce_cloud() inf = MagicMock() - inf.get_next_vm_id.return_value = 1 - vm = VirtualMachine(inf, "1", gce_cloud.cloud, "", "", gce_cloud) + vm = VirtualMachine(inf, "1", gce_cloud.cloud, "", "", gce_cloud, 1) driver = MagicMock() get_driver.return_value = driver @@ -293,8 +290,7 @@ def test_60_finalize(self, sleep, get_driver): radl = radl_parse.parse_radl(radl_data) inf = MagicMock() - inf.get_next_vm_id.return_value = 1 - vm = VirtualMachine(inf, "1", gce_cloud.cloud, radl, radl, gce_cloud) + vm = VirtualMachine(inf, "1", gce_cloud.cloud, radl, radl, gce_cloud, 1) driver = MagicMock() driver.name = "OpenStack" diff --git a/test/unit/connectors/Kubernetes.py b/test/unit/connectors/Kubernetes.py index 8b4a403e4..3bc50b610 100755 --- a/test/unit/connectors/Kubernetes.py +++ b/test/unit/connectors/Kubernetes.py @@ -194,9 +194,8 @@ def test_30_updateVMInfo(self, requests): kube_cloud = self.get_kube_cloud() inf = MagicMock() - inf.get_next_vm_id.return_value = 1 inf.id = "namespace" - vm = VirtualMachine(inf, "1", kube_cloud.cloud, radl, radl, kube_cloud) + vm = VirtualMachine(inf, "1", kube_cloud.cloud, radl, radl, kube_cloud, 1) requests.side_effect = self.get_response @@ -233,9 +232,8 @@ def test_55_alter(self, requests): kube_cloud = self.get_kube_cloud() inf = MagicMock() - inf.get_next_vm_id.return_value = 1 inf.id = "namespace" - vm = VirtualMachine(inf, "1", kube_cloud.cloud, radl, radl, kube_cloud) + vm = VirtualMachine(inf, "1", kube_cloud.cloud, radl, radl, kube_cloud, 1) requests.side_effect = self.get_response @@ -250,9 +248,8 @@ def test_60_finalize(self, requests): kube_cloud = self.get_kube_cloud() inf = MagicMock() - inf.get_next_vm_id.return_value = 1 inf.id = "namespace" - vm = VirtualMachine(inf, "1", kube_cloud.cloud, "", "", kube_cloud) + vm = VirtualMachine(inf, "1", kube_cloud.cloud, "", "", kube_cloud, 1) requests.side_effect = self.get_response diff --git a/test/unit/connectors/LibCloud.py b/test/unit/connectors/LibCloud.py index 7fc4fcdb1..665b5ec62 100755 --- a/test/unit/connectors/LibCloud.py +++ b/test/unit/connectors/LibCloud.py @@ -197,8 +197,7 @@ def test_30_updateVMInfo(self, get_driver): lib_cloud = self.get_lib_cloud() inf = MagicMock() - inf.get_next_vm_id.return_value = 1 - vm = VirtualMachine(inf, "1", lib_cloud.cloud, radl, radl, lib_cloud) + vm = VirtualMachine(inf, "1", lib_cloud.cloud, radl, radl, lib_cloud, 1) driver = MagicMock() driver.name = "Amazon EC2" @@ -239,8 +238,7 @@ def test_40_stop(self, get_driver): lib_cloud = self.get_lib_cloud() inf = MagicMock() - inf.get_next_vm_id.return_value = 1 - vm = VirtualMachine(inf, "1", lib_cloud.cloud, "", "", lib_cloud) + vm = VirtualMachine(inf, "1", lib_cloud.cloud, "", "", lib_cloud, 1) driver = MagicMock() get_driver.return_value = driver @@ -265,8 +263,7 @@ def test_50_start(self, get_driver): lib_cloud = self.get_lib_cloud() inf = MagicMock() - inf.get_next_vm_id.return_value = 1 - vm = VirtualMachine(inf, "1", lib_cloud.cloud, "", "", lib_cloud) + vm = VirtualMachine(inf, "1", lib_cloud.cloud, "", "", lib_cloud, 1) driver = MagicMock() get_driver.return_value = driver @@ -313,8 +310,7 @@ def test_55_alter(self, get_driver): lib_cloud = self.get_lib_cloud() inf = MagicMock() - inf.get_next_vm_id.return_value = 1 - vm = VirtualMachine(inf, "1", lib_cloud.cloud, radl, radl, lib_cloud) + vm = VirtualMachine(inf, "1", lib_cloud.cloud, radl, radl, lib_cloud, 1) driver = MagicMock() get_driver.return_value = driver @@ -353,8 +349,7 @@ def test_60_finalize(self, get_driver): radl = radl_parse.parse_radl(radl_data) inf = MagicMock() - inf.get_next_vm_id.return_value = 1 - vm = VirtualMachine(inf, "1", lib_cloud.cloud, radl, radl, lib_cloud) + vm = VirtualMachine(inf, "1", lib_cloud.cloud, radl, radl, lib_cloud, 1) vm.keypair = "" driver = MagicMock() diff --git a/test/unit/connectors/OCCI.py b/test/unit/connectors/OCCI.py index 37109b27c..e4b9ccd66 100755 --- a/test/unit/connectors/OCCI.py +++ b/test/unit/connectors/OCCI.py @@ -203,8 +203,7 @@ def test_30_updateVMInfo(self, get_keystone_uri, requests): occi_cloud = self.get_occi_cloud() inf = MagicMock() - inf.get_next_vm_id.return_value = 1 - vm = VirtualMachine(inf, "1", occi_cloud.cloud, radl, radl, occi_cloud) + vm = VirtualMachine(inf, "1", occi_cloud.cloud, radl, radl, occi_cloud, 1) requests.side_effect = self.get_response @@ -222,8 +221,7 @@ def test_40_stop(self, get_keystone_uri, requests): occi_cloud = self.get_occi_cloud() inf = MagicMock() - inf.get_next_vm_id.return_value = 1 - vm = VirtualMachine(inf, "1", occi_cloud.cloud, "", "", occi_cloud) + vm = VirtualMachine(inf, "1", occi_cloud.cloud, "", "", occi_cloud, 1) requests.side_effect = self.get_response @@ -241,8 +239,7 @@ def test_50_start(self, get_keystone_uri, requests): occi_cloud = self.get_occi_cloud() inf = MagicMock() - inf.get_next_vm_id.return_value = 1 - vm = VirtualMachine(inf, "1", occi_cloud.cloud, "", "", occi_cloud) + vm = VirtualMachine(inf, "1", occi_cloud.cloud, "", "", occi_cloud, 1) requests.side_effect = self.get_response @@ -284,8 +281,7 @@ def test_55_alter(self, get_keystone_uri, requests): occi_cloud = self.get_occi_cloud() inf = MagicMock() - inf.get_next_vm_id.return_value = 1 - vm = VirtualMachine(inf, "1", occi_cloud.cloud, radl, radl, occi_cloud) + vm = VirtualMachine(inf, "1", occi_cloud.cloud, radl, radl, occi_cloud, 1) requests.side_effect = self.get_response @@ -303,10 +299,9 @@ def test_60_finalize(self, get_keystone_uri, requests): occi_cloud = self.get_occi_cloud() inf = MagicMock() - inf.get_next_vm_id.return_value = 1 radl = RADL() radl.systems.append(system("test")) - vm = VirtualMachine(inf, "1", occi_cloud.cloud, radl, radl, occi_cloud) + vm = VirtualMachine(inf, "1", occi_cloud.cloud, radl, radl, occi_cloud, 1) requests.side_effect = self.get_response diff --git a/test/unit/connectors/OpenNebula.py b/test/unit/connectors/OpenNebula.py index 396e22546..be4c9c291 100755 --- a/test/unit/connectors/OpenNebula.py +++ b/test/unit/connectors/OpenNebula.py @@ -168,8 +168,7 @@ def test_30_updateVMInfo(self, server_proxy): one_cloud = self.get_one_cloud() inf = MagicMock() - inf.get_next_vm_id.return_value = 1 - vm = VirtualMachine(inf, "1", one_cloud.cloud, radl, radl, one_cloud) + vm = VirtualMachine(inf, "1", one_cloud.cloud, radl, radl, one_cloud, 1) one_server = MagicMock() one_server.one.vm.info.return_value = (True, read_file_as_string("files/vm_info.xml"), 0) @@ -187,8 +186,7 @@ def test_40_stop(self, server_proxy): one_cloud = self.get_one_cloud() inf = MagicMock() - inf.get_next_vm_id.return_value = 1 - vm = VirtualMachine(inf, "1", one_cloud.cloud, "", "", one_cloud) + vm = VirtualMachine(inf, "1", one_cloud.cloud, "", "", one_cloud, 1) one_server = MagicMock() one_server.one.vm.action.return_value = (True, "", 0) @@ -206,8 +204,7 @@ def test_50_start(self, server_proxy): one_cloud = self.get_one_cloud() inf = MagicMock() - inf.get_next_vm_id.return_value = 1 - vm = VirtualMachine(inf, "1", one_cloud.cloud, "", "", one_cloud) + vm = VirtualMachine(inf, "1", one_cloud.cloud, "", "", one_cloud, 1) one_server = MagicMock() one_server.one.vm.action.return_value = (True, "", 0) @@ -252,8 +249,7 @@ def test_55_alter(self, checkResize, server_proxy): one_cloud = self.get_one_cloud() inf = MagicMock() - inf.get_next_vm_id.return_value = 1 - vm = VirtualMachine(inf, "1", one_cloud.cloud, radl, radl, one_cloud) + vm = VirtualMachine(inf, "1", one_cloud.cloud, radl, radl, one_cloud, 1) checkResize.return_value = True one_server = MagicMock() @@ -275,8 +271,7 @@ def test_60_finalize(self, server_proxy): one_cloud = self.get_one_cloud() inf = MagicMock() - inf.get_next_vm_id.return_value = 1 - vm = VirtualMachine(inf, "1", one_cloud.cloud, "", "", one_cloud) + vm = VirtualMachine(inf, "1", one_cloud.cloud, "", "", one_cloud, 1) one_server = MagicMock() one_server.one.vm.action.return_value = (True, "", 0) diff --git a/test/unit/connectors/OpenStack.py b/test/unit/connectors/OpenStack.py index 5f388666a..b670f84de 100755 --- a/test/unit/connectors/OpenStack.py +++ b/test/unit/connectors/OpenStack.py @@ -204,8 +204,7 @@ def test_30_updateVMInfo(self, get_driver): ost_cloud = self.get_ost_cloud() inf = MagicMock() - inf.get_next_vm_id.return_value = 1 - vm = VirtualMachine(inf, "1", ost_cloud.cloud, radl, radl, ost_cloud) + vm = VirtualMachine(inf, "1", ost_cloud.cloud, radl, radl, ost_cloud, 1) driver = MagicMock() get_driver.return_value = driver @@ -251,8 +250,7 @@ def test_40_stop(self, get_driver): ost_cloud = self.get_ost_cloud() inf = MagicMock() - inf.get_next_vm_id.return_value = 1 - vm = VirtualMachine(inf, "1", ost_cloud.cloud, "", "", ost_cloud) + vm = VirtualMachine(inf, "1", ost_cloud.cloud, "", "", ost_cloud, 1) driver = MagicMock() get_driver.return_value = driver @@ -280,8 +278,7 @@ def test_50_start(self, get_driver): ost_cloud = self.get_ost_cloud() inf = MagicMock() - inf.get_next_vm_id.return_value = 1 - vm = VirtualMachine(inf, "1", ost_cloud.cloud, "", "", ost_cloud) + vm = VirtualMachine(inf, "1", ost_cloud.cloud, "", "", ost_cloud, 1) driver = MagicMock() get_driver.return_value = driver @@ -331,8 +328,7 @@ def test_55_alter(self, get_driver): ost_cloud = self.get_ost_cloud() inf = MagicMock() - inf.get_next_vm_id.return_value = 1 - vm = VirtualMachine(inf, "1", ost_cloud.cloud, radl, radl, ost_cloud) + vm = VirtualMachine(inf, "1", ost_cloud.cloud, radl, radl, ost_cloud, 1) driver = MagicMock() get_driver.return_value = driver @@ -376,8 +372,7 @@ def test_60_finalize(self, sleep, get_driver): radl = radl_parse.parse_radl(radl_data) inf = MagicMock() - inf.get_next_vm_id.return_value = 1 - vm = VirtualMachine(inf, "1", ost_cloud.cloud, radl, radl, ost_cloud) + vm = VirtualMachine(inf, "1", ost_cloud.cloud, radl, radl, ost_cloud, 1) driver = MagicMock() driver.name = "OpenStack" diff --git a/test/unit/test_im_logic.py b/test/unit/test_im_logic.py index 3ac9e233e..aa97911a9 100755 --- a/test/unit/test_im_logic.py +++ b/test/unit/test_im_logic.py @@ -285,6 +285,82 @@ def test_inf_creation2(self): self.assertEqual(call[3], 1) IM.DestroyInfrastructure(infId, auth0) + def test_inf_creation_errors(self): + """Create infrastructure """ + + radl = """" + network publica (outbound = 'yes') + network privada () + system front ( + net_interface.0.connection = 'publica' and + net_interface.1.connection = 'privada' and + disk.0.image.url = ['one://localhost/image', 'http://localhost:443/image'] and + disk.0.os.credentials.username = 'ubuntu' + ) + system wn ( + net_interface.0.connection = 'privada' and + disk.0.image.url = ['one://localhost/image', 'http://localhost:443/image'] and + disk.0.os.credentials.username = 'ubuntu' + ) + deploy front 1 + deploy wn 2 + """ + + # this case must fail only with one error + auth0 = Authentication([{'id': 'ost', 'type': 'OpenStack', 'username': 'user', + 'password': 'pass', 'tenant': 'ten', 'host': 'localhost:5000'}, + {'type': 'InfrastructureManager', 'username': 'test', + 'password': 'tests'}]) + with self.assertRaises(Exception) as ex: + IM.CreateInfrastructure(radl, auth0) + self.assertEqual(str(ex.exception), + 'Some deploys did not proceed successfully: All machines could not be launched: \n' + 'Attempt 1: Error, no concrete system to deploy: front in cloud: ost. ' + 'Check if a correct image is being used\n\n') + + # this case must fail with two errors, first the OpenNebula one + auth0 = Authentication([{'id': 'ost', 'type': 'OpenStack', 'username': 'user', + 'password': 'pass', 'tenant': 'ten', 'host': 'localhost:5000'}, + {'id': 'one', 'type': 'OpenNebula', 'username': 'user', + 'password': 'pass', 'host': 'localhost:2633'}, + {'type': 'InfrastructureManager', 'username': 'test', + 'password': 'tests'}]) + with self.assertRaises(Exception) as ex: + IM.CreateInfrastructure(radl, auth0) + self.assertEqual(str(ex.exception), + 'Some deploys did not proceed successfully: All machines could not be launched: \n' + 'Attempt 1: Error launching the VMs of type front to cloud ID one of type OpenNebula. ' + 'Cloud Provider Error: [Errno 111] Connection refused\n' + 'Attempt 2: Error, no concrete system to deploy: front in cloud: ost. ' + 'Check if a correct image is being used\n\n') + + # this case must fail with two errors, first the OCCI one + auth0 = Authentication([{'id': 'occi', 'type': 'OCCI', 'proxy': 'proxy', + 'host': 'http://localhost:443'}, + {'id': 'one', 'type': 'OpenNebula', 'username': 'user', + 'password': 'pass', 'host': 'localhost:2633'}, + {'type': 'InfrastructureManager', 'username': 'test', + 'password': 'tests'}]) + with self.assertRaises(Exception) as ex: + IM.CreateInfrastructure(radl, auth0) + self.assertIn(str(ex.exception), + 'Some deploys did not proceed successfully: All machines could not be launched: \n' + 'Attempt 1: Error launching the VMs of type front to cloud ID occi of type OCCI. ' + 'Cloud Provider Error: Error getting os_tpl scheme. ' + 'Check that the image specified is supported in the OCCI server.\n' + 'Attempt 2: Error launching the VMs of type front to cloud ID one of type OpenNebula. ' + 'Cloud Provider Error: [Errno 111] Connection refused\n\n') + + # this case must work OK + auth0 = Authentication([{'id': 'ost', 'type': 'OpenStack', 'username': 'user', + 'password': 'pass', 'tenant': 'ten', 'host': 'localhost:5000'}, + {'id': 'one', 'type': 'OpenNebula', 'username': 'user', + 'password': 'pass', 'host': 'localhost:2633'}, + {'id': 'dummy', 'type': 'Dummy'}, + {'type': 'InfrastructureManager', 'username': 'test', + 'password': 'tests'}]) + IM.CreateInfrastructure(radl, auth0) + def test_inf_auth(self): """Try to access not owned Infs.""" @@ -422,13 +498,11 @@ def test_inf_addresources3(self, suds_cli): n0, n1 = 2, 5 # Machines to deploy radl = RADL() radl.add(system("s0", [Feature("disk.0.image.url", "=", "mock0://linux.for.ev.er"), - SoftFeatures( - 10, [Feature("memory.size", "<=", 500)]), + SoftFeatures(10, [Feature("memory.size", "<=", 500)]), Feature("disk.0.os.credentials.username", "=", "user"), Feature("disk.0.os.credentials.password", "=", "pass")])) radl.add(system("s1", [Feature("disk.0.image.url", "=", "mock0://linux.for.ev.er"), - SoftFeatures( - 10, [Feature("memory.size", ">=", 800)]), + SoftFeatures(10, [Feature("memory.size", ">=", 800)]), Feature("disk.0.os.credentials.username", "=", "user"), Feature("disk.0.os.credentials.password", "=", "pass")])) radl.add(deploy("s0", n0)) @@ -488,7 +562,7 @@ def test_inf_addresources4(self): IM.DestroyInfrastructure(infId, auth0) - def test_inf_addresources5(self): + def test_inf_addresources_parallel(self): """Deploy n independent virtual machines.""" radl = """" @@ -528,7 +602,7 @@ def test_inf_addresources5(self): auth0 = self.getAuth([0], [], [("Mock", 0)]) infId = IM.CreateInfrastructure("", auth0) - # in this case it will take aprox 20 secs + # in this case it will take aprox 15 secs before = int(time.time()) Config.MAX_SIMULTANEOUS_LAUNCHES = 1 vms = IM.AddResource(infId, str(radl), auth0) @@ -536,7 +610,7 @@ def test_inf_addresources5(self): self.assertLess(delay, 17) self.assertGreater(delay, 14) - self.assertEqual(len(vms), 6) + self.assertEqual(vms, [0, 1, 2, 3, 4, 5]) self.assertEqual(cloud.launch.call_count, 3) self.assertEqual(cloud.launch.call_args_list[0][0][3], 1) self.assertEqual(cloud.launch.call_args_list[1][0][3], 3) @@ -551,11 +625,13 @@ def test_inf_addresources5(self): Config.MAX_SIMULTANEOUS_LAUNCHES = 3 # Test the pool vms = IM.AddResource(infId, str(radl), auth0) delay = int(time.time()) - before - self.assertLess(delay, 7) - self.assertGreater(delay, 4) + self.assertLess(delay, 17) + self.assertGreater(delay, 14) + # self.assertLess(delay, 7) + # self.assertGreater(delay, 4) Config.MAX_SIMULTANEOUS_LAUNCHES = 1 - self.assertEqual(len(vms), 6) + self.assertEqual(vms, [6, 7, 8, 9, 10, 11]) self.assertEqual(cloud.launch.call_count, 3) self.assertEqual(cloud.launch.call_args_list[0][0][3], 1) self.assertEqual(cloud.launch.call_args_list[1][0][3], 3) @@ -946,8 +1022,8 @@ def test_db(self): radl = RADL() radl.add(system("s0", [Feature("disk.0.image.url", "=", "mock0://linux.for.ev.er")])) radl.add(deploy("s0", 1)) - vm1 = VirtualMachine(inf, "1", cloud, radl, radl) - vm2 = VirtualMachine(inf, "2", cloud, radl, radl) + vm1 = VirtualMachine(inf, "1", cloud, radl, radl, None, 1) + vm2 = VirtualMachine(inf, "2", cloud, radl, radl, None, 2) inf.vm_list = [vm1, vm2] inf.vm_master = vm1 # first create the DB table