예제 #1
0
    def ui_command_create(self, mapped_lun, tpg_lun, write_protect=None):
        '''
        Creates a mapping to one of the TPG LUNs for the initiator referenced
        by the ACL. The provided I{tpg_lun} will appear to that initiator as
        LUN I{mapped_lun}. If the I{write_protect} flag is set to B{1}, the
        initiator will not have write access to the Mapped LUN.

        SEE ALSO
        ========
        B{delete}
        '''
        self.assert_root()
        try:
            tpg_lun = int(tpg_lun)
            mapped_lun = int(mapped_lun)
        except ValueError:
            self.shell.log.error("Incorrect LUN value.")
            return

        if tpg_lun in (ml.tpg_lun.lun for ml in self.rtsnode.mapped_luns):
            self.shell.log.warning(
                "Warning: TPG LUN %d already mapped to this NodeACL" % tpg_lun)

        mlun = MappedLUN(self.rtsnode, mapped_lun, tpg_lun, write_protect)
        ui_mlun = UIMappedLUN(mlun, self)
        self.shell.log.info("Created Mapped LUN %s." % mlun.mapped_lun)
        return self.new_node(ui_mlun)
예제 #2
0
    def ui_command_create(self, wwn, add_mapped_luns=None):
        '''
        Creates a Node ACL for the initiator node with the specified I{wwn}.
        The node's I{wwn} must match the expected WWN Type of the target's
        fabric module.

        If I{add_mapped_luns} is omitted, the global parameter
        B{auto_add_mapped_luns} will be used, else B{true} or B{false} are
        accepted. If B{true}, then after creating the ACL, mapped LUNs will be
        automatically created for all existing LUNs.

        SEE ALSO
        ========
        B{delete}
        '''
        self.assert_root()

        add_mapped_luns = self.ui_eval_param(
            add_mapped_luns, 'bool', self.shell.prefs['auto_add_mapped_luns'])

        node_acl = NodeACL(self.tpg, wwn, mode="create")
        ui_node_acl = UINodeACL(node_acl.node_wwn, self)
        self.shell.log.info("Created Node ACL for %s" % node_acl.node_wwn)

        if add_mapped_luns:
            for lun in self.tpg.luns:
                MappedLUN(node_acl, lun.lun, lun.lun, write_protect=False)
                self.shell.log.info("Created mapped LUN %d." % lun.lun)
            self.refresh()

        return self.new_node(ui_node_acl)
예제 #3
0
    def ui_command_create(self,
                          mapped_lun,
                          tpg_lun_or_backstore,
                          write_protect=None):
        '''
        Creates a mapping to one of the TPG LUNs for the initiator referenced
        by the ACL. The provided I{tpg_lun_or_backstore} will appear to that
        initiator as LUN I{mapped_lun}. If the I{write_protect} flag is set to
        B{1}, the initiator will not have write access to the Mapped LUN.

        A storage object may also be given for the I{tpg_lun_or_backstore} parameter,
        in which case the TPG LUN will be created for that backstore before
        mapping the LUN to the initiator. If a TPG LUN for the backstore already
        exists, the Mapped LUN will map to that TPG LUN.

        SEE ALSO
        ========
        B{delete}
        '''
        self.assert_root()
        try:
            mapped_lun = int(mapped_lun)
        except ValueError:
            self.shell.log.error("mapped_lun must be an integer")
            return

        try:
            if tpg_lun_or_backstore.startswith("lun"):
                tpg_lun_or_backstore = tpg_lun_or_backstore[3:]
            tpg_lun = int(tpg_lun_or_backstore)
        except ValueError:
            try:
                so = self.get_node(tpg_lun_or_backstore).rtsnode
            except ValueError:
                self.shell.log.error("LUN or storage object not found")
                return

            ui_tpg = self.parent.parent

            for lun in ui_tpg.rtsnode.luns:
                if so == lun.storage_object:
                    tpg_lun = lun.lun
                    break
            else:
                lun_object = LUN(ui_tpg.rtsnode, storage_object=so)
                self.shell.log.info("Created LUN %s." % lun_object.lun)
                ui_lun = UILUN(lun_object, ui_tpg.get_node("luns"))
                tpg_lun = ui_lun.rtsnode.lun

        if tpg_lun in (ml.tpg_lun.lun for ml in self.rtsnodes[0].mapped_luns):
            self.shell.log.warning(
                "Warning: TPG LUN %d already mapped to this NodeACL" % tpg_lun)

        for na in self.rtsnodes:
            mlun = MappedLUN(na, mapped_lun, tpg_lun, write_protect)

        ui_mlun = UIMappedLUN(mlun, self)
        self.shell.log.info("Created Mapped LUN %s." % mlun.mapped_lun)
        return self.new_node(ui_mlun)
