Esempio n. 1
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)
Esempio n. 2
0
    def ui_command_delete(self, lun):
        """
        Deletes the supplied LUN from the Target Portal Group. The I{lun} must
        be a positive number matching an existing LUN.

        Alternatively, the syntax I{lunX} where I{X} is a positive number is
        also accepted.

        SEE ALSO
        ========
        B{create}
        """
        self.assert_root()
        if lun.lower().startswith("lun"):
            lun = lun[3:]
        try:
            lun_object = LUN(self.tpg, lun)
        except:
            raise RTSLibError("Invalid LUN")
        lun_object.delete()
        self.shell.log.info("Deleted LUN %s." % lun)
        # Refresh the TPG as we need to also refresh acls MappedLUNs
        self.parent.refresh()
Esempio n. 3
0
    def ui_command_delete(self, lun):
        '''
        Deletes the supplied LUN from the Target Portal Group. The I{lun} must
        be a positive number matching an existing LUN.

        Alternatively, the syntax I{lunX} where I{X} is a positive number is
        also accepted.

        SEE ALSO
        ========
        B{create}
        '''
        self.assert_root()
        if lun.lower().startswith("lun"):
            lun = lun[3:]
        try:
            lun_object = LUN(self.tpg, lun)
        except:
            raise RTSLibError("Invalid LUN")
        lun_object.delete()
        self.shell.log.info("Deleted LUN %s." % lun)
        # Refresh the TPG as we need to also refresh acls MappedLUNs
        self.parent.refresh()
Esempio n. 4
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()
Esempio n. 5
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]
Esempio n. 6
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)
Esempio n. 7
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)
Esempio n. 8
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()
Esempio n. 9
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)