Esempio n. 1
0
def mp_permission(request, path):
    path = urllib.unquote_plus(path)
    #FIXME: dojo cannot handle urls partially urlencoded %2F => /
    if not path.startswith('/'):
        path = '/' + path
    if request.method == 'POST':
        form = forms.MountPointAccessForm(request.POST)
        if form.is_valid():
            form.commit(path=path)
            return JsonResp(
                request,
                message=_("Mount Point permissions successfully updated."))
    else:
        form = forms.MountPointAccessForm(initial={'path': path})
    return render(request, 'storage/permission.html', {
        'path': path,
        'form': form,
    })
Esempio n. 2
0
def volume_create_passphrase(request, object_id):

    volume = models.Volume.objects.get(id=object_id)
    if request.method == "POST":
        form = forms.CreatePassphraseForm(request.POST)
        if form.is_valid():
            try:
                form.done(volume=volume)
                return JsonResp(
                    request,
                    message=_("Passphrase created"))
            except ClientException as e:
                form._errors['__all__'] = form.error_class([str(e)])
    else:
        form = forms.CreatePassphraseForm()
    return render(request, "storage/create_passphrase.html", {
        'volume': volume,
        'form': form,
    })
Esempio n. 3
0
def index(request):
    if request.method == 'POST':
        if request.POST.get('eula') == 'unaccept':
            request.session.pop('noeula', None)
            with client as c:
                c.call('truenas.unaccept_eula')
            return HttpResponseRedirect('/')

    sw_name = get_sw_name().lower()

    license = utils.get_license()[0]
    allow_update = True
    if hasattr(notifier, 'failover_status'):
        status = notifier().failover_status()
        if status not in ('MASTER', 'SINGLE'):
            allow_update = False

    context = {
        'sw_name': sw_name,
        'license': license,
        'fc_enabled': utils.fc_enabled(),
        'allow_update': allow_update,
    }
    for c in appPool.hook_view_context('support.index', request):
        context.update(c)
    if not notifier().is_freenas():
        with client as c:
            context['eula_not_accepted'] = not c.call('truenas.is_eula_accepted')

    if not notifier().is_freenas():
        form = forms.ProductionForm()
        if request.method == 'POST':
            form = forms.ProductionForm(request.POST)
            if form.is_valid():
                form.save()
                return JsonResp(
                    request,
                    message='Production status successfully updated.'
                )

        context['production_form'] = form

    return render(request, 'support/home.html', context)
Esempio n. 4
0
def zpool_scrub(request, vid):
    volume = models.Volume.objects.get(pk=vid)
    try:
        pool = notifier().zpool_parse(volume.vol_name)
    except:
        raise MiddlewareError(
            _('Pool output could not be parsed. Is the pool imported?')
        )
    if request.method == "POST":
        if request.POST.get("scrub") == 'IN_PROGRESS':
            notifier().zfs_scrub(str(volume.vol_name), stop=True)
        else:
            notifier().zfs_scrub(str(volume.vol_name))
        return JsonResp(request, message=_("The scrub process has begun"))

    return render(request, 'storage/scrub_confirm.html', {
        'volume': volume,
        'scrub': pool.scrub,
    })
Esempio n. 5
0
def services_s3(request):
    try:
        s3 = models.S3.objects.all()[0]
    except:
        s3 = models.S3()

    if request.method == "POST":
        form = S3Form(request.POST, instance=s3)
        if form.is_valid():
            form.save()
        else:
            return JsonResp(request, form=form)

    else:
        form = S3Form(instance=s3)

    return render(request, 'services/s3.html', {
        'form': form,
    })
Esempio n. 6
0
def vcp_home(request):
    aux_enable_https = models.VcenterAuxSettings.objects.latest('id').vc_enable_https
    if request.method == 'POST':
        form = VcenterConfigurationForm(request.POST)
        if form.is_valid():

            if form.install_plugin():
                form.save()
                obj = models.VcenterConfiguration.objects.latest('id')
                obj.vc_version = utils.get_plugin_version()
                obj.vc_password = ''
                obj.save()
            else:
                return JsonResp(
                    request, error=True, message=_(
                        form.vcp_status))
        else:
            form.is_update_needed()
            return render(
                request,
                "vcp/index.html",
                {
                    'form': form,
                    'aux_enable_https': aux_enable_https,
                }
            )
    try:
        obj = models.VcenterConfiguration.objects.latest('id')
        form = VcenterConfigurationForm(instance=obj)
        form.fields['vc_ip'].widget.attrs['readonly'] = True
        form.is_update_needed()
    except:
        form = VcenterConfigurationForm()
        form.is_update_needed()
    return render(
        request,
        "vcp/index.html",
        {
            'form': form,
            'aux_enable_https': aux_enable_https,
        }
    )
Esempio n. 7
0
def volume_key(request, object_id):

    if request.method == "POST":
        form = forms.KeyForm(request.POST)
        if form.is_valid():
            request.session["allow_gelikey"] = True
            return JsonResp(
                request,
                message=_("GELI key download starting..."),
                events=["window.location='%s';" % (
                    reverse("storage_volume_key_download",
                        kwargs={'object_id': object_id}),
                )],
            )
    else:
        form = forms.KeyForm()

    return render(request, "storage/key.html", {
        'form': form,
    })
Esempio n. 8
0
def volimport(request):

    if request.method == "POST":

        form = forms.VolumeImportForm(request.POST)
        if form.is_valid():
            form.done(request)
            return JsonResp(request, message=_("Volume successfully added."))
        else:

            if 'volume_disks' in request.POST:
                disks = request.POST.getlist('volume_disks')
            else:
                disks = None
    else:
        form = forms.VolumeImportForm()
        disks = []
    return render(request, 'storage/import.html', {
        'form': form,
        'disks': disks
    })
Esempio n. 9
0
def volumemanager_zfs(request):

    if request.method == "POST":

        form = forms.ZFSVolumeWizardForm(request.POST)
        events = []
        if form.is_valid() and form.done(request, events):
            return JsonResp(
                request,
                message=_("Volume successfully added."),
                events=events,
            )
        else:
            if 'volume_disks' in request.POST:
                disks = request.POST.getlist('volume_disks')
            else:
                disks = None
            zpoolfields = re.compile(r'zpool_(.+)')
            zfsextra = [
                (zpoolfields.search(i).group(1), i, request.POST.get(i))
                for i in list(request.POST.keys()) if zpoolfields.match(i)
            ]
            zfsextradisks = [v[0] for v in zfsextra if v[2] != 'none']

    else:
        form = forms.ZFSVolumeWizardForm()
        disks = []
        zfsextra = None
        zfsextradisks = []
    # dedup = forms._dedup_enabled()
    dedup = True
    return render(
        request, 'storage/zfswizard.html', {
            'form': form,
            'disks': disks,
            'zfsextra': zfsextra,
            'zfsextradisks': zfsextradisks,
            'dedup': dedup,
        })
