示例#1
0
def search_volume(volname):
    """Search for a Volume by name in all Hosting Volumes"""
    volhash = get_volname_hash(volname)
    subdir_path = get_volume_path(PV_TYPE_SUBVOL, volhash, volname)
    virtblock_path = get_volume_path(PV_TYPE_VIRTBLOCK, volhash, volname)

    host_volumes = get_pv_hosting_volumes()
    for hvol in host_volumes:
        mntdir = os.path.join(HOSTVOL_MOUNTDIR, hvol)
        # Try to mount the Host Volume, handle failure if already mounted
        mount_glusterfs(hvol, mntdir)
        for info_path in [subdir_path, virtblock_path]:
            info_path_full = os.path.join(mntdir, "info", info_path + ".json")
            voltype = PV_TYPE_SUBVOL if "/%s/" % PV_TYPE_SUBVOL \
                in info_path_full else PV_TYPE_VIRTBLOCK

            if os.path.exists(info_path_full):
                data = {}
                with open(info_path_full) as info_file:
                    data = json.load(info_file)

                return Volume(volname=volname,
                              voltype=voltype,
                              volhash=volhash,
                              hostvol=hvol,
                              size=data["size"])
    return None
示例#2
0
def search_volume(volname):
    """Search for a Volume by name in all Hosting Volumes"""
    volhash = get_volname_hash(volname)
    subdir_path = get_volume_path(PV_TYPE_SUBVOL, volhash, volname)
    virtblock_path = get_volume_path(PV_TYPE_VIRTBLOCK, volhash, volname)

    host_volumes = get_pv_hosting_volumes()
    for volume in host_volumes:
        hvol = volume['name']
        mntdir = os.path.join(HOSTVOL_MOUNTDIR, hvol)
        mount_glusterfs(volume, mntdir)
        # Check for mount availability before checking the info file
        retry_errors(os.statvfs, [mntdir], [ENOTCONN])

        for info_path in [subdir_path, virtblock_path]:
            info_path_full = os.path.join(mntdir, "info", info_path + ".json")
            voltype = PV_TYPE_SUBVOL if "/%s/" % PV_TYPE_SUBVOL \
                in info_path_full else PV_TYPE_VIRTBLOCK

            if os.path.exists(info_path_full):
                data = {}
                with open(info_path_full) as info_file:
                    data = json.load(info_file)

                return Volume(volname=volname,
                              voltype=voltype,
                              volhash=volhash,
                              hostvol=hvol,
                              size=data["size"])
    return None
示例#3
0
def handle_quota(quota_report, brick_path, volname, pvtype):
    """Sets Quota if info file is available"""

    volhash = get_volname_hash(volname)
    volpath = get_volume_path(pvtype, volhash, volname)
    subdir_path = os.path.join(brick_path, volpath)
    projid = "#%d" % os.lstat(subdir_path).st_ino
    limit_hard = 0
    for line in quota_report:
        if line.startswith(projid):
            limit_hard = int(line.split()[3])
            break

    # Quota is already set, continue
    # TODO: Handle PV resize requests
    if limit_hard > 0:
        return

    pvinfo_file_path = os.path.join(brick_path, "info", volpath + ".json")
    if os.path.exists(pvinfo_file_path):
        data = {}
        with open(pvinfo_file_path) as pvinfo_file:
            data = json.loads(pvinfo_file.read().strip())

            try:
                set_quota(os.path.dirname(brick_path), subdir_path,
                          data["size"])
            except CommandException as err:
                logging.error(
                    logf("Failed to set Quota",
                         err=err.err,
                         path=subdir_path.replace(brick_path, ""),
                         size=data["size"]))
    return
示例#4
0
def create_virtblock_volume(hostvol_mnt, volname, size):
    """Create virtual block volume"""
    volhash = get_volname_hash(volname)
    volpath = get_volume_path(PV_TYPE_VIRTBLOCK, volhash, volname)
    volpath_full = os.path.join(hostvol_mnt, volpath)
    logging.debug(logf("Volume hash", volhash=volhash))

    # Create a file with required size
    makedirs(os.path.dirname(volpath_full))
    logging.debug(
        logf("Created virtblock directory", path=os.path.dirname(volpath)))

    volpath_fd = os.open(volpath_full, os.O_CREAT | os.O_RDWR)
    os.close(volpath_fd)
    os.truncate(volpath_full, size)
    logging.debug(
        logf("Truncated file to required size", path=volpath, size=size))

    # TODO: Multiple FS support based on volume_capability mount option
    execute(MKFS_XFS_CMD, volpath_full)
    logging.debug(
        logf("Created Filesystem", path=volpath, command=MKFS_XFS_CMD))
    save_pv_metadata(hostvol_mnt, volpath, size)
    return Volume(
        volname=volname,
        voltype=PV_TYPE_VIRTBLOCK,
        volhash=volhash,
        hostvol=os.path.basename(hostvol_mnt),
        size=size,
        volpath=volpath,
    )
