Пример #1
0
 def get_children(self, hierarchical=True, include_root=True):
     if self.vol_fstype == 'ZFS':
         return zfs.zfs_list(path=self.vol_name,
                             recursive=True,
                             types=["filesystem", "volume"],
                             hierarchical=hierarchical,
                             include_root=include_root)
Пример #2
0
 def get_children(self, hierarchical=True, include_root=True):
     return zfs.zfs_list(
         path=self.vol_name,
         recursive=True,
         types=["filesystem", "volume"],
         hierarchical=hierarchical,
         include_root=include_root)
Пример #3
0
    def zfs_list(self, *args):
        """Wrapper to serialize zfs.zfs_list"""
        rv = zfs.zfs_list(*args)

        def serialize(i):
            data = {}
            if isinstance(i, zfs.ZFSList):
                for k, v in list(i.items()):
                    data[k] = serialize(v)
            elif isinstance(i, (zfs.ZFSVol, zfs.ZFSDataset)):
                data = i.__dict__
                data['children'] = [serialize(j) for j in data.get('children') or []]
            return data

        return serialize(rv)
Пример #4
0
    def zfs_list(self, *args):
        """Wrapper to serialize zfs.zfs_list"""
        rv = zfs.zfs_list(*args)

        def serialize(i):
            data = {}
            if isinstance(i, zfs.ZFSList):
                for k, v in i.items():
                    data[k] = serialize(v)
            elif isinstance(i, (zfs.ZFSVol, zfs.ZFSDataset)):
                data = i.__dict__
                data['children'] = [serialize(j) for j in data.get('children') or []]
            return data

        return serialize(rv)