Esempio n. 10
0
def start(request, id):
    vm = models.VM.objects.get(id=id)
    raw_file_cnt = None
    raw_file_resize = 0
    if request.method == 'POST':
        if vm.vm_type == 'Container Provider':
            devices = models.Device.objects.filter(vm__id=vm.id)
            for device in devices:
                if device.dtype == 'RAW' and device.attributes.get('boot'):
                    raw_file_cnt = device.attributes.get('path')
                    raw_file_resize = device.attributes.get('size')

            with client as c:
                job_id = c.call('vm.fetch_image', 'RancherOS')
                status = None
                while status != 'SUCCESS':
                    __call = c.call('vm.get_download_status', job_id)
                    status = __call.get('state')
                    utils.dump_download_progress(__call)
                    if status == 'FAILED':
                        return HttpResponse('Error: Image download failed!')
                    elif status == 'ABORTED':
                        return HttpResponse('Error: Download aborted!')
                if status == 'SUCCESS':
                    prebuilt_image = c.call('vm.image_path', 'RancherOS')
                    if prebuilt_image and raw_file_cnt:
                        c.call('vm.decompress_gzip', prebuilt_image,
                               raw_file_cnt)
                        c.call('vm.raw_resize', raw_file_cnt, raw_file_resize)
                    elif prebuilt_image is False:
                        return HttpResponse(
                            'Error: Checksum error in downloaded image. Image removed. Please retry.'
                        )
        with client as c:
            c.call('vm.start', id)
        return JsonResp(request, message='VM Started')
    return render(request, "vm/start.html", {
        'name': vm.name,
    })
Esempio n. 11
0
def user_change(request):

    extra_context = {}
    changeform = forms.UserChangeForm(instance=request.user)

    if request.method == 'POST':
        changeform = forms.UserChangeForm(
            instance=request.user,
            data=request.POST,
        )
        if changeform.is_valid():
            changeform.save()
            return JsonResp(
                request,
                message=_("Admin user successfully updated.")
            )

    extra_context.update({
        'form': changeform,
        'inline': True,
        })
    return render(request, 'account/changeform.html', extra_context)
Esempio n. 12
0
def volume_lock(request, object_id):
    volume = models.Volume.objects.get(id=object_id)
    assert(volume.vol_encrypt > 0)

    if request.method == "POST":
        notifier().volume_detach(volume)
        if hasattr(notifier, 'failover_status') and notifier().failover_status() == 'MASTER':
            from freenasUI.failover.enc_helper import LocalEscrowCtl
            escrowctl = LocalEscrowCtl()
            escrowctl.clear()
            try:
                os.unlink('/tmp/.failover_master')
            except Exception:
                pass
            try:
                with client as c:
                    c.call('failover.call_remote', 'failover.encryption_clearkey')
            except Exception:
                log.warn('Failed to clear key on standby node, is it down?', exc_info=True)
        notifier().restart("system_datasets")
        return JsonResp(request, message=_("Volume locked"))
    return render(request, "storage/lock.html")
Esempio n. 13
0
def volume_recoverykey_add(request, object_id):

    volume = models.Volume.objects.get(id=object_id)
    if request.method == "POST":
        form = forms.KeyForm(request.POST)
        if form.is_valid():
            reckey = notifier().geli_recoverykey_add(volume)
            request.session["allow_gelireckey"] = reckey
            return JsonResp(
                request,
                message=_("GELI recovery key download starting..."),
                events=["window.location='%s';" % (
                    reverse("storage_volume_recoverykey_download",
                        kwargs={'object_id': object_id}),
                )],
            )
    else:
        form = forms.KeyForm()

    return render(request, "storage/recoverykey_add.html", {
        'form': form,
    })
Esempio n. 14
0
 def alert_dismiss(self, request):
     from freenasUI.freeadmin.views import JsonResp
     from freenasUI.system.models import Alert
     from freenasUI.system.alert import alert_node
     msgid = request.POST.get("msgid", None)
     dismiss = request.POST.get("dismiss", None)
     assert msgid is not None  # FIX ME
     try:
         alert = Alert.objects.get(node=alert_node(), message_id=msgid)
         if dismiss == "0":
             alert.dismiss = False
             alert.save()
         elif dismiss == "1":
             alert.dismiss = True
             alert.save()
     except Alert.DoesNotExist:
         if dismiss == "1":
             alert = Alert.objects.create(
                 node=alert_node(),
                 message_id=msgid,
                 dismiss=True,
             )
     return JsonResp(request, message="OK")
Esempio n. 15
0
def password_change(request):

    extra_context = {}
    password_change_form = forms.PasswordChangeForm
    passform = password_change_form(user=request.user)

    if request.method == 'POST':
        passform = password_change_form(user=request.user, data=request.POST)
        if passform.is_valid():
            if passform.cleaned_data['change_root']:
                root = models.bsdUsers.objects.get(bsdusr_username='******')
                new_password = passform.cleaned_data.get('new_password1')
                bsdpasswdform = forms.bsdUserPasswordForm(instance=root)
                bsdpasswdform.cleaned_data = {}
                bsdpasswdform.cleaned_data['bsdusr_password1'] = new_password
                bsdpasswdform.cleaned_data['bsdusr_password2'] = new_password
                bsdpasswdform.save()
            usable = request.user.has_usable_password()
            passform.save()
            events = []
            if not usable:
                from freenasUI.tools.alert import Alert
                alert = Alert()
                alert.perform()
                alert.write()
                del alert
                events.append("loadalert()")

            return JsonResp(request,
                            message=_("Password successfully updated."),
                            events=events)

    extra_context.update({
        'form': passform,
        'inline': True,
    })
    return render(request, 'account/passform.html', extra_context)