示例#5
0
def create_subdir_volume(hostvol_mnt, volname, size):
    """Create sub directory Volume"""
    volhash = get_volname_hash(volname)
    volpath = get_volume_path(PV_TYPE_SUBVOL, volhash, volname)
    logging.debug(logf("Volume hash", volhash=volhash))

    # Check for mount availability before creating subdir volume
    retry_errors(os.statvfs, [hostvol_mnt], [ENOTCONN])

    # Create a subdir
    makedirs(os.path.join(hostvol_mnt, volpath))
    logging.debug(logf("Created PV directory", pvdir=volpath))

    # Write info file so that Brick's quotad sidecar
    # container picks it up.
    save_pv_metadata(hostvol_mnt, volpath, size)

    # Wait for quota set
    # TODO: Handle Timeout
    pvsize_buffer = size * 0.05  # 5%
    pvsize_min = (size - pvsize_buffer)
    pvsize_max = (size + pvsize_buffer)
    logging.debug(
        logf(
            "Watching df of pv directory",
            pvdir=volpath,
            pvsize_buffer=pvsize_buffer,
        ))

    count = 0
    while True:
        count += 1
        pvstat = retry_errors(os.statvfs, [os.path.join(hostvol_mnt, volpath)],
                              [ENOTCONN])
        volsize = pvstat.f_blocks * pvstat.f_bsize
        if pvsize_min < volsize < pvsize_max:
            logging.debug(
                logf("Matching df output, Quota set successful",
                     volsize=volsize,
                     num_tries=count))
            break

        if count >= 6:
            logging.warning(
                logf("Waited for some time, Quota set failed, continuing.",
                     volsize=volsize,
                     num_tries=count))
            break

        time.sleep(1)

    return Volume(
        volname=volname,
        voltype=PV_TYPE_SUBVOL,
        volhash=volhash,
        hostvol=os.path.basename(hostvol_mnt),
        size=size,
        volpath=volpath,
    )
示例#6
0
 def setpath(self):
     """Set Volume path based on hash and volume name"""
     if self.volpath is None:
         self.volpath = get_volume_path(
             self.voltype,
             self.volhash,
             self.volname
         )
示例#7
0
def create_virtblock_volume(hostvol_mnt, volname, size):
    """Create virtual block volume"""
    volhash = get_volname_hash(volname)
    volpath = get_volume_path(PV_TYPE_VIRTBLOCK, volhash, volname)
    volpath_full = os.path.join(hostvol_mnt, volpath)
    logging.debug(logf(
        "Volume hash",
        volhash=volhash
    ))

    # Check for mount availability before creating virtblock volume
    retry_errors(os.statvfs, [hostvol_mnt], [ENOTCONN])

    # Create a file with required size
    makedirs(os.path.dirname(volpath_full))
    logging.debug(logf(
        "Created virtblock directory",
        path=os.path.dirname(volpath)
    ))

    if os.path.exists(volpath_full):
        rand = time.time()
        logging.info(logf(
            "Getting 'Create request' on existing file, renaming.",
            path=volpath_full, random=rand
        ))
        os.rename(volpath_full, "%s.%s" % (volpath_full, rand))

    volpath_fd = os.open(volpath_full, os.O_CREAT | os.O_RDWR)
    os.close(volpath_fd)
    os.truncate(volpath_full, size)
    logging.debug(logf(
        "Truncated file to required size",
        path=volpath,
        size=size
    ))

    # TODO: Multiple FS support based on volume_capability mount option
    execute(MKFS_XFS_CMD, volpath_full)
    logging.debug(logf(
        "Created Filesystem",
        path=volpath,
        command=MKFS_XFS_CMD
    ))
    save_pv_metadata(hostvol_mnt, volpath, size)
    return Volume(
        volname=volname,
        voltype=PV_TYPE_VIRTBLOCK,
        volhash=volhash,
        hostvol=os.path.basename(hostvol_mnt),
        size=size,
        volpath=volpath,
    )
