def toggleRepo(self, repo_id, enable): """ Enable a given repository """ r = self._get_source_entry(repo_id) if r is None: raise NotFoundError('GGBREPOS0012E', {'repo_id': repo_id}) if enable and not r.disabled: raise InvalidOperation('GGBREPOS0015E', {'repo_id': repo_id}) if not enable and r.disabled: raise InvalidOperation('GGBREPOS0016E', {'repo_id': repo_id}) if enable: line = 'deb' else: line = '#deb' gingerBaseLock.acquire() try: repos = self._get_repos() repos.remove(r) repos.add(line, r.uri, r.dist, r.comps, file=self.filename) repos.save() except Exception: if enable: raise OperationFailed('GGBREPOS0020E', {'repo_id': repo_id}) raise OperationFailed('GGBREPOS0021E', {'repo_id': repo_id}) finally: gingerBaseLock.release() return repo_id
def toggleRepo(self, repo_id, enable): repos = self._get_repos('GGBREPOS0011E') if repo_id not in repos.keys(): raise NotFoundError('GGBREPOS0012E', {'repo_id': repo_id}) entry = repos.get(repo_id) if enable and entry.enabled: raise InvalidOperation('GGBREPOS0015E', {'repo_id': repo_id}) if not enable and not entry.enabled: raise InvalidOperation('GGBREPOS0016E', {'repo_id': repo_id}) gingerBaseLock.acquire() try: if enable: entry.enable() else: entry.disable() write_repo_to_file(entry) except Exception: if enable: raise OperationFailed('GGBREPOS0020E', {'repo_id': repo_id}) raise OperationFailed('GGBREPOS0021E', {'repo_id': repo_id}) finally: gingerBaseLock.release() return repo_id
def addRepo(self, params): """ Add a given repository to YumBase """ # At least one base url, or one mirror, must be given. baseurl = params.get('baseurl', '') config = params.get('config', {}) mirrorlist = config.get('mirrorlist', '') metalink = config.get('metalink', '') if not baseurl and not mirrorlist and not metalink: raise MissingParameter('GGBREPOS0013E') if baseurl: validate_repo_url(get_expanded_url(baseurl)) if mirrorlist: validate_repo_url(get_expanded_url(mirrorlist)) if metalink: validate_repo_url(get_expanded_url(metalink)) if mirrorlist and metalink: raise InvalidOperation('GGBREPOS0030E') repo_id = params.get('repo_id', None) if repo_id is None: repo_id = 'gingerbase_repo_%s' % str(int(time.time() * 1000)) repos = self._get_repos('GGBREPOS0026E') if repo_id in repos.keys(): raise InvalidOperation('GGBREPOS0022E', {'repo_id': repo_id}) repo_name = config.get('repo_name', repo_id) repo = { 'baseurl': baseurl, 'mirrorlist': mirrorlist, 'name': repo_name, 'gpgcheck': 1, 'gpgkey': [], 'enabled': 1, 'metalink': metalink } # write a repo file in the system with repo{} information. parser = SafeConfigParser() parser.add_section(repo_id) for key, value in repo.items(): if value: parser.set(repo_id, key, value) repofile = os.path.join(self._confdir, repo_id + '.repo') try: with open(repofile, 'w') as fd: parser.write(fd) except Exception: raise OperationFailed('GGBREPOS0018E', {'repo_file': repofile}) return repo_id
def delete(self, name): if self._pool_used_by_template(name): raise InvalidOperation('KCHPOOL0035E', {'name': name}) pool = self.get_storagepool(name, self.conn) if pool.isActive(): raise InvalidOperation("KCHPOOL0005E", {'name': name}) try: pool.undefine() except libvirt.libvirtError as e: raise OperationFailed("KCHPOOL0011E", {'name': name, 'err': e.get_error_message()})
def delete(self, name): if self._is_network_in_use(name): vms = self._get_vms_attach_to_a_network(name) vms.sort() raise InvalidOperation("KCHNET0017E", {'name': name, 'vms': ', '.join(vms)}) network = self.get_network(self.conn.get(), name) if network.isActive(): raise InvalidOperation("KCHNET0005E", {'name': name}) self._remove_vlan_tagged_bridge(network) network.undefine()
def delete(self, name): in_use, used_by_vms, used_by_tmpls = self._is_network_in_use(name) vms = 'N/A' if len(used_by_vms) == 0 else ', '.join(used_by_vms) tmpls = 'N/A' if len(used_by_tmpls) == 0 else ', '.join(used_by_tmpls) if in_use: raise InvalidOperation("KCHNET0017E", {'name': name, 'vms': vms, 'tmpls': tmpls}) network = self.get_network(self.conn.get(), name) if network.isActive(): raise InvalidOperation("KCHNET0005E", {'name': name}) self._remove_bridge(network) network.undefine()
def _check_lvm(self, name, from_vg): vgdisplay_cmd = ['vgdisplay', name.encode('utf-8')] output, error, returncode = run_command(vgdisplay_cmd) # From vgdisplay error codes: # 1 error reading VGDA # 2 volume group doesn't exist # 3 not all physical volumes of volume group online # 4 volume group not found # 5 no volume groups found at all # 6 error reading VGDA from lvmtab if from_vg and returncode in [2, 4, 5]: raise InvalidOperation("KCHPOOL0038E", {'name': name}) if not from_vg and returncode not in [2, 4, 5]: raise InvalidOperation("KCHPOOL0036E", {'name': name})
def delete(self, vm_name, dev_name): try: bus_type = self.lookup(vm_name, dev_name)['bus'] dom = VMModel.get_vm(vm_name, self.conn) except NotFoundError: raise if (bus_type not in HOTPLUG_TYPE and DOM_STATE_MAP[dom.info()[0]] != 'shutoff'): raise InvalidOperation('KCHVMSTOR0011E') try: disk = get_device_node(dom, dev_name) path = get_vm_disk_info(dom, dev_name)['path'] if path is None or len(path) < 1: path = self.lookup(vm_name, dev_name)['path'] # This has to be done before it's detached. If it wasn't # in the obj store, its ref count would have been updated # by get_disk_used_by() if path is not None: used_by = get_disk_used_by(self.objstore, self.conn, path) else: wok_log.error("Unable to decrement volume used_by on" " delete because no path could be found.") dom.detachDeviceFlags(etree.tostring(disk), get_vm_config_flag(dom, 'all')) except Exception as e: raise OperationFailed("KCHVMSTOR0010E", {'error': e.message}) if used_by is not None and vm_name in used_by: used_by.remove(vm_name) set_disk_used_by(self.objstore, path, used_by) else: wok_log.error("Unable to update %s:%s used_by on delete." % (vm_name, dev_name))
def create(self, params, *args): try: create = getattr(self.model, model_fn(self, 'create')) except AttributeError: e = InvalidOperation( 'WOKAPI0005E', {'resource': get_class_name(self)}) raise cherrypy.HTTPError(405, str(e)) validate_params(params, self, 'create') args = self.model_args + [params] task = create(*args) cherrypy.response.status = 202 # log request method = 'POST' code = self.getRequestMessage(method) reqParams = utf8_dict(self.log_args, params) log_id = log_request( code, reqParams, None, method, cherrypy.response.status, class_name=get_class_name(self), ) save_request_log_id(log_id, task['id']) return wok.template.render('Task', task)
def delete(self): try: fn = getattr(self.model, model_fn(self, 'delete')) task = fn(*self.model_args) except AttributeError: e = InvalidOperation( 'WOKAPI0002E', {'resource': get_class_name(self)}) raise cherrypy.HTTPError(405, str(e)) cherrypy.response.status = 202 # log request method = 'DELETE' code = self.getRequestMessage(method) reqParams = utf8_dict(self.log_args) log_id = log_request( code, reqParams, None, method, cherrypy.response.status, class_name=get_class_name(self), ) save_request_log_id(log_id, task['id']) return wok.template.render('Task', task)
def create(self, params): conn = self.conn.get() name = params['name'] if name in self.get_list(): raise InvalidOperation("KCHNET0001E", {'name': name}) # handle connection type connection = params["connection"] if connection in ['nat', 'isolated']: if connection == 'nat': params['forward'] = {'mode': 'nat'} # set subnet; bridge/macvtap networks do not need subnet self._set_network_subnet(params) else: self._check_network_interface(params) if connection == 'macvtap': self._set_network_macvtap(params) elif connection == 'bridge': self._set_network_bridge(params) elif connection == 'vepa': self._set_network_vepa(params) # create network XML params['name'] = escape(params['name']) xml = to_network_xml(**params) try: network = conn.networkDefineXML(xml.encode("utf-8")) network.setAutostart(True) except libvirt.libvirtError as e: raise OperationFailed("KCHNET0008E", {'name': name, 'err': e.get_error_message()}) return name
def deactivate(self, name): if self._pool_used_by_template(name): raise InvalidOperation('KCHPOOL0034E', {'name': name}) pool = self.get_storagepool(name, self.conn) # FIXME: nfs workaround - do not try to deactivate a NFS pool # if the NFS server is not reachable. xml = pool.XMLDesc(0) pool_type = xpath_get_text(xml, "/pool/@type")[0] if pool_type == 'netfs' and not self._nfs_status_online(pool): # block the user from dactivating the pool. source = self._get_storage_source(pool_type, xml) raise OperationFailed("KCHPOOL0033E", { 'name': name, 'server': source['addr'] }) return try: persistent = pool.isPersistent() pool.destroy() except libvirt.libvirtError as e: raise OperationFailed("KCHPOOL0010E", { 'name': name, 'err': e.get_error_message() }) # If pool was not persistent, then it was erased by destroy() and # must return nothing here, to trigger _redirect() and avoid errors if not persistent: return ""
def create(self, params): conn = self.conn.get() name = params['name'] if name in self.get_list(): raise InvalidOperation("KCHNET0001E", {'name': name}) connection = params["connection"] # set forward mode, isolated do not need forward if connection != 'isolated': params['forward'] = {'mode': connection} # set subnet, bridge network do not need subnet if connection in ["nat", 'isolated']: self._set_network_subnet(params) # only bridge network need bridge(linux bridge) or interface(macvtap) if connection == 'bridge': self._set_network_bridge(params) params['name'] = escape(params['name']) xml = to_network_xml(**params) try: network = conn.networkDefineXML(xml.encode("utf-8")) network.setAutostart(True) except libvirt.libvirtError as e: raise OperationFailed("KCHNET0008E", {'name': name, 'err': e.get_error_message()}) return name
def create(self, params): if utils.is_lun_scan_enabled(): wok_log.error( "Lun scan is enabled. Cannot add/remove LUNs manually.") raise InvalidOperation("GS390XSTG00009") if 'hbaId' not in params: wok_log.error("hbaId is required for adding a LUN") raise MissingParameter("GS390XSTG00010") hbaId = params['hbaId'] utils.validate_hba_id(hbaId) if 'remoteWwpn' not in params: wok_log.error("remoteWwpn is required for adding a LUN") raise MissingParameter("GS390XSTG00011") wwpn = params['remoteWwpn'] utils.validate_wwpn_or_lun(wwpn) if 'lunId' not in params: wok_log.error("lunId is required for adding a LUN") raise MissingParameter("GS390XSTG00012") lunId = params['lunId'] utils.validate_wwpn_or_lun(lunId) utils.add_lun(hbaId, wwpn, lunId) lun_path = hbaId + ":" + wwpn + ":" + lunId return lun_path
def _tar_create_archive(directory_path, archive_id, include, exclude_flag): archive_file = os.path.join(directory_path, archive_id + '.tar.gz') backup_dir = os.path.join( PluginPaths('ginger').state_dir, 'ginger_backups') bkp = re.compile(backup_dir) if filter(bkp.match, include) and (len(include) == 1): raise InvalidOperation('GINHBK0012E', {'dir': backup_dir}) exclude = ['--exclude=' + backup_dir] if exclude_flag: exclude.extend( ['--exclude=' + toExclude for toExclude in exclude_flag]) cmd = [ 'tar', '--create', '--ignore-failed-read', '--gzip', '--absolute-names', '--file', archive_file, '--selinux', '--acl', '--xattrs' ] + exclude + include out, err, rc = run_command(cmd) if rc != 0: if 'file changed as we read it' in err: raise OperationFailed('GINHBK0010E', {'file': err.split(': ')[1]}) raise OperationFailed('GINHBK0001E', { 'name': archive_file, 'cmd': ' '.join(cmd) }) return archive_file
def create(self, params): task_id = None conn = self.conn.get() from_vg = params.get('source', {}).get('from_vg', False) try: name = params['name'] if name == ISO_POOL_NAME: raise InvalidOperation("KCHPOOL0031E") # The user may want to create a logical pool with the same name # used before but a volume group will already exist with this name # So check the volume group does not exist to create the pool if params['type'] == 'logical': self._check_lvm(name, from_vg) if params['type'] == 'kimchi-iso': task_id = self._do_deep_scan(params) if params['type'] == 'scsi': adapter_name = params['source']['adapter_name'] extra_params = self.device.lookup(adapter_name) # Adds name, adapter_type, wwpn and wwnn to source information params['source'].update(extra_params) params['fc_host_support'] = self.caps.fc_host_support poolDef = StoragePoolDef.create(params) poolDef.prepare(conn) xml = poolDef.xml.encode("utf-8") except KeyError, item: raise MissingParameter("KCHPOOL0004E", { 'item': str(item), 'name': name })
def update(self, vm, mac, params): dom = VMModel.get_vm(vm, self.conn) iface = self._get_vmiface(vm, mac) if iface is None: raise NotFoundError("KCHVMIF0001E", {'name': vm, 'iface': mac}) # cannot change mac address in a running system if DOM_STATE_MAP[dom.info()[0]] != "shutoff": raise InvalidOperation('KCHVMIF0011E') # mac address is a required parameter if 'mac' not in params: raise MissingParameter('KCHVMIF0008E') # new mac address must be unique if self._get_vmiface(vm, params['mac']) is not None: raise InvalidParameter('KCHVMIF0009E', {'name': vm, 'mac': params['mac']}) flags = 0 if dom.isPersistent(): flags |= libvirt.VIR_DOMAIN_AFFECT_CONFIG # remove the current nic xml = etree.tostring(iface) dom.detachDeviceFlags(xml, flags=flags) # add the nic with the desired mac address iface.mac.attrib['address'] = params['mac'] xml = etree.tostring(iface) dom.attachDeviceFlags(xml, flags=flags) return [vm, params['mac']]
def get_current_settings_s390x(self): """ Method to return current SMT settings ('/proc/cmdline') for s390x architecture. Returns: current_smt_settings: dictionary {status, value} """ command = ['cat', '/proc/cmdline'] threads_per_core = LsCpu().get_threads_per_core() output, error, retcode = run_command(command) if retcode != 0: raise OperationFailed('GINSMT003E', {'error': error}) elif (SMT_TWO in output or SMT not in output): status = 'enabled' value = threads_per_core elif SMT_ONE in output and threads_per_core < 2: status = 'enabled' value = 1 elif NOSMT in output and threads_per_core < 2: status = 'disabled' value = NOSMT else: raise InvalidOperation('GINSMT0001E') current_smt_settings = {'status': status, 'smt': value} return current_smt_settings
def save_template(self, params): # Creates the template class with necessary information t = LibvirtVMTemplate(params, scan=True, conn=self.conn) # Validate cpu info t.cpuinfo_validate() # Validate memory t._validate_memory() # Validate volumes for disk in t.info.get('disks'): volume = disk.get('volume') # volume can be None if 'volume' in disk.keys(): self.template_volume_validate(volume, disk['pool']) # template with the same name already exists: raise exception name = params['name'] with self.objstore as session: if name in session.get_list('template'): raise InvalidOperation("KCHTMPL0001E", {'name': name}) # Store template on objectstore try: with self.objstore as session: session.store('template', name, t.info, get_kimchi_version()) except InvalidOperation: raise except Exception, e: raise OperationFailed('KCHTMPL0020E', {'err': e.message})
def delete(self, path): if utils.is_lun_scan_enabled(): wok_log.error( "Lun scan is enabled. Cannot add/remote LUNs manually.") raise InvalidOperation("GS390XSTG00009") path_components = utils.validate_lun_path(path) utils.remove_lun(*path_components)
def enable(self, name, smt_val): """ Enables the SMT. """ if ARCH.startswith('s390x'): self.enable_smt_s390x(name, smt_val) else: raise InvalidOperation('GINSMT0007E', {'name': 'enable'})
def disable(self, name): """ Disables the SMT. """ if ARCH.startswith('s390x'): self.disable_smt_s390x(name) else: raise InvalidOperation('GINSMT0007E', {'name': 'disable'})
def get_list(self, pool_name): pool = StoragePoolModel.get_storagepool(pool_name, self.conn) if not pool.isActive(): raise InvalidOperation("KCHVOL0006E", {'pool': pool_name}) try: pool.refresh(0) except Exception, e: wok_log.error("Pool refresh failed: %s" % str(e))
def _detach_device(self, cb, params): cb('Detaching device') self._cb = cb vmid = params['vmid'] dev_name = params['dev_name'] dom = params['dom'] hostdev = params['hostdev'] lock = params['lock'] with lock: pci_devs = { DeviceModel.deduce_dev_name(e, self.conn): e for e in hostdev if e.attrib['type'] == 'pci' } dev_info = self.dev_model.lookup(dev_name) is_3D_device = self.dev_model.is_device_3D_controller(dev_info) if is_3D_device and DOM_STATE_MAP[dom.info()[0]] != 'shutoff': raise InvalidOperation( 'KCHVMHDEV0006E', {'name': dev_info['name']}) if not pci_devs.get(dev_name): raise NotFoundError( 'KCHVMHDEV0001E', {'vmid': vmid, 'dev_name': dev_name} ) dev_name_elem = pci_devs[dev_name] self._managed = dev_name_elem.get('managed', 'no') == 'yes' # check for multifunction and detach all functions together try: multi = self.unplug_multifunction_pci( dom, hostdev, dev_name_elem) except libvirt.libvirtError: multi = False # successfully detached all functions: finish operation if multi: if is_3D_device: devsmodel = VMHostDevsModel(conn=self.conn) devsmodel.update_mmio_guest(vmid, False) if DOM_STATE_MAP[dom.info()[0]] == 'shutoff': cb('OK', True) return # detach individually xmlstr = etree.tostring(dev_name_elem) dom.detachDeviceFlags(xmlstr, get_vm_config_flag(dom, mode='all')) if dev_name_elem.attrib['type'] == 'pci': self._delete_affected_pci_devices(dom, dev_name, pci_devs) if is_3D_device: devsmodel = VMHostDevsModel(conn=self.conn) devsmodel.update_mmio_guest(vmid, False) if DOM_STATE_MAP[dom.info()[0]] == 'shutoff': cb('OK', True)
def delete(self, name): if self._pool_used_by_template(name): raise InvalidOperation('KCHPOOL0035E', {'name': name}) pool = self.get_storagepool(name, self.conn) if pool.isActive(): raise InvalidOperation('KCHPOOL0005E', {'name': name}) vms = self._get_vms_attach_to_storagepool(name) if len(vms) > 0: raise InvalidOperation( 'KCHPOOL0039E', {'name': name, 'vms': ','.join(vms)}) try: pool.undefine() except libvirt.libvirtError as e: raise OperationFailed( 'KCHPOOL0011E', {'name': name, 'err': e.get_error_message()} )
def delete(self): try: fn = getattr(self.model, model_fn(self, 'delete')) fn(*self.model_args) cherrypy.response.status = 204 except AttributeError: e = InvalidOperation('WOKAPI0002E', {'resource': get_class_name(self)}) raise cherrypy.HTTPError(405, e.message)
def get_list(self, pool_name): pool = StoragePoolModel.get_storagepool(pool_name, self.conn) if not pool.isActive(): raise InvalidOperation('KCHVOL0006E', {'pool': pool_name}) try: pool.refresh(0) except Exception as e: wok_log.error(f'Pool refresh failed: {e}') return sorted(pool.listVolumes())
def deactivate(self, name): if self._is_network_in_use(name): vms = self._get_vms_attach_to_a_network(name) vms.sort() raise InvalidOperation("KCHNET0018E", {'name': name, 'vms': ', '.join(vms)}) network = self.get_network(self.conn.get(), name) network.destroy()
def delete(self, name): try: vg_details = self.lookup(name) if vg_details['Cur LV'] > 0: raise InvalidOperation('GINVG00017E', {'name': name}) utils._remove_vg(name) except OperationFailed: raise OperationFailed("GINVG00004E", {'name': name})
def delete(self): try: fn = getattr(self.model, model_fn(self, 'delete')) task = fn(*self.model_args) except AttributeError: e = InvalidOperation('WOKAPI0002E', {'resource': get_class_name(self)}) raise cherrypy.HTTPError(405, e.message) except OperationFailed, e: raise cherrypy.HTTPError(500, e.message)