예제 #4
0
    def ui_command_delete(self, mapped_lun):
        '''
        Deletes the specified I{mapped_lun}.

        SEE ALSO
        ========
        B{create}
        '''
        self.assert_root()
        mlun = MappedLUN(self.rtsnode, mapped_lun)
        mlun.delete()
        self.shell.log.info("Deleted Mapped LUN %s." % mapped_lun)
        self.refresh()
예제 #5
0
def apply_delete_obj(obj):
    '''
    Deletes an object from the live system.
    '''
    # TODO Factorize this when stable
    # TODO storage fabric cannot be deleted from the system, find a way to
    # handle this when i.e. path 'storage fileio' is in current config, but
    # no objects are hanging under it.

    root = get_root()
    log.debug("apply_delete(%s)" % obj.data)
    if obj.key[0] == 'mapped_lun':
        acl = obj.parent
        if acl.parent.key[0] == 'tpgt':
            tpg = acl.parent
            target = tpg.parent
        else:
            tpg = None
            target = acl.parent
        fabric = target.parent
        lio_fabric = FabricModule(fabric.key[1])
        lio_target = Target(lio_fabric, wwn=target.key[1], mode='lookup')
        if tpg is None:
            tpgt = 1
        else:
            tpgt = int(tpg.key[1])
        lio_tpg = TPG(lio_target, tpgt, mode='lookup')
        node_wwn = acl.key[1]
        lio_acl = NodeACL(lio_tpg, node_wwn, mode='lookup')
        mlun = int(obj.key[1])
        lio_mlun = MappedLUN(lio_acl, mlun)
        lio_mlun.delete()

    elif obj.key[0] == 'acl':
        if obj.parent.key[0] == 'tpgt':
            tpg = obj.parent
            target = tpg.parent
        else:
            tpg = None
            target = obj.parent
        fabric = target.parent
        lio_fabric = FabricModule(fabric.key[1])
        lio_target = Target(lio_fabric, wwn=target.key[1], mode='lookup')
        if tpg is None:
            tpgt = 1
        else:
            tpgt = int(tpg.key[1])
        lio_tpg = TPG(lio_target, tpgt, mode='lookup')
        node_wwn = obj.key[1]
        lio_acl = NodeACL(lio_tpg, node_wwn, mode='lookup')
        lio_acl.delete()

    elif obj.key[0] == 'portal':
        if obj.parent.key[0] == 'tpgt':
            tpg = obj.parent
            target = tpg.parent
        else:
            tpg = None
            target = obj.parent
        fabric = target.parent
        lio_fabric = FabricModule(fabric.key[1])
        lio_target = Target(lio_fabric, wwn=target.key[1], mode='lookup')
        if tpg is None:
            tpgt = 1
        else:
            tpgt = int(tpg.key[1])
        lio_tpg = TPG(lio_target, tpgt, mode='lookup')
        (address, _, port) = obj.key[1].partition(':')
        port = int(port)
        lio_portal = NetworkPortal(lio_tpg, address, port, mode='lookup')
        lio_portal.delete()

    elif obj.key[0] == 'lun':
        if obj.parent.key[0] == 'tpgt':
            tpg = obj.parent
            target = tpg.parent
        else:
            tpg = None
            target = obj.parent
        fabric = target.parent
        lio_fabric = FabricModule(fabric.key[1])
        lio_target = Target(lio_fabric, wwn=target.key[1], mode='lookup')
        if tpg is None:
            tpgt = 1
        else:
            tpgt = int(tpg.key[1])
        lio_tpg = TPG(lio_target, tpgt, mode='lookup')
        lun = int(obj.key[1])
        lio_lun = LUN(lio_tpg, lun)
        lio_lun.delete()

    elif obj.key[0] == 'tpgt':
        target = obj.parent
        fabric = target.parent
        lio_fabric = FabricModule(fabric.key[1])
        lio_target = Target(lio_fabric, wwn=target.key[1], mode='lookup')
        tpgt = int(obj.key[1])
        lio_tpg = TPG(lio_target, tpgt, mode='lookup')
        # FIXME IS this really needed ?
        lio_tpg.enable = True
        lio_tpg.delete()

    elif obj.key[0] == 'target':
        fabric = obj.parent
        wwn = obj.key[1]
        lio_fabric = FabricModule(fabric.key[1])
        lio_target = Target(lio_fabric, wwn=wwn, mode='lookup')
        lio_target.delete()

    elif obj.key[0] == 'disk':
        plugin = obj.parent.key[1]
        name = obj.key[1]
        matching_lio_so = [
            so for so in root.storage_objects
            if so.backstore.plugin == plugin and so.name == name
        ]
        log.debug("Looking for storage object %s in %s" %
                  (obj.path_str,
                   str([
                       "%s/%s" % (so.backstore.plugin, so.name)
                       for so in root.storage_objects
                   ])))
        if len(matching_lio_so) > 1:
            raise ConfigError("Detected unsupported configfs storage objects "
                              "allocation schema for storage object '%s'" %
                              obj.path_str)
        elif len(matching_lio_so) == 0:
            raise ConfigError("Could not find storage object '%s'" %
                              obj.path_str)
        else:
            lio_so = matching_lio_so[0]
            lio_so.delete()
