Ejemplo n.º 1
0
import ui_assist
from crm_gv import gv_types

err_buf = ErrorBuffer.getInstance()
cib_factory = CibFactory.getInstance()


def _type_completions():
    "completer for type: use in show"
    typelist = cib_factory.type_list()
    return ['type:%s' % (t) for t in typelist]


# Tab completion helpers
_id_list = compl.call(cib_factory.id_list)
_id_xml_list = compl.join(_id_list, compl.choice(['xml']))
_id_show_list = compl.join(_id_list,
                           compl.choice(['xml', 'changed']),
                           compl.call(_type_completions))
_prim_id_list = compl.call(cib_factory.prim_id_list)
_f_prim_free_id_list = compl.call(cib_factory.f_prim_free_id_list)
_f_group_id_list = compl.call(cib_factory.f_group_id_list)
_f_children_id_list = compl.call(cib_factory.f_children_id_list)
_rsc_id_list = compl.call(cib_factory.rsc_id_list)
_top_rsc_id_list = compl.call(cib_factory.top_rsc_id_list)
_node_id_list = compl.call(cib_factory.node_id_list)
_rsc_template_list = compl.call(cib_factory.rsc_template_list)
_group_completer = compl.join(_f_prim_free_id_list, compl.choice(['params', 'meta']))
_clone_completer = compl.choice(['params', 'meta'])
_ms_completer = compl.choice(['params', 'meta'])
Ejemplo n.º 2
0
class Template(command.UI):
    '''
    Configuration templates.
    '''
    name = "template"

    def __init__(self):
        command.UI.__init__(self)
        self.curr_conf = ''
        self.init_dir()

    @command.skill_level('administrator')
    @command.completers_repeating(compl.null, compl.call(utils.listtemplates))
    def do_new(self, context, name, *args):
        "usage: new <config> <template> [<template> ...] [params name=value ...]"
        if not utils.is_filename_sane(name):
            return False
        if os.path.isfile("%s/%s" % (userdir.CRMCONF_DIR, name)):
            common_err("config %s exists; delete it first" % name)
            return False
        lt = LoadTemplate(name)
        rc = True
        mode = 0
        params = {}
        for s in args:
            if mode == 0 and s == "params":
                params["id"] = name
                mode = 1
            elif mode == 1:
                a = s.split('=')
                if len(a) != 2:
                    syntax_err(args, context='new')
                    rc = False
                else:
                    params[a[0]] = a[1]
            elif not lt.load_template(s):
                rc = False
        if rc:
            lt.post_process(params)
        if not rc or not lt.write_config(name):
            return False
        self.curr_conf = name

    @command.skill_level('administrator')
    @command.completers(compl.call(utils.listconfigs))
    def do_delete(self, context, name, force=''):
        "usage: delete <config> [force]"
        if force:
            if force != "force" and force != "--force":
                syntax_err((context.get_command_name(), force),
                           context='delete')
                return False
        if not self.config_exists(name):
            return False
        if name == self.curr_conf:
            if not force and not config.core.force and \
                    not utils.ask("Do you really want to remove config %s which is in use?" %
                                  self.curr_conf):
                return False
            else:
                self.curr_conf = ''
        os.remove("%s/%s" % (userdir.CRMCONF_DIR, name))

    @command.skill_level('administrator')
    @command.completers(compl.call(utils.listconfigs))
    def do_load(self, context, name=''):
        "usage: load [<config>]"
        if not name:
            self.curr_conf = ''
            return True
        if not self.config_exists(name):
            return False
        self.curr_conf = name

    @command.skill_level('administrator')
    @command.completers(compl.call(utils.listconfigs))
    def do_edit(self, context, name=''):
        "usage: edit [<config>]"
        if not name and not self.curr_conf:
            common_err("please load a config first")
            return False
        if name:
            if not self.config_exists(name):
                return False
            utils.edit_file("%s/%s" % (userdir.CRMCONF_DIR, name))
        else:
            utils.edit_file("%s/%s" % (userdir.CRMCONF_DIR, self.curr_conf))

    @command.completers(compl.call(utils.listconfigs))
    def do_show(self, context, name=''):
        "usage: show [<config>]"
        if not name and not self.curr_conf:
            common_err("please load a config first")
            return False
        if name:
            if not self.config_exists(name):
                return False
            print self.process(name)
        else:
            print self.process()

    @command.skill_level('administrator')
    @command.completers(
        compl.join(compl.call(utils.listconfigs),
                   compl.choice(['replace', 'update'])),
        compl.call(utils.listconfigs))
    def do_apply(self, context, *args):
        "usage: apply [<method>] [<config>]"
        method = "replace"
        name = ''
        if len(args) > 0:
            i = 0
            if args[0] in ("replace", "update"):
                method = args[0]
                i += 1
            if len(args) > i:
                name = args[i]
        if not name and not self.curr_conf:
            common_err("please load a config first")
            return False
        if name:
            if not self.config_exists(name):
                return False
            s = self.process(name)
        else:
            s = self.process()
        if not s:
            return False
        tmp = utils.str2tmp(s)
        if not tmp:
            return False
        if method == "replace":
            if options.interactive and cib_factory.has_cib_changed():
                if not utils.ask(
                        "This operation will erase all changes. Do you want to proceed?"
                ):
                    return False
            cib_factory.erase()
        set_obj = mkset_obj()
        rc = set_obj.import_file(method, tmp)
        try:
            os.unlink(tmp)
        except:
            pass
        return rc

    @command.completers(compl.choice(['templates']))
    def do_list(self, context, templates=''):
        "usage: list [templates]"
        if templates == "templates":
            utils.multicolumn(utils.listtemplates())
        else:
            utils.multicolumn(utils.listconfigs())

    def init_dir(self):
        '''Create the conf directory, link to templates'''
        if not os.path.isdir(userdir.CRMCONF_DIR):
            try:
                os.makedirs(userdir.CRMCONF_DIR)
            except os.error, msg:
                common_err("makedirs: %s" % msg)
