def add_a_gridcell_to_gluster_pool(hostname):
    """Given a hostname, it attempts to add that hostname to the gluster trusted storage pool.

    If the command runs without an error, it returns a dict with the return status and the xml root
    """
    d = None
    try:
        localhost = socket.getfqdn().strip()

        status_dict = None
        if hostname != localhost:
            cmd = "gluster peer probe %s --xml" % hostname
            # print 'executing gluster cmd'
            d, err = xml_parse.run_gluster_command(cmd)
            if err:
                raise Exception(err)
        else:
            raise Exception(
                "The GRIDCell %s is the localhost and hence already part of the pool"
                % hostname)
    except Exception, e:
        if hostname:
            return None, "Error adding GRIDCell %s to the storage pool : %s" % (
                hostname, e)
        else:
            return None, "Error adding GRIDCell to the storage pool : %s" % (e)
Ejemplo n.º 2
0
def change_quota_status(vol_name, action):
    """Enable/disable quotas for a gluster volume

    If the command runs without an error, it returns True, else False
    vol_name - the volume name
    action - Either 'enable' or 'disable'.
    """

    try:
        cmd = 'gluster --mode=script volume quota %s %s --xml' % (vol_name,
                                                                  action)
        d, err = xml_parse.run_gluster_command(cmd)
        if err:
            raise Exception(err)
        if action == 'enable':
            cmd = 'gluster volume set %s quota-deem-statfs on --xml' % vol_name
            d, err = xml_parse.run_gluster_command(cmd)
            if err:
                raise Exception(err)

    except Exception, e:
        return False, 'Error changing volume quota status : %s' % (str(e))
def change_quota_status(vol_name, action):
    """Enable/disable quotas for a gluster volume

    If the command runs without an error, it returns True, else False
    vol_name - the volume name
    action - Either 'enable' or 'disable'.
    """

    try:
        cmd = 'gluster --mode=script volume quota %s %s --xml' % (
            vol_name, action)
        d, err = xml_parse.run_gluster_command(cmd)
        if err:
            raise Exception(err)
        if action == 'enable':
            cmd = 'gluster volume set %s quota-deem-statfs on --xml' % vol_name
            d, err = xml_parse.run_gluster_command(cmd)
            if err:
                raise Exception(err)

    except Exception, e:
        return False, 'Error changing volume quota status : %s' % (str(e))
Ejemplo n.º 4
0
def remove_volume_dir_quota(vol_name, dir):
    """Removes a directory quota for a gluster volume

    If the command runs without an error, it returns True, else False
    vol_name - the volume name
    dir - the directory for which the quota need to be set
    """

    try:
        cmd = 'gluster volume quota %s remove %s --xml' % (vol_name, dir)
        d, err = xml_parse.run_gluster_command(cmd)
        if err:
            raise Exception(err)
    except Exception, e:
        return False, 'Error removing volume quota : %s' % str(e)
Ejemplo n.º 5
0
def activate_snapshot(snapshot_name):
    """Activate the snapshot with the given name

    If the command runs without an error, it returns a dict with the return status and the xml root
    snapshot_name - the name of the snapshot.
    """

    d = None
    try:
        cmd = 'gluster --mode=script snapshot activate  %s --xml' % snapshot_name
        d, err = xml_parse.run_gluster_command(cmd)
        if err:
            raise Exception(err)
    except Exception, e:
        return None, 'Error activating snapshot : %s' % str(e)
def activate_snapshot(snapshot_name):
    """Activate the snapshot with the given name

    If the command runs without an error, it returns a dict with the return status and the xml root
    snapshot_name - the name of the snapshot.
    """

    d = None
    try:
        cmd = 'gluster --mode=script snapshot activate  %s --xml' % snapshot_name
        d, err = xml_parse.run_gluster_command(cmd)
        if err:
            raise Exception(err)
    except Exception, e:
        return None, 'Error activating snapshot : %s' % str(e)
def remove_volume_dir_quota(vol_name, dir):
    """Removes a directory quota for a gluster volume

    If the command runs without an error, it returns True, else False
    vol_name - the volume name
    dir - the directory for which the quota need to be set
    """

    try:
        cmd = 'gluster volume quota %s remove %s --xml' % (vol_name, dir)
        d, err = xml_parse.run_gluster_command(cmd)
        if err:
            raise Exception(err)
    except Exception, e:
        return False, 'Error removing volume quota : %s' % str(e)