Пример #5
0
def main():
    """Use the django ORM to generate a config file.  We'll build the
    config file as a series of lines, and once that is done write it
    out in one go"""

    from freenasUI.services.models import iSCSITargetGlobalConfiguration
    from freenasUI.services.models import iSCSITargetPortal
    from freenasUI.services.models import iSCSITargetPortalIP
    from freenasUI.services.models import iSCSITargetAuthCredential
    from freenasUI.services.models import iSCSITarget
    from freenasUI.storage.models import Disk

    gconf = iSCSITargetGlobalConfiguration.objects.order_by('-id')[0]

    if gconf.iscsi_isns_servers:
        for server in gconf.iscsi_isns_servers.split(' '):
            addline('isns-server %s\n\n' % server)

    # We support multiple authentications for a single group
    auths = defaultdict(list)
    for auth in iSCSITargetAuthCredential.objects.order_by('iscsi_target_auth_tag'):
        auths[auth.iscsi_target_auth_tag].append(auth)

    for auth_tag, auth_list in auths.items():
        auth_group_config(auth_tag, auth_list)

    # Generate the portal-group section
    for portal in iSCSITargetPortal.objects.all():
        addline("portal-group pg%s {\n" % portal.iscsi_target_portal_tag)
        addline("\tdiscovery-filter portal-name\n")
        disc_authmethod = gconf.iscsi_discoveryauthmethod
        if disc_authmethod == "None" or ((disc_authmethod == "Auto" or disc_authmethod == "auto") and gconf.iscsi_discoveryauthgroup is None):
            addline("\tdiscovery-auth-group no-authentication\n")
        else:
            addline("\tdiscovery-auth-group ag%s\n" % gconf.iscsi_discoveryauthgroup)
        listen = iSCSITargetPortalIP.objects.filter(iscsi_target_portalip_portal=portal)
        for obj in listen:
            if ':' in obj.iscsi_target_portalip_ip:
                address = '[%s]' % obj.iscsi_target_portalip_ip
            else:
                address = obj.iscsi_target_portalip_ip
            addline("\tlisten %s:%s\n" % (address, obj.iscsi_target_portalip_port))
        addline("}\n\n")

    # Cache zpool threshold
    poolthreshold = {}
    zpoollist = zfs.zpool_list()

    # Generate the target section
    target_basename = gconf.iscsi_basename
    for target in iSCSITarget.objects.all():
        if target.iscsi_target_authgroup:
            auth_list = iSCSITargetAuthCredential.objects.filter(iscsi_target_auth_tag=target.iscsi_target_authgroup)
        else:
            auth_list = []
        agname = '4tg_%d' % target.id
        has_auth = auth_group_config(auth_tag=agname, auth_list=auth_list, auth_type=target.iscsi_target_authtype, initiator=target.iscsi_target_initiatorgroup)
        if target.iscsi_target_name.startswith("iqn."):
            addline("target %s {\n" % target.iscsi_target_name)
        else:
            addline("target %s:%s {\n" % (target_basename, target.iscsi_target_name))
        if target.iscsi_target_name:
            addline("\talias %s\n" % target.iscsi_target_name)
        if not has_auth:
            addline("\tauth-group no-authentication\n")
        else:
            addline("\tauth-group ag%s\n" % agname)
        addline("\tportal-group pg%d\n" % (
            target.iscsi_target_portalgroup.iscsi_target_portal_tag,
        ))
        used_lunids = [
            o.iscsi_lunid
            for o in target.iscsitargettoextent_set.all().exclude(
                iscsi_lunid=None,
            )
        ]
        cur_lunid = 0
        for t2e in target.iscsitargettoextent_set.all().extra({
            'null_first': 'iscsi_lunid IS NULL',
        }).order_by('null_first', 'iscsi_lunid'):

            path = t2e.iscsi_extent.iscsi_target_extent_path
            unmap = False
            poolname = None
            lunthreshold = None
            if t2e.iscsi_extent.iscsi_target_extent_type == 'Disk':
                disk = Disk.objects.filter(id=path).order_by('disk_enabled')
                if not disk.exists():
                    continue
                disk = disk[0]
                if disk.disk_multipath_name:
                    path = "/dev/multipath/%s" % disk.disk_multipath_name
                else:
                    path = "/dev/%s" % disk.identifier_to_device()
            else:
                if not path.startswith("/mnt"):
                    poolname = path.split('/', 2)[1]
                    if gconf.iscsi_pool_avail_threshold:
                        if poolname in zpoollist:
                            poolthreshold[poolname] = int(
                                zpoollist.get(poolname).get('size') * (
                                    gconf.iscsi_pool_avail_threshold / 100.0
                                )
                            )
                    if t2e.iscsi_extent.iscsi_target_extent_avail_threshold:
                        zvolname = path.split('/', 1)[1]
                        zfslist = zfs.zfs_list(path=zvolname, types=['volume'])
                        if zfslist:
                            lunthreshold = int(zfslist[zvolname].volsize * (t2e.iscsi_extent.iscsi_target_extent_avail_threshold / 100.0))
                    path = "/dev/" + path
                    unmap = True
                else:
                    if t2e.iscsi_extent.iscsi_target_extent_avail_threshold and os.path.exists(path):
                        try:
                            stat = os.stat(path)
                            lunthreshold = int(stat.st_size * (t2e.iscsi_extent.iscsi_target_extent_avail_threshold / 100.0))
                        except OSError:
                            pass
            if os.path.exists(path):
                addline("\t\t\n")
                if t2e.iscsi_lunid is None:
                    while cur_lunid in used_lunids:
                        cur_lunid += 1
                    addline("\t\tlun %s {\n" % cur_lunid)
                    cur_lunid += 1
                else:
                    addline("\t\tlun %s {\n" % t2e.iscsi_lunid)
                size = t2e.iscsi_extent.iscsi_target_extent_filesize
                if unmap:
                    addline("\t\t\toption unmap on\n")
                addline("\t\t\tpath %s\n" % path)
                addline("\t\t\tblocksize %s\n" % t2e.iscsi_extent.iscsi_target_extent_blocksize)
                if t2e.iscsi_extent.iscsi_target_extent_pblocksize:
                    addline("\t\t\toption pblocksize 0\n")
                if t2e.iscsi_lunid is None:
                    addline("\t\t\tserial %s%s\n" % (target.iscsi_target_serial, str(cur_lunid-1)))
                else:
                    addline("\t\t\tserial %s%s\n" % (target.iscsi_target_serial, str(t2e.iscsi_lunid)))
                padded_serial = target.iscsi_target_serial
                if t2e.iscsi_lunid is None:
                    padded_serial += str(cur_lunid-1)
                else:
                    padded_serial += str(t2e.iscsi_lunid)
                if not t2e.iscsi_extent.iscsi_target_extent_xen:
                    for i in xrange(31-len(target.iscsi_target_serial)):
                        padded_serial += " "
                addline('\t\t\tdevice-id "iSCSI Disk      %s"\n' % padded_serial)
                if size != "0":
                    if size.endswith('B'):
                        size = size.strip('B')
                    addline("\t\t\tsize %s\n" % size)
                addline('\t\t\toption vendor "FreeBSD"\n')
                addline('\t\t\toption product "iSCSI Disk"\n')
                addline('\t\t\toption revision "0123"\n')
                addline('\t\t\toption naa %s\n' % t2e.iscsi_extent.iscsi_target_extent_naa)
                if t2e.iscsi_extent.iscsi_target_extent_insecure_tpc:
                    addline('\t\t\toption insecure_tpc on\n')

                if lunthreshold:
                    addline('\t\t\toption avail-threshold %s\n' % lunthreshold)
                if poolname is not None and poolname in poolthreshold:
                    addline('\t\t\toption pool-avail-threshold %s\n' % poolthreshold[poolname])
                if t2e.iscsi_extent.iscsi_target_extent_rpm == "Unknown":
                    addline('\t\t\toption rpm 0\n')
                elif t2e.iscsi_extent.iscsi_target_extent_rpm == "SSD":
                    addline('\t\t\toption rpm 1\n')
                else:
                    addline('\t\t\toption rpm %s\n' % t2e.iscsi_extent.iscsi_target_extent_rpm)
                addline("\t\t}\n")
        addline("}\n\n")

    os.umask(077)
    # Write out the CTL config file
    fh = open(ctl_config, "w")
    for line in cf_contents:
        fh.write(line)
    fh.close()

    # Write out the CTL config file with redacted CHAP passwords
    fh = open(ctl_config_shadow, "w")
    for line in cf_contents_shadow:
        fh.write(line)
    fh.close()
