Example #1
0
class PBIUploadForm(Form):
    pbifile = FileField(label=_("PBI file to be installed"), required=True)
    pjail = forms.ChoiceField(
        label=_("Plugin Jail"),
        help_text=_("The plugin jail that the PBI is to be installed in."),
        choices=(),
        widget=forms.Select(attrs={'class': 'required'}),
    )

    def __init__(self, *args, **kwargs):
        self.jail = None
        if kwargs and kwargs.has_key('jail'):
            self.jail = kwargs.pop('jail')

        super(PBIUploadForm, self).__init__(*args, **kwargs)

        if not self.jail:
            jc = JailsConfiguration.objects.order_by("-id")[0]
            try:
                clean_path_execbit(jc.jc_path)
            except forms.ValidationError, e:
                self.errors['__all__'] = self.error_class(e.messages)

            pjlist = []
            wlist = Warden().list()
            for wj in wlist:
                if wj[WARDEN_KEY_TYPE] == WARDEN_TYPE_PLUGINJAIL and \
                    wj[WARDEN_KEY_STATUS] == WARDEN_STATUS_RUNNING:
                    pjlist.append(wj[WARDEN_KEY_HOST])

            self.fields['pjail'].choices = [(pj, pj) for pj in pjlist]

        else:
Example #2
0
class FirmwareTemporaryLocationForm(Form):
    mountpoint = forms.ChoiceField(
        label=_("Place to temporarily place firmware file"),
        help_text=_("The system will use this place to temporarily store the "
                    "firmware file before it's being applied."),
        choices=(),
        widget=forms.Select(attrs={'class': 'required'}),
    )

    def clean_mountpoint(self):
        mp = self.cleaned_data.get("mountpoint")
        if mp.startswith('/'):
            clean_path_execbit(mp)
        clean_path_locked(mp)
        return mp

    def __init__(self, *args, **kwargs):
        super(FirmwareTemporaryLocationForm, self).__init__(*args, **kwargs)
        self.fields['mountpoint'].choices = [
            (x.mp_path, x.mp_path)
            for x in MountPoint.objects.exclude(mp_volume__vol_fstype='iscsi')
        ]
        self.fields['mountpoint'].choices.append(
            (':temp:', _('Memory device')))

    def done(self, *args, **kwargs):
        mp = str(self.cleaned_data["mountpoint"])
        if mp == ":temp:":
            notifier().create_upload_location()
        else:
            notifier().change_upload_location(mp)
Example #3
0
    def __init__(self, *args, **kwargs):
        self.jail = None
        if kwargs and kwargs.has_key('jail'):
            self.jail = kwargs.pop('jail') 

        super(MkdirForm, self).__init__(*args, **kwargs)

        if self.jail:
            self.jc = JailsConfiguration.objects.order_by("-id")[0]
            jail_path = "%s/%s" % (self.jc.jc_path, self.jail.jail_host)

            self.fields['path'].widget.attrs['root'] = (jail_path)
            self.fields['jail'].initial = self.jail.jail_host
            self.fields['jail'].widget.attrs = {
                'readonly': True,
                'class': (
                    'dijitDisabled dijitTextBoxDisabled'
                    'dijitValidationTextBoxDisabled' 
                ),
            }

        else:
            self.fields['jail'] = forms.ChoiceField(
                label=_("Jail"),
                choices=(),
                widget=forms.Select(attrs={'class': 'required'}),
            )

            pjlist = []
            wlist = Warden().list()
            for wj in wlist:
                if wj[WARDEN_KEY_STATUS] == WARDEN_STATUS_RUNNING:
                    pjlist.append(wj[WARDEN_KEY_HOST])

            self.fields['jail'].choices = [(pj, pj) for pj in pjlist ]