def set_volume_dir_quota(vol_name, dir, limit, unit):
    """Sets a directory or volume quota for a gluster volume. Setting the dir to '/' sets it for the whole volume.

    If the command runs without an error, it returns True, else False
    vol_name - the volume name
    dir - the directory for which the quota need to be set
    limit - a number specifying the quantity
    unit - GB/MB
    """

    try:
        cmd = 'gluster volume quota %s limit-usage %s %s%s --xml' % (
            vol_name, dir, limit, unit)
        d, err = xml_parse.run_gluster_command(cmd)
        if err:
            raise Exception
    except Exception, e:
        return False, 'Error setting volume quota : %s' % str(e)
Ejemplo n.º 9
0
def set_volume_dir_quota(vol_name, dir, limit, unit):
    """Sets a directory or volume quota for a gluster volume. Setting the dir to '/' sets it for the whole volume.

    If the command runs without an error, it returns True, else False
    vol_name - the volume name
    dir - the directory for which the quota need to be set
    limit - a number specifying the quantity
    unit - GB/MB
    """

    try:
        cmd = 'gluster volume quota %s limit-usage %s %s%s --xml' % (
            vol_name, dir, limit, unit)
        d, err = xml_parse.run_gluster_command(cmd)
        if err:
            raise Exception
    except Exception, e:
        return False, 'Error setting volume quota : %s' % str(e)
def get_volume_quotas(vol_name):
    """Get volume quotas for a volume

    If the command runs without an error, it returns a dict with the quota info, else False
    vol_name - the volume name
    """

    quotas = None
    try:
        cmd = 'gluster volume quota %s list --xml /' % (vol_name)
        d, err = xml_parse.run_gluster_command(cmd)
        if err:
            raise Exception(err)
        root = d["root"]
        quotas, err = xml_parse.get_vol_quotas(root)
        if err:
            raise Exception(err)
    except Exception, e:
        return None, 'Error getting volume quota : %s' % str(e)
Ejemplo n.º 11
0
def get_volume_quotas(vol_name):
    """Get volume quotas for a volume

    If the command runs without an error, it returns a dict with the quota info, else False
    vol_name - the volume name
    """

    quotas = None
    try:
        cmd = 'gluster volume quota %s list --xml /' % (vol_name)
        d, err = xml_parse.run_gluster_command(cmd)
        if err:
            raise Exception(err)
        root = d["root"]
        quotas, err = xml_parse.get_vol_quotas(root)
        if err:
            raise Exception(err)
    except Exception, e:
        return None, 'Error getting volume quota : %s' % str(e)
def get_peer_list():
    """Get the list of all the gluster peers to this node.

    If the command runs without an error, it returns a list of peers
    """

    peer_list = None
    try:
        cmd = '/usr/sbin/gluster peer status --xml'
        d, err = xml_parse.run_gluster_command(cmd)
        if err:
            raise Exception(err)
        peer_list = None
        if d and 'root' in d and d['root']:
            peer_list, err = xml_parse.get_peer_list(d["root"])
            if err:
                raise Exception(err)
    except Exception, e:
        return None, 'Error getting peer list: %s' % str(e)
def create_snapshot(vol_name, snapshot_name):
    """Create a snapshot with the given name

    If the command runs without an error, it returns a dict with the return status and the xml root
    snapshot_name - the name of the snapshot.
    vol_name - the volume on which the snapshot needs to be taken.
    """

    d = None
    try:
        if (not vol_name) or (not snapshot_name):
            raise Exception('Required parameter not provided')

        cmd = 'gluster snapshot create %s  %s --xml' % (
            snapshot_name, vol_name)
        d, err = xml_parse.run_gluster_command(cmd)
        if err:
            raise Exception(err)
    except Exception, e:
        return None, 'Error creating snapshot: %s' % str(e)
Ejemplo n.º 14
0
def create_snapshot(vol_name, snapshot_name):
    """Create a snapshot with the given name

    If the command runs without an error, it returns a dict with the return status and the xml root
    snapshot_name - the name of the snapshot.
    vol_name - the volume on which the snapshot needs to be taken.
    """

    d = None
    try:
        if (not vol_name) or (not snapshot_name):
            raise Exception('Required parameter not provided')

        cmd = 'gluster snapshot create %s  %s --xml' % (snapshot_name,
                                                        vol_name)
        d, err = xml_parse.run_gluster_command(cmd)
        if err:
            raise Exception(err)
    except Exception, e:
        return None, 'Error creating snapshot: %s' % str(e)