Пример #6
0
def main():
    """Use the django ORM to generate a config file.  We'll build the
    config file as a series of lines, and once that is done write it
    out in one go"""

    from freenasUI.services.models import iSCSITargetGlobalConfiguration
    from freenasUI.services.models import iSCSITargetPortal
    from freenasUI.services.models import iSCSITargetPortalIP
    from freenasUI.services.models import iSCSITargetAuthCredential
    from freenasUI.services.models import iSCSITargetExtent
    from freenasUI.services.models import iSCSITarget
    from freenasUI.storage.models import Disk

    gconf = iSCSITargetGlobalConfiguration.objects.order_by('-id')[0]

    if gconf.iscsi_isns_servers:
        for server in gconf.iscsi_isns_servers.split(' '):
            addline('isns-server %s\n\n' % server)

    # Generate the portal-group section
    addline('portal-group default {\n}\n\n')
    for portal in iSCSITargetPortal.objects.all():
        # Prepare auth group for the portal group
        if portal.iscsi_target_portal_discoveryauthgroup:
            auth_list = iSCSITargetAuthCredential.objects.filter(
                iscsi_target_auth_tag=portal.
                iscsi_target_portal_discoveryauthgroup)
        else:
            auth_list = []
        agname = '4pg%d' % portal.iscsi_target_portal_tag
        auth = auth_group_config(
            auth_tag=agname,
            auth_list=auth_list,
            auth_type=portal.iscsi_target_portal_discoveryauthmethod)

        addline("portal-group pg%s {\n" % portal.iscsi_target_portal_tag)
        addline("\tdiscovery-filter portal-name\n")
        if auth:
            addline("\tdiscovery-auth-group ag%s\n" % agname)
        else:
            addline("\tdiscovery-auth-group no-authentication\n")
        listen = iSCSITargetPortalIP.objects.filter(
            iscsi_target_portalip_portal=portal)
        for obj in listen:
            if ':' in obj.iscsi_target_portalip_ip:
                address = '[%s]' % obj.iscsi_target_portalip_ip
            else:
                address = obj.iscsi_target_portalip_ip
            addline("\tlisten %s:%s\n" %
                    (address, obj.iscsi_target_portalip_port))
        addline("}\n\n")

    # Cache zpool threshold
    poolthreshold = {}
    zpoollist = zfs.zpool_list()

    # Generate the LUN section
    for extent in iSCSITargetExtent.objects.all():
        path = extent.iscsi_target_extent_path
        poolname = None
        lunthreshold = None
        if extent.iscsi_target_extent_type == 'Disk':
            disk = Disk.objects.filter(id=path).order_by('disk_enabled')
            if not disk.exists():
                continue
            disk = disk[0]
            if disk.disk_multipath_name:
                path = "/dev/multipath/%s" % disk.disk_multipath_name
            else:
                path = "/dev/%s" % disk.identifier_to_device()
        else:
            if not path.startswith("/mnt"):
                poolname = path.split('/', 2)[1]
                if gconf.iscsi_pool_avail_threshold:
                    if poolname in zpoollist:
                        poolthreshold[poolname] = int(
                            zpoollist.get(poolname).get('size') *
                            (gconf.iscsi_pool_avail_threshold / 100.0))
                if extent.iscsi_target_extent_avail_threshold:
                    zvolname = path.split('/', 1)[1]
                    zfslist = zfs.zfs_list(path=zvolname, types=['volume'])
                    if zfslist:
                        lunthreshold = int(
                            zfslist[zvolname].volsize *
                            (extent.iscsi_target_extent_avail_threshold /
                             100.0))
                path = "/dev/" + path
            else:
                if extent.iscsi_target_extent_avail_threshold and os.path.exists(
                        path):
                    try:
                        stat = os.stat(path)
                        lunthreshold = int(
                            stat.st_size *
                            (extent.iscsi_target_extent_avail_threshold /
                             100.0))
                    except OSError:
                        pass
        addline("lun \"%s\" {\n" % extent.iscsi_target_extent_name)
        size = extent.iscsi_target_extent_filesize
        addline("\tpath \"%s\"\n" % path)
        addline("\tblocksize %s\n" % extent.iscsi_target_extent_blocksize)
        if extent.iscsi_target_extent_pblocksize:
            addline("\toption pblocksize 0\n")
        addline("\tserial \"%s\"\n" % (extent.iscsi_target_extent_serial, ))
        padded_serial = extent.iscsi_target_extent_serial
        if not extent.iscsi_target_extent_xen:
            for i in xrange(31 - len(extent.iscsi_target_extent_serial)):
                padded_serial += " "
        addline('\tdevice-id "iSCSI Disk      %s"\n' % padded_serial)
        if size != "0":
            if size.endswith('B'):
                size = size.strip('B')
            addline("\t\tsize %s\n" % size)
        addline('\toption vendor "FreeBSD"\n')
        addline('\toption product "iSCSI Disk"\n')
        addline('\toption revision "0123"\n')
        addline('\toption naa %s\n' % extent.iscsi_target_extent_naa)
        if extent.iscsi_target_extent_insecure_tpc:
            addline('\toption insecure_tpc on\n')
            if lunthreshold:
                addline('\toption avail-threshold %s\n' % lunthreshold)
        if poolname is not None and poolname in poolthreshold:
            addline('\toption pool-avail-threshold %s\n' %
                    poolthreshold[poolname])
        if extent.iscsi_target_extent_rpm == "Unknown":
            addline('\toption rpm 0\n')
        elif extent.iscsi_target_extent_rpm == "SSD":
            addline('\toption rpm 1\n')
        else:
            addline('\toption rpm %s\n' % extent.iscsi_target_extent_rpm)
        addline("}\n")
        addline("\n")

    # Generate the target section
    target_basename = gconf.iscsi_basename
    for target in iSCSITarget.objects.all():

        has_auth = False
        authgroups = {}
        for grp in target.iscsitargetgroups_set.all():
            if grp.iscsi_target_authgroup:
                auth_list = iSCSITargetAuthCredential.objects.filter(
                    iscsi_target_auth_tag=grp.iscsi_target_authgroup)
            else:
                auth_list = []
            agname = '4tg%d_%d' % (target.id, grp.id)
            if auth_group_config(auth_tag=agname,
                                 auth_list=auth_list,
                                 auth_type=grp.iscsi_target_authtype,
                                 initiator=grp.iscsi_target_initiatorgroup):
                authgroups[grp.id] = agname
        if (target.iscsi_target_name.startswith("iqn.")
                or target.iscsi_target_name.startswith("eui.")
                or target.iscsi_target_name.startswith("naa.")):
            addline("target %s {\n" % target.iscsi_target_name)
        else:
            addline("target %s:%s {\n" %
                    (target_basename, target.iscsi_target_name))
        if target.iscsi_target_alias:
            addline("\talias \"%s\"\n" % target.iscsi_target_alias)
        elif target.iscsi_target_name:
            addline("\talias \"%s\"\n" % target.iscsi_target_name)

        for fctt in target.fiberchanneltotarget_set.all():
            addline("\tport %s\n" % fctt.fc_port)

        for grp in target.iscsitargetgroups_set.all():
            agname = authgroups.get(grp.id) or None
            addline("\tportal-group pg%d %s\n" % (
                grp.iscsi_target_portalgroup.iscsi_target_portal_tag,
                'ag' + agname if agname else 'no-authentication',
            ))
        addline("\n")
        used_lunids = [
            o.iscsi_lunid for o in
            target.iscsitargettoextent_set.all().exclude(iscsi_lunid=None, )
        ]
        cur_lunid = 0
        for t2e in target.iscsitargettoextent_set.all().extra({
                'null_first':
                'iscsi_lunid IS NULL',
        }).order_by('null_first', 'iscsi_lunid'):

            if t2e.iscsi_lunid is None:
                while cur_lunid in used_lunids:
                    cur_lunid += 1
                addline("\tlun %s \"%s\"\n" %
                        (cur_lunid, t2e.iscsi_extent.iscsi_target_extent_name))
                cur_lunid += 1
            else:
                addline("\tlun %s \"%s\"\n" %
                        (t2e.iscsi_lunid,
                         t2e.iscsi_extent.iscsi_target_extent_name))
        addline("}\n\n")

    os.umask(077)
    # Write out the CTL config file
    fh = open(ctl_config, "w")
    for line in cf_contents:
        fh.write(line)
    fh.close()

    # Write out the CTL config file with redacted CHAP passwords
    fh = open(ctl_config_shadow, "w")
    for line in cf_contents_shadow:
        fh.write(line)
    fh.close()
