def _check_default_pools(self): pools = {} # Don't create default pool if it's not # explicitly specified in template.conf if is_s390x() and 'pool' not in tmpl_defaults['disks'][0]: return default_pool = tmpl_defaults['disks'][0]['pool']['name'] default_pool = default_pool.split('/')[-1] pools[default_pool] = {} if default_pool == 'default': pools[default_pool] = {'path': '/var/lib/libvirt/images'} if config.get('kimchi', {}).get('create_iso_pool', False): pools['ISO'] = {'path': '/var/lib/kimchi/isos'} conn = self.conn.get() for pool_name in pools: error_msg = ("Storage pool %s does not exist or is not " "active. Please, check the configuration in " "%s/template.conf to ensure it lists only valid " "storage." % (pool_name, kimchiPaths.sysconf_dir)) try: pool = conn.storagePoolLookupByName(pool_name) except libvirt.libvirtError, e: pool_path = pools[pool_name].get('path') if pool_path is None: msg = "Fatal: Unable to find storage pool %s. " wok_log.error(msg % pool_name) wok_log.error("Details: %s", e.message) raise Exception(error_msg) # Try to create the pool pool = E.pool(E.name(pool_name), type='dir') pool.append(E.target(E.path(pool_path))) xml = ET.tostring(pool) try: pool = conn.storagePoolDefineXML(xml, 0) except libvirt.libvirtError, e: msg = "Fatal: Unable to create storage pool %s. " wok_log.error(msg % pool_name) wok_log.error("Details: %s", e.message) raise Exception(error_msg) # Build and set autostart value to pool # Ignore error as the pool was already successfully created try: # Add build step to make sure target directory created # The build process may fail when the pool directory # already exists on system pool.build(libvirt.VIR_STORAGE_POOL_BUILD_NEW) pool.setAutostart(1) except: pass
def _get_resources(self, flag_filter): res_list = super(Partitions, self)._get_resources(flag_filter) res_list = filter(lambda x: x.info['available'], res_list) if is_s390x(): # On s390x arch filter out the DASD block devices which # don't have any partition(s). This is necessary because # DASD devices without any partitions are not valid # block device(s) for operations like pvcreate on s390x res_list = filter(lambda x: (x.info['name'].startswith( 'dasd') and x.info['type'] == 'part') or ( not x.info['name'].startswith('dasd')), res_list) res_list.sort(key=lambda x: x.info['path']) return res_list
def __init__(self, args, scan=False, netboot=False): """ Construct a VM Template from a widely variable amount of information. The only required parameter is a name for the VMTemplate. If present, the os_distro and os_version fields are used to lookup recommended settings. Any parameters provided by the caller will override the defaults. If scan is True and a cdrom or a base img is present, the operating system will be detected by probing the installation media. If netboot is True, no cdrom or base img will be used to boot the VM. """ self.info = {} self.fc_host_support = args.get('fc_host_support') # Fetch defaults based on the os distro and version if netboot: distro = version = 'unknown' else: try: distro, version = self._get_os_info(args, scan) except ImageFormatError as e: raise OperationFailed('KCHTMPL0020E', {'err': e.message}) os_distro = args.get('os_distro', distro) os_version = args.get('os_version', version) entry = osinfo.lookup(os_distro, os_version) self.info.update(entry) # Auto-generate a template name if no one is passed if 'name' not in args or args['name'] == '': args['name'] = self._gen_name(distro, version) self.name = args['name'] # Merge graphics settings graph_args = args.get('graphics') if graph_args: graphics = dict(self.info['graphics']) graphics.update(graph_args) args['graphics'] = graphics default_disk = self.info['disks'][0] # Complete memory args, because dict method update is not recursive if 'memory' in args: if 'current' not in args['memory']: args['memory']['current'] = self.info['memory']['current'] if 'maxmemory' not in args['memory']: args['memory']['maxmemory'] = self.info['memory']['maxmemory'] # Override template values according to 'args' self.info.update(args) disks = self.info.get('disks') basic_disk = ['index', 'format', 'pool', 'size'] basic_path_disk = ['index', 'format', 'path', 'size'] ro_disk = ['index', 'format', 'pool', 'volume'] base_disk = ['index', 'base', 'pool', 'size', 'format'] base_path_disk = ['index', 'base', 'path', 'size', 'format'] for index, disk in enumerate(disks): disk_info = dict(default_disk) if is_s390x(): # Default disk should have either pool or path. if 'pool' not in default_disk and 'path' not in default_disk: raise InvalidParameter('KCHTMPL0040E') # Each disk should have either pool or path. # if not then use "default_disk" configuration. pool = disk.get('pool') path = disk.get('path') if not path and not pool: # If default disk is path then set disk with default path if default_disk.get('path'): path = default_disk.get('path') # If default disk is pool then set disk with default pool elif default_disk.get('pool'): pool = default_disk.get('pool') else: pool = disk.get('pool', default_disk.get('pool')) if pool: pool_type = self._get_storage_type(pool['name']) if pool_type in ['iscsi', 'scsi']: disk_info = {'index': 0, 'format': 'raw', 'volume': None} # This check is required where 'pool' disk # has to be added and hence default path # has to be removed during template update. if 'path' in disk_info: del disk_info['path'] disk_info.update(disk) pool_name = disk_info.get('pool', {}).get('name') if pool_name is None: raise MissingParameter('KCHTMPL0028E') keys = sorted(disk_info.keys()) if ((keys != sorted(basic_disk)) and (keys != sorted(ro_disk)) and (keys != sorted(base_disk))): # Addition check required only on s390x if not is_s390x() or (keys != sorted(basic_path_disk)): raise MissingParameter('KCHTMPL0028E') if pool_type in ['logical', 'iscsi', 'scsi']: if disk_info['format'] != 'raw': raise InvalidParameter('KCHTMPL0029E') disk_info['pool']['type'] = pool_type disk_info['index'] = disk_info.get('index', index) self.info['disks'][index] = disk_info elif is_s390x(): # This check is required where 'path' disk # has to be added and hence default pool # has to be removed during template update. if 'pool' in disk_info: del disk_info['pool'] disk_info.update(disk) keys = sorted(disk_info.keys()) if ((keys != sorted(basic_path_disk)) and (keys != sorted(base_path_disk))): raise MissingParameter('KCHTMPL0042E') disk_info['path'] = path disk_info['index'] = disk_info.get('index', index) self.info['disks'][index] = disk_info
def create(self, vm_name, params): # Path will never be blank due to API.json verification. # There is no need to cover this case here. if not ('vol' in params) ^ ('path' in params): if not is_s390x(): raise InvalidParameter('KCHVMSTOR0017E') if 'dir_path' not in params: raise InvalidParameter('KCHVMSTOR0019E') dom = VMModel.get_vm(vm_name, self.conn) params['bus'] = _get_device_bus(params['type'], dom) if is_s390x() and params['type'] == 'disk' and 'dir_path' in params: if 'format' not in params: raise InvalidParameter('KCHVMSTOR0020E') size = params['size'] name = params['name'] dir_path = params.get('dir_path') params['path'] = dir_path + '/' + name if os.path.exists(params['path']): raise InvalidParameter('KCHVMSTOR0021E', {'disk_path': params['path']}) create_disk_image(format_type=params['format'], path=params['path'], capacity=size) else: params['format'] = 'raw' dev_list = [ dev for dev, bus in get_vm_disks(dom).items() if bus == params['bus'] ] dev_list.sort() if len(dev_list) == 0: params['index'] = 0 else: char = dev_list.pop()[2] params['index'] = string.ascii_lowercase.index(char) + 1 if (params['bus'] not in HOTPLUG_TYPE and DOM_STATE_MAP[dom.info()[0]] != 'shutoff'): raise InvalidOperation('KCHVMSTOR0011E') if params.get('vol'): vol_info = self._get_vol_info(params) params['path'] = vol_info['path'] params['disk'] = vol_info['type'] params.update(self._get_available_bus_address(params['bus'], vm_name)) # Add device to VM dev, xml = get_disk_xml(params) try: dom = VMModel.get_vm(vm_name, self.conn) dom.attachDeviceFlags(xml, get_vm_config_flag(dom, 'all')) except Exception as e: raise OperationFailed('KCHVMSTOR0008E', {'error': str(e)}) # Don't put a try-block here. Let the exception be raised. If we # allow disks used_by to be out of sync, data corruption could # occur if a disk is added to two guests unknowingly. if params.get('vol'): used_by = vol_info['used_by'] used_by.append(vm_name) return dev
def create(self, vm_name, params): # Path will never be blank due to API.json verification. # There is no need to cover this case here. if not ('vol' in params) ^ ('path' in params): if not is_s390x(): raise InvalidParameter('KCHVMSTOR0017E') if 'dir_path' not in params: raise InvalidParameter('KCHVMSTOR0019E') dom = VMModel.get_vm(vm_name, self.conn) params['bus'] = _get_device_bus(params['type'], dom) if is_s390x() and params['type'] == 'disk' and 'dir_path' in params: if 'format' not in params: raise InvalidParameter('KCHVMSTOR0020E') size = params['size'] name = params['name'] dir_path = params.get('dir_path') params['path'] = dir_path + '/' + name if os.path.exists(params['path']): raise InvalidParameter( 'KCHVMSTOR0021E', {'disk_path': params['path']}) create_disk_image( format_type=params['format'], path=params['path'], capacity=size ) else: params['format'] = 'raw' dev_list = [ dev for dev, bus in get_vm_disks(dom).items() if bus == params['bus'] ] dev_list.sort() if len(dev_list) == 0: params['index'] = 0 else: char = dev_list.pop()[2] params['index'] = string.ascii_lowercase.index(char) + 1 if ( params['bus'] not in HOTPLUG_TYPE and DOM_STATE_MAP[dom.info()[0]] != 'shutoff' ): raise InvalidOperation('KCHVMSTOR0011E') if params.get('vol'): vol_info = self._get_vol_info(params) params['path'] = vol_info['path'] params['disk'] = vol_info['type'] params.update(self._get_available_bus_address(params['bus'], vm_name)) # Add device to VM dev, xml = get_disk_xml(params) try: dom = VMModel.get_vm(vm_name, self.conn) dom.attachDeviceFlags(xml, get_vm_config_flag(dom, 'all')) except Exception as e: raise OperationFailed('KCHVMSTOR0008E', {'error': str(e)}) # Don't put a try-block here. Let the exception be raised. If we # allow disks used_by to be out of sync, data corruption could # occur if a disk is added to two guests unknowingly. if params.get('vol'): used_by = vol_info['used_by'] used_by.append(vm_name) return dev
def create(self, vm_name, params): vol_model = None # Path will never be blank due to API.json verification. # There is no need to cover this case here. if not ('vol' in params) ^ ('path' in params): if not is_s390x(): raise InvalidParameter("KCHVMSTOR0017E") if 'dir_path' not in params: raise InvalidParameter("KCHVMSTOR0019E") dom = VMModel.get_vm(vm_name, self.conn) params['bus'] = _get_device_bus(params['type'], dom) if is_s390x() and params['type'] == 'disk' and 'dir_path' in params: if 'format' not in params: raise InvalidParameter("KCHVMSTOR0020E") size = params['size'] name = params['name'] dir_path = params.get('dir_path') params['path'] = dir_path + "/" + name if os.path.exists(params['path']): raise InvalidParameter("KCHVMSTOR0021E", {'disk_path': params['path']}) create_disk_image(format_type=params['format'], path=params['path'], capacity=size) else: params['format'] = 'raw' dev_list = [dev for dev, bus in get_vm_disks(dom).iteritems() if bus == params['bus']] dev_list.sort() if len(dev_list) == 0: params['index'] = 0 else: char = dev_list.pop()[2] params['index'] = string.ascii_lowercase.index(char) + 1 if (params['bus'] not in HOTPLUG_TYPE and DOM_STATE_MAP[dom.info()[0]] != 'shutoff'): raise InvalidOperation('KCHVMSTOR0011E') if params.get('vol'): try: pool = params['pool'] vol_model = StorageVolumeModel(conn=self.conn, objstore=self.objstore) vol_info = vol_model.lookup(pool, params['vol']) except KeyError: raise InvalidParameter("KCHVMSTOR0012E") except Exception as e: raise InvalidParameter("KCHVMSTOR0015E", {'error': e}) if len(vol_info['used_by']) != 0: raise InvalidParameter("KCHVMSTOR0016E") valid_format = { "disk": ["raw", "qcow", "qcow2", "qed", "vmdk", "vpc"], "cdrom": "iso"} if vol_info['type'] == 'file': if (params['type'] == 'disk' and vol_info['format'] in valid_format[params['type']]): params['format'] = vol_info['format'] else: raise InvalidParameter("KCHVMSTOR0018E", {"format": vol_info['format'], "type": params['type']}) if (params['format'] == 'raw' and not vol_info['isvalid']): message = 'This is not a valid RAW disk image.' raise OperationFailed('KCHVMSTOR0008E', {'error': message}) params['path'] = vol_info['path'] params['disk'] = vol_info['type'] params.update(self._get_available_bus_address(params['bus'], vm_name)) # Add device to VM dev, xml = get_disk_xml(params) try: dom = VMModel.get_vm(vm_name, self.conn) dom.attachDeviceFlags(xml, get_vm_config_flag(dom, 'all')) except Exception as e: raise OperationFailed("KCHVMSTOR0008E", {'error': e.message}) # Don't put a try-block here. Let the exception be raised. If we # allow disks used_by to be out of sync, data corruption could # occour if a disk is added to two guests unknowingly. if params.get('vol'): used_by = vol_info['used_by'] used_by.append(vm_name) return dev
def __init__(self, args, scan=False, netboot=False): """ Construct a VM Template from a widely variable amount of information. The only required parameter is a name for the VMTemplate. If present, the os_distro and os_version fields are used to lookup recommended settings. Any parameters provided by the caller will override the defaults. If scan is True and a cdrom or a base img is present, the operating system will be detected by probing the installation media. If netboot is True, no cdrom or base img will be used to boot the VM. """ self.info = {} self.fc_host_support = args.get('fc_host_support') # Fetch defaults based on the os distro and version if netboot: distro = version = 'unknown' else: try: distro, version = self._get_os_info(args, scan) except ImageFormatError as e: raise OperationFailed('KCHTMPL0020E', {'err': e.message}) os_distro = args.get('os_distro', distro) os_version = args.get('os_version', version) entry = osinfo.lookup(os_distro, os_version) self.info.update(entry) # Auto-generate a template name if no one is passed if 'name' not in args or args['name'] == '': args['name'] = self._gen_name(distro, version) self.name = args['name'] # Merge graphics settings graph_args = args.get('graphics') if graph_args: graphics = dict(self.info['graphics']) graphics.update(graph_args) args['graphics'] = graphics default_disk = self.info['disks'][0] # Complete memory args, because dict method update is not recursive if 'memory' in args: if 'current' not in args['memory']: args['memory']['current'] = self.info['memory']['current'] if 'maxmemory' not in args['memory']: args['memory']['maxmemory'] = self.info['memory']['maxmemory'] # Override template values according to 'args' self.info.update(args) disks = self.info.get('disks') basic_disk = ['index', 'format', 'pool', 'size'] basic_path_disk = ['index', 'format', 'path', 'size'] ro_disk = ['index', 'format', 'pool', 'volume'] base_disk = ['index', 'base', 'pool', 'size', 'format'] base_path_disk = ['index', 'base', 'path', 'size', 'format'] for index, disk in enumerate(disks): disk_info = dict(default_disk) if is_s390x(): # Default disk should have either pool or path. if 'pool' not in default_disk and 'path' not in default_disk: raise InvalidParameter('KCHTMPL0040E') # Each disk should have either pool or path. # if not then use "default_disk" configuration. pool = disk.get('pool') path = disk.get('path') if not path and not pool: # If default disk is path then set disk with default path if default_disk.get('path'): path = default_disk.get('path') # If default disk is pool then set disk with default pool elif default_disk.get('pool'): pool = default_disk.get('pool') else: pool = disk.get('pool', default_disk.get('pool')) if pool: pool_type = self._get_storage_type(pool['name']) if pool_type in ['iscsi', 'scsi']: disk_info = {'index': 0, 'format': 'raw', 'volume': None} # This check is required where 'pool' disk # has to be added and hence default path # has to be removed during template update. if 'path' in disk_info: del disk_info['path'] disk_info.update(disk) pool_name = disk_info.get('pool', {}).get('name') if pool_name is None: raise MissingParameter('KCHTMPL0028E') keys = sorted(disk_info.keys()) if ( (keys != sorted(basic_disk)) and (keys != sorted(ro_disk)) and (keys != sorted(base_disk)) ): # Addition check required only on s390x if not is_s390x() or (keys != sorted(basic_path_disk)): raise MissingParameter('KCHTMPL0028E') if pool_type in ['logical', 'iscsi', 'scsi']: if disk_info['format'] != 'raw': raise InvalidParameter('KCHTMPL0029E') disk_info['pool']['type'] = pool_type disk_info['index'] = disk_info.get('index', index) self.info['disks'][index] = disk_info elif is_s390x(): # This check is required where 'path' disk # has to be added and hence default pool # has to be removed during template update. if 'pool' in disk_info: del disk_info['pool'] disk_info.update(disk) keys = sorted(disk_info.keys()) if (keys != sorted(basic_path_disk)) and ( keys != sorted(base_path_disk) ): raise MissingParameter('KCHTMPL0042E') disk_info['path'] = path disk_info['index'] = disk_info.get('index', index) self.info['disks'][index] = disk_info
def __init__(self, args, scan=False, netboot=False): """ Construct a VM Template from a widely variable amount of information. The only required parameter is a name for the VMTemplate. If present, the os_distro and os_version fields are used to lookup recommended settings. Any parameters provided by the caller will override the defaults. If scan is True and a cdrom or a base img is present, the operating system will be detected by probing the installation media. If netboot is True, no cdrom or base img will be used to boot the VM. """ self.info = {} self.fc_host_support = args.get("fc_host_support") # Fetch defaults based on the os distro and version if netboot: distro = version = "unknown" else: try: distro, version = self._get_os_info(args, scan) except ImageFormatError as e: raise OperationFailed("KCHTMPL0020E", {"err": e.message}) os_distro = args.get("os_distro", distro) os_version = args.get("os_version", version) entry = osinfo.lookup(os_distro, os_version) self.info.update(entry) # Auto-generate a template name if no one is passed if "name" not in args or args["name"] == "": args["name"] = self._gen_name(distro, version) self.name = args["name"] # Merge graphics settings graph_args = args.get("graphics") if graph_args: graphics = dict(self.info["graphics"]) graphics.update(graph_args) args["graphics"] = graphics default_disk = self.info["disks"][0] # Complete memory args, because dict method update is not recursive if "memory" in args: if "current" not in args["memory"]: args["memory"]["current"] = self.info["memory"]["current"] if "maxmemory" not in args["memory"]: args["memory"]["maxmemory"] = self.info["memory"]["maxmemory"] # Override template values according to 'args' self.info.update(args) disks = self.info.get("disks") basic_disk = ["index", "format", "pool", "size"] basic_path_disk = ["index", "format", "path", "size"] ro_disk = ["index", "format", "pool", "volume"] base_disk = ["index", "base", "pool", "size", "format"] base_path_disk = ["index", "base", "path", "size", "format"] for index, disk in enumerate(disks): disk_info = dict(default_disk) if is_s390x(): # Default disk should have either pool or path. if "pool" not in default_disk and "path" not in default_disk: raise InvalidParameter("KCHTMPL0040E") # Each disk should have either pool or path. # if not then use "default_disk" configuration. pool = disk.get("pool") path = disk.get("path") if not path and not pool: # If default disk is path then set disk with default path if default_disk.get("path"): path = default_disk.get("path") # If default disk is pool then set disk with default pool elif default_disk.get("pool"): pool = default_disk.get("pool") else: pool = disk.get("pool", default_disk.get("pool")) if pool: pool_type = self._get_storage_type(pool["name"]) if pool_type in ["iscsi", "scsi"]: disk_info = {"index": 0, "format": "raw", "volume": None} # This check is required where 'pool' disk # has to be added and hence default path # has to be removed during template update. if "path" in disk_info: del disk_info["path"] disk_info.update(disk) pool_name = disk_info.get("pool", {}).get("name") if pool_name is None: raise MissingParameter("KCHTMPL0028E") keys = sorted(disk_info.keys()) if (keys != sorted(basic_disk)) and (keys != sorted(ro_disk)) and (keys != sorted(base_disk)): # Addition check required only on s390x if not is_s390x() or (keys != sorted(basic_path_disk)): raise MissingParameter("KCHTMPL0028E") if pool_type in ["logical", "iscsi", "scsi"]: if disk_info["format"] != "raw": raise InvalidParameter("KCHTMPL0029E") disk_info["pool"]["type"] = pool_type disk_info["index"] = disk_info.get("index", index) self.info["disks"][index] = disk_info elif is_s390x(): # This check is required where 'path' disk # has to be added and hence default pool # has to be removed during template update. if "pool" in disk_info: del disk_info["pool"] disk_info.update(disk) keys = sorted(disk_info.keys()) if (keys != sorted(basic_path_disk)) and (keys != sorted(base_path_disk)): raise MissingParameter("KCHTMPL0042E") disk_info["path"] = path disk_info["index"] = disk_info.get("index", index) self.info["disks"][index] = disk_info