def remove_a_gridcell_from_gluster_pool(hostname):
    """Given a hostname, it attempts to removes that hostname from the gluster trusted storage pool.

    If the command runs without an error, it returns a dict with the return status and the xml root
    """
    d = None
    try:
        if not hostname:
            raise Exception('Required parameter not passed')
        localhost = socket.getfqdn().strip()
        if hostname != localhost:
            d = {}
            cmd = 'gluster peer detach %s --xml' % hostname
            d, err = xml_parse.run_gluster_command(cmd)
            if err:
                raise Exception(err)
    except Exception, e:
        if hostname:
            return None, "Error removing GRIDCell %s from the storage pool : %s" % (
                hostname, e)
        else:
            return None, "Error removing GRIDCell from the storage pool : %s" % (
                e)
def create_volume(request):
    """ Used to actually create the volume"""

    return_dict = {}
    try:
        gluster_lck, err = lock.get_lock('gluster_commands')
        if err:
            raise Exception(err)

        if not gluster_lck:
            raise Exception(
                'This action cannot be performed as an underlying storage command is being run. Please retry this operation after a few seconds.')

        return_dict['base_template'] = "volume_base.html"
        return_dict["page_title"] = 'Create a volume'
        return_dict['tab'] = 'view_volumes_tab'
        return_dict["error"] = 'Error creating a volume'

        if request.method != "POST":
            raise Exception("Invalid access method. Please use the menus.")

        if 'cmd' not in request.POST or 'dataset_list' not in request.POST:
            raise Exception('Required parameters not passed.')

        # cmd represents the actual gluster volume creation command built using
        # the wizard choices.
        cmd = request.POST['cmd']
        # print cmd

        # dataset_list is a list of hostname:dataset components of the datasets
        # that need to br created on various gridcells.
        dsl = request.POST.getlist('dataset_list')
        dataset_dict = {}
        for ds in dsl:
            tl = ds.split(':')
            dataset_dict[tl[0]] = tl[1]

        iv_logging.info("create volume command %s" % cmd)

        # First create the datasets on which the bricks will reside.
        # revert_list will consist of the set of node:command components to
        # perform to undo dataset creation in case of some failures.
        client = salt.client.LocalClient()
        revert_list = []
        errors = ""
        for node, dataset in dataset_dict.items():
            dataset_cmd = 'zfs create %s' % dataset
            dataset_revert_cmd = 'zfs destroy %s' % dataset
            r1 = client.cmd(node, 'cmd.run_all', [dataset_cmd])
            if r1:
                for node, ret in r1.items():
                    # print ret
                    if ret["retcode"] != 0:
                        errors += ", Error creating the underlying storage brick on %s" % node
                        # print errors
                    else:
                        revert_list.append({node: dataset_revert_cmd})

        if errors != "":
            # print errors
            if revert_list:
                # Undo the creation of the datasets
                for revert in revert_list:
                    for node, dsr_cmd in revert.items():
                        r1 = client.cmd(node, 'cmd.run_all', [dsr_cmd])
                        if r1:
                            for node, ret in r1.items():
                                # print ret
                                if ret["retcode"] != 0:
                                    errors += ", Error undoing the creating the underlying storage brick on %s" % node
            raise Exception(errors)

        # Underlying storage created so now create the volume

        d, errors = xml_parse.run_gluster_command("%s force" % cmd)
        # print d, errors
        if not errors:
            # All ok so mount and change the owner and group of the volume to
            # integralstor
            (ret, rc), err = command.execute_with_rc("gluster volume set " +
                                                     request.POST['vol_name'] + " storage.owner-gid 1000")
            if err:
                raise Exception('Error setting volume owner : %s' % err)

            # Now start the volume
            (ret, rc), err = command.execute_with_rc(
                "gluster volume start " + request.POST['vol_name'])
            if err:
                raise Exception('Error starting volume : %s' % err)

            '''
      #Set the client side quorum count
      cmd = "gluster volume set %s quorum-count 2 --xml"%request.POST['vol_name']
      d, err = xml_parse.run_gluster_command(cmd)
      if err:
        raise Exception('Error setting volume client side quorum count : %s'%err)

      #Set the client side quorum type
      cmd = "gluster volume set %s quorum-type fixed --xml"%request.POST['vol_name']
      d, err = xml_parse.run_gluster_command(cmd)
      if err:
        raise Exception('Errot setting volume client side quorum type : %s'%err)
      '''

            # Temporarily mount the volume
            (ret, rc), err = command.execute_with_rc(
                "mount -t glusterfs localhost:/" + request.POST['vol_name'] + " /mnt")
            if err:
                raise Exception(err)

            # Set the volume permissions
            (ret, rc), err = command.execute_with_rc("chmod 770 /mnt")
            if err:
                raise Exception(err)

            #..and unmount the volume
            (ret, rc), err = command.execute_with_rc("umount /mnt")
            if err:
                raise Exception(err)

            # If it is an ISCSI volume, then add it to the iscsi volume list..
            # print request.POST['vol_access']
            if request.POST["vol_access"] == "iscsi":
                ret, err = iscsi.add_iscsi_volume(request.POST["vol_name"])
                if err:
                    raise Exception(err)

            # Success so audit the change
            audit_str = "Create "
            if request.POST["vol_type"] in ["replicated"]:
                audit_str = audit_str + \
                    "replicated (count %d) " % int(request.POST["repl_count"])
            else:
                audit_str = audit_str + "distributed  "
            audit_str = audit_str + \
                " volume named %s" % request.POST["vol_name"]
            ret, err = audit.audit("create_volume", audit_str, request)
            if err:
                raise Exception(err)
        else:
            # Volume creation itself failed so try and delete the underlying
            # datasets if they were created..
            if not errors:
                errors = ""
            if revert_list:
                # Undo the creation of the datasets
                for revert in revert_list:
                    for node, dsr_cmd in revert.items():
                        r1 = client.cmd(node, 'cmd.run_all', [dsr_cmd])
                        if r1:
                            for node, ret in r1.items():
                                print ret
                                if ret["retcode"] != 0:
                                    errors += ", Error undoing the creating the underlying storage brick on %s" % node
        if errors:
            raise Exception(errors)

        if request.POST['vol_type'] == 'replicated':
            return_dict['repl_count'] = request.POST['repl_count']
        return_dict['vol_type'] = request.POST['vol_type']
        return_dict['vol_name'] = request.POST['vol_name']
        return_dict['node_list_str'] = request.POST['node_list_str']
        return_dict['cmd'] = cmd
        return_dict['result_dict'] = d

        return django.shortcuts.render_to_response('vol_create_wiz_result.html', return_dict, context_instance=django.template.context.RequestContext(request))
    except Exception, e:
        s = str(e)
        if "Another transaction is in progress".lower() in s.lower():
            return_dict["error_details"] = "An underlying storage operation has locked a volume so we are unable to process this request. Please try after a couple of seconds"
        else:
            return_dict["error_details"] = "An error occurred when processing your request : %s" % s
        return django.shortcuts.render_to_response("logged_in_error.html", return_dict, context_instance=django.template.context.RequestContext(request))