Example #4
0
class PBITemporaryLocationForm(Form):
    mountpoint = forms.ChoiceField(
        label=_("Place to temporarily place PBI file"),
        help_text=_("The system will use this place to temporarily store the "
                    "PBI file before it's installed."),
        choices=(),
        widget=forms.Select(attrs={'class': 'required'}),
    )

    def __init__(self, *args, **kwargs):
        super(PBITemporaryLocationForm, self).__init__(*args, **kwargs)
        mp = PluginsJail.objects.order_by("-id")
        if mp and notifier().plugins_jail_configured():
            mp = mp[0]
            self.fields['mountpoint'].choices = [
                (mp.plugins_path, mp.plugins_path),
            ]
        else:
            self.fields['mountpoint'].choices = [(x.mp_path, x.mp_path) \
                for x in MountPoint.objects.exclude(
                    mp_volume__vol_fstype='iscsi')]

    def done(self, *args, **kwargs):
        notifier().change_upload_location(
            self.cleaned_data["mountpoint"].__str__())
Example #5
0
    def __init__(self, *args, **kwargs):
        self.jail = None
        if kwargs and 'jail' in kwargs:
            self.jail = kwargs.pop('jail')

        super(NullMountPointForm, self).__init__(*args, **kwargs)

        if kwargs and 'instance' in kwargs:
            self.instance = kwargs.pop('instance')
            if not self.jail:
                self.jail = Jails.objects.filter(
                    jail_host=self.instance.jail)[0]

        self.jc = JailsConfiguration.objects.order_by("-id")[0]
        self.fields['jail'] = forms.ChoiceField(
            label=_("Jail"),
            choices=(),
            widget=forms.Select(attrs={'class': 'required'}),
        )
        if self.jail:
            self.fields['jail'].initial = self.jail.jail_host
            self.fields['jail'].widget.attrs['readonly'] = True

        try:
            clean_path_execbit(self.jc.jc_path)
        except forms.ValidationError, e:
            self.errors['__all__'] = self.error_class(e.messages)
Example #6
0
class ZFSDataset_CreateForm(Form):
    dataset_name = forms.CharField(max_length=128, label=_('Dataset Name'))
    dataset_compression = forms.ChoiceField(
        choices=choices.ZFS_CompressionChoices,
        widget=forms.Select(attrs=attrs_dict),
        label=_('Compression level'))
    dataset_atime = forms.ChoiceField(
        choices=choices.ZFS_AtimeChoices,
        widget=forms.RadioSelect(attrs=attrs_dict),
        label=_('Enable atime'))
    dataset_refquota = forms.CharField(max_length=128,
                                       initial=0,
                                       label=_('Quota for this dataset'),
                                       help_text=_('0=Unlimited; example: 1g'))
    dataset_quota = forms.CharField(
        max_length=128,
        initial=0,
        label=_('Quota for this dataset and all children'),
        help_text=_('0=Unlimited; example: 1g'))
    dataset_refreserv = forms.CharField(
        max_length=128,
        initial=0,
        label=_('Reserved space for this dataset'),
        help_text=_('0=None; example: 1g'))
    dataset_reserv = forms.CharField(
        max_length=128,
        initial=0,
        label=_('Reserved space for this dataset and all children'),
        help_text=_('0=None; example: 1g'))

    def __init__(self, *args, **kwargs):
        self.fs = kwargs.pop('fs')
        super(ZFSDataset_CreateForm, self).__init__(*args, **kwargs)

    def clean_dataset_name(self):
        name = self.cleaned_data["dataset_name"]
        if not re.search(r'^[a-zA-Z0-9][a-zA-Z0-9_\-:.]*$', name):
            raise forms.ValidationError(
                _("Dataset names must begin with an "
                  "alphanumeric character and may only contain "
                  "\"-\", \"_\", \":\" and \".\"."))
        return name

    def clean(self):
        cleaned_data = _clean_quota_fields(
            self, ('refquota', 'quota', 'reserv', 'refreserv'), "dataset_")
        full_dataset_name = "%s/%s" % (self.fs,
                                       cleaned_data.get("dataset_name"))
        if len(zfs.list_datasets(path=full_dataset_name)) > 0:
            msg = _(u"You already have a dataset with the same name")
            self._errors["dataset_name"] = self.error_class([msg])
            del cleaned_data["dataset_name"]
        return cleaned_data

    def set_error(self, msg):
        msg = u"%s" % msg
        self._errors['__all__'] = self.error_class([msg])
        del self.cleaned_data