예제 #6
0
def apply_create_obj(obj):
    '''
    Creates an object on the live system.
    '''
    # TODO Factorize this when stable, merging it with update and delete,
    # leveraging rtslib 'any' mode (create if not exist)
    # TODO storage
    root = get_root()
    log.debug("apply_create(%s)" % obj.data)
    if obj.key[0] == 'mapped_lun':
        acl = obj.parent
        if acl.parent.key[0] == 'tpgt':
            tpg = acl.parent
            target = tpg.parent
        else:
            tpg = None
            target = acl.parent
        fabric = target.parent
        lio_fabric = FabricModule(fabric.key[1])
        lio_target = Target(lio_fabric, wwn=target.key[1], mode='lookup')
        if tpg is None:
            tpgt = 1
        else:
            tpgt = int(tpg.key[1])
        lio_tpg = TPG(lio_target, tpgt, mode='lookup')
        node_wwn = acl.key[1]
        lio_acl = NodeACL(lio_tpg, node_wwn, mode='lookup')
        mlun = int(obj.key[1])

        write_protect = obj_attr(obj, "write_protect")
        tpg_lun = int(obj_attr(obj, "target_lun").rpartition(' ')[2])
        lio_mlun = MappedLUN(lio_acl, mlun, tpg_lun, write_protect)
        apply_group_attrs(obj, lio_mlun)

    elif obj.key[0] == 'acl':
        if obj.parent.key[0] == 'tpgt':
            tpg = obj.parent
            target = tpg.parent
        else:
            tpg = None
            target = obj.parent
        fabric = target.parent
        lio_fabric = FabricModule(fabric.key[1])
        lio_target = Target(lio_fabric, wwn=target.key[1], mode='lookup')
        if tpg is None:
            tpgt = 1
        else:
            tpgt = int(tpg.key[1])
        lio_tpg = TPG(lio_target, tpgt, mode='lookup')
        node_wwn = obj.key[1]
        lio_acl = NodeACL(lio_tpg, node_wwn)
        apply_group_attrs(obj, lio_acl)

    elif obj.key[0] == 'portal':
        if obj.parent.key[0] == 'tpgt':
            tpg = obj.parent
            target = tpg.parent
        else:
            tpg = None
            target = obj.parent
        fabric = target.parent
        lio_fabric = FabricModule(fabric.key[1])
        lio_target = Target(lio_fabric, wwn=target.key[1], mode='lookup')
        if tpg is None:
            tpgt = 1
        else:
            tpgt = int(tpg.key[1])
        lio_tpg = TPG(lio_target, tpgt, mode='lookup')
        (address, _, port) = obj.key[1].partition(':')
        port = int(port)
        lio_portal = NetworkPortal(lio_tpg, address, port)
        apply_group_attrs(obj, lio_portal)

    elif obj.key[0] == 'lun':
        if obj.parent.key[0] == 'tpgt':
            tpg = obj.parent
            target = tpg.parent
        else:
            tpg = None
            target = obj.parent
        fabric = target.parent
        lio_fabric = FabricModule(fabric.key[1])
        lio_target = Target(lio_fabric, wwn=target.key[1], mode='lookup')
        if tpg is None:
            tpgt = 1
        else:
            tpgt = int(tpg.key[1])
        lio_tpg = TPG(lio_target, tpgt, mode='lookup')
        lun = int(obj.key[1])
        (plugin, name) = obj_attr(obj, "backend")

        # TODO move that to a separate function, use for disk too
        matching_lio_so = [
            so for so in root.storage_objects
            if so.backstore.plugin == plugin and so.name == name
        ]

        if len(matching_lio_so) > 1:
            raise ConfigError("Detected unsupported configfs storage objects "
                              "allocation schema for storage object '%s'" %
                              obj.path_str)
        elif len(matching_lio_so) == 0:
            raise ConfigError(
                "Could not find storage object '%s %s' for '%s'" %
                (plugin, name, obj.path_str))
        else:
            lio_so = matching_lio_so[0]

        lio_lun = LUN(lio_tpg, lun, lio_so)
        apply_group_attrs(obj, lio_lun)

    elif obj.key[0] == 'tpgt':
        target = obj.parent
        fabric = target.parent
        has_enable = len(obj.search([("enable", ".*")])) != 0
        if has_enable:
            enable = obj_attr(obj, "enable")
        lio_fabric = FabricModule(fabric.key[1])
        lio_target = Target(lio_fabric, wwn=target.key[1], mode='lookup')
        tpgt = int(obj.key[1])
        try:
            nexus_wwn = obj_attr(obj, "nexus_wwn")
            lio_tpg = TPG(lio_target, tpgt, nexus_wwn=nexus_wwn)
        except ConfigError:
            lio_tpg = TPG(lio_target, tpgt)
        if has_enable:
            lio_tpg.enable = enable
        apply_group_attrs(obj, lio_tpg)

    elif obj.key[0] == 'target':
        fabric = obj.parent
        wwn = obj.key[1]
        lio_fabric = FabricModule(fabric.key[1])
        lio_target = Target(lio_fabric, wwn=wwn)
        apply_group_attrs(obj, lio_target)
        if not lio_target.has_feature("tpgts"):
            try:
                nexus_wwn = obj_attr(obj, "nexus_wwn")
                lio_tpg = TPG(lio_target, 1, nexus_wwn=nexus_wwn)
            except ConfigError:
                lio_tpg = TPG(lio_target, 1)
            if len(obj.search([("enable", ".*")])) != 0:
                lio_tpg.enable = True

    elif obj.key[0] == 'fabric':
        lio_fabric = FabricModule(obj.key[1])
        apply_group_attrs(obj, lio_fabric)

    elif obj.key[0] == 'disk':
        plugin = obj.parent.key[1]
        name = obj.key[1]
        idx = max([0] +
                  [b.index for b in root.backstores if b.plugin == plugin]) + 1
        if plugin == 'fileio':
            dev = obj_attr(obj, "path")
            size = obj_attr(obj, "size")
            try:
                wwn = obj_attr(obj, "wwn")
            except ConfigError:
                wwn = None
            buffered = obj_attr(obj, "buffered")
            lio_bs = FileIOBackstore(idx)
            lio_so = lio_bs.storage_object(name, dev, size, wwn, buffered)
            apply_group_attrs(obj, lio_so)
        elif plugin == 'iblock':
            # TODO Add policy for iblock
            lio_bs = IBlockBackstore(idx)
            dev = obj_attr(obj, "path")
            wwn = obj_attr(obj, "wwn")
            lio_so = lio_bs.storage_object(name, dev, wwn)
            apply_group_attrs(obj, lio_so)
        elif plugin == 'pscsi':
            # TODO Add policy for pscsi
            lio_bs = PSCSIBackstore(idx)
            dev = obj_attr(obj, "path")
            lio_so = lio_bs.storage_object(name, dev)
            apply_group_attrs(obj, lio_so)
        elif plugin == 'rd_mcp':
            # TODO Add policy for rd_mcp
            lio_bs = RDMCPBackstore(idx)
            size = obj_attr(obj, "size")
            wwn = obj_attr(obj, "wwn")
            nullio = obj_attr(obj, "nullio")
            lio_so = lio_bs.storage_object(name, size, wwn, nullio)
            apply_group_attrs(obj, lio_so)
        else:
            raise ConfigError("Unknown backend '%s' for backstore '%s'" %
                              (plugin, obj))

        matching_lio_so = [
            so for so in root.storage_objects
            if so.backstore.plugin == plugin and so.name == name
        ]
        if len(matching_lio_so) > 1:
            raise ConfigError("Detected unsupported configfs storage objects "
                              "allocation schema for '%s'" % obj.path_str)
        elif len(matching_lio_so) == 0:
            raise ConfigError("Could not find backstore '%s'" % obj.path_str)
        else:
            lio_so = matching_lio_so[0]
