예제 #1
0
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")
예제 #2
0
파일: raid.py 프로젝트: xuejinze1/subiquity
class RaidForm(CompoundDiskForm):
    def __init__(self, model, possible_components, initial, raid_names):
        self.raid_names = raid_names
        super().__init__(model, possible_components, initial)

    name = RaidnameField(_("Name:"))
    level = ChoiceField(_("RAID Level:"), choices=raidlevel_choices)
    devices = MultiDeviceField(_("Devices:"))
    size = ReadOnlyField(_("Size:"))

    def clean_name(self, val):
        if not val:
            raise ValueError("The name cannot be empty")
        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)
        if self.name.value in ('/dev/md/.', '/dev/md/..'):
            return _(". and .. are not valid names for RAID devices")

    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()
예제 #3
0
class GuidedChoiceForm(SubForm):

    disk = ChoiceField(caption=NO_CAPTION, help=NO_HELP, choices=["x"])
    use_lvm = BooleanField(_("Set up this disk as an LVM group"), help=NO_HELP)
    lvm_options = SubFormField(LVMOptionsForm, "", help=NO_HELP)

    def __init__(self, parent):
        super().__init__(parent)
        options = []
        tables = []
        initial = -1
        for disk in parent.model.all_disks():
            for obj, cells in summarize_device(disk):
                table = TablePile([TableRow(cells)])
                tables.append(table)
                enabled = False
                if obj is disk and disk.size > 6 * (2**30):
                    enabled = True
                    if initial < 0:
                        initial = len(options)
                options.append(Option((table, enabled, obj)))
        t0 = tables[0]
        for t in tables[1:]:
            t0.bind(t)
        self.disk.widget.options = options
        self.disk.widget.index = initial
        connect_signal(self.use_lvm.widget, 'change', self._toggle)
        self.lvm_options.enabled = self.use_lvm.value

    def _toggle(self, sender, val):
        self.lvm_options.enabled = val
예제 #4
0
파일: raid.py 프로젝트: posm/subiquity
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)
예제 #5
0
class KeyboardForm(Form):

    cancel_label = _("Back")

    layout = ChoiceField(_("Layout:"), choices=["dummy"])
    variant = ChoiceField(_("Variant:"), choices=["dummy"])
예제 #6
0
class IdentityForm(Form):

    realname = RealnameField(_("Your name:"))
    hostname = UsernameField(
        _("Your server's name:"),
        help=_("The name it uses when it talks to other computers."))
    username = UsernameField(_("Pick a username:"******"Choose a password:"******"Confirm your password:"******"Import SSH identity:"),
        choices=[
            (_("No"), True, None),
            (_("from Github"), True, "gh"),
            (_("from Launchpad"), True, "lp"),
        ],
        help=_("You can import your SSH keys from Github or Launchpad."))
    import_username = UsernameField(_ssh_import_data[None]['caption'])

    def validate_realname(self):
        if len(self.realname.value) < 1:
            return _("Real name must not be empty.")
        if len(self.realname.value) > REALNAME_MAXLEN:
            return _("Realname too long, must be < ") + str(REALNAME_MAXLEN)

    def validate_hostname(self):
        if len(self.hostname.value) < 1:
            return _("Server name must not be empty")

        if len(self.hostname.value) > HOSTNAME_MAXLEN:
            return (_("Server name too long, must be < ") +
                    str(HOSTNAME_MAXLEN))

        if not re.match(r'[a-z_][a-z0-9_-]*', self.hostname.value):
            return _("Hostname must match NAME_REGEX, i.e. [a-z_][a-z0-9_-]*")

    def validate_username(self):
        if len(self.username.value) < 1:
            return _("Username missing")

        if len(self.username.value) > USERNAME_MAXLEN:
            return _("Username too long, must be < ") + str(USERNAME_MAXLEN)

        if not re.match(r'[a-z_][a-z0-9_-]*', self.username.value):
            return _("Username must match NAME_REGEX, i.e. [a-z_][a-z0-9_-]*")

    def validate_password(self):
        if len(self.password.value) < 1:
            return _("Password must be set")

    def validate_confirm_password(self):
        if self.password.value != self.confirm_password.value:
            return _("Passwords do not match")

    # validation of the import username does not read from
    # ssh_import_id.value because it is sometimes done from the
    # 'select' signal of the import id selector, which is called
    # before the import id selector's value has actually changed. so
    # the signal handler stuffs the value here before doing
    # validation (yes, this is a hack).
    ssh_import_id_value = None

    def validate_import_username(self):
        if self.ssh_import_id_value is None:
            return
        username = self.import_username.value
        if len(username) == 0:
            return _("This field must not be blank.")
        if len(username) > SSH_IMPORT_MAXLEN:
            return _("SSH id too long, must be < ") + str(SSH_IMPORT_MAXLEN)
        if self.ssh_import_id_value == 'lp':
            lp_regex = r"^[a-z0-9][a-z0-9\+\.\-]+$"
            if not re.match(lp_regex, self.import_username.value):
                return _("A Launchpad username must be at least two "
                         "characters long and start with a letter or "
                         "number. All letters must be lower-case. The "
                         "characters +, - and . are also allowed after "
                         "the first character."
                         "")
        elif self.ssh_import_id_value == 'gh':
            if username.startswith('-') or (
                    username.endswith('-') or '--' in username
                    or not re.match(r'^[a-zA-Z0-9\-]+$', username)):
                return _("A Github username may only contain alphanumeric "
                         "characters or single hyphens, and cannot begin or "
                         "end with a hyphen.")