Example #7
0
    def __init__(self, *args, **kwargs):
        self.jail = None
        if kwargs and 'jail' in kwargs:
            self.jail = kwargs.pop('jail')

        super(JailMountPointForm, self).__init__(*args, **kwargs)

        self._full = None

        if kwargs and 'instance' in kwargs:
            self.instance = kwargs.pop('instance')
            if not self.jail and self.instance.id:
                try:
                    self.jail = Jails.objects.filter(
                        jail_host=self.instance.jail
                    )[0]
                except:
                    pass

        self.jc = JailsConfiguration.objects.order_by("-id")[0]
        self.fields['jail'] = forms.ChoiceField(
            label=_("Jail"),
            choices=(),
            widget=forms.Select(attrs={'class': 'required'}),
        )
        if self.jail:
            self.fields['jail'].initial = self.jail.jail_host
            self.fields['jail'].widget.attrs['readonly'] = True
            jail_path = "%s/%s" % (self.jc.jc_path, self.jail.jail_host)
            self.fields['destination'].widget.attrs['root'] = jail_path

        try:
            clean_path_execbit(self.jc.jc_path)
        except forms.ValidationError as e:
            self.errors['__all__'] = self.error_class(e.messages)

        pjlist = []
        try:
            wlist = Warden().cached_list()
        except:
            wlist = []

        for wj in wlist:
            pjlist.append(wj[WARDEN_KEY_HOST])

        self.fields['jail'].choices = [('', '')] + [(pj, pj) for pj in pjlist]
        self.fields['jail'].widget.attrs['onChange'] = (
            'addStorageJailChange(this);'
        )

        self.fields['mpjc_path'].widget = forms.widgets.HiddenInput()
        self.fields['mpjc_path'].initial = self.jc.jc_path

        if self.instance.id:
            self.fields['mounted'].initial = self.instance.mounted
        else:
            self.fields['mounted'].widget = forms.widgets.HiddenInput()
Example #8
0
    def __init__(self, *args, **kwargs):
        super(iSCSITargetExtentForm, self).__init__(*args, **kwargs)
        key_order(self, 1, 'iscsi_target_extent_type', instance=True)

        if not self._api:
            self.fields['iscsi_target_extent_disk'] = forms.ChoiceField(
                choices=(),
                widget=forms.Select(attrs={'maxHeight': 200}),
                label=_('Device'),
                required=False,
            )
        else:
            self.fields['iscsi_target_extent_disk'] = forms.CharField(
                required=False,
            )

        key_order(self, 2, 'iscsi_target_extent_disk', instance=True)

        if self.instance.id:
            with client as c:
                e = self.instance.iscsi_target_extent_path
                exclude = [e] if not self._api else []

                disk_choices = list(c.call(
                    'iscsi.extent.disk_choices', exclude
                ).items())

                disk_choices.sort(key=lambda x: x[1])

            if self.instance.iscsi_target_extent_type == 'File':
                self.fields['iscsi_target_extent_type'].initial = 'File'
            else:
                self.fields['iscsi_target_extent_type'].initial = 'Disk'
            if not self._api:
                self.fields['iscsi_target_extent_disk'].choices = disk_choices
            if self.instance.iscsi_target_extent_type in ('ZVOL', 'HAST'):
                self.fields['iscsi_target_extent_disk'].initial = disk_choices
            else:
                self.fields['iscsi_target_extent_disk'].initial = self.instance.get_device()[5:]
            self._path = self.instance.iscsi_target_extent_path
            self._name = self.instance.iscsi_target_extent_name
        elif not self._api:
            with client as c:
                disk_choices = list(c.call(
                    'iscsi.extent.disk_choices'
                ).items())

                disk_choices.sort(key=lambda x: x[1])

            self.fields['iscsi_target_extent_disk'].choices = disk_choices
        self.fields['iscsi_target_extent_type'].widget.attrs['onChange'] = "iscsiExtentToggle();extentZvolToggle();"
        self.fields['iscsi_target_extent_path'].required = False

        self.fields['iscsi_target_extent_disk'].widget.attrs['onChange'] = (
            'extentZvolToggle();'
        )