Esempio n. 16
0
def zvol_create(request, parent):
    defaults = {
        'zvol_compression': 'inherit',
    }
    if request.method == 'POST':
        zvol_form = forms.ZVol_CreateForm(request.POST, vol_name=parent)
        if zvol_form.is_valid():
            props = {}
            cleaned_data = zvol_form.cleaned_data
            zvol_volsize = cleaned_data.get('zvol_volsize')
            zvol_blocksize = cleaned_data.get("zvol_blocksize")
            zvol_name = "%s/%s" % (parent, cleaned_data.get('zvol_name'))
            zvol_comments = cleaned_data.get('zvol_comments')
            zvol_compression = cleaned_data.get('zvol_compression')
            props['compression'] = str(zvol_compression)
            if zvol_blocksize:
                props['volblocksize'] = zvol_blocksize
            errno, errmsg = notifier().create_zfs_vol(name=str(zvol_name),
                                                      size=str(zvol_volsize),
                                                      sparse=cleaned_data.get(
                                                          "zvol_sparse",
                                                          False),
                                                      props=props)
            notifier().zfs_set_option(name=str(zvol_name),
                                      item="org.freenas:description",
                                      value=zvol_comments)
            if errno == 0:
                return JsonResp(request,
                                message=_("ZFS Volume successfully added."))
            else:
                zvol_form.set_error(errmsg)
    else:
        zvol_form = forms.ZVol_CreateForm(initial=defaults, vol_name=parent)
    return render(request, 'storage/zvols.html', {
        'form': zvol_form,
        'volume_name': parent,
    })
Esempio n. 17
0
def fiberchanneltotarget(request):

    i = 0
    while True:

        fc_port = request.POST.get('fcport-%d-port' % i)
        fc_target = request.POST.get('fcport-%d-target' % i)

        if fc_port is None:
            break

        qs = models.FiberChannelToTarget.objects.filter(fc_port=fc_port)
        if qs.exists():
            fctt = qs[0]
        else:
            fctt = models.FiberChannelToTarget()
            fctt.fc_port = fc_port
        if fc_target in ('false', False):
            fctt.fc_target = None
            fctt.save()
        elif fc_target is None:
            if fctt.id:
                fctt.delete()
        else:
            fctt.fc_target = models.iSCSITarget.objects.get(id=fc_target)
            fctt.save()

        i += 1

    if i > 0:
        notifier().reload("iscsitarget")

    return JsonResp(
        request,
        message=_('Fiber Channel Ports have been successfully changed.'),
    )
Esempio n. 18
0
def volume_rekey(request, object_id):

    _n = notifier()
    standby_offline = False
    if not _n.is_freenas() and _n.failover_licensed():
        try:
            with client as c:
                c.call('failover.call_remote', 'core.ping')
        except Exception:
            standby_offline = True

    volume = models.Volume.objects.get(id=object_id)
    if request.method == "POST":
        form = forms.ReKeyForm(request.POST, volume=volume)
        if form.is_valid() and form.done():
            return JsonResp(request, message=_("Encryption re-key succeeded"))
    else:
        form = forms.ReKeyForm(volume=volume)

    return render(request, "storage/rekey.html", {
        'form': form,
        'volume': volume,
        'standby_offline': standby_offline,
    })
Esempio n. 19
0
    def delete(self, request, oid, mf=None):
        from freenasUI.freeadmin.navtree import navtree
        from freenasUI.freeadmin.views import JsonResp
        from freenasUI.freeadmin.utils import get_related_objects

        m = self._model
        instance = get_object_or_404(m, pk=oid)

        try:
            _temp = __import__('%s.forms' % m._meta.app_label, globals(),
                               locals(), [m._admin.delete_form], 0)
            form = getattr(_temp, m._admin.delete_form)
        except:
            form = None

        if not isinstance(navtree._modelforms[m], dict):
            mf = navtree._modelforms[m]
        else:
            if mf is None:
                try:
                    mf = navtree._modelforms[m][m._admin.edit_modelform]
                except:
                    mf = list(navtree._modelforms[m].values())[-1]
            else:
                mf = navtree._modelforms[m][mf]

        related, related_num = get_related_objects(instance)
        context = {
            'app': m._meta.app_label,
            'model': m._meta.model_name,
            'oid': oid,
            'object': instance,
            'model_name': m._meta.model_name,
            'verbose_name': instance._meta.verbose_name,
            'related': related,
            'related_num': related_num,
        }

        form_i = None
        mf = mf(data=request.POST, instance=instance)
        if request.method == "POST":
            if form:
                form_i = form(request.POST, instance=instance)
                if form_i.is_valid():
                    if '__confirm' not in request.POST:
                        message = self.get_confirm_message(
                            'delete',
                            obj=instance,
                            form=form_i,
                        )
                        if message:
                            return JsonResp(
                                request,
                                confirm=self.confirm(message),
                            )
                    events = []
                    if hasattr(form_i, "done"):
                        form_i.done(events=events)
                    mf.delete(events=events)
                    return JsonResp(request,
                                    message=_("%s successfully deleted.") %
                                    (m._meta.verbose_name, ),
                                    events=events)

            else:
                if '__confirm' not in request.POST:
                    message = self.get_confirm_message(
                        'delete',
                        obj=instance,
                        form=form_i,
                    )
                    if message:
                        return JsonResp(
                            request,
                            confirm=self.confirm(message),
                        )
                events = []
                mf.delete(events=events)
                return JsonResp(request,
                                message=_("%s successfully deleted.") %
                                (m._meta.verbose_name, ),
                                events=events)
        if form and form_i is None:
            form_i = form(instance=instance)
        if form:
            context.update({'form': form_i})

        template = "%s/%s_delete.html" % (
            m._meta.app_label,
            m._meta.object_name.lower(),
        )
        try:
            get_template(template)
        except TemplateDoesNotExist:
            template = 'freeadmin/generic_model_delete.html'

        return render(request, template, context)
