Example #1
0
def handle_create_cache_tier(request, service):
    """Create a cache tier on a cold pool.  Modes supported are
    "writeback" and "readonly".

    :param request: dict of request operations and params
    :param service: The ceph client to run the command under.
    :returns: dict. exit-code and reason if not 0
    """
    # mode = "writeback" | "readonly"
    storage_pool = request.get('cold-pool')
    cache_pool = request.get('hot-pool')
    cache_mode = request.get('mode')

    if cache_mode is None:
        cache_mode = "writeback"

    # cache and storage pool must exist first
    if not pool_exists(service=service, name=storage_pool) or not pool_exists(
            service=service, name=cache_pool):
        msg = ("cold-pool: {} and hot-pool: {} must exist. Please create "
               "them first".format(storage_pool, cache_pool))
        log(msg, level=ERROR)
        return {'exit-code': 1, 'stderr': msg}

    p = Pool(service=service, name=storage_pool)
    p.add_cache_tier(cache_pool=cache_pool, mode=cache_mode)
def make_cache_tier():
    backer_pool = action_get("backer-pool")
    cache_pool = action_get("cache-pool")
    cache_mode = action_get("cache-mode")

    # Pre flight checks
    if not pool_exists('admin', backer_pool):
        log("Please create {} pool before calling create-cache-tier".format(
            backer_pool))
        action_fail("create-cache-tier failed. Backer pool {} must exist "
                    "before calling this".format(backer_pool))

    if not pool_exists('admin', cache_pool):
        log("Please create {} pool before calling create-cache-tier".format(
            cache_pool))
        action_fail("create-cache-tier failed. Cache pool {} must exist "
                    "before calling this".format(cache_pool))

    pool = Pool(service='admin', name=backer_pool)
    try:
        pool.add_cache_tier(cache_pool=cache_pool, mode=cache_mode)
    except CalledProcessError as err:
        log("Add cache tier failed with message: {}".format(err.message))
        action_fail("create-cache-tier failed.  Add cache tier failed with "
                    "message: {}".format(err.message))
def make_cache_tier():
    backer_pool = action_get("backer-pool")
    cache_pool = action_get("cache-pool")
    cache_mode = action_get("cache-mode")

    # Pre flight checks
    if not pool_exists('admin', backer_pool):
        log("Please create {} pool before calling create-cache-tier".format(
            backer_pool))
        action_fail("create-cache-tier failed. Backer pool {} must exist "
                    "before calling this".format(backer_pool))

    if not pool_exists('admin', cache_pool):
        log("Please create {} pool before calling create-cache-tier".format(
            cache_pool))
        action_fail("create-cache-tier failed. Cache pool {} must exist "
                    "before calling this".format(cache_pool))

    pool = Pool(service='admin', name=backer_pool)
    try:
        pool.add_cache_tier(cache_pool=cache_pool, mode=cache_mode)
    except CalledProcessError as err:
        log("Add cache tier failed with message: {}".format(
            err.message))
        action_fail("create-cache-tier failed.  Add cache tier failed with "
                    "message: {}".format(err.message))
def delete_cache_tier():
    backer_pool = action_get("backer-pool")
    cache_pool = action_get("cache-pool")

    # Pre flight checks
    if not pool_exists('admin', backer_pool):
        log("Backer pool {} must exist before calling this".format(
            backer_pool))
        action_fail("remove-cache-tier failed. Backer pool {} must exist "
                    "before calling this".format(backer_pool))

    if not pool_exists('admin', cache_pool):
        log("Cache pool {} must exist before calling this".format(
            cache_pool))
        action_fail("remove-cache-tier failed. Cache pool {} must exist "
                    "before calling this".format(cache_pool))

    pool = Pool(service='admin', name=backer_pool)
    try:
        pool.remove_cache_tier(cache_pool=cache_pool)
    except CalledProcessError as err:
        log("Removing the cache tier failed with message: {}".format(
            err.message))
        action_fail("remove-cache-tier failed. Removing the cache tier failed "
                    "with message: {}".format(err.message))