Example #9
0
class ZFSDataset_EditForm(Form):
    dataset_compression = forms.ChoiceField(
        choices=choices.ZFS_CompressionChoices,
        widget=forms.Select(attrs=attrs_dict),
        label=_('Compression level'))
    dataset_atime = forms.ChoiceField(
        choices=choices.ZFS_AtimeChoices,
        widget=forms.RadioSelect(attrs=attrs_dict),
        label=_('Enable atime'))
    dataset_refquota = forms.CharField(max_length=128,
                                       initial=0,
                                       label=_('Quota for this dataset'),
                                       help_text=_('0=Unlimited; example: 1g'))
    dataset_quota = forms.CharField(
        max_length=128,
        initial=0,
        label=_('Quota for this dataset and all children'),
        help_text=_('0=Unlimited; example: 1g'))
    dataset_refreservation = forms.CharField(
        max_length=128,
        initial=0,
        label=_('Reserved space for this dataset'),
        help_text=_('0=None; example: 1g'))
    dataset_reservation = forms.CharField(
        max_length=128,
        initial=0,
        label=_('Reserved space for this dataset and all children'),
        help_text=_('0=None; example: 1g'))

    def __init__(self, *args, **kwargs):
        self._fs = kwargs.pop("fs", None)
        super(ZFSDataset_EditForm, self).__init__(*args, **kwargs)
        data = notifier().zfs_get_options(self._fs)
        self.fields['dataset_compression'].initial = data['compression']
        self.fields['dataset_atime'].initial = data['atime']

        for attr in ('refquota', 'quota', 'reservation', 'refreservation'):
            formfield = 'dataset_%s' % (attr)
            if data[attr] == 'none':
                self.fields[formfield].initial = 0
            else:
                self.fields[formfield].initial = data[attr]

    def clean(self):
        return _clean_quota_fields(
            self, ('refquota', 'quota', 'reservation', 'refreservation'),
            "dataset_")

    def set_error(self, msg):
        msg = u"%s" % msg
        self._errors['__all__'] = self.error_class([msg])
        del self.cleaned_data
Example #10
0
    def __init__(self, *args, **kwargs):
        self.jail = None
        if kwargs and kwargs.has_key('jail'):
            self.jail = kwargs.pop('jail') 

        super(NullMountPointForm, self).__init__(*args, **kwargs)

        if kwargs and kwargs.has_key('instance'):
            self.instance = kwargs.pop('instance') 

        if self.jail:
            self.fields['jail'].initial = self.jail.jail_host
            self.fields['jail'].widget.attrs = {
                'readonly': True,
                'class': (
                    'dijitDisabled dijitTextBoxDisabled'
                    'dijitValidationTextBoxDisabled' 
                ),
            }

            self.jc = JailsConfiguration.objects.order_by("-id")[0]
            jail_path = "%s/%s" % (self.jc.jc_path, self.jail.jail_host)

            self.fields['destination'].widget.attrs['root'] = (jail_path)

        else:
            self.fields['jail'] = forms.ChoiceField(
                label=_("Jail"),
                choices=(),
                widget=forms.Select(attrs={'class': 'required'}),
            )

            jc = JailsConfiguration.objects.order_by("-id")[0]
            try:
                clean_path_execbit(jc.jc_path)
            except forms.ValidationError, e:
                self.errors['__all__'] = self.error_class(e.messages)

            pjlist = []
            wlist = Warden().list()
            for wj in wlist:
                if wj[WARDEN_KEY_STATUS] == WARDEN_STATUS_RUNNING:
                    pjlist.append(wj[WARDEN_KEY_HOST])

            self.fields['jail'].choices = [(pj, pj) for pj in pjlist ]
Example #11
0
class FirmwareTemporaryLocationForm(Form):
    mountpoint = forms.ChoiceField(
        label=_("Place to temporarily place firmware file"),
        help_text=_("The system will use this place to temporarily store the "
                    "firmware file before it's being applied."),
        choices=(),
        widget=forms.Select(attrs={'class': 'required'}),
    )

    def __init__(self, *args, **kwargs):
        super(FirmwareTemporaryLocationForm, self).__init__(*args, **kwargs)
        self.fields['mountpoint'].choices = [
            (x.mp_path, x.mp_path)
            for x in MountPoint.objects.exclude(mp_volume__vol_fstype='iscsi')
        ]

    def done(self, *args, **kwargs):
        notifier().change_upload_location(
            self.cleaned_data["mountpoint"].__str__())