Esempio n. 20
0
    def edit(self, request, oid, mf=None):

        from freenasUI.freeadmin.navtree import navtree
        from freenasUI.freeadmin.views import JsonResp
        m = self._model

        if 'inline' in request.GET:
            inline = True
        else:
            inline = False

        context = {
            'app': m._meta.app_label,
            'model': m,
            'modeladmin': m._admin,
            'mf': mf,
            'oid': oid,
            'inline': inline,
            'extra_js': m._admin.extra_js,
            'model_name': m._meta.model_name,
            'verbose_name': m._meta.verbose_name,
            'deletable': m._admin.deletable,
        }

        if 'deletable' in request.GET:
            context.update({'deletable': False})

        instance = get_object_or_404(m, pk=oid)
        if not isinstance(navtree._modelforms[m], dict):
            mf = navtree._modelforms[m]
        else:
            if mf is None:
                try:
                    mf = navtree._modelforms[m][m.FreeAdmin.edit_modelform]
                except:
                    mf = list(navtree._modelforms[m].values())[-1]
            else:
                mf = navtree._modelforms[m][mf]

        formsets = {}
        if request.method == "POST":
            mf = mf(request.POST, request.FILES, instance=instance)
            if m._admin.advanced_fields:
                mf.advanced_fields.extend(m._admin.advanced_fields)

            valid = True
            if m._admin.inlines:
                for inlineopts in m._admin.inlines:
                    inline = inlineopts.get("form")
                    prefix = inlineopts.get("prefix")
                    formset = inlineopts.get("formset")

                    _temp = __import__('%s.forms' % m._meta.app_label,
                                       globals(), locals(), [inline], 0)
                    inline = getattr(_temp, inline)

                    if formset:
                        formset = getattr(_temp, formset)
                    else:
                        formset = FreeBaseInlineFormSet

                    extrakw = {
                        'can_delete': True,
                    }
                    fset_fac = inlineformset_factory(m,
                                                     inline._meta.model,
                                                     form=inline,
                                                     formset=formset,
                                                     extra=0,
                                                     **extrakw)
                    try:
                        fsname = 'formset_%s' % (
                            inline._meta.model._meta.model_name, )
                        fset = fset_fac(request.POST,
                                        prefix=prefix,
                                        parent=mf,
                                        instance=instance)
                        formsets[fsname] = {
                            'instance': fset,
                            'position': inlineopts.get('position', 'bottom'),
                        }
                    except dforms.ValidationError:
                        pass

            for name, fsinfo in list(formsets.items()):
                for frm in fsinfo['instance'].forms:
                    valid &= frm.is_valid()
                valid &= fsinfo['instance'].is_valid()

            valid &= mf.is_valid(formsets=formsets)

            if valid:
                if '__confirm' not in request.POST:
                    message = self.get_confirm_message(
                        'edit',
                        obj=instance,
                        form=mf,
                    )
                    if message:
                        return JsonResp(
                            request,
                            confirm=self.confirm(message),
                        )
                try:
                    mf.save()
                    if not isinstance(mf, MiddlewareModelForm):
                        for name, fsinfo in list(formsets.items()):
                            fsinfo['instance'].save()
                    events = []
                    if hasattr(mf, "done") and callable(mf.done):
                        mf.done(request=request, events=events)
                    if 'iframe' in request.GET:
                        return JsonResp(request,
                                        form=mf,
                                        formsets=formsets,
                                        message=_("%s successfully updated.") %
                                        (m._meta.verbose_name, ))
                    else:
                        return JsonResp(request,
                                        form=mf,
                                        formsets=formsets,
                                        message=_("%s successfully updated.") %
                                        (m._meta.verbose_name, ),
                                        events=events)
                except ValidationErrors as e:
                    handle_middleware_validation(mf, e)
                    return JsonResp(request, form=mf, formsets=formsets)
                except ServiceFailed as e:
                    return JsonResp(
                        request,
                        form=mf,
                        error=True,
                        message=e.value,
                        events=["serviceFailed(\"%s\")" % e.service])
                except MiddlewareError as e:
                    return JsonResp(request,
                                    form=mf,
                                    error=True,
                                    message=_("Error: %s") % str(e))
            else:
                return JsonResp(request, form=mf, formsets=formsets)

        else:
            mf = mf(instance=instance)
            if m._admin.advanced_fields:
                mf.advanced_fields.extend(m._admin.advanced_fields)

            if m._admin.inlines:
                extrakw = {
                    'can_delete': True,
                }
                for inlineopts in m._admin.inlines:
                    inline = inlineopts.get("form")
                    prefix = inlineopts.get("prefix")
                    formset = inlineopts.get("formset")

                    _temp = __import__('%s.forms' % m._meta.app_label,
                                       globals(), locals(), [inline], 0)
                    inline = getattr(_temp, inline)

                    if formset:
                        formset = getattr(_temp, formset)
                    else:
                        formset = FreeBaseInlineFormSet
                    """
                    Do not add any extra empty form for the inline formset
                    in case there is already any item in the relationship
                    """
                    extra = 1
                    fk_name = None
                    for field in inline._meta.model._meta.fields:
                        if isinstance(field, ForeignKey) and m is field.rel.to:
                            fk_name = field.name
                            break
                    if fk_name:
                        qs = inline._meta.model.objects.filter(
                            **{'%s__id' % fk_name: instance.pk})
                        if qs.count() > 0:
                            extra = 0

                    fset_fac = inlineformset_factory(m,
                                                     inline._meta.model,
                                                     form=inline,
                                                     formset=formset,
                                                     extra=extra,
                                                     **extrakw)
                    fsname = 'formset_%s' % (
                        inline._meta.model._meta.model_name, )
                    fset = fset_fac(
                        prefix=prefix,
                        instance=instance,
                        parent=mf,
                    )
                    fset.verbose_name = (inline._meta.model._meta.verbose_name)
                    formsets[fsname] = {
                        'instance': fset,
                        'position': inlineopts.get('position', 'bottom'),
                    }

        context.update({
            'form':
            mf,
            'formsets':
            formsets,
            'instance':
            instance,
            'delete_url':
            reverse('freeadmin_%s_%s_delete' % (
                m._meta.app_label,
                m._meta.model_name,
            ),
                    kwargs={
                        'oid': instance.pk,
                    }),
            'hook_buttons':
            appPool.hook_form_buttons(
                str(type(mf).__name__),
                mf,
                'edit',
            ),
        })

        context.update(self.get_extra_context('edit', request=request,
                                              form=mf))

        template = "%s/%s_edit.html" % (
            m._meta.app_label,
            m._meta.object_name.lower(),
        )
        try:
            get_template(template)
        except TemplateDoesNotExist:
            template = 'freeadmin/generic_model_edit.html'

        if 'iframe' in request.GET:
            resp = render(request, template, context, content_type='text/html')
            resp.content = ("<html><body><textarea>" + resp.content +
                            "</textarea></boby></html>")
            return resp
        else:
            return render(request, template, context, content_type='text/html')