Ejemplo n.º 17
0
def create_volume(request):
    """ Used to actually create the volume"""

    return_dict = {}
    try:
        gluster_lck, err = lock.get_lock('gluster_commands')
        if err:
            raise Exception(err)

        if not gluster_lck:
            raise Exception(
                'This action cannot be performed as an underlying storage command is being run. Please retry this operation after a few seconds.'
            )

        return_dict['base_template'] = "volume_base.html"
        return_dict["page_title"] = 'Create a volume'
        return_dict['tab'] = 'view_volumes_tab'
        return_dict["error"] = 'Error creating a volume'

        if request.method != "POST":
            raise Exception("Invalid access method. Please use the menus.")

        if 'cmd' not in request.POST or 'dataset_list' not in request.POST:
            raise Exception('Required parameters not passed.')

        # cmd represents the actual gluster volume creation command built using
        # the wizard choices.
        cmd = request.POST['cmd']
        # print cmd

        # dataset_list is a list of hostname:dataset components of the datasets
        # that need to br created on various gridcells.
        dsl = request.POST.getlist('dataset_list')
        dataset_dict = {}
        for ds in dsl:
            tl = ds.split(':')
            dataset_dict[tl[0]] = tl[1]

        iv_logging.info("create volume command %s" % cmd)

        # First create the datasets on which the bricks will reside.
        # revert_list will consist of the set of node:command components to
        # perform to undo dataset creation in case of some failures.
        client = salt.client.LocalClient()
        revert_list = []
        errors = ""
        for node, dataset in dataset_dict.items():
            dataset_cmd = 'zfs create %s' % dataset
            dataset_revert_cmd = 'zfs destroy %s' % dataset
            r1 = client.cmd(node, 'cmd.run_all', [dataset_cmd])
            if r1:
                for node, ret in r1.items():
                    # print ret
                    if ret["retcode"] != 0:
                        errors += ", Error creating the underlying storage brick on %s" % node
                        # print errors
                    else:
                        revert_list.append({node: dataset_revert_cmd})

        if errors != "":
            # print errors
            if revert_list:
                # Undo the creation of the datasets
                for revert in revert_list:
                    for node, dsr_cmd in revert.items():
                        r1 = client.cmd(node, 'cmd.run_all', [dsr_cmd])
                        if r1:
                            for node, ret in r1.items():
                                # print ret
                                if ret["retcode"] != 0:
                                    errors += ", Error undoing the creating the underlying storage brick on %s" % node
            raise Exception(errors)

        # Underlying storage created so now create the volume

        d, errors = xml_parse.run_gluster_command("%s force" % cmd)
        # print d, errors
        if not errors:
            # All ok so mount and change the owner and group of the volume to
            # integralstor
            (ret, rc), err = command.execute_with_rc("gluster volume set " +
                                                     request.POST['vol_name'] +
                                                     " storage.owner-gid 1000")
            if err:
                raise Exception('Error setting volume owner : %s' % err)

            # Now start the volume
            (ret, rc), err = command.execute_with_rc("gluster volume start " +
                                                     request.POST['vol_name'])
            if err:
                raise Exception('Error starting volume : %s' % err)
            '''
      #Set the client side quorum count
      cmd = "gluster volume set %s quorum-count 2 --xml"%request.POST['vol_name']
      d, err = xml_parse.run_gluster_command(cmd)
      if err:
        raise Exception('Error setting volume client side quorum count : %s'%err)

      #Set the client side quorum type
      cmd = "gluster volume set %s quorum-type fixed --xml"%request.POST['vol_name']
      d, err = xml_parse.run_gluster_command(cmd)
      if err:
        raise Exception('Errot setting volume client side quorum type : %s'%err)
      '''

            # Temporarily mount the volume
            (ret, rc), err = command.execute_with_rc(
                "mount -t glusterfs localhost:/" + request.POST['vol_name'] +
                " /mnt")
            if err:
                raise Exception(err)

            # Set the volume permissions
            (ret, rc), err = command.execute_with_rc("chmod 770 /mnt")
            if err:
                raise Exception(err)

            #..and unmount the volume
            (ret, rc), err = command.execute_with_rc("umount /mnt")
            if err:
                raise Exception(err)

            # If it is an ISCSI volume, then add it to the iscsi volume list..
            # print request.POST['vol_access']
            if request.POST["vol_access"] == "iscsi":
                ret, err = iscsi.add_iscsi_volume(request.POST["vol_name"])
                if err:
                    raise Exception(err)

            # Success so audit the change
            audit_str = "Create "
            if request.POST["vol_type"] in ["replicated"]:
                audit_str = audit_str + \
                    "replicated (count %d) " % int(request.POST["repl_count"])
            else:
                audit_str = audit_str + "distributed  "
            audit_str = audit_str + \
                " volume named %s" % request.POST["vol_name"]
            ret, err = audit.audit("create_volume", audit_str, request)
            if err:
                raise Exception(err)
        else:
            # Volume creation itself failed so try and delete the underlying
            # datasets if they were created..
            if not errors:
                errors = ""
            if revert_list:
                # Undo the creation of the datasets
                for revert in revert_list:
                    for node, dsr_cmd in revert.items():
                        r1 = client.cmd(node, 'cmd.run_all', [dsr_cmd])
                        if r1:
                            for node, ret in r1.items():
                                print ret
                                if ret["retcode"] != 0:
                                    errors += ", Error undoing the creating the underlying storage brick on %s" % node
        if errors:
            raise Exception(errors)

        if request.POST['vol_type'] == 'replicated':
            return_dict['repl_count'] = request.POST['repl_count']
        return_dict['vol_type'] = request.POST['vol_type']
        return_dict['vol_name'] = request.POST['vol_name']
        return_dict['node_list_str'] = request.POST['node_list_str']
        return_dict['cmd'] = cmd
        return_dict['result_dict'] = d

        return django.shortcuts.render_to_response(
            'vol_create_wiz_result.html',
            return_dict,
            context_instance=django.template.context.RequestContext(request))
    except Exception, e:
        s = str(e)
        if "Another transaction is in progress".lower() in s.lower():
            return_dict[
                "error_details"] = "An underlying storage operation has locked a volume so we are unable to process this request. Please try after a couple of seconds"
        else:
            return_dict[
                "error_details"] = "An error occurred when processing your request : %s" % s
        return django.shortcuts.render_to_response(
            "logged_in_error.html",
            return_dict,
            context_instance=django.template.context.RequestContext(request))