Example #12
0
class DiskReplacementForm(forms.Form):

    volume_disks = forms.ChoiceField(choices=(),
                                     widget=forms.Select(attrs=attrs_dict),
                                     label=_('Member disk'))

    def __init__(self, *args, **kwargs):
        self.disk = kwargs.pop('disk', None)
        super(DiskReplacementForm, self).__init__(*args, **kwargs)
        self.fields['volume_disks'].choices = self._populate_disk_choices()
        self.fields['volume_disks'].choices.sort(key=lambda a: float(
            re.sub(r'^.*?([0-9]+)[^0-9]*([0-9]*).*$', r'\1.\2', a[0])))

    def _populate_disk_choices(self):

        diskchoices = dict()
        used_disks = []
        for v in models.Volume.objects.all():
            used_disks.extend(v.get_disks())
        if self.disk and self.disk in used_disks:
            used_disks.remove(self.disk)

        # Grab partition list
        # NOTE: This approach may fail if device nodes are not accessible.
        disks = notifier().get_disks()

        for disk in disks:
            if disk in used_disks:
                continue
            devname, capacity = disks[disk]['devname'], disks[disk]['capacity']
            capacity = humanize_number_si(int(capacity))
            if devname == self.disk:
                diskchoices[devname] = "In-place [%s (%s)]" % (devname,
                                                               capacity)
            else:
                diskchoices[devname] = "%s (%s)" % (devname, capacity)

        choices = diskchoices.items()
        choices.sort(key=lambda a: float(
            re.sub(r'^.*?([0-9]+)[^0-9]*([0-9]*).*$', r'\1.\2', a[0])))
        return choices
Example #13
0
    def __init__(self, *args, **kwargs):
        self.jail = None
        if kwargs and 'jail' in kwargs:
            self.jail = kwargs.pop('jail')

        super(PBIUploadForm, self).__init__(*args, **kwargs)

        if self.jail:
            self.fields['pjail'] = forms.ChoiceField(
                label=_("Plugin Jail"),
                help_text=_(
                    "The plugin jail that the PBI is to be installed in."),
                choices=((self.jail.jail_host, self.jail.jail_host), ),
                widget=forms.Select(
                    attrs={
                        'class': ('requireddijitDisabled dijitTextBoxDisabled '
                                  'dijitValidationTextBoxDisabled'),
                        'readonly':
                        True,
                    }),
                required=False,
            )
Example #14
0
class ZVol_CreateForm(Form):
    zvol_name = forms.CharField(max_length=128, label=_('ZFS Volume Name'))
    zvol_size = forms.CharField(max_length=128,
                                label=_('Size for this ZFS Volume'),
                                help_text=_('Example: 1g'))
    zvol_compression = forms.ChoiceField(
        choices=choices.ZFS_CompressionChoices,
        widget=forms.Select(attrs=attrs_dict),
        label=_('Compression level'))

    def __init__(self, *args, **kwargs):
        self.vol_name = kwargs.pop('vol_name')
        super(ZVol_CreateForm, self).__init__(*args, **kwargs)

    def clean_dataset_name(self):
        name = self.cleaned_data["zvol_name"]
        if not re.search(r'^[a-zA-Z0-9][a-zA-Z0-9_\-:.]*$', name):
            raise forms.ValidationError(
                _("ZFS Volume names must begin with "
                  "an alphanumeric character and may only contain "
                  "(-), (_), (:) and (.)."))
        return name

    def clean(self):
        cleaned_data = self.cleaned_data
        full_zvol_name = "%s/%s" % (self.vol_name,
                                    cleaned_data.get("zvol_name"))
        if len(zfs.list_datasets(path=full_zvol_name)) > 0:
            msg = _(u"You already have a dataset with the same name")
            self._errors["zvol_name"] = self.error_class([msg])
            del cleaned_data["zvol_name"]
        return cleaned_data

    def set_error(self, msg):
        msg = u"%s" % msg
        self._errors['__all__'] = self.error_class([msg])
        del self.cleaned_data
