diff --git a/virtManager/fsdetails.py b/virtManager/fsdetails.py index 3ed89003..1bfe5ac5 100644 --- a/virtManager/fsdetails.py +++ b/virtManager/fsdetails.py @@ -286,6 +286,7 @@ class vmmFSDetails(vmmGObjectUI): else: self._dev.source = source self._dev.target = target + self._dev.validate_target(target) if mode: self._dev.accessmode = mode if fstype: diff --git a/virtinst/devices/filesystem.py b/virtinst/devices/filesystem.py index e8803992..e593dea2 100644 --- a/virtinst/devices/filesystem.py +++ b/virtinst/devices/filesystem.py @@ -43,21 +43,7 @@ class DeviceFilesystem(Device): readonly = XMLProperty("./readonly", is_bool=True) units = XMLProperty("./source/@units") - - def _validate_set_target(self, val): - # In case of qemu for default fs type (mount) target is not - # actually a directory, it is merely a arbitrary string tag - # that is exported to the guest as a hint for where to mount - if ((self.conn.is_qemu() or self.conn.is_test()) and - (self.type is None or - self.type == self.TYPE_MOUNT)): - pass - elif not os.path.isabs(val): - raise ValueError(_("Filesystem target '%s' must be an absolute " - "path") % val) - return val - target = XMLProperty("./target/@dir", - set_converter=_validate_set_target) + target = XMLProperty("./target/@dir") _source_dir = XMLProperty("./source/@dir") _source_name = XMLProperty("./source/@name") @@ -101,6 +87,33 @@ class DeviceFilesystem(Device): type = property(_get_type, _set_type) + + ############## + # Validation # + ############## + + def validate_target(self, target): + # In case of qemu for default fs type (mount) target is not + # actually a directory, it is merely a arbitrary string tag + # that is exported to the guest as a hint for where to mount + if ((self.conn.is_qemu() or self.conn.is_test()) and + (self.type is None or + self.type == self.TYPE_MOUNT)): + return + + if not os.path.isabs(target): + raise ValueError(_("Filesystem target '%s' must be an absolute " + "path") % target) + + def validate(self): + if self.target: + self.validate_target(self.target) + + + ################## + # Default config # + ################## + def set_defaults(self, guest): ignore = guest diff --git a/virtinst/devices/graphics.py b/virtinst/devices/graphics.py index 233f4eb7..81c7d5b4 100644 --- a/virtinst/devices/graphics.py +++ b/virtinst/devices/graphics.py @@ -98,8 +98,8 @@ class DeviceGraphics(Device): self._local_keymap = -1 - _XML_PROP_ORDER = ["type", "gl", "port", "tlsPort", "autoport", - "keymap", "listen", + _XML_PROP_ORDER = ["type", "gl", "_port", "_tlsPort", "autoport", + "_keymap", "_listen", "passwd", "display", "xauth"] def _get_local_keymap(self): @@ -108,27 +108,36 @@ class DeviceGraphics(Device): self._local_keymap = hostkeymap.default_keymap() return self._local_keymap - def _set_keymap_converter(self, val): + def _set_keymap(self, val): if val == self.KEYMAP_DEFAULT: # Leave it up to the hypervisor - return None - if val == self.KEYMAP_LOCAL: - return self._get_local_keymap() - return val - keymap = XMLProperty("./@keymap", set_converter=_set_keymap_converter) + val = None + elif val == self.KEYMAP_LOCAL: + val = self._get_local_keymap() + self._keymap = val + def _get_keymap(self): + return self._keymap + _keymap = XMLProperty("./@keymap") + keymap = property(_get_keymap, _set_keymap) - def _set_port_converter(self, val): + def _set_port(self, val): val = _validate_port("Port", val) self.autoport = self._get_default_autoport() - return val - def _set_tlsport_converter(self, val): + self._port = val + def _get_port(self): + return self._port + _port = XMLProperty("./@port", is_int=True) + port = property(_get_port, _set_port) + + def _set_tlsport(self, val): val = _validate_port("TLS Port", val) self.autoport = self._get_default_autoport() - return val - port = XMLProperty("./@port", is_int=True, - set_converter=_set_port_converter) - tlsPort = XMLProperty("./@tlsPort", is_int=True, - set_converter=_set_tlsport_converter) + self._tlsPort = val + def _get_tlsport(self): + return self._tlsPort + _tlsPort = XMLProperty("./@tlsPort", is_int=True) + tlsPort = property(_get_tlsport, _set_tlsport) + autoport = XMLProperty("./@autoport", is_yesno=True) channel_main_mode = _get_mode_prop(CHANNEL_TYPE_MAIN) @@ -145,14 +154,17 @@ class DeviceGraphics(Device): def _set_listen(self, val): # Update the corresponding block find_listen = [l for l in self.listens if - (l.type == "address" and l.address == self.listen)] + (l.type == "address" and l.address == self._listen)] if find_listen: if val is None: self.remove_child(find_listen[0]) else: find_listen[0].address = val - return val - listen = XMLProperty("./@listen", set_converter=_set_listen) + self._listen = val + def _get_listen(self): + return self._listen + _listen = XMLProperty("./@listen") + listen = property(_get_listen, _set_listen) type = XMLProperty("./@type") passwd = XMLProperty("./@passwd") diff --git a/virtinst/domain/cpu.py b/virtinst/domain/cpu.py index 89d34086..ed7fb69b 100644 --- a/virtinst/domain/cpu.py +++ b/virtinst/domain/cpu.py @@ -68,7 +68,7 @@ class DomainCpu(XMLBuilder): MATCHS = ["minimum", "exact", "strict"] XML_NAME = "cpu" - _XML_PROP_ORDER = ["mode", "match", "model", "vendor", + _XML_PROP_ORDER = ["mode", "match", "_model", "vendor", "sockets", "cores", "threads", "features"] special_mode_was_set = False @@ -190,8 +190,12 @@ class DomainCpu(XMLBuilder): self.mode = "custom" if not self.match: self.match = "exact" - return val - model = XMLProperty("./model", set_converter=_set_model) + self._model = val + def _get_model(self): + return self._model + _model = XMLProperty("./model") + model = property(_get_model, _set_model) + model_fallback = XMLProperty("./model/@fallback") match = XMLProperty("./@match") diff --git a/virtinst/guest.py b/virtinst/guest.py index a5903b9e..a94066d8 100644 --- a/virtinst/guest.py +++ b/virtinst/guest.py @@ -110,9 +110,9 @@ class Guest(XMLBuilder): XML_NAME = "domain" _XML_PROP_ORDER = ["type", "name", "uuid", "title", "description", - "hotplugmemorymax", "hotplugmemoryslots", "maxmemory", "memory", + "hotplugmemorymax", "hotplugmemoryslots", "maxmemory", "_memory", "blkiotune", "memtune", "memoryBacking", - "vcpus", "curvcpus", "vcpu_placement", + "_vcpus", "curvcpus", "vcpu_placement", "cpuset", "numatune", "resource", "sysinfo", "bootloader", "os", "idmap", "features", "cpu", "clock", "on_poweroff", "on_reboot", "on_crash", @@ -145,28 +145,32 @@ class Guest(XMLBuilder): name = XMLProperty("./name") def _set_memory(self, val): - if val is None: - return None + if val is not None: + val = int(val) + if self.maxmemory is None or self.maxmemory < val: + self.maxmemory = val + self._memory = val + def _get_memory(self): + return self._memory + _memory = XMLProperty("./currentMemory", is_int=True) + memory = property(_get_memory, _set_memory) - if self.maxmemory is None or self.maxmemory < val: - self.maxmemory = val - return val - memory = XMLProperty("./currentMemory", is_int=True, - set_converter=_set_memory) maxmemory = XMLProperty("./memory", is_int=True) hotplugmemorymax = XMLProperty("./maxMemory", is_int=True) hotplugmemoryslots = XMLProperty("./maxMemory/@slots", is_int=True) def _set_vcpus(self, val): - if val is None: - return None + if val is not None: + val = int(val) + # Don't force set curvcpus unless already specified + if self.curvcpus is not None and self.curvcpus > val: + self.curvcpus = val + self._vcpus = val + def _get_vcpus(self): + return self._vcpus + _vcpus = XMLProperty("./vcpu", is_int=True) + vcpus = property(_get_vcpus, _set_vcpus) - # Don't force set curvcpus unless already specified - if self.curvcpus is not None and self.curvcpus > val: - self.curvcpus = val - return val - vcpus = XMLProperty("./vcpu", is_int=True, - set_converter=_set_vcpus) curvcpus = XMLProperty("./vcpu/@current", is_int=True) vcpu_placement = XMLProperty("./vcpu/@placement") cpuset = XMLProperty("./vcpu/@cpuset") diff --git a/virtinst/xmlbuilder.py b/virtinst/xmlbuilder.py index 8ba8b866..51f52a40 100644 --- a/virtinst/xmlbuilder.py +++ b/virtinst/xmlbuilder.py @@ -165,7 +165,6 @@ class XMLChildProperty(_XMLPropertyBase): class XMLProperty(_XMLPropertyBase): def __init__(self, xpath, - set_converter=None, is_bool=False, is_int=False, is_yesno=False, is_onoff=False, do_abspath=False): """ @@ -184,11 +183,6 @@ class XMLProperty(_XMLPropertyBase): in a typical XML document :param name: Just a string to print for debugging, only needed if xpath isn't specified. - :param set_converter: optional function for converting the property - value from the virtinst API to the guest XML. For example, - the Guest.memory API was once in MiB, but the libvirt domain - memory API is in KiB. So, if xpath is specified, on a 'get' - operation we convert the XML value with int(val) / 1024. :param is_bool: Whether this is a boolean property in the XML :param is_int: Whether this is an integer property in the XML :param is_yesno: Whether this is a yes/no property in the XML @@ -205,8 +199,6 @@ class XMLProperty(_XMLPropertyBase): self._is_onoff = is_onoff self._do_abspath = do_abspath - self._convert_value_for_setter_cb = set_converter - if sum([int(bool(i)) for i in [self._is_bool, self._is_int, self._is_yesno, self._is_onoff]]) > 1: @@ -244,7 +236,7 @@ class XMLProperty(_XMLPropertyBase): ret = val return ret - def _convert_set_value(self, xmlbuilder, val): + def _convert_set_value(self, val): if self._do_abspath and val is not None: val = os.path.abspath(val) elif self._is_onoff and val is not None: @@ -256,9 +248,6 @@ class XMLProperty(_XMLPropertyBase): if "0x" in str(val): intkwargs["base"] = 16 val = int(val, **intkwargs) - - if self._convert_value_for_setter_cb: - val = self._convert_value_for_setter_cb(xmlbuilder, val) return val def _nonxml_fset(self, xmlbuilder, val): @@ -329,7 +318,7 @@ class XMLProperty(_XMLPropertyBase): _seenprops.append(self) self._is_tracked = True - setval = self._convert_set_value(xmlbuilder, val) + setval = self._convert_set_value(val) self._nonxml_fset(xmlbuilder, setval) def _set_xml(self, xmlbuilder, setval):