Ejemplo n.º 3
0
    def do_log(self, context, *args):
        "usage: log [<node> ...]"
        self._init_source()
        return crm_report.log(*args)

    def ptest(self, nograph, scores, utilization, actions, verbosity):
        'Send a decompressed self.pe_file to ptest'
        try:
            s = bz2.decompress(open(self.pe_file).read())
        except IOError, msg:
            common_err("open: %s" % msg)
            return False
        return utils.run_ptest(s, nograph, scores, utilization, actions, verbosity)

    @command.skill_level('administrator')
    @command.completers_repeating(compl.join(compl.call(crm_report.peinputs_list),
                                             compl.choice(['v'])))
    def do_peinputs(self, context, *args):
        """usage: peinputs [{<range>|<number>} ...] [v]"""
        self._init_source()
        argl = list(args)
        opt_l = utils.fetch_opts(argl, ["v"])
        if argl:
            l = []
            for s in argl:
                a = utils.convert2ints(s.split(':'))
                if a and len(a) == 2 and not utils.check_range(a):
                    common_err("%s: invalid peinputs range" % a)
                    return False
                l += crm_report.pelist(a, long=("v" in opt_l))
        else:
            l = crm_report.pelist(long=("v" in opt_l))
Ejemplo n.º 4
0
        self._init_source()
        return crm_report().log(*args)

    def ptest(self, nograph, scores, utilization, actions, verbosity):
        'Send a decompressed self.pe_file to ptest'
        try:
            s = bz2.decompress(open(self.pe_file).read())
        except IOError, msg:
            common_err("open: %s" % msg)
            return False
        return utils.run_ptest(s, nograph, scores, utilization, actions,
                               verbosity)

    @command.skill_level('administrator')
    @command.completers_repeating(
        compl.join(compl.call(lambda: crm_report().peinputs_list()),
                   compl.choice(['v'])))
    def do_peinputs(self, context, *args):
        """usage: peinputs [{<range>|<number>} ...] [v]"""
        self._init_source()
        argl = list(args)
        opt_l = utils.fetch_opts(argl, ["v"])
        if argl:
            l = []
            for s in argl:
                a = utils.convert2ints(s.split(':'))
                if a and len(a) == 2 and not utils.check_range(a):
                    common_err("%s: invalid peinputs range" % a)
                    return False
                l += crm_report().pelist(a, long=("v" in opt_l))
        else:
            l = crm_report().pelist(long=("v" in opt_l))
