def get_config_option(res_id, option, config_path): ''' Retrieves an option in a configuration file. @param res_id: the hypervisor's id corresponding to a section in the configuration file @type res_id: str @param option: the option to retrieve the value @type option: str @param config_path: the path to the configuration file @type config_path: str ''' # Retrive the configuration file config = read_config_file(config_path) # If the section exists in the configuration file if config.has_section(res_id): try: # Return the value of the given option return config.get(res_id, option) except ConfigParser.NoOptionError: raise ResourceException("The option '%s' doesn't exist in " "libvirt configuration file." % option) else: raise ResourceException("The cloud manager '%s' doesn't exist in the " "configuration file." % res_id)
def delete(self, res_id=None, attributes=None): status = {} error = None required_keys = ["name"] # Check if the name of the virtual machine to delete exists in the # attributes self._check_keys_in_dict(attributes, required_keys) # Retrieve the good module cm_type = self._get_cloudmanager_type(res_id) module = self._load_driver_module(cm_type) # Initialize mandatory attributes depending on cloud manager's type module._init_cloudmanager_attributes(res_id, attributes) # Check if the virtual machine exists if module._exists(attributes): status['vm_name'] = attributes['name'] num_status = module._get_status(attributes) # If the machine is running and the attribute 'force' is not #specified, then the machine can't be removed if (("force" not in attributes or attributes['force'] == False) and module._get_readable_status(num_status) == cm_util.VM_STATE_RUNNING): status['vm_status'] = module._get_readable_status(num_status) status['deleted'] = False raise ResourceException("The VM is " "currently running. Use the option " "force or shutdown the VM.") # Otherwise, we can remove the virtual machine else: state = module._delete_VM(attributes) status['vm_status'] = module._get_readable_status(state) status['deleted'] = True # If the machine doesn't exist else: status['vm_name'] = attributes['name'] status['vm_status'] = cm_util.VM_STATE_UNKNOWN status['deleted'] = False raise ResourceException("The specified VM doesn't exist") status['cloudmanager'] = res_id return status
def _get_vcpus(attributes): vm = _get_VM(attributes) if not vm['status'] == 'ACTIVE': raise ResourceException("The CPUs info can't be retrieved while the VM is not running") vm_id = vm['id'] flavor = _get_flavor(attributes, vm_id) return flavor['vcpus']
def _resume(attributes): ''' Pauses a VM. @param attributes: the dictionary of the attributes that will be used to pause a virtual machine @type attributes: dict ''' vm = _get_VM(attributes) if _get_status(attributes) == "PAUSED": conn = Connection(attributes["cm_nova_url"], username="", password="") tenant_id, x_auth_token = _get_keystone_tokens(attributes) body = '{"unpause": null}' headers = {"Content-type": "application/json", "x-auth-token": x_auth_token.encode()} uri = tenant_id + "/servers/" + vm['id'] + "/action" resp = conn.request_post(uri, body=body, headers=headers) status = resp[u'headers']['status'] if status == '200' or status == '304' or status == '202': log.info("VM is unpaused and status is %s" % _get_status(attributes)) else: log.error("_resume: Bad HTTP return code: %s" % status) else: raise ResourceException("The VM must be paused") return _get_status(attributes)
def _check_keys_in_dict(self, dictionary, keys): ''' Checks if keys exist in a dict. @param dictionary: the dictionary on which the keys will be checked @type dictionary: dict @param keys: the keys to check in the given dictionary @type keys: list ''' for key in keys: if key not in dictionary: raise ResourceException("Mandatory attribute '%s' is missing" % key) elif key is None: raise ResourceException("Mandatory attribute '%s' is None" % key)
def _check_attributes_values(self, attributes): ''' Checks values of the attributes dictionary in terms of semantic @param attributes: the dictionary of attributes @type attributes: dict ''' if "name" in attributes: if attributes['name'] == "": raise ResourceException("The VM name must not be empty.") if "flavor" in attributes: if attributes['flavor'] == "": raise ResourceException("The flavor must be specified.") if "image" in attributes: if attributes['image'] == "": raise ResourceException("The image must be specified")
def read_config_file(file_name): ''' Returns a parsed configuration file. @param file_name: the path to the configuration file @type file_name: str ''' config = ConfigParser.ConfigParser() try: ret = config.read(file_name) if not ret: raise ResourceException( "The configuration file '%s' doesn't exist" % file_name) except ConfigParser.MissingSectionHeaderError: raise ResourceException("Couldn't parse configuration file '%s'" % file_name) return config
def read(self, res_id=None, attributes=None): """ """ status = {} if res_id is None or res_id == '': status['docks'] = self.config.keys() elif res_id in self.docks: try: client = self.docks[res_id] if attributes.get('container'): status = client.inspect_container(attributes['container']) else: status = client.containers() except Exception as e: raise ResourceException(e) else: raise ResourceException("%s not found." % res_id) return status
def _check_int_attributes(self, attributes, keys): ''' Checks integer values in a dictionary @param attributes: the dictionary on which the integer keys will be checked @type attributes: dict @param keys: the keys of the integer attributes @type keys: list ''' for key in keys: if key in attributes: try: int(attributes[key]) except ValueError: raise ResourceException("Attribute '%s' must be integer" % key) except TypeError: raise ResourceException("Attribute '%s' is None" % key)
def create(self, res_id, attributes): """ collection: docks id: Antwerp attributes: image: .... name: hostname memory (MB): ... cpu_share: ... command: ... """ status = {} try: client = self.docks[res_id] ports = [] volumes = {} binds = {} if attributes.get('ports'): for port in attributes['ports']: ports.append("%s:%s" % (port['local'], port['remote'])) if attributes.get('volumes'): for vol in attributes['volumes']: volumes[vol['remote']] = {} binds[vol['local']] = vol['remote'] container_id = client.create_container(attributes['image'], attributes['command'], ports=ports, volumes=volumes)['Id'] client.start(container_id, binds=binds) try: status = self.read(res_id, {'container': container_id}) except ResourceException: raise ResourceException("The container does not exist or is " "terminated.") except KeyError as e: raise ResourceException("%s attribute missing." % e) return status
def delete(self, res_id, attributes): """ """ status = {} try: client = self.docks[res_id] client.kill(attributes['container']) status['Id'] = attributes['container'] except KeyError as e: raise ResourceException("%s attribute missing." % e) return status
def _get_VM(attributes): conn = Connection(attributes["cm_nova_url"], username="", password="") tenant_id, x_auth_token = _get_keystone_tokens(attributes) resp = conn.request_get("/" + tenant_id +"/servers/detail", args={}, headers={'content-type':'application/json', 'accept':'application/json', 'x-auth-token':x_auth_token}) status = resp[u'headers']['status'] found = 0 if status == '200' or status == '304': servers = json.loads(resp['body']) for vm in servers['servers']: if attributes['name'] == vm['name']: found = 1 return vm if found == 0: #return False raise ResourceException("vm %s not found" % attributes['name']) else: log.error("_get_VM: Bad HTTP return code: %s" % status)
def listimages(self, res_id=None, attributes=None): status = {} error = None if (attributes is None): status['cloudmanagers'] = res_id status['url'] = cm_util.get_config_option( res_id, "url", self.CLOUDMANAGERS_CONFIG_FILE) # Retrieve the good module cm_type = self._get_cloudmanager_type(res_id) module = self._load_driver_module(cm_type) # Initialize mandatory attributes depending on cloud manager's type module._init_cloudmanager_attributes(res_id, attributes) status['images'] = module._get_images(attributes) else: raise ResourceException( "No arguments are yet allowed for this method") return status
def _set_status(self, res_id, attributes): ''' Retrieves the status number and executes the corresponding action. @param res_id: cloud manager's id @type res_id: str @param attributes: the different attributes which will be used to update the status of a virtual machine @type attributes: dict ''' # Retrieve the good module cm_type = self._get_cloudmanager_type(res_id) module = self._load_driver_module(cm_type) # If the virtual machine is already in the given state, then this state # is returned if attributes['status'] == module._get_status(attributes): return module._get_status(attributes) try: # Retrieve a reference to the method of the module to call to # update the status of a virtual machine status_action = { cm_util.VM_STATE_RUNNING: self._run_vm(res_id, attributes), cm_util.VM_STATE_PAUSED: module._pause, cm_util.VM_STATE_SHUTDOWN: module._shutdown, cm_util.VM_STATE_REBOOTING: module._reboot, cm_util.VM_STATE_RESUME: module._resume }[attributes['status']] except KeyError: raise ResourceException("The given status is unknown") # Call the method and return the final status of the virtual machine return status_action(attributes)
def update(self, res_id=None, attributes={}): status = {} error = None keys_upd_status = ["status"] keys_upd_flavor = ["flavor"] cmd_mandatory_keys = [keys_upd_status, keys_upd_flavor] # Check if there is at least one update command with all required # attributes cpt = 0 for keys in cmd_mandatory_keys: try: self._check_keys_in_dict(attributes, keys) cpt += 1 except ResourceException: pass # Retrieve the good module and the corresponding connection cm_type = self._get_cloudmanager_type(res_id) module = self._load_driver_module(cm_type) # Initialize mandatory attributes depending on cloud manager's type module._init_cloudmanager_attributes(res_id, attributes) # If none of the tests has passed, an error message is appended if cpt == 0: raise ResourceException("There must be at least " "one command to do an update") # If the virtual machine exists elif module._exists(attributes): # Check the semantic values of some attributes self._check_attributes_values(attributes) status['vm_name'] = attributes['name'] # Update the status if "status" in attributes: num_status = module._get_status(attributes) str_status = module._get_readable_status(num_status) # Check if the virtual machine is not in the required # state if (attributes['status'] != str_status): num_status = self._set_status(res_id, attributes) status['vm_status'] = module._get_readable_status( num_status) else: status['vm_status'] = str_status # Update the flavor if ("flavor" in attributes): vm = module._get_VM(attributes) vm_id = vm['id'] current_flavor = module._get_flavor(attributes, vm_id) new_flavor = attributes["flavor"] flavor_dict = module._set_flavor(attributes, vm_id, current_flavor["id"], new_flavor) status['vm_flavor'] = flavor_dict["id"] # If the virtual machine doesn't exist else: raise ResourceException("The specified VM doesn't " "exist") status['cloudmanager'] = res_id return status
try: vm = module._get_VM(attributes) vm_id = vm['id'] flavor = module._get_flavor(attributes, vm['id']) status['vm_flavor'] = flavor['id'] except ResourceException, ex: status['vm_flavor'] = str(ex) status['vm_vnc_port'] = module._get_vnc_port(attributes) # Verifies if this is a vnx request # TODO: the vnc part should come here else: raise ResourceException("The specified VM doesn't exist") num_status = module._get_status(attributes) status['vm_status'] = module._get_readable_status(num_status) return status #----------------------------------------------------------------------------- def create(self, res_id=None, attributes={}): status = {} error = '' passed = True cm_type = None module = None