Пример #7
0
def main():
    """Use the django ORM to generate a config file.  We'll build the
    config file as a series of lines, and once that is done write it
    out in one go"""

    from freenasUI.services.models import iSCSITargetGlobalConfiguration
    from freenasUI.services.models import iSCSITargetPortal
    from freenasUI.services.models import iSCSITargetPortalIP
    from freenasUI.services.models import iSCSITargetAuthCredential
    from freenasUI.services.models import iSCSITargetExtent
    from freenasUI.services.models import iSCSITarget
    from freenasUI.storage.models import Disk

    gconf = iSCSITargetGlobalConfiguration.objects.order_by('-id')[0]

    if gconf.iscsi_isns_servers:
        for server in gconf.iscsi_isns_servers.split(' '):
            addline('isns-server %s\n\n' % server)

    # Generate the portal-group section
    addline('portal-group default {\n}\n\n')
    for portal in iSCSITargetPortal.objects.all():
        # Prepare auth group for the portal group
        if portal.iscsi_target_portal_discoveryauthgroup:
            auth_list = iSCSITargetAuthCredential.objects.filter(iscsi_target_auth_tag=portal.iscsi_target_portal_discoveryauthgroup)
        else:
            auth_list = []
        agname = '4pg%d' % portal.iscsi_target_portal_tag
        auth = auth_group_config(auth_tag=agname, auth_list=auth_list, auth_type=portal.iscsi_target_portal_discoveryauthmethod)

        addline("portal-group pg%s {\n" % portal.iscsi_target_portal_tag)
        addline("\tdiscovery-filter portal-name\n")
        if auth:
            addline("\tdiscovery-auth-group ag%s\n" % agname)
        else:
            addline("\tdiscovery-auth-group no-authentication\n")
        listen = iSCSITargetPortalIP.objects.filter(iscsi_target_portalip_portal=portal)
        for obj in listen:
            if ':' in obj.iscsi_target_portalip_ip:
                address = '[%s]' % obj.iscsi_target_portalip_ip
            else:
                address = obj.iscsi_target_portalip_ip
            addline("\tlisten %s:%s\n" % (address, obj.iscsi_target_portalip_port))
        addline("}\n\n")

    # Cache zpool threshold
    poolthreshold = {}
    zpoollist = zfs.zpool_list()

    # Generate the LUN section
    for extent in iSCSITargetExtent.objects.all():
        path = extent.iscsi_target_extent_path
        poolname = None
        lunthreshold = None
        if extent.iscsi_target_extent_type == 'Disk':
            disk = Disk.objects.filter(id=path).order_by('disk_enabled')
            if not disk.exists():
                continue
            disk = disk[0]
            if disk.disk_multipath_name:
                path = "/dev/multipath/%s" % disk.disk_multipath_name
            else:
                path = "/dev/%s" % disk.identifier_to_device()
        else:
            if not path.startswith("/mnt"):
                poolname = path.split('/', 2)[1]
                if gconf.iscsi_pool_avail_threshold:
                    if poolname in zpoollist:
                        poolthreshold[poolname] = int(
                            zpoollist.get(poolname).get('size') * (
                                gconf.iscsi_pool_avail_threshold / 100.0
                            )
                        )
                if extent.iscsi_target_extent_avail_threshold:
                    zvolname = path.split('/', 1)[1]
                    zfslist = zfs.zfs_list(path=zvolname, types=['volume'])
                    if zfslist:
                        lunthreshold = int(zfslist[zvolname].volsize * (extent.iscsi_target_extent_avail_threshold / 100.0))
                path = "/dev/" + path
            else:
                if extent.iscsi_target_extent_avail_threshold and os.path.exists(path):
                    try:
                        stat = os.stat(path)
                        lunthreshold = int(stat.st_size * (extent.iscsi_target_extent_avail_threshold / 100.0))
                    except OSError:
                        pass
        addline("lun \"%s\" {\n" % extent.iscsi_target_extent_name)
        size = extent.iscsi_target_extent_filesize
        addline("\tpath \"%s\"\n" % path)
        addline("\tblocksize %s\n" % extent.iscsi_target_extent_blocksize)
        if extent.iscsi_target_extent_pblocksize:
            addline("\toption pblocksize 0\n")
        addline("\tserial \"%s\"\n" % (extent.iscsi_target_extent_serial, ))
        padded_serial = extent.iscsi_target_extent_serial
        if not extent.iscsi_target_extent_xen:
            for i in xrange(31-len(extent.iscsi_target_extent_serial)):
                padded_serial += " "
        addline('\tdevice-id "iSCSI Disk      %s"\n' % padded_serial)
        if size != "0":
            if size.endswith('B'):
                size = size.strip('B')
            addline("\t\tsize %s\n" % size)
        addline('\toption vendor "FreeBSD"\n')
        addline('\toption product "iSCSI Disk"\n')
        addline('\toption revision "0123"\n')
        addline('\toption naa %s\n' % extent.iscsi_target_extent_naa)
        if extent.iscsi_target_extent_insecure_tpc:
            addline('\toption insecure_tpc on\n')
            if lunthreshold:
                addline('\toption avail-threshold %s\n' % lunthreshold)
        if poolname is not None and poolname in poolthreshold:
            addline('\toption pool-avail-threshold %s\n' % poolthreshold[poolname])
        if extent.iscsi_target_extent_rpm == "Unknown":
            addline('\toption rpm 0\n')
        elif extent.iscsi_target_extent_rpm == "SSD":
            addline('\toption rpm 1\n')
        else:
            addline('\toption rpm %s\n' % extent.iscsi_target_extent_rpm)
        addline("}\n")
        addline("\n")

    # Generate the target section
    target_basename = gconf.iscsi_basename
    for target in iSCSITarget.objects.all():

        has_auth = False
        authgroups = {}
        for grp in target.iscsitargetgroups_set.all():
            if grp.iscsi_target_authgroup:
                auth_list = iSCSITargetAuthCredential.objects.filter(iscsi_target_auth_tag=grp.iscsi_target_authgroup)
            else:
                auth_list = []
            agname = '4tg%d_%d' % (target.id, grp.id)
            if auth_group_config(auth_tag=agname, auth_list=auth_list, auth_type=grp.iscsi_target_authtype, initiator=grp.iscsi_target_initiatorgroup):
                authgroups[grp.id] = agname
        if (target.iscsi_target_name.startswith("iqn.") or
                target.iscsi_target_name.startswith("eui.") or
                target.iscsi_target_name.startswith("naa.")):
            addline("target %s {\n" % target.iscsi_target_name)
        else:
            addline("target %s:%s {\n" % (target_basename, target.iscsi_target_name))
        if target.iscsi_target_alias:
            addline("\talias \"%s\"\n" % target.iscsi_target_alias)
        elif target.iscsi_target_name:
            addline("\talias \"%s\"\n" % target.iscsi_target_name)

        for fctt in target.fiberchanneltotarget_set.all():
            addline("\tport %s\n" % fctt.fc_port)

        for grp in target.iscsitargetgroups_set.all():
            agname = authgroups.get(grp.id) or None
            addline("\tportal-group pg%d %s\n" % (
                grp.iscsi_target_portalgroup.iscsi_target_portal_tag,
                'ag' + agname if agname else 'no-authentication',
            ))
        addline("\n")
        used_lunids = [
            o.iscsi_lunid
            for o in target.iscsitargettoextent_set.all().exclude(
                iscsi_lunid=None,
            )
        ]
        cur_lunid = 0
        for t2e in target.iscsitargettoextent_set.all().extra({
            'null_first': 'iscsi_lunid IS NULL',
        }).order_by('null_first', 'iscsi_lunid'):

            if t2e.iscsi_lunid is None:
                while cur_lunid in used_lunids:
                    cur_lunid += 1
                addline("\tlun %s \"%s\"\n" % (cur_lunid, t2e.iscsi_extent.iscsi_target_extent_name))
                cur_lunid += 1
            else:
                addline("\tlun %s \"%s\"\n" % (t2e.iscsi_lunid, t2e.iscsi_extent.iscsi_target_extent_name))
        addline("}\n\n")

    os.umask(077)
    # Write out the CTL config file
    fh = open(ctl_config, "w")
    for line in cf_contents:
        fh.write(line)
    fh.close()

    # Write out the CTL config file with redacted CHAP passwords
    fh = open(ctl_config_shadow, "w")
    for line in cf_contents_shadow:
        fh.write(line)
    fh.close()