Esempio n. 21
0
    def add(self, request, mf=None):
        """
        Magic happens here

        We dynamically import the module based on app and model names
        passed as view argument

        From there we retrieve the ModelForm associated (which was discovered
        previously on the auto_generate process)
        """
        from freenasUI.freeadmin.navtree import navtree
        from freenasUI.freeadmin.views import JsonResp

        m = self._model
        app = self._model._meta.app_label
        context = {
            'app': app,
            'model': m,
            'modeladmin': m._admin,
            'mf': mf,
            'model_name': m._meta.model_name,
            'verbose_name': m._meta.verbose_name,
            'extra_js': m._admin.extra_js,
        }

        if not isinstance(navtree._modelforms[m], dict):
            mf = navtree._modelforms[m]
        else:
            if mf is None:
                try:
                    mf = navtree._modelforms[m][m._admin.create_modelform]
                except:
                    try:
                        mf = navtree._modelforms[m][m._admin.edit_modelform]
                    except:
                        mf = list(navtree._modelforms[m].values())[-1]
            else:
                mf = navtree._modelforms[m][mf]

        instance = m()
        formsets = {}
        if request.method == "POST":
            mf = mf(request.POST, request.FILES, instance=instance)
            if m._admin.advanced_fields:
                mf.advanced_fields.extend(m._admin.advanced_fields)

            valid = True
            if m._admin.inlines:
                for inlineopts in m._admin.inlines:
                    inline = inlineopts.get("form")
                    prefix = inlineopts.get("prefix")
                    formset = inlineopts.get("formset")

                    _temp = __import__('%s.forms' % app, globals(), locals(),
                                       [inline], 0)
                    inline = getattr(_temp, inline)

                    if formset:
                        formset = getattr(_temp, formset)
                    else:
                        formset = FreeBaseInlineFormSet

                    extrakw = {'can_delete': False}
                    fset_fac = inlineformset_factory(m,
                                                     inline._meta.model,
                                                     form=inline,
                                                     formset=formset,
                                                     extra=0,
                                                     **extrakw)
                    try:
                        fsname = 'formset_%s' % (
                            inline._meta.model._meta.model_name, )
                        fset = fset_fac(request.POST,
                                        prefix=prefix,
                                        parent=mf,
                                        instance=instance)
                        formsets[fsname] = {
                            'instance': fset,
                            'position': inlineopts.get('position', 'bottom')
                        }
                    except dforms.ValidationError:
                        pass

            for name, fsinfo in list(formsets.items()):
                for frm in fsinfo['instance'].forms:
                    valid &= frm.is_valid()
                valid &= fsinfo['instance'].is_valid()

            valid &= mf.is_valid(formsets=formsets)

            if valid:
                if '__confirm' not in request.POST:
                    message = self.get_confirm_message(
                        'add',
                        obj=instance,
                        form=mf,
                    )
                    if message:
                        return JsonResp(
                            request,
                            confirm=self.confirm(message),
                        )
                try:
                    mf.save()
                    if not isinstance(mf, MiddlewareModelForm):
                        for name, fsinfo in list(formsets.items()):
                            fsinfo['instance'].save()
                    events = []
                    if hasattr(mf, "done") and callable(mf.done):
                        mf.done(request=request, events=events)
                    return JsonResp(request,
                                    form=mf,
                                    formsets=formsets,
                                    message=_("%s successfully updated.") %
                                    (m._meta.verbose_name, ),
                                    events=events)
                except ValidationErrors as e:
                    handle_middleware_validation(mf, e)
                    return JsonResp(request, form=mf, formsets=formsets)
                except ServiceFailed as e:
                    return JsonResp(
                        request,
                        error=True,
                        message=e.value,
                        events=["serviceFailed(\"%s\")" % e.service])
                except MiddlewareError as e:
                    return JsonResp(request,
                                    error=True,
                                    message=_("Error: %s") % str(e))
            else:
                return JsonResp(request, form=mf, formsets=formsets)

        else:
            mf = mf()
            if m._admin.advanced_fields:
                mf.advanced_fields.extend(m._admin.advanced_fields)
            if m._admin.inlines:
                extrakw = {'can_delete': False}
                for inlineopts in m._admin.inlines:
                    inline = inlineopts.get("form")
                    prefix = inlineopts.get("prefix")
                    formset = inlineopts.get("formset")

                    _temp = __import__('%s.forms' % app, globals(), locals(),
                                       [inline], 0)
                    inline = getattr(_temp, inline)

                    if formset:
                        formset = getattr(_temp, formset)
                    else:
                        formset = FreeBaseInlineFormSet

                    fset_fac = inlineformset_factory(m,
                                                     inline._meta.model,
                                                     form=inline,
                                                     formset=formset,
                                                     extra=1,
                                                     **extrakw)
                    fsname = 'formset_%s' % (
                        inline._meta.model._meta.model_name, )
                    fset = fset_fac(prefix=prefix,
                                    instance=instance,
                                    parent=mf)
                    fset.verbose_name = (inline._meta.model._meta.verbose_name)
                    formsets[fsname] = {
                        'instance': fset,
                        'position': inlineopts.get('position', 'bottom'),
                    }

        context.update({
            'form': mf,
            'formsets': formsets,
        })

        context.update(self.get_extra_context('add', request=request, form=mf))

        template = "%s/%s_add.html" % (
            m._meta.app_label,
            m._meta.object_name.lower(),
        )
        try:
            get_template(template)
        except TemplateDoesNotExist:
            template = 'freeadmin/generic_model_add.html'

        return render(request, template, context)
Esempio n. 22
0
def fibrechanneltotarget(request):

    i = 0
    sysctl_set = {}
    loader = False
    while True:

        fc_port = request.POST.get('fcport-%d-port' % i)
        fc_target = request.POST.get('fcport-%d-target' % i)

        if fc_port is None:
            break

        port = fc_port.replace('isp', '').replace('/', ',')
        if ',' in port:
            port_number, vport = port.split(',', 1)
            mibname = '%s.chan%s' % (port_number, vport)
        else:
            port_number = port
            vport = None
            mibname = port

        role = sysctl.filter('dev.isp.%s.role' % mibname)
        if role:
            role = role[0]
        tun_var = 'hint.isp.%s.role' % mibname

        qs = models.FibreChannelToTarget.objects.filter(fc_port=fc_port)
        if qs.exists():
            fctt = qs[0]
        else:
            fctt = models.FibreChannelToTarget()
            fctt.fc_port = fc_port
        # Initiator mode
        if fc_target in ('false', False):
            if role:
                # From disabled to initiator, just set sysctl
                if role.value == 0:
                    role.value = 2
                # From target to initiator, reload ctld then set to 2
                elif role.value == 1:
                    sysctl_set[mibname] = 2
            fctt.fc_target = None
            fctt.save()
            qs = Tunable.objects.filter(tun_var=tun_var)
            if qs.exists():
                tun = qs[0]
                if tun.tun_value != '2':
                    tun.tun_value = '2'
                    loader = True
                tun.save()
            else:
                tun = Tunable()
                tun.tun_var = tun_var
                tun.tun_value = '2'
                tun.save()
                loader = True
        # Disabled
        elif fc_target is None:
            if role:
                # From initiator to disabled, just set sysctl
                if role.value == 2:
                    role.value = 0
            if fctt.id:
                fctt.delete()
            qs = Tunable.objects.filter(tun_var=tun_var)
            if qs.exists():
                loader = True
                qs.delete()
        # Target mode
        else:
            if role:
                # From initiator to target, first set sysctl
                if role.value == 2:
                    role.value = 0
            fctt.fc_target = models.iSCSITarget.objects.get(id=fc_target)
            fctt.save()
            qs = Tunable.objects.filter(tun_var=tun_var)
            if qs.exists():
                loader = True
                qs.delete()

        i += 1

    if i > 0:
        notifier().reload("iscsitarget")

    for mibname, val in list(sysctl_set.items()):
        role = sysctl.filter('dev.isp.%s.role' % mibname)
        if role:
            role = role[0]
            role.value = val

    if loader:
        notifier().reload('loader')

    return JsonResp(
        request,
        message=_('Fibre Channel Ports have been successfully changed.'),
    )