예제 #7
0
    def ui_command_tag(self, wwn_or_tag, new_tag):
        '''
        Tag a NodeACL.

        Usage: tag <wwn_or_tag> <new_tag>

        Tags help manage initiator WWNs. A tag can apply to one or
        more WWNs. This can give a more meaningful name to a single
        initiator's configuration, or allow multiple initiators with
        identical settings to be configured en masse.

        The WWNs described by <wwn_or_tag> will be given the new
        tag. If new_tag already exists, its new members will adopt the
        current tag's configuration.

        Within a tag, the 'info' command shows the WWNs the tag applies to.

        Use 'untag' to remove tags.

        NOTE: tags are only supported in kernel 3.8 and above.
        '''
        if wwn_or_tag == new_tag:
            return

        # Since all WWNs have a '.' in them, let's avoid confusion.
        if '.' in new_tag:
            self.shell.log.error("'.' not permitted in tag names.")
            return

        src = list(self.find_tagged(wwn_or_tag))
        if not src:
            self.shell.log.error("wwn_or_tag %s not found." % wwn_or_tag)
            return

        old_tag_members = list(self.find_tagged(new_tag))

        # handle overlap
        src_wwns = [na.node_wwn for na in src]
        old_tag_members = [
            old for old in old_tag_members if old.node_wwn not in src_wwns
        ]

        for na in src:
            na.tag = new_tag

            # if joining a tag, take its config
            if old_tag_members:
                model = old_tag_members[0]

                for mlun in na.mapped_luns:
                    mlun.delete()

                for mlun in model.mapped_luns:
                    MappedLUN(na, mlun.mapped_lun, mlun.tpg_lun,
                              mlun.write_protect)

                if self.parent.rtsnode.has_feature("auth"):
                    for param in auth_params:
                        setattr(na, "chap_" + param,
                                getattr(model, "chap_" + param))

                for item in model.list_attributes(writable=True):
                    na.set_attribute(item, model.get_attribute(item))
                for item in model.list_parameters(writable=True):
                    na.set_parameter(item, model.get_parameter(item))

        self.refresh()