Example #15
0
class VolumeAutoImportForm(forms.Form):

    volume_disks = forms.ChoiceField(choices=(),
                                     widget=forms.Select(attrs=attrs_dict),
                                     label=_('Volume'))

    def __init__(self, *args, **kwargs):
        super(VolumeAutoImportForm, self).__init__(*args, **kwargs)
        self.fields['volume_disks'].choices = self._populate_disk_choices()

    def _populate_disk_choices(self):

        diskchoices = dict()
        used_disks = []
        for v in models.Volume.objects.all():
            used_disks.extend(v.get_disks())

        # Grab partition list
        # NOTE: This approach may fail if device nodes are not accessible.
        vols = notifier().detect_volumes()

        for vol in list(vols):
            for vdev in vol['disks']['vdevs']:
                for disk in vdev['disks']:
                    if filter(lambda x: x is not None and \
                                disk['name'].startswith(x),
                            used_disks):
                        vols.remove(vol)
                        break
                else:
                    continue
                break

        for vol in vols:
            if vol.get("id", None):
                devname = "%s [%s, id=%s]" % (vol['label'], vol['type'],
                                              vol['id'])
            else:
                devname = "%s [%s]" % (vol['label'], vol['type'])
            diskchoices[vol['label']] = "%s" % (devname, )

        choices = diskchoices.items()
        return choices

    def clean(self):
        cleaned_data = self.cleaned_data
        vols = notifier().detect_volumes()
        for vol in vols:
            if vol['label'] == cleaned_data['volume_disks']:
                cleaned_data['volume'] = vol
                break

        if cleaned_data.get('volume', None) == None:
            self._errors['__all__'] = self.error_class([
                _("You must select a volume."),
            ])

        else:
            if models.Volume.objects.filter(
                    vol_name=cleaned_data['volume']['label']).count() > 0:
                msg = _(u"You already have a volume with same name")
                self._errors["volume_disks"] = self.error_class([msg])
                del cleaned_data["volume_disks"]

            if cleaned_data['volume']['type'] == 'geom':
                if cleaned_data['volume']['group_type'] == 'mirror':
                    dev = "/dev/mirror/%s" % (cleaned_data['volume']['label'])
                elif cleaned_data['volume']['group_type'] == 'stripe':
                    dev = "/dev/stripe/%s" % (cleaned_data['volume']['label'])
                elif cleaned_data['volume']['group_type'] == 'raid3':
                    dev = "/dev/raid3/%s" % (cleaned_data['volume']['label'])
                else:
                    raise NotImplementedError

                isvalid = notifier().precheck_partition(dev, 'UFS')
                if not isvalid:
                    msg = _(u"The selected disks were not verified for this "
                            "import rules.")
                    self._errors["volume_disks"] = self.error_class([msg])

                    if "volume_disks" in cleaned_data:
                        del cleaned_data["volume_disks"]

            elif cleaned_data['volume']['type'] != 'zfs':
                raise NotImplementedError

        return cleaned_data

    def done(self, request):

        vol = self.cleaned_data['volume']
        volume_name = vol['label']
        group_type = vol['group_type']
        if vol['type'] == 'geom':
            volume_fstype = 'UFS'
        elif vol['type'] == 'zfs':
            volume_fstype = 'ZFS'

        with transaction.commit_on_success():
            volume = models.Volume(vol_name=volume_name,
                                   vol_fstype=volume_fstype)
            volume.save()
            self.volume = volume

            mp = models.MountPoint(mp_volume=volume,
                                   mp_path='/mnt/' + volume_name,
                                   mp_options='rw')
            mp.save()

            if vol['type'] != 'zfs':
                notifier().label_disk(volume_name,
                                      "%s/%s" % (group_type, volume_name),
                                      'UFS')
            else:
                volume.vol_guid = vol['id']
                volume.save()
                models.Scrub.objects.create(scrub_volume=volume)

            if vol['type'] == 'zfs' and not notifier().zfs_import(
                    vol['label'], vol['id']):
                raise MiddlewareError(
                    _('The volume "%s" failed to import, '
                      'for futher details check pool status') % vol['label'])

        notifier().reload("disk")
