class NetworkConfigForm(Form): def __init__(self, ip_version, initial={}): self.ip_version = ip_version fam = ip_families[ip_version] self.ip_address_cls = fam['address_cls'] self.ip_network_cls = fam['network_cls'] super().__init__(initial) ok_label = _("Save") subnet = IPField(_("Subnet:"), has_mask=True) address = IPField(_("Address:")) gateway = IPField(_("Gateway:")) nameservers = StringField(_("Name servers:"), help=_("IP addresses, comma separated")) searchdomains = StringField(_("Search domains:"), help=_("Domains, comma separated")) def clean_subnet(self, subnet): if '/' not in subnet: if self.ip_version == 4: example = "xx.xx.xx.xx/yy" else: example = "xx:xx:..:xx/yy" raise ValueError( _("should be in CIDR form ({example})").format( example=example)) return self.ip_network_cls(subnet) def clean_address(self, address): address = self.ip_address_cls(address) try: subnet = self.subnet.value except ValueError: return if address not in subnet: raise ValueError( _("'%s' is not contained in '%s'") % (address, subnet)) return address def clean_gateway(self, gateway): if not gateway: return None return self.ip_address_cls(gateway) def clean_nameservers(self, value): nameservers = [] for ns in value.split(','): ns = ns.strip() if ns: nameservers.append(ipaddress.ip_address(ns)) return nameservers def clean_searchdomains(self, value): domains = [] for domain in value.split(','): domain = domain.strip() if domain: domains.append(domain) return domains
class NetworkConfigForm(Form): def __init__(self, ip_version): self.ip_version = ip_version super().__init__() fam = ip_families[ip_version] self.ip_address_cls = fam['address_cls'] self.ip_network_cls = fam['network_cls'] subnet = IPField("Subnet:", has_mask=True) address = IPField("Address:") gateway = IPField("Gateway:") nameservers = StringField("Name servers:", help="IP addresses, comma separated") searchdomains = StringField("Search domains:", help="Domains, comma separated") def clean_subnet(self, subnet): log.debug("clean_subnet %r", subnet) if '/' not in subnet: raise ValueError("should be in CIDR form (xx.xx.xx.xx/yy)") return self.ip_network_cls(subnet) def clean_address(self, address): address = self.ip_address_cls(address) try: subnet = self.subnet.value except ValueError: return if address not in subnet: raise ValueError("'%s' is not contained in '%s'" % (address, subnet)) return address def clean_gateway(self, gateway): if not gateway: return None return self.ip_address_cls(gateway) def clean_nameservers(self, value): nameservers = [] for ns in value.split(','): ns = ns.strip() if ns: nameservers.append(ipaddress.ip_address(ns)) return nameservers def clean_searchdomains(self, value): domains = [] for domain in value.split(','): domain = domain.strip() if domain: domains.append(domain) return domains
class RaidForm(CompoundDiskForm): def __init__(self, model, possible_components, initial, raid_names): self.raid_names = raid_names super().__init__(model, possible_components, initial) name = StringField(_("Name:")) level = ChoiceField(_("RAID Level:"), choices=raidlevel_choices) devices = MultiDeviceField(_("Devices:")) size = ReadOnlyField(_("Size:")) def clean_name(self, val): if not re.match('md[0-9]+', val): val = 'md/' + val return val def validate_name(self): if self.name.value in self.raid_names: return _("There is already a RAID named '{}'").format( self.name.value) def validate_devices(self): log.debug('validate_devices %s %s', len(self.devices.value), self.level.value) active_device_count = len(self.devices.widget.active_devices) if active_device_count < self.level.value.min_devices: return _( 'RAID Level "{}" requires at least {} active devices').format( self.level.value.name, self.level.value.min_devices) return super().validate_devices()
class BondForm(Form): def __init__(self, initial, candidate_netdevs, all_netdev_names): self.candidate_netdevs = candidate_netdevs self.all_netdev_names = all_netdev_names super().__init__(initial) connect_signal(self.mode.widget, 'select', self._select_level) self._select_level(None, self.mode.value) name = StringField(_("Name:")) devices = MultiNetdevField(_("Devices: ")) mode = ChoiceField(_("Bond mode:"), choices=BondParameters.modes) xmit_hash_policy = ChoiceField(_("XMIT hash policy:"), choices=BondParameters.xmit_hash_policies) lacp_rate = ChoiceField(_("LACP rate:"), choices=BondParameters.lacp_rates) ok_label = _("Save") def _select_level(self, sender, new_value): self.xmit_hash_policy.enabled = ( new_value in BondParameters.supports_xmit_hash_policy) self.lacp_rate.enabled = (new_value in BondParameters.supports_lacp_rate) def validate_name(self): name = self.name.value if name in self.all_netdev_names: return _('There is already a network device named "{}"').format( name) if len(name) == 0: return _("Name cannot be empty") if len(name) > 16: return _("Name cannot be more than 16 characters long")
class VlanForm(Form): ok_label = _("Create") def __init__(self, parent, device): self.parent = parent self.device = device super().__init__() vlan = StringField(_("VLAN ID:")) def clean_vlan(self, value): try: vlanid = int(value) except ValueError: vlanid = None if vlanid is None or vlanid < 1 or vlanid > 4095: raise ValueError(_("VLAN ID must be between 1 and 4095")) return vlanid def validate_vlan(self): new_name = '%s.%s' % (self.device.name, self.vlan.value) if new_name in self.parent.model.devices_by_name: if self.parent.model.devices_by_name[new_name].config is not None: return _("%s already exists") % new_name
class VlanForm(Form): ok_label = _("Create") def __init__(self, parent, dev_name): self.parent = parent self.dev_name = dev_name super().__init__() vlan = StringField(_("VLAN ID:")) def clean_vlan(self, value): try: vlanid = int(value) except ValueError: vlanid = None if vlanid is None or vlanid < 1 or vlanid > 4095: raise ValueError( _("VLAN ID must be between 1 and 4095")) return vlanid def validate_vlan(self): new_name = '%s.%s' % (self.dev_name, self.vlan.value) if new_name in self.parent.cur_netdev_names: return _("{netdev} already exists").format(netdev=new_name)
class PartitionForm(Form): def __init__(self, mountpoints, max_size, initial, ok_for_slash_boot, lvm_names): self.mountpoints = mountpoints self.ok_for_slash_boot = ok_for_slash_boot self.max_size = max_size if max_size is not None: self.size_str = humanize_size(max_size) self.size.caption = _("Size (max {}):").format(self.size_str) self.lvm_names = lvm_names super().__init__(initial) if max_size is None: self.remove_field('size') connect_signal(self.fstype.widget, 'select', self.select_fstype) self.select_fstype(None, self.fstype.widget.value) def select_fstype(self, sender, fs): self.mount.enabled = fs.is_mounted name = StringField(_("Name: ")) size = SizeField() fstype = FSTypeField(_("Format:")) mount = MountField(_("Mount:")) def clean_size(self, val): if not val: return self.max_size suffixes = ''.join(HUMAN_UNITS) + ''.join(HUMAN_UNITS).lower() if val[-1] not in suffixes: val += self.size_str[-1] if val == self.size_str: return self.max_size else: return dehumanize_size(val) def clean_mount(self, val): if self.fstype.value.is_mounted: return val else: return None def validate_name(self): log.debug("validate_name %s %s", self.name.value, self.lvm_names) if self.name.value in self.lvm_names: return _("There is already a logical volume named {}.").format( self.name.value) def validate_mount(self): mount = self.mount.value if mount is None: return # /usr/include/linux/limits.h:PATH_MAX if len(mount) > 4095: return _('Path exceeds PATH_MAX') dev = self.mountpoints.get(mount) if dev is not None: return _("{} is already mounted at {}.").format( dev.label.title(), mount) if mount == "/boot" and not self.ok_for_slash_boot: return _("/boot must be on a partition of a local disk.")
class RaidForm(Form): def __init__(self, mountpoint_to_devpath_mapping, all_devices, initial, raid_names): self.mountpoint_to_devpath_mapping = mountpoint_to_devpath_mapping self.all_devices = all_devices self.raid_names = raid_names super().__init__(initial) connect_signal(self.fstype.widget, 'select', self.select_fstype) self.select_fstype(None, self.fstype.widget.value) name = StringField(_("Name:")) level = ChoiceField(_("RAID Level:"), choices=raidlevel_choices) devices = MultiDeviceField(_("Devices:")) size = ReadOnlyField(_("Size:")) def select_fstype(self, sender, fs): self.mount.enabled = fs.is_mounted fstype = FSTypeField(_("Format:")) mount = MountField(_("Mount:")) def clean_mount(self, val): if self.fstype.value.is_mounted: return val else: return None def clean_name(self, val): if not re.match('md[0-9]+', val): val = 'md/' + val return val def validate_name(self): if self.name.value in self.raid_names: return _("There is already a RAID named '{}'").format( self.name.value) def validate_devices(self): log.debug( 'validate_devices %s %s', len(self.devices.value), self.level.value) active_device_count = len(self.devices.widget.active_devices) if active_device_count < self.level.value.min_devices: return _( 'RAID Level "{}" requires at least {} active devices').format( self.level.value.name, self.level.value.min_devices) def validate_mount(self): mount = self.mount.value if mount is None: return # /usr/include/linux/limits.h:PATH_MAX if len(mount) > 4095: return _('Path exceeds PATH_MAX') dev = self.mountpoint_to_devpath_mapping.get(mount) if dev is not None: return _("{} is already mounted at {}").format(dev, mount)
class WLANForm(Form): ssid = StringField(caption="Network Name:") psk = PasswordField(caption="Password:"******"Password must be at least 8 characters long if present" elif len(psk) > 63: return "Password must be less than 63 characters long"
class VolGroupForm(CompoundDiskForm): def __init__(self, model, possible_components, initial, vg_names): self.vg_names = vg_names super().__init__(model, possible_components, initial) name = StringField(_("Name:")) devices = MultiDeviceField(_("Devices:")) size = ReadOnlyField(_("Size:")) def validate_devices(self): if len(self.devices.value) < 1: return _("Select at least one device to be part of the volume " "group.") def validate_name(self): if self.name.value in self.vg_names: return _("There is already a volume group named '{}'").format( self.name.value)