예제 #7
0
class NetworkMethodForm(Form):
    ok_label = _("Save")
    method = ChoiceField("IPv{ip_version} Method: ", choices=network_choices)
예제 #8
0
class SSHForm(Form):

    install_server = BooleanField(_("Install OpenSSH server"))

    ssh_import_id = ChoiceField(
        _("Import SSH identity:"),
        choices=[
            (_("No"), True, None),
            (_("from GitHub"), True, "gh"),
            (_("from Launchpad"), True, "lp"),
            ],
        help=_("You can import your SSH keys from GitHub or Launchpad."))

    import_username = UsernameField(_ssh_import_data[None]['caption'])

    pwauth = BooleanField(_("Allow password authentication over SSH"))

    cancel_label = _("Back")

    def __init__(self, initial):
        super().__init__(initial=initial)
        connect_signal(
            self.install_server.widget, 'change', self._toggle_server)
        self._toggle_server(None, self.install_server.value)

    def _toggle_server(self, sender, new_value):
        if new_value:
            self.ssh_import_id.enabled = True
            self.import_username.enabled = self.ssh_import_id.value is not None
            self.pwauth.enabled = self.ssh_import_id.value is not None
        else:
            self.ssh_import_id.enabled = False
            self.import_username.enabled = False
            self.pwauth.enabled = False

    # validation of the import username does not read from
    # ssh_import_id.value because it is sometimes done from the
    # 'select' signal of the import id selector, which is called
    # before the import id selector's value has actually changed. so
    # the signal handler stuffs the value here before doing
    # validation (yes, this is a hack).
    ssh_import_id_value = None

    def validate_import_username(self):
        if self.ssh_import_id_value is None:
            return
        username = self.import_username.value
        if len(username) == 0:
            return _("This field must not be blank.")
        if len(username) > SSH_IMPORT_MAXLEN:
            return _("SSH id too long, must be < ") + str(SSH_IMPORT_MAXLEN)
        if self.ssh_import_id_value == 'lp':
            lp_regex = r"^[a-z0-9][a-z0-9\+\.\-]*$"
            if not re.match(lp_regex, self.import_username.value):
                return _("A Launchpad username must start with a letter or "
                         "number. All letters must be lower-case. The "
                         "characters +, - and . are also allowed after "
                         "the first character.""")
        elif self.ssh_import_id_value == 'gh':
            if not re.match(r'^[a-zA-Z0-9\-]+$', username):
                return _("A GitHub username may only contain alphanumeric "
                         "characters or single hyphens, and cannot begin or "
                         "end with a hyphen.")