Esempio n. 23
0
    def edit(self, request, oid, mf=None):

        from freenasUI.freeadmin.navtree import navtree
        from freenasUI.freeadmin.views import JsonResp
        m = self._model

        if 'inline' in request.GET:
            inline = True
        else:
            inline = False

        context = {
            'app': m._meta.app_label,
            'model': m,
            'modeladmin': m._admin,
            'mf': mf,
            'oid': oid,
            'inline': inline,
            'extra_js': m._admin.extra_js,
            'verbose_name': m._meta.verbose_name,
            'deletable': m._admin.deletable,
        }

        if 'deletable' in request.GET:
            context.update({'deletable': False})

        instance = get_object_or_404(m, pk=oid)
        if not isinstance(navtree._modelforms[m], dict):
            mf = navtree._modelforms[m]
        else:
            if mf is None:
                try:
                    mf = navtree._modelforms[m][m.FreeAdmin.edit_modelform]
                except:
                    mf = navtree._modelforms[m].values()[-1]
            else:
                mf = navtree._modelforms[m][mf]

        formsets = {}
        if request.method == "POST":
            mf = mf(request.POST, request.FILES, instance=instance)
            if m._admin.advanced_fields:
                mf.advanced_fields.extend(m._admin.advanced_fields)

            valid = True
            if m._admin.inlines:
                for inlineopts in m._admin.inlines:
                    inline = inlineopts.get("form")
                    prefix = inlineopts.get("prefix")
                    _temp = __import__(
                        '%s.forms' % m._meta.app_label,
                        globals(),
                        locals(),
                        [inline],
                        -1)
                    inline = getattr(_temp, inline)
                    extrakw = {
                        'can_delete': True,
                    }
                    fset_fac = inlineformset_factory(
                        m,
                        inline._meta.model,
                        form=inline,
                        formset=FreeBaseInlineFormSet,
                        extra=0,
                        **extrakw)
                    try:
                        fsname = 'formset_%s' % (
                            inline._meta.model._meta.model_name,
                        )
                        fset = fset_fac(
                            request.POST,
                            prefix=prefix,
                            parent=mf,
                            instance=instance)
                        formsets[fsname] = {
                            'instance': fset,
                            'position': inlineopts.get('position', 'bottom'),
                        }
                    except dforms.ValidationError:
                        pass

            for name, fsinfo in formsets.items():
                for frm in fsinfo['instance'].forms:
                    valid &= frm.is_valid()
                valid &= fsinfo['instance'].is_valid()

            valid &= mf.is_valid(formsets=formsets)

            if valid:
                if '__confirm' not in request.POST:
                    message = self.get_confirm_message(
                        'edit',
                        obj=instance,
                        form=mf,
                    )
                    if message:
                        return JsonResp(
                            request,
                            confirm=self.confirm(message),
                        )
                try:
                    mf.save()
                    for name, fsinfo in formsets.items():
                        fsinfo['instance'].save()
                    events = []
                    if hasattr(mf, "done") and callable(mf.done):
                        mf.done(request=request, events=events)
                    if 'iframe' in request.GET:
                        return JsonResp(
                            request,
                            form=mf,
                            formsets=formsets,
                            message=_("%s successfully updated.") % (
                                m._meta.verbose_name,
                            ))
                    else:
                        return JsonResp(
                            request,
                            form=mf,
                            formsets=formsets,
                            message=_("%s successfully updated.") % (
                                m._meta.verbose_name,
                            ),
                            events=events)
                except ServiceFailed, e:
                    return JsonResp(
                        request,
                        form=mf,
                        error=True,
                        message=_("The service failed to restart."),
                        events=["serviceFailed(\"%s\")" % e.service])
                except MiddlewareError, e:
                    return JsonResp(
                        request,
                        form=mf,
                        error=True,
                        message=_(u"Error: %s") % unicode(e))
Esempio n. 24
0
def plugin_update(request, oid):
    host = get_base_url(request)

    jc = JailsConfiguration.objects.order_by("-id")[0]
    logfile = '%s/warden.log' % jc.jc_path
    if os.path.exists(logfile):
        os.unlink(logfile)
    if os.path.exists(WARDEN_EXTRACT_STATUS_FILE):
        os.unlink(WARDEN_EXTRACT_STATUS_FILE)
    if os.path.exists("/tmp/.plugin_upload_install"):
        os.unlink("/tmp/.plugin_upload_install")
    if os.path.exists("/tmp/.jailcreate"):
        os.unlink("/tmp/.jailcreate")
    if os.path.exists(PROGRESS_FILE):
        os.unlink(PROGRESS_FILE)

    iplugin = models.Plugins.objects.filter(id=oid)
    if not iplugin:
        raise MiddlewareError(_("Plugin not installed"))
    iplugin = iplugin[0]

    rplugin = None
    for rp in availablePlugins.get_remote(cache=True):
        if rp.name.lower() == iplugin.plugin_name.lower():
            rplugin = rp
            break

    if not rplugin:
        raise MiddlewareError(_("Invalid plugin"))

    (p, js, jail_status) = get_plugin_status([iplugin, host, request])
    if js and js['status'] == 'RUNNING':
        (p, js, jail_status) = get_plugin_stop([iplugin, host, request])

    if request.method == "POST":
        plugin_upload_path = notifier().get_plugin_upload_path()
        notifier().change_upload_location(plugin_upload_path)

        if not rplugin.download("/var/tmp/firmware/pbifile.pbi"):
            raise MiddlewareError(_("Failed to download plugin"))

        jail = Jails.objects.filter(jail_host=iplugin.plugin_jail)
        if not jail:
            raise MiddlewareError(_("Jail does not exist"))

        if notifier().update_pbi(plugin=iplugin):
            notifier()._start_plugins(
                jail=iplugin.plugin_jail,
                plugin=iplugin.plugin_name,
            )

        else:
            raise MiddlewareError(_("Failed to update plugin"))

        return JsonResp(
            request,
            message=_("Plugin successfully updated"),
            events=['reloadHttpd()'],
        )

    return render(request, "plugins/plugin_update.html", {
        'plugin': rplugin,
    })