예제 #8
0
    def ui_command_create(self,
                          storage_object,
                          lun=None,
                          add_mapped_luns=None):
        '''
        Creates a new LUN in the Target Portal Group, attached to a storage
        object. If the I{lun} parameter is omitted, the first available LUN in
        the TPG will be used. If present, it must be a number greater than 0.
        Alternatively, the syntax I{lunX} where I{X} is a positive number is
        also accepted.

        The I{storage_object} must be the path of an existing storage object,
        i.e. B{/backstore/pscsi0/mydisk} to reference the B{mydisk} storage
        object of the virtual HBA B{pscsi0}.

        If I{add_mapped_luns} is omitted, the global parameter
        B{auto_add_mapped_luns} will be used, else B{true} or B{false} are
        accepted. If B{true}, then after creating the LUN, mapped LUNs will be
        automatically created for all existing node ACLs, mapping the new LUN.

        SEE ALSO
        ========
        B{delete}
        '''
        self.assert_root()

        add_mapped_luns = \
                self.ui_eval_param(add_mapped_luns, 'bool',
                                   self.shell.prefs['auto_add_mapped_luns'])

        try:
            so = self.get_node(storage_object).rtsnode
        except ValueError:
            self.shell.log.error("Invalid storage object %s." % storage_object)
            return

        if so in (l.storage_object for l in self.parent.rtsnode.luns):
            raise ExecutionError("lun for storage object %s already exists" \
                                     % storage_object)

        if lun and lun.lower().startswith('lun'):
            lun = lun[3:]
        lun_object = LUN(self.tpg, lun, so)
        self.shell.log.info("Created LUN %s." % lun_object.lun)
        ui_lun = UILUN(lun_object, self)

        if add_mapped_luns:
            for acl in self.tpg.node_acls:
                if lun:
                    mapped_lun = lun
                else:
                    mapped_lun = 0
                existing_mluns = [mlun.mapped_lun for mlun in acl.mapped_luns]
                if mapped_lun in existing_mluns:
                    mapped_lun = None
                    for possible_mlun in xrange(LUN.MAX_LUN):
                        if possible_mlun not in existing_mluns:
                            mapped_lun = possible_mlun
                            break

                if mapped_lun == None:
                    self.shell.log.warning(
                        "Cannot map new lun %s into ACL %s" %
                        (lun_object.lun, acl.node_wwn))
                else:
                    mlun = MappedLUN(acl,
                                     mapped_lun,
                                     lun_object,
                                     write_protect=False)
                    self.shell.log.info(
                        "Created LUN %d->%d mapping in node ACL %s" %
                        (mlun.tpg_lun.lun, mlun.mapped_lun, acl.node_wwn))
            self.parent.refresh()

        return self.new_node(ui_lun)