Example #16
0
class iSCSITargetDeviceExtentForm(ModelForm):

    iscsi_extent_disk = forms.ChoiceField(
        choices=(),
        widget=forms.Select(attrs={'maxHeight': 200}),
        label=_('Disk device'))

    class Meta:
        model = models.iSCSITargetExtent
        exclude = ('iscsi_target_extent_type', 'iscsi_target_extent_path',
                   'iscsi_target_extent_filesize')

    def __init__(self, *args, **kwargs):
        super(iSCSITargetDeviceExtentForm, self).__init__(*args, **kwargs)
        if kwargs.has_key("instance"):
            self.fields[
                'iscsi_extent_disk'].choices = self._populate_disk_choices(
                    exclude=self.instance)
            if self.instance.iscsi_target_extent_type == 'ZVOL':
                self.fields[
                    'iscsi_extent_disk'].initial = self.instance.iscsi_target_extent_path
            else:
                self.fields[
                    'iscsi_extent_disk'].initial = self.instance.get_device(
                    )[5:]
            self._path = self.instance.iscsi_target_extent_path
            self._name = self.instance.iscsi_target_extent_name
        else:
            self.fields[
                'iscsi_extent_disk'].choices = self._populate_disk_choices()
        self.fields['iscsi_extent_disk'].choices.sort()

    # TODO: This is largely the same with disk wizard.
    def _populate_disk_choices(self, exclude=None):

        diskchoices = dict()

        qs = models.iSCSITargetExtent.objects.filter(
            iscsi_target_extent_type='Disk')
        if exclude:
            qs = qs.exclude(id=exclude.id)
        diskids = [i[0] for i in qs.values_list('iscsi_target_extent_path')]
        used_disks = [d.disk_name for d in Disk.objects.filter(id__in=diskids)]

        qs = models.iSCSITargetExtent.objects.filter(
            iscsi_target_extent_type='ZVOL')
        if exclude:
            qs = qs.exclude(id=exclude.id)
        used_zvol = [i[0] for i in qs.values_list('iscsi_target_extent_path')]

        for v in models.Volume.objects.all():
            used_disks.extend(v.get_disks())

        for volume in Volume.objects.filter(vol_fstype__exact='ZFS'):
            zvols = notifier().list_zfs_vols(volume.vol_name)
            for zvol, attrs in zvols.items():
                if "zvol/" + zvol not in used_zvol:
                    diskchoices["zvol/" +
                                zvol] = "%s (%s)" % (zvol, attrs['volsize'])

        # Grab partition list
        # NOTE: This approach may fail if device nodes are not accessible.
        disks = notifier().get_disks()
        for name, disk in disks.items():
            if name in used_disks:
                continue
            capacity = humanize_size(disk['capacity'])
            diskchoices[name] = "%s (%s)" % (name, capacity)

        # HAST Devices through GEOM GATE
        gate_pipe = os.popen(
            """/usr/sbin/diskinfo `/sbin/geom gate status -s"""
            """| /usr/bin/cut -d" " -f1` | /usr/bin/cut -f1,3""")
        gate_diskinfo = gate_pipe.read().strip().split('\n')
        for disk in gate_diskinfo:
            if disk:
                devname, capacity = disk.split('\t')
                capacity = humanize_size(capacity)
                diskchoices[devname] = "%s (%s)" % (devname, capacity)

        return diskchoices.items()

    def save(self, commit=True):
        oExtent = super(iSCSITargetDeviceExtentForm, self).save(commit=False)
        if commit:
            # label it only if it is a real disk
            if self.cleaned_data["iscsi_extent_disk"].startswith("zvol"):
                oExtent.iscsi_target_extent_path = self.cleaned_data[
                    "iscsi_extent_disk"]
                oExtent.iscsi_target_extent_type = 'ZVOL'
            elif self.cleaned_data["iscsi_extent_disk"].startswith(
                    "multipath"):
                notifier().unlabel_disk(
                    str(self.cleaned_data["iscsi_extent_disk"]))
                notifier().label_disk(
                    "extent_%s" % self.cleaned_data["iscsi_extent_disk"],
                    self.cleaned_data["iscsi_extent_disk"])
                mp_name = self.cleaned_data["iscsi_extent_disk"].split("/")[-1]
                diskobj = models.Disk.objects.get(disk_multipath_name=mp_name)
                oExtent.iscsi_target_extent_type = 'Disk'
                oExtent.iscsi_target_extent_path = str(diskobj.id)
            else:
                notifier().unlabel_disk(
                    str(self.cleaned_data["iscsi_extent_disk"]))
                diskobj = models.Disk.objects.get(
                    disk_name=self.cleaned_data["iscsi_extent_disk"])
                if diskobj.disk_identifier.startswith("{devicename}") or \
                        diskobj.disk_identifier.startswith("{uuid}"):
                    notifier().label_disk(
                        "extent_%s" % self.cleaned_data["iscsi_extent_disk"],
                        self.cleaned_data["iscsi_extent_disk"])
                    notifier().sync_disk(
                        self.cleaned_data["iscsi_extent_disk"])
                oExtent.iscsi_target_extent_type = 'Disk'
                oExtent.iscsi_target_extent_path = str(diskobj.id)
            oExtent.iscsi_target_extent_filesize = 0
            oExtent.save()
        started = notifier().reload("iscsitarget")
        if started is False and models.services.objects.get(
                srv_service='iscsitarget').srv_enable:
            raise ServiceFailed("iscsitarget",
                                _("The iSCSI service failed to reload."))
        return oExtent