Esempio n. 25
0
def dataset_edit(request, dataset_name):
    if request.method == 'POST':
        dataset_form = forms.ZFSDataset(
            request.POST, fs=dataset_name, create=False
        )
        if dataset_form.is_valid():
            if dataset_form.cleaned_data["dataset_quota"] == "0":
                dataset_form.cleaned_data["dataset_quota"] = "none"
            if dataset_form.cleaned_data["dataset_refquota"] == "0":
                dataset_form.cleaned_data["dataset_refquota"] = "none"

            error = False
            errors = {}

            for attr in (
                'org.freenas:description',
                'compression',
                'atime',
                'dedup',
                'reservation',
                'refreservation',
                'quota',
                'refquota',
                'share_type'
            ):
                if attr == 'org.freenas:description':
                    formfield = 'dataset_comments'
                else:
                    formfield = 'dataset_%s' % attr
                val = dataset_form.cleaned_data[formfield]

                if val == "inherit":
                    success, err = notifier().zfs_inherit_option(
                        dataset_name,
                        attr)
                else:
                    if attr == "share_type":
                        notifier().change_dataset_share_type(
                            dataset_name, val)
                    else:
                        success, err = notifier().zfs_set_option(
                            dataset_name,
                            attr,
                            val)
                error |= not success
                if not success:
                    errors[formfield] = err

            if not error:
                return JsonResp(
                    request,
                    message=_("Dataset successfully edited."))
            else:
                for field, err in errors.items():
                    dataset_form._errors[field] = dataset_form.error_class([
                        err,
                    ])
                return JsonResp(request, form=dataset_form)
        else:
            return JsonResp(request, form=dataset_form)
    else:
        dataset_form = forms.ZFSDataset(fs=dataset_name, create=False)
    return render(request, 'storage/dataset_edit.html', {
        'dataset_name': dataset_name,
        'form': dataset_form
    })
Esempio n. 26
0
def dataset_create(request, fs):
    defaults = {'dataset_compression': 'inherit', 'dataset_atime': 'inherit'}
    if request.method == 'POST':
        dataset_form = forms.ZFSDataset(request.POST, fs=fs)
        if dataset_form.is_valid():
            props = {}
            cleaned_data = dataset_form.cleaned_data
            dataset_name = "%s/%s" % (fs, cleaned_data.get('dataset_name'))
            dataset_compression = cleaned_data.get('dataset_compression')
            dataset_share_type = cleaned_data.get('dataset_share_type')
            if dataset_share_type == "windows":
                props['aclmode'] = 'restricted'
            props['casesensitivity'] = cleaned_data.get(
                'dataset_case_sensitivity'
            )
            props['compression'] = dataset_compression.__str__()
            dataset_atime = cleaned_data.get('dataset_atime')
            props['atime'] = dataset_atime.__str__()
            refquota = cleaned_data.get('dataset_refquota')
            if refquota != '0':
                props['refquota'] = refquota.__str__()
            quota = cleaned_data.get('dataset_quota')
            if quota != '0':
                props['quota'] = quota.__str__()
            refreservation = cleaned_data.get('dataset_refreservation')
            if refreservation != '0':
                props['refreservation'] = refreservation.__str__()
            refreservation = cleaned_data.get('dataset_reservation')
            if refreservation != '0':
                props['refreservation'] = refreservation.__str__()
            dedup = cleaned_data.get('dataset_dedup')
            if dedup != 'inherit':
                props['dedup'] = dedup.__str__()
            recordsize = cleaned_data.get('dataset_recordsize')
            if recordsize:
                props['recordsize'] = recordsize
            dataset_comments = cleaned_data.get('dataset_comments')
            errno, errmsg = notifier().create_zfs_dataset(
                path=str(dataset_name),
                props=props)
            notifier().zfs_set_option(name=str(dataset_name), item="org.freenas:description", value=dataset_comments)
            if errno == 0:
                if dataset_share_type == "unix":
                    notifier().dataset_init_unix(dataset_name)
                elif dataset_share_type == "windows":
                    notifier().dataset_init_windows(dataset_name)
                elif dataset_share_type == "mac":
                    notifier().dataset_init_apple(dataset_name)
                return JsonResp(
                    request,
                    message=_("Dataset successfully added."))
            else:
                dataset_form.set_error(errmsg)
                return JsonResp(request, form=dataset_form)
        else:
            return JsonResp(request, form=dataset_form)
    else:
        dataset_form = forms.ZFSDataset(initial=defaults, fs=fs)
    return render(request, 'storage/datasets.html', {
        'form': dataset_form,
        'fs': fs,
    })
Esempio n. 27
0
        except Exception as e:
            raise MiddlewareError(e)

        newplugin = []
        if notifier().install_pbi(jail.jail_host, newplugin):
            newplugin = newplugin[0]
            notifier()._restart_plugins(
                jail=newplugin.plugin_jail,
                plugin=newplugin.plugin_name,
            )
        else:
            jail.delete()

        return JsonResp(
            request,
            message=_("Plugin successfully installed"),
            events=['reloadHttpd()'],
        )

    return render(request, "plugins/available_install.html", {
        'plugin': plugin,
    })


def install_progress(request):
    jc = JailsConfiguration.objects.order_by("-id")[0]
    logfile = '%s/warden.log' % jc.jc_path
    data = {}
    if os.path.exists(PROGRESS_FILE):
        data = {'step': 1}
        with open(PROGRESS_FILE, 'r') as f:
Esempio n. 28
0
                            m._meta.verbose_name,
                        ),
                        events=events)
                except MiddlewareError, e:
                    return JsonResp(
                        request,
                        error=True,
                        message=_(u"Error: %s") % unicode(e))
                except ServiceFailed, e:
                    return JsonResp(
                        request,
                        error=True,
                        message=_("The service failed to restart.")
                    )
            else:
                return JsonResp(request, form=mf, formsets=formsets)

        else:
            mf = mf()
            if m._admin.advanced_fields:
                mf.advanced_fields.extend(m._admin.advanced_fields)
            if m._admin.inlines:
                extrakw = {
                    'can_delete': False
                }
                for inlineopts in m._admin.inlines:
                    inline = inlineopts.get("form")
                    prefix = inlineopts.get("prefix")
                    _temp = __import__(
                        '%s.forms' % app,
                        globals(),
Esempio n. 29
0
def volumemanager(request):

    if request.method == "POST":
        form = forms.VolumeManagerForm(request.POST)
        if form.is_valid() and form.save():
            events = []
            form.done(request, events)
            return JsonResp(
                request,
                message=_("Volume successfully added."),
                events=events,
            )
        else:
            return JsonResp(request,
                            form=form,
                            formsets={'layout': {
                                'instance': form._formset,
                            }})

    _n = notifier()
    disks = []
    # Grab disk list
    # Root device already ruled out
    for disk, info in list(_n.get_disks().items()):
        disks.append(
            forms.Disk(info['devname'],
                       info['capacity'],
                       serial=info.get('ident')))
    disks = sorted(disks, key=cmp_to_key(_diskcmp))

    # Exclude what's already added
    used_disks = []
    for v in models.Volume.objects.all():
        used_disks.extend(v.get_disks())

    qs = iSCSITargetExtent.objects.filter(iscsi_target_extent_type='Disk')
    used_disks.extend([i.get_device()[5:] for i in qs])

    bysize = dict()
    for d in list(disks):
        if d.dev in used_disks:
            continue
        hsize = forms.humanize_number_si(d.size)
        if hsize not in bysize:
            bysize[hsize] = []
        display_name = d.dev
        if '/' in display_name:
            display_name = display_name.split('/')[-1]
        bysize[hsize].append({
            'dev': d.dev,
            'name': str(d),
            'displayName': display_name,
            'size': d.size,
            'serial': d.serial,
        })

    bysize = OrderedDict(sorted(iter(bysize.items()), reverse=True))

    swap = Advanced.objects.latest('id').adv_swapondrive

    encwarn = (
        '<span style="color: red; font-size:110%%;">%s</span>'
        '<p>%s</p>'
        '<p>%s</p>'
        '<p>%s</p>'
    ) % (
        _('WARNING!'),
        _('Always backup the key! If the key is lost, the data on the disks '
          'will also be lost with no hope of recovery.'),
        _('This type of encryption is primarily targeted at users who are '
          'storing sensitive data and want the ability to remove disks from '
          'the pool and dispose of/re-use them without concern for erasure.'),
        _('iXsystems, Inc. can not be held responsible for any lost '
          'or unrecoverable data as a consequence of using this feature.'),
    )

    extend = [{'value': '', 'label': '-----'}]
    qs = models.Volume.objects.all()
    for vol in qs:
        if not vol.is_decrypted():
            continue
        try:
            _n.zpool_parse(vol.vol_name)
        except:
            continue
        extend.append({
            'label': vol.vol_name,
            'value': vol.vol_name,
            'enc': vol.vol_encrypt > 0
        })

    return render(
        request, "storage/volumemanager.html", {
            'disks': json.dumps(bysize),
            'dedup_warning': forms.DEDUP_WARNING,
            'encryption_warning': encwarn,
            'swap_size': swap * 1024 * 1024 * 1024,
            'manual_url': reverse('storage_volumemanager_zfs'),
            'extend': json.dumps(extend),
        })
Esempio n. 30
0
    def add(self, request, mf=None):
        """
        Magic happens here

        We dynamically import the module based on app and model names
        passed as view argument

        From there we retrieve the ModelForm associated (which was discovered
        previously on the auto_generate process)
        """
        from freenasUI.freeadmin.navtree import navtree
        from freenasUI.freeadmin.views import JsonResp

        m = self._model
        app = self._model._meta.app_label
        context = {
            'app': app,
            'model': m,
            'modeladmin': m._admin,
            'mf': mf,
            'verbose_name': m._meta.verbose_name,
            'extra_js': m._admin.extra_js,
        }

        if not isinstance(navtree._modelforms[m], dict):
            mf = navtree._modelforms[m]
        else:
            if mf is None:
                try:
                    mf = navtree._modelforms[m][m._admin.create_modelform]
                except:
                    try:
                        mf = navtree._modelforms[m][m._admin.edit_modelform]
                    except:
                        mf = navtree._modelforms[m].values()[-1]
            else:
                mf = navtree._modelforms[m][mf]

        instance = m()
        formsets = {}
        if request.method == "POST":
            mf = mf(request.POST, request.FILES, instance=instance)
            if m._admin.advanced_fields:
                mf.advanced_fields.extend(m._admin.advanced_fields)

            valid = True
            if m._admin.inlines:
                for inlineopts in m._admin.inlines:
                    inline = inlineopts.get("form")
                    prefix = inlineopts.get("prefix")
                    _temp = __import__(
                        '%s.forms' % app,
                        globals(),
                        locals(),
                        [inline],
                        -1)
                    inline = getattr(_temp, inline)
                    extrakw = {
                        'can_delete': False
                    }
                    fset = inlineformset_factory(
                        m,
                        inline._meta.model,
                        form=inline,
                        extra=0,
                        **extrakw)
                    try:
                        fsname = 'formset_%s' % (
                            inline._meta.model._meta.module_name,
                        )
                        formsets[fsname] = fset(
                            request.POST,
                            prefix=prefix,
                            instance=instance)
                    except dforms.ValidationError:
                        pass

            for name, fs in formsets.items():
                for frm in fs.forms:
                    frm.parent = mf
                valid &= fs.is_valid()

            valid &= mf.is_valid(formsets=formsets)

            if valid:
                try:
                    mf.save()
                    for name, fs in formsets.items():
                        fs.save()
                    events = []
                    if hasattr(mf, "done") and callable(mf.done):
                        mf.done(request=request, events=events)
                    return JsonResp(
                        request,
                        form=mf,
                        formsets=formsets,
                        message=_("%s successfully updated.") % (
                            m._meta.verbose_name,
                        ),
                        events=events)
                except MiddlewareError, e:
                    return JsonResp(
                        request,
                        error=True,
                        message=_(u"Error: %s") % unicode(e))
                except ServiceFailed, e:
                    return JsonResp(
                        request,
                        error=True,
                        message=_("The service failed to restart.")
                    )