Example #5
0
def handle_create_cache_tier(request, service):
    """Create a cache tier on a cold pool.  Modes supported are
    "writeback" and "readonly".

    :param request: dict of request operations and params
    :param service: The ceph client to run the command under.
    :returns: dict. exit-code and reason if not 0
    """
    # mode = "writeback" | "readonly"
    storage_pool = request.get('cold-pool')
    cache_pool = request.get('hot-pool')
    cache_mode = request.get('mode')

    if cache_mode is None:
        cache_mode = "writeback"

    # cache and storage pool must exist first
    if not pool_exists(service=service, name=storage_pool) or not pool_exists(
            service=service, name=cache_pool):
        msg = ("cold-pool: {} and hot-pool: {} must exist. Please create "
               "them first".format(storage_pool, cache_pool))
        log(msg, level=ERROR)
        return {'exit-code': 1, 'stderr': msg}

    p = Pool(service=service, name=storage_pool)
    p.add_cache_tier(cache_pool=cache_pool, mode=cache_mode)
Example #6
0
def handle_remove_cache_tier(request, service):
    storage_pool = request.get('cold-pool')
    cache_pool = request.get('hot-pool')
    # cache and storage pool must exist first
    if not pool_exists(service=service, name=storage_pool) or not pool_exists(
            service=service, name=cache_pool):
        msg = ("cold-pool: {} or hot-pool: {} doesn't exist. Not "
               "deleting cache tier".format(storage_pool, cache_pool))
        log(msg, level=ERROR)
        return {'exit-code': 1, 'stderr': msg}

    pool = Pool(name=storage_pool, service=service)
    pool.remove_cache_tier(cache_pool=cache_pool)
def handle_remove_cache_tier(request, service):
    storage_pool = request.get('cold-pool')
    cache_pool = request.get('hot-pool')
    # cache and storage pool must exist first
    if not pool_exists(service=service, name=storage_pool) or not pool_exists(
            service=service, name=cache_pool):
        msg = ("cold-pool: {} or hot-pool: {} doesn't exist. Not "
               "deleting cache tier".format(storage_pool, cache_pool))
        log(msg, level=ERROR)
        return {'exit-code': 1, 'stderr': msg}

    pool = Pool(name=storage_pool, service=service)
    pool.remove_cache_tier(cache_pool=cache_pool)
def handle_erasure_pool(request, service):
    pool_name = request.get('name')
    erasure_profile = request.get('erasure-profile')
    quota = request.get('max-bytes')

    if erasure_profile is None:
        erasure_profile = "default-canonical"

    # Check for missing params
    if pool_name is None:
        msg = "Missing parameter. name is required for the pool"
        log(msg, level=ERROR)
        return {'exit-code': 1, 'stderr': msg}

    # TODO: Default to 3/2 erasure coding. I believe this requires min 5 osds
    if not erasure_profile_exists(service=service, name=erasure_profile):
        # TODO: Fail and tell them to create the profile or default
        msg = ("erasure-profile {} does not exist.  Please create it with: "
               "create-erasure-profile".format(erasure_profile))
        log(msg, level=ERROR)
        return {'exit-code': 1, 'stderr': msg}

    pool = ErasurePool(service=service, name=pool_name,
                       erasure_code_profile=erasure_profile)
    # Ok make the erasure pool
    if not pool_exists(service=service, name=pool_name):
        log("Creating pool '%s' (erasure_profile=%s)" % (pool.name,
                                                         erasure_profile),
            level=INFO)
        pool.create()

    # Set a quota if requested
    if quota is not None:
        set_pool_quota(service=service, pool_name=pool_name, max_bytes=quota)