예제 #9
0
    def ui_command_create(self,
                          mapped_lun,
                          tpg_lun_or_backstore,
                          write_protect=None):
        '''
        Creates a mapping to one of the TPG LUNs for the initiator referenced
        by the ACL. The provided I{tpg_lun_or_backstore} will appear to that
        initiator as LUN I{mapped_lun}. If the I{write_protect} flag is set to
        B{1}, the initiator will not have write access to the Mapped LUN.

        A storage object may also be given for the I{tpg_lun_or_backstore} parameter,
        in which case the TPG LUN will be created for that backstore before
        mapping the LUN to the initiator. If a TPG LUN for the backstore already
        exists, the Mapped LUN will map to that TPG LUN.

        Finally, a path to an existing block device or file can be given. If so,
        a storage object of the appropriate type is created with default parameters,
        followed by the TPG LUN and the Mapped LUN.

        SEE ALSO
        ========
        B{delete}
        '''
        self.assert_root()
        try:
            mapped_lun = int(mapped_lun)
        except ValueError:
            raise ExecutionError("mapped_lun must be an integer")

        try:
            if tpg_lun_or_backstore.startswith("lun"):
                tpg_lun_or_backstore = tpg_lun_or_backstore[3:]
            tpg_lun = int(tpg_lun_or_backstore)
        except ValueError:
            try:
                so = self.get_node(tpg_lun_or_backstore).rtsnode
            except ValueError:
                try:
                    so = StorageObjectFactory(tpg_lun_or_backstore)
                    self.shell.log.info("Created storage object %s." % so.name)
                except RTSLibError:
                    raise ExecutionError(
                        "LUN, storage object, or path not valid")
                self.get_node("/backstores").refresh()

            ui_tpg = self.parent.parent

            for lun in ui_tpg.rtsnode.luns:
                if so == lun.storage_object:
                    tpg_lun = lun.lun
                    break
            else:
                lun_object = LUN(ui_tpg.rtsnode, storage_object=so)
                self.shell.log.info("Created LUN %s." % lun_object.lun)
                ui_lun = UILUN(lun_object, ui_tpg.get_node("luns"))
                tpg_lun = ui_lun.rtsnode.lun

        if tpg_lun in (ml.tpg_lun.lun for ml in self.rtsnodes[0].mapped_luns):
            self.shell.log.warning(
                "Warning: TPG LUN %d already mapped to this NodeACL" % tpg_lun)

        for na in self.rtsnodes:
            mlun = MappedLUN(na, mapped_lun, tpg_lun, write_protect)

        ui_mlun = UIMappedLUN(mlun, self)
        self.shell.log.info("Created Mapped LUN %s." % mlun.mapped_lun)
        return self.new_node(ui_mlun)