示例#8
0
def create_subdir_volume(hostvol_mnt, volname, size):
    """Create sub directory Volume"""
    volhash = get_volname_hash(volname)
    volpath = get_volume_path(PV_TYPE_SUBVOL, volhash, volname)
    logging.debug(logf("Volume hash", volhash=volhash))

    # Create a subdir
    os.makedirs(os.path.join(hostvol_mnt, volpath), exist_ok=True)
    logging.debug(logf("Created PV directory", pvdir=volpath))

    # Write info file so that Brick's quotad sidecar
    # container picks it up.
    save_pv_metadata(hostvol_mnt, volpath, size)

    # Wait for quota set
    # TODO: Handle Timeout
    pvsize_buffer = size * 0.05  # 5%
    pvsize_min = (size - pvsize_buffer)
    pvsize_max = (size + pvsize_buffer)
    logging.debug(
        logf(
            "Watching df of pv directory",
            pvdir=volpath,
            pvsize_buffer=pvsize_buffer,
        ))

    count = 0
    while True:
        count += 1
        pvstat = os.statvfs(os.path.join(hostvol_mnt, volpath))
        volsize = pvstat.f_blocks * pvstat.f_bsize
        if pvsize_min < volsize < pvsize_max:
            logging.debug(
                logf("Matching df output, Quota set successful",
                     volsize=volsize,
                     num_tries=count))
            break

        time.sleep(1)

    return Volume(volname=volname,
                  voltype=PV_TYPE_SUBVOL,
                  volhash=volhash,
                  hostvol=os.path.basename(hostvol_mnt),
                  size=size)
示例#9
0
def handle_quota(brick_path, volname, pvtype):
    """Sets Quota if info file is available"""

    volhash = get_volname_hash(volname)
    volpath = get_volume_path(pvtype, volhash, volname)
    subdir_path = os.path.join(brick_path, volpath)

    pvinfo_file_path = os.path.join(brick_path, "info", volpath + ".json")
    if os.path.exists(pvinfo_file_path):
        data = {}
        with open(pvinfo_file_path) as pvinfo_file:
            data = json.loads(pvinfo_file.read().strip())

            # global dictionary to avoid init to None
            global SIZE_LIMITS

            # Add every new entry of volnames
            if volname not in SIZE_LIMITS:
                SIZE_LIMITS[volname] = {}

            # Handle PV resize quota updates

            # Init existing_size to -1 to handle new quota requests
            # Update existing_size for every update requests
            if data["size"] > SIZE_LIMITS[volname].get('existing_size', -1):
                SIZE_LIMITS[volname]['existing_size'] = data["size"]
            # Quota already set for size, return
            else:
                return

            try:
                set_quota(os.path.dirname(brick_path), subdir_path,
                          data["size"])
                logging.info(logf("Quota set for size", size=data["size"]))
            except CommandException as err:
                logging.error(
                    logf("Failed to set Quota",
                         err=err.err,
                         path=subdir_path.replace(brick_path, ""),
                         size=data["size"]))
    return
示例#10
0
def update_virtblock_volume(hostvol_mnt, volname, expansion_requested_pvsize):
    """Update virtual block volume"""

    volhash = get_volname_hash(volname)
    volpath = get_volume_path(PV_TYPE_VIRTBLOCK, volhash, volname)
    volpath_full = os.path.join(hostvol_mnt, volpath)
    logging.debug(logf("Volume hash", volhash=volhash))

    # Check for mount availability before updating virtblock volume
    retry_errors(os.statvfs, [hostvol_mnt], [ENOTCONN])

    # Update the file with required size
    makedirs(os.path.dirname(volpath_full))
    logging.debug(
        logf("Updated virtblock directory", path=os.path.dirname(volpath)))

    volpath_fd = os.open(volpath_full, os.O_CREAT | os.O_RDWR)
    os.close(volpath_fd)

    execute("truncate", "-s", expansion_requested_pvsize, volpath_full)
    logging.debug(
        logf("Truncated file to required size",
             path=volpath,
             size=expansion_requested_pvsize))

    # TODO: Multiple FS support based on volume_capability mount option
    execute(MKFS_XFS_CMD, volpath_full)
    logging.debug(
        logf("Created Filesystem", path=volpath, command=MKFS_XFS_CMD))

    update_pv_metadata(hostvol_mnt, volpath, expansion_requested_pvsize)
    return Volume(
        volname=volname,
        voltype=PV_TYPE_VIRTBLOCK,
        volhash=volhash,
        hostvol=os.path.basename(hostvol_mnt),
        size=expansion_requested_pvsize,
        volpath=volpath,
    )