Example #17
0
class VolumeImportForm(forms.Form):

    volume_name = forms.CharField(max_length=30, label=_('Volume name'))
    volume_disks = forms.ChoiceField(choices=(),
                                     widget=forms.Select(attrs=attrs_dict),
                                     label=_('Member disk'))
    volume_fstype = forms.ChoiceField(
        choices=((x, x) for x in ('UFS', 'NTFS', 'MSDOSFS', 'EXT2FS')),
        widget=forms.RadioSelect(attrs=attrs_dict),
        label='File System type')

    def __init__(self, *args, **kwargs):
        super(VolumeImportForm, self).__init__(*args, **kwargs)
        self.fields['volume_disks'].choices = self._populate_disk_choices()

    def _populate_disk_choices(self):

        used_disks = []
        for v in models.Volume.objects.all():
            used_disks.extend(v.get_disks())

        qs = iSCSITargetExtent.objects.filter(iscsi_target_extent_type='Disk')
        diskids = [i[0] for i in qs.values_list('iscsi_target_extent_path')]
        used_disks.extend(
            [d.disk_name for d in models.Disk.objects.filter(id__in=diskids)])

        n = notifier()
        # Grab partition list
        # NOTE: This approach may fail if device nodes are not accessible.
        _parts = n.get_partitions()
        for name, part in _parts.items():
            if len([i for i in used_disks \
                    if part['devname'].startswith(i)]) > 0:
                del _parts[name]

        parts = []
        for name, part in _parts.items():
            parts.append(Disk(part['devname'], part['capacity']))

        choices = sorted(parts)
        choices = [tuple(p) for p in choices]
        return choices

    def clean(self):
        cleaned_data = self.cleaned_data
        volume_name = cleaned_data.get("volume_name")
        if models.Volume.objects.filter(vol_name=volume_name).count() > 0:
            msg = _(u"You already have a volume with same name")
            self._errors["volume_name"] = self.error_class([msg])
            del cleaned_data["volume_name"]

        devpath = "/dev/%s" % (cleaned_data.get('volume_disks', []), )
        isvalid = notifier().precheck_partition(
            devpath, cleaned_data.get('volume_fstype', ''))
        if not isvalid:
            msg = _(u"The selected disks were not verified for this import "
                    "rules.")
            self._errors["volume_name"] = self.error_class([msg])
            if "volume_name" in cleaned_data:
                del cleaned_data["volume_name"]

        if "volume_name" in cleaned_data:
            dolabel = notifier().label_disk(cleaned_data["volume_name"],
                                            devpath,
                                            cleaned_data['volume_fstype'])
            if not dolabel:
                msg = _(u"An error occurred while labeling the disk.")
                self._errors["volume_name"] = self.error_class([msg])
                cleaned_data.pop("volume_name", None)

        return cleaned_data

    def done(self, request):
        # Construct and fill forms into database.
        volume_name = self.cleaned_data['volume_name']
        volume_fstype = self.cleaned_data['volume_fstype']

        volume = models.Volume(vol_name=volume_name, vol_fstype=volume_fstype)
        volume.save()
        self.volume = volume

        mp = models.MountPoint(mp_volume=volume,
                               mp_path='/mnt/' + volume_name,
                               mp_options='rw')
        mp.save()

        notifier().start("mx-fstab")
        notifier().mount_volume(volume)