예제 #10
0
    def ui_command_create(self,
                          storage_object,
                          lun=None,
                          add_mapped_luns=None):
        '''
        Creates a new LUN in the Target Portal Group, attached to a storage
        object. If the I{lun} parameter is omitted, the first available LUN in
        the TPG will be used. If present, it must be a number greater than 0.
        Alternatively, the syntax I{lunX} where I{X} is a positive number is
        also accepted.
        
        The I{storage_object} must be the path of an existing storage object,
        i.e. B{/backstore/pscsi0/mydisk} to reference the B{mydisk} storage
        object of the virtual HBA B{pscsi0}.

        If I{add_mapped_luns} is omitted, the global parameter
        B{auto_add_mapped_luns} will be used, else B{true} or B{false} are
        accepted. If B{true}, then after creating the LUN, mapped LUNs will be
        automatically created for all existing node ACLs, mapping the new LUN.

        SEE ALSO
        ========
        B{delete}
        '''
        self.assert_root()
        if lun is None:
            luns = [lun.lun for lun in self.tpg.luns]
            for index in range(1048576):
                if index not in luns:
                    lun = index
                    break
            if lun is None:
                self.shell.log.error("Cannot find an available LUN.")
                return
            else:
                self.shell.log.info("Selected LUN %d." % lun)
        else:
            try:
                if lun.startswith('lun'):
                    lun = lun[3:]
                lun = int(lun)
            except ValueError:
                self.shell.log.error("The LUN must be an integer value.")
                return
            else:
                if lun < 0:
                    self.shell.log.error("The LUN cannot be negative.")
                    return

        add_mapped_luns = \
                self.ui_eval_param(add_mapped_luns, 'bool',
                                   self.shell.prefs['auto_add_mapped_luns'])

        try:
            storage_object = self.get_node(storage_object).rtsnode
        except ValueError:
            self.shell.log.error("Invalid storage object %s." % storage_object)
            return

        lun_object = LUN(self.tpg, lun, storage_object)
        self.shell.log.info("Created LUN %s." % lun_object.lun)
        ui_lun = UILUN(lun_object, self)

        if add_mapped_luns:
            for acl in self.tpg.node_acls:
                mapped_lun = lun
                existing_mluns = [mlun.mapped_lun for mlun in acl.mapped_luns]
                if mapped_lun in existing_mluns:
                    tentative_mlun = 0
                    while mapped_lun == lun:
                        if tentative_mlun not in existing_mluns:
                            mapped_lun = tentative_mlun
                            self.shell.log.warning(
                                "Mapped LUN %d already " % lun +
                                "exists in ACL %s, using %d instead." %
                                (acl.node_wwn, mapped_lun))
                        else:
                            tentative_mlun += 1
                mlun = MappedLUN(acl, mapped_lun, lun, write_protect=False)
                self.shell.log.info("Created mapped LUN %d in node ACL %s" %
                                    (mapped_lun, acl.node_wwn))
            self.parent.refresh()

        return self.new_node(ui_lun)
예제 #11
0
        add_mapped_luns = \
                self.ui_eval_param(add_mapped_luns, 'bool',
                                   self.shell.prefs['auto_add_mapped_luns'])

        try:
            node_acl = NodeACL(self.tpg, wwn, mode="create")
        except RTSLibError, msg:
            self.shell.log.error(str(msg))
            return
        else:
            self.shell.log.info("Created Node ACL for %s" % node_acl.node_wwn)
            ui_node_acl = UINodeACL(node_acl, self)

        if add_mapped_luns:
            for lun in self.tpg.luns:
                MappedLUN(node_acl, lun.lun, lun.lun, write_protect=False)
                self.shell.log.info("Created mapped LUN %d." % lun.lun)
            self.refresh()

        return self.new_node(ui_node_acl)

    def ui_command_delete(self, wwn):
        '''
        Deletes the Node ACL with the specified I{wwn}.

        SEE ALSO
        ========
        B{create}
        '''
        self.assert_root()
        node_acl = NodeACL(self.tpg, wwn, mode='lookup')