示例#11
0
def create_subdir_volume(hostvol_mnt, volname, size):
    """Create sub directory Volume"""
    volhash = get_volname_hash(volname)
    volpath = get_volume_path(PV_TYPE_SUBVOL, volhash, volname)
    logging.debug(logf("Volume hash", volhash=volhash))

    # Check for mount availability before creating subdir volume
    retry_errors(os.statvfs, [hostvol_mnt], [ENOTCONN])

    # Create a subdir
    makedirs(os.path.join(hostvol_mnt, volpath))
    logging.debug(logf("Created PV directory", pvdir=volpath))

    # Write info file so that Brick's quotad sidecar
    # container picks it up.
    save_pv_metadata(hostvol_mnt, volpath, size)

    # Wait for quota set
    # TODO: Handle Timeout
    pvsize_buffer = size * 0.05  # 5%
    pvsize_min = (size - pvsize_buffer)
    pvsize_max = (size + pvsize_buffer)
    logging.debug(
        logf(
            "Watching df of pv directory",
            pvdir=volpath,
            pvsize_buffer=pvsize_buffer,
        ))

    #setfattr -n trusted.glusterfs.namespace -v true
    #setfattr -n trusted.gfs.squota.limit -v size
    try:
        retry_errors(os.setxattr, [
            os.path.join(hostvol_mnt, volpath), "trusted.glusterfs.namespace",
            "true".encode()
        ], [ENOTCONN])
        retry_errors(os.setxattr, [
            os.path.join(hostvol_mnt, volpath), "trusted.gfs.squota.limit",
            str(size).encode()
        ], [ENOTCONN])
    # noqa # pylint: disable=broad-except
    except Exception as err:
        logging.info(
            logf("Failed to set quota using simple-quota. Continuing",
                 error=err))

    count = 0
    while True:
        count += 1
        pvstat = retry_errors(os.statvfs, [os.path.join(hostvol_mnt, volpath)],
                              [ENOTCONN])
        volsize = pvstat.f_blocks * pvstat.f_bsize
        if pvsize_min < volsize < pvsize_max:
            logging.debug(
                logf("Matching df output, Quota set successful",
                     volsize=volsize,
                     num_tries=count))
            break

        if count >= 6:
            logging.warning(
                logf("Waited for some time, Quota set failed, continuing.",
                     volsize=volsize,
                     num_tries=count))
            break

        time.sleep(1)

    return Volume(
        volname=volname,
        voltype=PV_TYPE_SUBVOL,
        volhash=volhash,
        hostvol=os.path.basename(hostvol_mnt),
        size=size,
        volpath=volpath,
    )
示例#12
0
def update_subdir_volume(hostvol_mnt, hostvoltype, volname,
                         expansion_requested_pvsize):
    """Update sub directory Volume"""

    volhash = get_volname_hash(volname)
    volpath = get_volume_path(PV_TYPE_SUBVOL, volhash, volname)
    logging.debug(logf("Volume hash", volhash=volhash))

    # Check for mount availability before updating subdir volume
    retry_errors(os.statvfs, [hostvol_mnt], [ENOTCONN])

    # Create a subdir
    makedirs(os.path.join(hostvol_mnt, volpath))
    logging.debug(logf("Updated PV directory", pvdir=volpath))

    # Write info file so that Brick's quotad sidecar
    # container picks it up.
    update_pv_metadata(hostvol_mnt, volpath, expansion_requested_pvsize)

    # Wait for quota set
    # TODO: Handle Timeout
    pvsize_buffer = expansion_requested_pvsize * 0.05  # 5%
    pvsize_min = (expansion_requested_pvsize - pvsize_buffer)
    pvsize_max = (expansion_requested_pvsize + pvsize_buffer)
    logging.debug(
        logf(
            "Watching df of pv directory",
            pvdir=volpath,
            pvsize_buffer=pvsize_buffer,
        ))

    # Handle this case in calling function
    if hostvoltype == 'External':
        return None

    retry_errors(os.setxattr, [
        os.path.join(hostvol_mnt, volpath), "trusted.gfs.squota.limit",
        str(expansion_requested_pvsize).encode()
    ], [ENOTCONN])

    count = 0
    while True:
        count += 1
        pvstat = retry_errors(os.statvfs, [os.path.join(hostvol_mnt, volpath)],
                              [ENOTCONN])
        volsize = pvstat.f_blocks * pvstat.f_bsize
        if pvsize_min < volsize < pvsize_max:
            logging.debug(
                logf("Matching df output, Quota update set successful",
                     volsize=volsize,
                     pvsize=expansion_requested_pvsize,
                     num_tries=count))
            break

        if count >= 6:
            logging.warning(
                logf(
                    "Waited for some time, Quota update set failed, continuing.",
                    volsize=volsize,
                    pvsize=expansion_requested_pvsize,
                    num_tries=count))
            break

        time.sleep(1)

    return Volume(
        volname=volname,
        voltype=PV_TYPE_SUBVOL,
        volhash=volhash,
        hostvol=os.path.basename(hostvol_mnt),
        size=expansion_requested_pvsize,
        volpath=volpath,
    )