Ejemplo n.º 5
0
class CibShadow(command.UI):
    '''
    CIB shadow management class
    '''
    name = "cib"
    extcmd = ">/dev/null </dev/null crm_shadow"
    extcmd_stdout = "</dev/null crm_shadow"

    def requires(self):
        if not utils.is_program('crm_shadow'):
            no_prog_err('crm_shadow')
            return False
        return True

    @command.level(ui_cibstatus.CibStatusUI)
    def do_cibstatus(self):
        pass

    @command.skill_level('administrator')
    @command.completers_repeating(compl.null, compl.choice(_NEWARGS))
    def do_new(self, context, *args):
        "usage: new [<shadow_cib>] [withstatus] [force] [empty]"
        argl = list(args)
        opt_l = utils.fetch_opts(argl,
                                 ["force", "--force", "withstatus", "empty"])
        if len(argl) > 1:
            context.fatal_error("Unexpected argument(s): " + ','.join(argl))

        name = None
        if argl:
            name = argl[0]
            if not utils.is_filename_sane(name):
                context.fatal_error("Bad filename: " + name)
            if name in (vars.tmp_cib_prompt, vars.live_cib_prompt):
                context.fatal_error("Shadow name '%s' is not allowed" % (name))
            del argl[0]
            vars.tmp_cib = False
        else:
            fd, fname = tmpfiles.create(dir=xmlutil.cib_shadow_dir(),
                                        prefix="shadow.crmsh_")
            name = os.path.basename(fname).replace("shadow.", "")
            vars.tmp_cib = True

        if "empty" in opt_l:
            new_cmd = "%s -e '%s'" % (self.extcmd, name)
        else:
            new_cmd = "%s -c '%s'" % (self.extcmd, name)
        if vars.tmp_cib or config.core.force or "force" in opt_l or "--force" in opt_l:
            new_cmd = "%s --force" % new_cmd
        if utils.ext_cmd(new_cmd) == 0:
            context.info("%s shadow CIB created" % name)
            self.do_use(context, name)
            if "withstatus" in opt_l:
                cib_status.load("shadow:%s" % name)

    def _find_pe(self, context, infile):
        'Find a pe input'
        for p in ("%s/%s", "%s/%s.bz2", "%s/pe-*-%s.bz2"):
            fl = glob.glob(p % (config.path.pe_state_dir, infile))
            if fl:
                break
        if not fl:
            context.fatal_error("no %s pe input file" % infile)
        if len(fl) > 1:
            context.fatal_error("more than one %s pe input file: %s" %
                                (infile, ' '.join(fl)))
        if not fl[0]:
            context.fatal_error("bad %s pe input file" % infile)
        return fl[0]

    @command.skill_level('administrator')
    @command.completers(compl.null, compl.shadows)
    def do_import(self, context, infile, name=None):
        "usage: import {<file>|<number>} [<shadow>]"
        if name and not utils.is_filename_sane(name):
            context.fatal_error("Bad filename: " + name)
        # where's the input?
        if not os.access(infile, os.F_OK):
            if "/" in infile:
                context.fatal_error(str(infile) + ": no such file")
            infile = self._find_pe(context, infile)
        if not name:
            name = os.path.basename(infile).replace(".bz2", "")
        if not xmlutil.pe2shadow(infile, name):
            context.fatal_error("Error copying PE file to shadow: %s -> %s" %
                                (infile, name))
        # use the shadow and load the status from there
        return self.do_use(context, name, "withstatus")

    @command.skill_level('administrator')
    @command.completers(compl.shadows)
    def do_delete(self, context, name):
        "usage: delete <shadow_cib>"
        if not utils.is_filename_sane(name):
            context.fatal_error("Bad filename: " + name)
        if utils.get_cib_in_use() == name:
            context.fatal_error("%s shadow CIB is in use" % name)
        if utils.ext_cmd("%s -D '%s' --force" % (self.extcmd, name)) == 0:
            context.info("%s shadow CIB deleted" % name)
        else:
            context.fatal_error("failed to delete %s shadow CIB" % name)

    @command.skill_level('administrator')
    @command.completers(compl.shadows)
    def do_reset(self, context, name):
        "usage: reset <shadow_cib>"
        if not utils.is_filename_sane(name):
            context.fatal_error("Bad filename: " + name)
        if utils.ext_cmd("%s -r '%s'" % (self.extcmd, name)) == 0:
            context.info("copied live CIB to %s" % name)
        else:
            context.fatal_error("failed to copy live CIB to %s" % name)

    @command.skill_level('administrator')
    @command.wait
    @command.completers(compl.shadows)
    def do_commit(self, context, name=None):
        "usage: commit [<shadow_cib>]"
        if name and not utils.is_filename_sane(name):
            context.fatal_error("Bad filename: " + name)
        if not name:
            name = utils.get_cib_in_use()
        if not name:
            context.fatal_error("There is nothing to commit")
        if utils.ext_cmd("%s -C '%s' --force" % (self.extcmd, name)) == 0:
            context.info("committed '%s' shadow CIB to the cluster" % name)
        else:
            context.fatal_error("failed to commit the %s shadow CIB" % name)
        if vars.tmp_cib:
            self._use('', '')

    @command.skill_level('administrator')
    def do_diff(self, context):
        "usage: diff"
        rc, s = utils.get_stdout(utils.add_sudo("%s -d" % self.extcmd_stdout))
        utils.page_string(s)

    @command.skill_level('administrator')
    def do_list(self, context):
        "usage: list"
        if options.regression_tests:
            for t in xmlutil.listshadows():
                print t
        else:
            utils.multicolumn(xmlutil.listshadows())

    def _use(self, name, withstatus):
        # Choose a shadow cib for further changes. If the name
        # provided is empty, then choose the live (cluster) cib.
        # Don't allow ' in shadow names
        if not name or name == "live":
            if withstatus:
                cib_status.load("live")
            if vars.tmp_cib:
                utils.ext_cmd("%s -D '%s' --force" %
                              (self.extcmd, utils.get_cib_in_use()))
                vars.tmp_cib = False
            utils.clear_cib_in_use()
        else:
            utils.set_cib_in_use(name)
            if withstatus:
                cib_status.load("shadow:%s" % name)
        return True

    @command.skill_level('administrator')
    @command.completers(compl.join(compl.shadows, compl.choice(['live'])),
                        compl.choice(['withstatus']))
    def do_use(self, context, name='', withstatus=''):
        "usage: use [<shadow_cib>] [withstatus]"
        # check the name argument
        if name and not utils.is_filename_sane(name):
            context.fatal_error("Bad filename: " + name)
        if name and name != "live":
            if not os.access(xmlutil.shadowfile(name), os.F_OK):
                context.fatal_error("%s: no such shadow CIB" % name)
        if withstatus and withstatus != "withstatus":
            context.fatal_error("Expected 'withstatus', got '%s'" %
                                (withstatus))
        # If invoked from configure
        # take special precautions
        if not context.previous_level_is("cibconfig"):
            return self._use(name, withstatus)
        if not cib_factory.has_cib_changed():
            ret = self._use(name, withstatus)
            # new CIB: refresh the CIB factory
            cib_factory.refresh()
            return ret
        saved_cib = utils.get_cib_in_use()
        self._use(name, '')  # don't load the status yet
        if not cib_factory.is_current_cib_equal(silent=True):
            # user made changes and now wants to switch to a
            # different and unequal CIB; we refuse to cooperate
            context.error_message(
                "the requested CIB is different from the current one")
            if config.core.force:
                context.info("CIB overwrite forced")
            elif not utils.ask(
                    "All changes will be dropped. Do you want to proceed?"):
                self._use(saved_cib, '')  # revert to the previous CIB
                return False
        return self._use(name, withstatus)  # now load the status too