Example #9
0
def handle_replicated_pool(request, service):
    pool_name = request.get('name')
    replicas = request.get('replicas')
    quota = request.get('max-bytes')

    # Optional params
    pg_num = request.get('pg_num')
    if pg_num:
        # Cap pg_num to max allowed just in case.
        osds = get_osds(service)
        if osds:
            pg_num = min(pg_num, (len(osds) * 100 // replicas))

    # Check for missing params
    if pool_name is None or replicas is None:
        msg = "Missing parameter. name and replicas are required"
        log(msg, level=ERROR)
        return {'exit-code': 1, 'stderr': msg}

    pool = ReplicatedPool(service=service,
                          name=pool_name,
                          replicas=replicas,
                          pg_num=pg_num)
    if not pool_exists(service=service, name=pool_name):
        log("Creating pool '%s' (replicas=%s)" % (pool.name, replicas),
            level=INFO)
        pool.create()
    else:
        log("Pool '%s' already exists - skipping create" % pool.name,
            level=DEBUG)

    # Set a quota if requested
    if quota is not None:
        set_pool_quota(service=service, pool_name=pool_name, max_bytes=quota)
Example #10
0
def handle_replicated_pool(request, service):
    pool_name = request.get('name')
    replicas = request.get('replicas')
    quota = request.get('max-bytes')

    # Optional params
    pg_num = request.get('pg_num')
    if pg_num:
        # Cap pg_num to max allowed just in case.
        osds = get_osds(service)
        if osds:
            pg_num = min(pg_num, (len(osds) * 100 // replicas))

    # Check for missing params
    if pool_name is None or replicas is None:
        msg = "Missing parameter. name and replicas are required"
        log(msg, level=ERROR)
        return {'exit-code': 1, 'stderr': msg}

    pool = ReplicatedPool(service=service,
                          name=pool_name,
                          replicas=replicas,
                          pg_num=pg_num)
    if not pool_exists(service=service, name=pool_name):
        log("Creating pool '%s' (replicas=%s)" % (pool.name, replicas),
            level=INFO)
        pool.create()
    else:
        log("Pool '%s' already exists - skipping create" % pool.name,
            level=DEBUG)

    # Set a quota if requested
    if quota is not None:
        set_pool_quota(service=service, pool_name=pool_name, max_bytes=quota)
Example #11
0
def handle_erasure_pool(request, service):
    pool_name = request.get('name')
    erasure_profile = request.get('erasure-profile')
    quota = request.get('max-bytes')

    if erasure_profile is None:
        erasure_profile = "default-canonical"

    # Check for missing params
    if pool_name is None:
        msg = "Missing parameter. name is required for the pool"
        log(msg, level=ERROR)
        return {'exit-code': 1, 'stderr': msg}

    # TODO: Default to 3/2 erasure coding. I believe this requires min 5 osds
    if not erasure_profile_exists(service=service, name=erasure_profile):
        # TODO: Fail and tell them to create the profile or default
        msg = ("erasure-profile {} does not exist.  Please create it with: "
               "create-erasure-profile".format(erasure_profile))
        log(msg, level=ERROR)
        return {'exit-code': 1, 'stderr': msg}

    pool = ErasurePool(service=service,
                       name=pool_name,
                       erasure_code_profile=erasure_profile)
    # Ok make the erasure pool
    if not pool_exists(service=service, name=pool_name):
        log("Creating pool '%s' (erasure_profile=%s)" %
            (pool.name, erasure_profile),
            level=INFO)
        pool.create()

    # Set a quota if requested
    if quota is not None:
        set_pool_quota(service=service, pool_name=pool_name, max_bytes=quota)
def handle_erasure_pool(request, service):
    """Create a new erasure coded pool.

    :param request: dict of request operations and params.
    :param service: The ceph client to run the command under.
    :returns: dict. exit-code and reason if not 0.
    """
    pool_name = request.get('name')
    erasure_profile = request.get('erasure-profile')
    max_bytes = request.get('max-bytes')
    max_objects = request.get('max-objects')
    weight = request.get('weight')
    group_name = request.get('group')
    allow_ec_overwrites = request.get('allow-ec-overwrites')

    if erasure_profile is None:
        erasure_profile = "default-canonical"

    app_name = request.get('app-name')

    # Check for missing params
    if pool_name is None:
        msg = "Missing parameter. name is required for the pool"
        log(msg, level=ERROR)
        return {'exit-code': 1, 'stderr': msg}

    if group_name:
        group_namespace = request.get('group-namespace')
        # Add the pool to the group named "group_name"
        add_pool_to_group(pool=pool_name,
                          group=group_name,
                          namespace=group_namespace)

    # TODO: Default to 3/2 erasure coding. I believe this requires min 5 osds
    if not erasure_profile_exists(service=service, name=erasure_profile):
        # TODO: Fail and tell them to create the profile or default
        msg = ("erasure-profile {} does not exist.  Please create it with: "
               "create-erasure-profile".format(erasure_profile))
        log(msg, level=ERROR)
        return {'exit-code': 1, 'stderr': msg}

    pool = ErasurePool(service=service,
                       name=pool_name,
                       erasure_code_profile=erasure_profile,
                       percent_data=weight,
                       app_name=app_name,
                       allow_ec_overwrites=allow_ec_overwrites)
    # Ok make the erasure pool
    if not pool_exists(service=service, name=pool_name):
        log("Creating pool '{}' (erasure_profile={})".format(
            pool.name, erasure_profile),
            level=INFO)
        pool.create()

    # Set a quota if requested
    if max_bytes or max_objects:
        set_pool_quota(service=service,
                       pool_name=pool_name,
                       max_bytes=max_bytes,
                       max_objects=max_objects)
Example #13
0
def handle_replicated_pool(request, service):
    """Create a new replicated pool.

    :param request: dict of request operations and params.
    :param service: The ceph client to run the command under.
    :returns: dict. exit-code and reason if not 0.
    """
    pool_name = request.get('name')
    replicas = request.get('replicas')
    quota = request.get('max-bytes')
    weight = request.get('weight')
    group_name = request.get('group')

    # Optional params
    pg_num = request.get('pg_num')
    if pg_num:
        # Cap pg_num to max allowed just in case.
        osds = get_osds(service)
        if osds:
            pg_num = min(pg_num, (len(osds) * 100 // replicas))

    app_name = request.get('app-name')
    # Check for missing params
    if pool_name is None or replicas is None:
        msg = "Missing parameter. name and replicas are required"
        log(msg, level=ERROR)
        return {'exit-code': 1, 'stderr': msg}

    if group_name:
        group_namespace = request.get('group-namespace')
        # Add the pool to the group named "group_name"
        add_pool_to_group(pool=pool_name,
                          group=group_name,
                          namespace=group_namespace)

    kwargs = {}
    if pg_num:
        kwargs['pg_num'] = pg_num
    if weight:
        kwargs['percent_data'] = weight
    if replicas:
        kwargs['replicas'] = replicas
    if app_name:
        kwargs['app_name'] = app_name

    pool = ReplicatedPool(service=service,
                          name=pool_name, **kwargs)
    if not pool_exists(service=service, name=pool_name):
        log("Creating pool '{}' (replicas={})".format(pool.name, replicas),
            level=INFO)
        pool.create()
    else:
        log("Pool '{}' already exists - skipping create".format(pool.name),
            level=DEBUG)

    # Set a quota if requested
    if quota is not None:
        set_pool_quota(service=service, pool_name=pool_name, max_bytes=quota)
Example #14
0
def handle_create_cephfs(request, service):
    """Create a new cephfs.

    :param request: The broker request
    :param service: The ceph client to run the command under.
    :returns: dict. exit-code and reason if not 0
    """
    cephfs_name = request.get('mds_name')
    data_pool = request.get('data_pool')
    metadata_pool = request.get('metadata_pool')
    # Check if the user params were provided
    if not cephfs_name or not data_pool or not metadata_pool:
        msg = "Missing mds_name, data_pool or metadata_pool params"
        log(msg, level=ERROR)
        return {'exit-code': 1, 'stderr': msg}

    # Sanity check that the required pools exist
    if not pool_exists(service=service, name=data_pool):
        msg = "CephFS data pool does not exist.  Cannot create CephFS"
        log(msg, level=ERROR)
        return {'exit-code': 1, 'stderr': msg}
    if not pool_exists(service=service, name=metadata_pool):
        msg = "CephFS metadata pool does not exist.  Cannot create CephFS"
        log(msg, level=ERROR)
        return {'exit-code': 1, 'stderr': msg}

    if get_cephfs(service=service):
        # CephFS new has already been called
        log("CephFS already created")
        return

        # Finally create CephFS
    try:
        check_output(["ceph",
                      '--id', service,
                      "fs", "new", cephfs_name,
                      metadata_pool,
                      data_pool])
    except CalledProcessError as err:
        if err.returncode == 22:
            log("CephFS already created")
            return
        else:
            log(err.output, level=ERROR)
            return {'exit-code': 1, 'stderr': err.output}
def handle_create_cephfs(request, service):
    """
    Create a new cephfs.
    :param request: The broker request
    :param service: The cephx user to run this command under
    :return:
    """
    cephfs_name = request.get('mds_name')
    data_pool = request.get('data_pool')
    metadata_pool = request.get('metadata_pool')
    # Check if the user params were provided
    if not cephfs_name or not data_pool or not metadata_pool:
        msg = "Missing mds_name, data_pool or metadata_pool params"
        log(msg, level=ERROR)
        return {'exit-code': 1, 'stderr': msg}

    # Sanity check that the required pools exist
    if not pool_exists(service=service, name=data_pool):
        msg = "CephFS data pool does not exist.  Cannot create CephFS"
        log(msg, level=ERROR)
        return {'exit-code': 1, 'stderr': msg}
    if not pool_exists(service=service, name=metadata_pool):
        msg = "CephFS metadata pool does not exist.  Cannot create CephFS"
        log(msg, level=ERROR)
        return {'exit-code': 1, 'stderr': msg}

    if get_cephfs(service=service):
        # CephFS new has already been called
        log("CephFS already created")
        return

        # Finally create CephFS
    try:
        check_output(["ceph",
                      '--id', service,
                      "fs", "new", cephfs_name,
                      metadata_pool,
                      data_pool])
    except CalledProcessError as err:
        if err.returncode == 22:
            log("CephFS already created")
            return
        else:
            log(err.output, level=ERROR)
            return {'exit-code': 1, 'stderr': err.output}
Example #16
0
def process_requests_v1(reqs):
    """Process v1 requests.

    Takes a list of requests (dicts) and processes each one. If an error is
    found, processing stops and the client is notified in the response.

    Returns a response dict containing the exit code (non-zero if any
    operation failed along with an explanation).
    """
    log("Processing %s ceph broker requests" % (len(reqs)), level=INFO)
    for req in reqs:
        op = req.get('op')
        log("Processing op='%s'" % (op), level=DEBUG)
        # Use admin client since we do not have other client key locations
        # setup to use them for these operations.
        svc = 'admin'
        if op == "create-pool":
            params = {'pool': req.get('name'), 'replicas': req.get('replicas')}
            if not all(params.iteritems()):
                msg = (
                    "Missing parameter(s): %s" %
                    (' '.join([k
                               for k in params.iterkeys() if not params[k]])))
                log(msg, level=ERROR)
                return {'exit-code': 1, 'stderr': msg}

            # Mandatory params
            pool = params['pool']
            replicas = params['replicas']

            # Optional params
            pg_num = req.get('pg_num')
            if pg_num:
                # Cap pg_num to max allowed just in case.
                osds = get_osds(svc)
                if osds:
                    pg_num = min(pg_num, (len(osds) * 100 // replicas))

                # Ensure string
                pg_num = str(pg_num)

            if not pool_exists(service=svc, name=pool):
                log("Creating pool '%s' (replicas=%s)" % (pool, replicas),
                    level=INFO)
                create_pool(service=svc,
                            name=pool,
                            replicas=replicas,
                            pg_num=pg_num)
            else:
                log("Pool '%s' already exists - skipping create" % (pool),
                    level=DEBUG)
        else:
            msg = "Unknown operation '%s'" % (op)
            log(msg, level=ERROR)
            return {'exit-code': 1, 'stderr': msg}

    return {'exit-code': 0}
Example #17
0
def handle_create_cache_tier(request, service):
    # mode = "writeback" | "readonly"
    storage_pool = request.get('cold-pool')
    cache_pool = request.get('hot-pool')
    cache_mode = request.get('mode')

    if cache_mode is None:
        cache_mode = "writeback"

    # cache and storage pool must exist first
    if not pool_exists(service=service, name=storage_pool) or not pool_exists(
            service=service, name=cache_pool):
        msg = "cold-pool: {} and hot-pool: {} must exist. Please create " \
              "them first".format(storage_pool, cache_pool)
        log(msg, level=ERROR)
        return {'exit-code': 1, 'stderr': msg}
    p = Pool(service=service, name=storage_pool)
    p.add_cache_tier(cache_pool=cache_pool, mode=cache_mode)
Example #18
0
def handle_replicated_pool(request, service):
    """Create a new replicated pool.

    :param request: dict of request operations and params.
    :param service: The ceph client to run the command under.
    :returns: dict. exit-code and reason if not 0.
    """
    pool_name = request.get('name')
    replicas = request.get('replicas')
    quota = request.get('max-bytes')
    weight = request.get('weight')
    group_name = request.get('group')

    # Optional params
    pg_num = request.get('pg_num')
    if pg_num:
        # Cap pg_num to max allowed just in case.
        osds = get_osds(service)
        if osds:
            pg_num = min(pg_num, (len(osds) * 100 // replicas))

    app_name = request.get('app-name')
    # Check for missing params
    if pool_name is None or replicas is None:
        msg = "Missing parameter. name and replicas are required"
        log(msg, level=ERROR)
        return {'exit-code': 1, 'stderr': msg}

    if group_name:
        group_namespace = request.get('group-namespace')
        # Add the pool to the group named "group_name"
        add_pool_to_group(pool=pool_name,
                          group=group_name,
                          namespace=group_namespace)

    kwargs = {}
    if pg_num:
        kwargs['pg_num'] = pg_num
    if weight:
        kwargs['percent_data'] = weight
    if replicas:
        kwargs['replicas'] = replicas
    if app_name:
        kwargs['app_name'] = app_name

    pool = ReplicatedPool(service=service, name=pool_name, **kwargs)
    if not pool_exists(service=service, name=pool_name):
        log("Creating pool '{}' (replicas={})".format(pool.name, replicas),
            level=INFO)
        pool.create()
    else:
        log("Pool '{}' already exists - skipping create".format(pool.name),
            level=DEBUG)

    # Set a quota if requested
    if quota is not None:
        set_pool_quota(service=service, pool_name=pool_name, max_bytes=quota)
Example #19
0
def handle_create_cache_tier(request, service):
    # mode = "writeback" | "readonly"
    storage_pool = request.get('cold-pool')
    cache_pool = request.get('hot-pool')
    cache_mode = request.get('mode')

    if cache_mode is None:
        cache_mode = "writeback"

    # cache and storage pool must exist first
    if not pool_exists(service=service, name=storage_pool) or not pool_exists(
            service=service, name=cache_pool):
        msg = "cold-pool: {} and hot-pool: {} must exist. Please create " \
              "them first".format(storage_pool, cache_pool)
        log(msg, level=ERROR)
        return {'exit-code': 1, 'stderr': msg}
    p = Pool(service=service, name=storage_pool)
    p.add_cache_tier(cache_pool=cache_pool, mode=cache_mode)
Example #20
0
def handle_remove_cache_tier(request, service):
    """Remove a cache tier from the cold pool.

    :param request: dict of request operations and params
    :param service: The ceph client to run the command under.
    :returns: dict. exit-code and reason if not 0
    """
    storage_pool = request.get('cold-pool')
    cache_pool = request.get('hot-pool')
    # cache and storage pool must exist first
    if not pool_exists(service=service, name=storage_pool) or not pool_exists(
            service=service, name=cache_pool):
        msg = ("cold-pool: {} or hot-pool: {} doesn't exist. Not "
               "deleting cache tier".format(storage_pool, cache_pool))
        log(msg, level=ERROR)
        return {'exit-code': 1, 'stderr': msg}

    pool = Pool(name=storage_pool, service=service)
    pool.remove_cache_tier(cache_pool=cache_pool)
Example #21
0
def handle_remove_cache_tier(request, service):
    """Remove a cache tier from the cold pool.

    :param request: dict of request operations and params
    :param service: The ceph client to run the command under.
    :returns: dict. exit-code and reason if not 0
    """
    storage_pool = request.get('cold-pool')
    cache_pool = request.get('hot-pool')
    # cache and storage pool must exist first
    if not pool_exists(service=service, name=storage_pool) or not pool_exists(
            service=service, name=cache_pool):
        msg = ("cold-pool: {} or hot-pool: {} doesn't exist. Not "
               "deleting cache tier".format(storage_pool, cache_pool))
        log(msg, level=ERROR)
        return {'exit-code': 1, 'stderr': msg}

    pool = Pool(name=storage_pool, service=service)
    pool.remove_cache_tier(cache_pool=cache_pool)
Example #22
0
def process_requests_v1(reqs):
    """Process v1 requests.

    Takes a list of requests (dicts) and processes each one. If an error is
    found, processing stops and the client is notified in the response.

    Returns a response dict containing the exit code (non-zero if any
    operation failed along with an explanation).
    """
    log("Processing %s ceph broker requests" % (len(reqs)), level=INFO)
    for req in reqs:
        op = req.get('op')
        log("Processing op='%s'" % (op), level=DEBUG)
        # Use admin client since we do not have other client key locations
        # setup to use them for these operations.
        svc = 'admin'
        if op == "create-pool":
            params = {'pool': req.get('name'),
                      'replicas': req.get('replicas')}
            if not all(params.iteritems()):
                msg = ("Missing parameter(s): %s" %
                       (' '.join([k for k in params.iterkeys()
                                  if not params[k]])))
                log(msg, level=ERROR)
                return {'exit-code': 1, 'stderr': msg}

            # Mandatory params
            pool = params['pool']
            replicas = params['replicas']

            # Optional params
            pg_num = req.get('pg_num')
            if pg_num:
                # Cap pg_num to max allowed just in case.
                osds = get_osds(svc)
                if osds:
                    pg_num = min(pg_num, (len(osds) * 100 // replicas))

                # Ensure string
                pg_num = str(pg_num)

            if not pool_exists(service=svc, name=pool):
                log("Creating pool '%s' (replicas=%s)" % (pool, replicas),
                    level=INFO)
                create_pool(service=svc, name=pool, replicas=replicas,
                            pg_num=pg_num)
            else:
                log("Pool '%s' already exists - skipping create" % (pool),
                    level=DEBUG)
        else:
            msg = "Unknown operation '%s'" % (op)
            log(msg, level=ERROR)
            return {'exit-code': 1, 'stderr': msg}

    return {'exit-code': 0}
Example #23
0
def handle_erasure_pool(request, service):
    """Create a new erasure coded pool.

    :param request: dict of request operations and params.
    :param service: The ceph client to run the command under.
    :returns: dict. exit-code and reason if not 0.
    """
    pool_name = request.get('name')
    erasure_profile = request.get('erasure-profile')
    quota = request.get('max-bytes')
    weight = request.get('weight')
    group_name = request.get('group')

    if erasure_profile is None:
        erasure_profile = "default-canonical"

    app_name = request.get('app-name')

    # Check for missing params
    if pool_name is None:
        msg = "Missing parameter. name is required for the pool"
        log(msg, level=ERROR)
        return {'exit-code': 1, 'stderr': msg}

    if group_name:
        group_namespace = request.get('group-namespace')
        # Add the pool to the group named "group_name"
        add_pool_to_group(pool=pool_name,
                          group=group_name,
                          namespace=group_namespace)

    # TODO: Default to 3/2 erasure coding. I believe this requires min 5 osds
    if not erasure_profile_exists(service=service, name=erasure_profile):
        # TODO: Fail and tell them to create the profile or default
        msg = ("erasure-profile {} does not exist.  Please create it with: "
               "create-erasure-profile".format(erasure_profile))
        log(msg, level=ERROR)
        return {'exit-code': 1, 'stderr': msg}

    pool = ErasurePool(service=service, name=pool_name,
                       erasure_code_profile=erasure_profile,
                       percent_data=weight, app_name=app_name)
    # Ok make the erasure pool
    if not pool_exists(service=service, name=pool_name):
        log("Creating pool '{}' (erasure_profile={})"
            .format(pool.name, erasure_profile), level=INFO)
        pool.create()

    # Set a quota if requested
    if quota is not None:
        set_pool_quota(service=service, pool_name=pool_name, max_bytes=quota)
Example #24
0
def delete_cache_tier():
    backer_pool = action_get("backer-pool")
    cache_pool = action_get("cache-pool")

    # Pre flight checks
    if not pool_exists('admin', backer_pool):
        log("Backer pool {} must exist before calling this".format(
            backer_pool))
        action_fail("remove-cache-tier failed. Backer pool {} must exist "
                    "before calling this".format(backer_pool))

    if not pool_exists('admin', cache_pool):
        log("Cache pool {} must exist before calling this".format(cache_pool))
        action_fail("remove-cache-tier failed. Cache pool {} must exist "
                    "before calling this".format(cache_pool))

    pool = Pool(service='admin', name=backer_pool)
    try:
        pool.remove_cache_tier(cache_pool=cache_pool)
    except CalledProcessError as err:
        log("Removing the cache tier failed with message: {}".format(str(err)))
        action_fail("remove-cache-tier failed. Removing the cache tier failed "
                    "with message: {}".format(str(err)))
Example #25
0
def handle_replicated_pool(request, service):
    """Create a new replicated pool.

    :param request: dict of request operations and params.
    :param service: The ceph client to run the command under.
    :returns: dict. exit-code and reason if not 0.
    """
    pool_name = request.get('name')
    group_name = request.get('group')

    # Optional params
    # NOTE: Check this against the handling in the Pool classes, reconcile and
    # remove.
    pg_num = request.get('pg_num')
    replicas = request.get('replicas')
    if pg_num:
        # Cap pg_num to max allowed just in case.
        osds = get_osds(service)
        if osds:
            pg_num = min(pg_num, (len(osds) * 100 // replicas))
            request.update({'pg_num': pg_num})

    if group_name:
        group_namespace = request.get('group-namespace')
        # Add the pool to the group named "group_name"
        add_pool_to_group(pool=pool_name,
                          group=group_name,
                          namespace=group_namespace)

    try:
        pool = ReplicatedPool(service=service,
                              op=request)
    except KeyError:
        msg = "Missing parameter."
        log(msg, level=ERROR)
        return {'exit-code': 1, 'stderr': msg}

    if not pool_exists(service=service, name=pool_name):
        log("Creating pool '{}' (replicas={})".format(pool.name, replicas),
            level=INFO)
        pool.create()
    else:
        log("Pool '{}' already exists - skipping create".format(pool.name),
            level=DEBUG)

    # Set/update properties that are allowed to change after pool creation.
    pool.update()
Example #26
0
def handle_erasure_pool(request, service):
    """Create a new erasure coded pool.

    :param request: dict of request operations and params.
    :param service: The ceph client to run the command under.
    :returns: dict. exit-code and reason if not 0.
    """
    pool_name = request.get('name')
    erasure_profile = request.get('erasure-profile')
    group_name = request.get('group')

    if erasure_profile is None:
        erasure_profile = "default-canonical"

    if group_name:
        group_namespace = request.get('group-namespace')
        # Add the pool to the group named "group_name"
        add_pool_to_group(pool=pool_name,
                          group=group_name,
                          namespace=group_namespace)

    # TODO: Default to 3/2 erasure coding. I believe this requires min 5 osds
    if not erasure_profile_exists(service=service, name=erasure_profile):
        # TODO: Fail and tell them to create the profile or default
        msg = ("erasure-profile {} does not exist.  Please create it with: "
               "create-erasure-profile".format(erasure_profile))
        log(msg, level=ERROR)
        return {'exit-code': 1, 'stderr': msg}

    try:
        pool = ErasurePool(service=service,
                           op=request)
    except KeyError:
        msg = "Missing parameter."
        log(msg, level=ERROR)
        return {'exit-code': 1, 'stderr': msg}

    # Ok make the erasure pool
    if not pool_exists(service=service, name=pool_name):
        log("Creating pool '{}' (erasure_profile={})"
            .format(pool.name, erasure_profile), level=INFO)
        pool.create()

    # Set/update properties that are allowed to change after pool creation.
    pool.update()
Example #27
0
 def test_pool_exists(self):
     '''It detects an rbd pool exists'''
     self.check_output.return_value = LS_POOLS
     self.assertTrue(ceph_utils.pool_exists('cinder', 'volumes'))
Example #28
0
 def test_pool_exists_error(self):
     ''' Ensure subprocess errors and sandboxed with False '''
     self.check_output.side_effect = CalledProcessError(1, 'rados')
     self.assertFalse(ceph_utils.pool_exists('cinder', 'foo'))
Example #29
0
 def test_pool_does_not_exist(self):
     '''It detects an rbd pool exists'''
     self.check_output.return_value = LS_POOLS
     self.assertFalse(ceph_utils.pool_exists('cinder', 'foo'))