Esempio n. 1
0
    def load_content(
        self,
        cib,
        returncode=0,
        stderr=None,
        name="runner.cib.load_content",
        instead=None,
        before=None,
    ):
        """
        Create call for loading CIB specified by its full content

        string cib -- CIB data (stdout of the loading process)
        string stderr -- error returned from the loading process
        int returncode -- exit code of the loading process
        string name -- key of the call
        string instead -- key of call instead of which this new call is to be
            placed
        string before -- key of call before which this new call is to be placed
        """
        command = "cibadmin --local --query"
        if returncode != 0:
            call = RunnerCall(command, stderr=stderr, returncode=returncode)
        else:
            call = RunnerCall(command, stdout=cib)
        self.__calls.place(name, call, before=before, instead=instead)
Esempio n. 2
0
    def load(
        self,
        modifiers=None,
        name="runner.cib.load",
        filename=None,
        before=None,
        returncode=0,
        stderr=None,
        instead=None,
        **modifier_shortcuts
    ):
        """
        Create call for loading cib.

        string name -- key of the call
        list of callable modifiers -- every callable takes etree.Element and
            returns new etree.Element with desired modification.
        string filename -- points to file with cib in the content
        string before -- key of call before which this new call is to be placed
        int returncode
        string stderr
        string instead -- key of call instead of which this new call is to be
            placed
        dict modifier_shortcuts -- a new modifier is generated from each
            modifier shortcut.
            As key there can be keys of MODIFIER_GENERATORS.
            Value is passed into appropriate generator from MODIFIER_GENERATORS.
            For details see pcs.test.tools.fixture_cib (mainly the variable
            MODIFIER_GENERATORS - please refer it when you are adding params
            here)
        """
        if(returncode != 0 or stderr is not None) and (
           modifiers is not None
           or
           filename is not None
           or
           modifier_shortcuts
        ):
            raise AssertionError(
                "Do not combine parameters 'returncode' and 'stderr' with"
                " parameters 'modifiers', 'filename' and 'modifier_shortcuts'"
            )

        command = "cibadmin --local --query"
        if returncode != 0:
            call = RunnerCall(command, stderr=stderr, returncode=returncode)
        else:
            cib = modify_cib(
                open(rc(filename if filename else self.cib_filename)).read(),
                modifiers,
                **modifier_shortcuts
            )
            call = RunnerCall(command, stdout=cib)

        self.__calls.place(name, call, before=before, instead=instead)
Esempio n. 3
0
    def wait(self,
             name="runner.pcmk.wait",
             stderr="",
             returncode=None,
             timeout=None):
        """
        Create call for waiting to pacemaker idle

        string name -- key of the call
        string stderr -- stderr of wait command
        int returncode -- has default value 0 if stderr is empty and has default
            configured value (62) if stderr is not empty. However the explicitly
            specified returncode is used if the returncode is specified.
        """
        if returncode is None:
            returncode = self.default_wait_error_returncode if stderr else 0

        self.__calls.place(
            name,
            RunnerCall(
                "crm_resource --wait --timeout={0}".format(
                    timeout if timeout else self.default_wait_timeout),
                stderr=stderr,
                returncode=returncode,
            ))
Esempio n. 4
0
    def load_state(self,
                   name="runner.pcmk.load_state",
                   filename="crm_mon.minimal.xml",
                   resources=None,
                   raw_resources=None):
        """
        Create call for loading pacemaker state.

        string name -- key of the call
        string filename -- points to file with the status in the content
        string resources -- xml - resources section, will be put to state
        """
        if resources and raw_resources is not None:
            raise AssertionError(
                "Cannot use 'resources' and 'raw_resources' together")

        state = etree.fromstring(open(rc(filename)).read())
        if raw_resources is not None:
            resources = fixture_state_resources_xml(**raw_resources)

        if resources:
            state.append(complete_state_resources(etree.fromstring(resources)))

        self.__calls.place(
            name,
            RunnerCall(
                "crm_mon --one-shot --as-xml --inactive",
                stdout=etree_to_str(state),
            ))
Esempio n. 5
0
 def diff(
     self,
     cib_old_file,
     cib_new_file,
     name="runner.cib.diff",
     stdout="resulting diff",
     stderr="",
     returncode=0
 ):
     """
     Create a call for diffing two CIBs stored in two files
     string cib_old_file -- path to a file with an old CIB
     string cib_new_file -- path to a file with a new CIB
     string name -- key of the call
     string stdout -- resulting diff
     string stderr -- error returned from the diff process
     int returncode -- exit code of the diff process
     """
     self.__calls.place(
         name,
         RunnerCall(
             "crm_diff --original {old} --new {new} --no-version".format(
                 old=cib_old_file, new=cib_new_file
             ),
             stdout=stdout,
             stderr=stderr,
             returncode=returncode,
         ),
     )
Esempio n. 6
0
    def load_fenced_metadata(
        self,
        name="runner.pcmk.load_fenced_metadata",
        stdout=None,
        stderr="",
        returncode=0,
        instead=None,
        before=None,
    ):
        """
        Create a call for loading fenced metadata - additional fence options

        string name -- the key of this call
        string stdout -- fenced stdout, default metadata if None
        string stderr -- fenced stderr
        int returncode -- fenced returncode
        string instead -- the key of a call instead of which this new call is to
            be placed
        string before -- the key of a call before which this new call is to be
            placed
        """
        self.__calls.place(
            name,
            RunnerCall(
                "/usr/libexec/pacemaker/pacemaker-fenced metadata",
                stdout=(
                    stdout if stdout is not None
                    else open(rc("fenced_metadata.xml")).read()
                ),
                stderr=stderr,
                returncode=returncode
            ),
            before=before,
            instead=instead,
        )
Esempio n. 7
0
    def local_node_name(
        self, name="runner.pcmk.local_node_name", instead=None, before=None,
        node_name="", stdout="", stderr="", returncode=0
    ):
        """
        Create a call for crm_node --name

        string name -- the key of this call
        string instead -- the key of a call instead of which this new call is to
            be placed
        string before -- the key of a call before which this new call is to be
            placed
        string node_name -- resulting node name
        string stdout -- crm_node's stdout
        string stderr -- crm_node's stderr
        int returncode -- crm_node's returncode
        """
        if node_name and (stdout or stderr or returncode):
            raise AssertionError(
                "Cannot specify node_name when stdout, stderr or returncode is "
                "specified"
            )
        cmd = ["crm_node", "--name"]
        self.__calls.place(
            name,
            RunnerCall(
                " ".join(cmd),
                stdout=(node_name if node_name else stdout),
                stderr=stderr,
                returncode=returncode
            ),
            before=before,
            instead=instead,
        )
Esempio n. 8
0
    def place(self,
              command,
              name="",
              stdout="",
              stderr="",
              returncode=0,
              check_stdin=None,
              before=None,
              instead=None):
        """
        Place new call to a config.

        string command -- cmdline call (e.g. "crm_mon --one-shot --as-xml")
        string name -- name of the call; it is possible to get it by the method
            "get"
        string stdout -- stdout of the call
        string stderr -- stderr of the call
        int returncode -- returncode of the call
        callable check_stdin -- callable that can check if stdin is as expected
        string before -- name of another call to insert this call before it
        string instead -- name of another call to replace it by this call
        """
        call = RunnerCall(command, stdout, stderr, returncode, check_stdin)
        self.__calls.place(name, call, before, instead)
        return self
Esempio n. 9
0
 def reload(self, name="runner.corosync.reload"):
     self.__calls.place(
         name,
         RunnerCall("corosync-cfgtool -R",
                    stdout=outdent("""\
                 Reloading corosync.conf...
                 Done
                 """)))
Esempio n. 10
0
 def version(self, name="runner.corosync.version", version="2.4.0"):
     self.__calls.place(
         name,
         RunnerCall("corosync -v",
                    stdout=outdent("""\
                 Corosync Cluster Engine, version '{0}'
                 Copyright...
                 """.format(version))))
Esempio n. 11
0
 def reload(self, name="runner.corosync.reload", instead=None, before=None):
     self.__calls.place(name,
                        RunnerCall("corosync-cfgtool -R",
                                   stdout=outdent("""\
                 Reloading corosync.conf...
                 Done
                 """)),
                        before=before,
                        instead=instead)
Esempio n. 12
0
    def upgrade(self, name="runner.cib.upgrade", before=None):
        """
        Create call for upgrading cib.

        string name -- key of the call
        string before -- key of call before which this new call is to be placed
        """
        self.__calls.place(name,
                           RunnerCall("cibadmin --upgrade --force"),
                           before=before)
Esempio n. 13
0
 def remove_node(
     self, node_name, stderr="", returncode=0, name="runner.pcmk.remove_node",
 ):
     self.__calls.place(
         name,
         RunnerCall(
             "crm_node --force --remove {0}".format(node_name),
             stderr=stderr,
             returncode=returncode,
         ),
     )
Esempio n. 14
0
    def can_wait(self,
                 name="runner.pcmk.can_wait",
                 before=None,
                 stdout="--wait"):
        """
        Create call that checks that wait for idle is supported

        string name -- key of the call
        string before -- key of call before which this new call is to be placed
        """
        self.__calls.place(name,
                           RunnerCall("crm_resource -?", stdout=stdout),
                           before=before)
Esempio n. 15
0
 def list_watchdogs(self,
                    output,
                    name="runner.sbd.list_watchdogs",
                    stderr="",
                    returncode=0,
                    instead=None,
                    before=None):
     self.__calls.place(name,
                        RunnerCall(
                            "{} query-watchdog".format(settings.sbd_binary),
                            stdout=output,
                            stderr=stderr,
                            returncode=returncode,
                        ),
                        before=before,
                        instead=instead)
Esempio n. 16
0
 def quorum_status(
     self,
     node_list=None,
     stdout=None,
     stderr="",
     returncode=0,
     name="runner.corosync.quorum_status",
 ):
     if bool(node_list) == bool(stdout):
         raise AssertionError(
             "Exactly one of 'node_list', 'stdout' must be specified")
     if node_list:
         stdout = outdent("""\
         Quorum information
         ------------------
         Date:             Fri Jan 16 13:03:28 2015
         Quorum provider:  corosync_votequorum
         Nodes:            {nodes_num}
         Node ID:          1
         Ring ID:          19860
         Quorate:          Yes\n
         Votequorum information
         ----------------------
         Expected votes:   {nodes_num}
         Highest expected: {nodes_num}
         Total votes:      {nodes_num}
         Quorum:           {quorum_num}
         Flags:            Quorate\n
         Membership information
         ----------------------
             Nodeid      Votes    Qdevice Name
         {nodes}\
         """).format(nodes_num=len(node_list),
                     quorum_num=(len(node_list) // 2) + 1,
                     nodes="".join([
                         _quorum_status_node_fixture(node_id, node)
                         for node_id, node in enumerate(node_list, 1)
                     ]))
     self.__calls.place(
         name,
         RunnerCall("{binary} -p".format(binary=os.path.join(
             settings.corosync_binaries, "corosync-quorumtool"), ),
                    stdout=stdout,
                    stderr=stderr,
                    returncode=returncode),
     )
Esempio n. 17
0
    def push(
        self,
        modifiers=None,
        name="runner.cib.push",
        load_key="runner.cib.load",
        instead=None,
        stderr="",
        returncode=0,
        **modifier_shortcuts
    ):
        """
        Create call for pushing cib.
        Cib is taken from the load call by default.

        string name -- key of the call
        list of callable modifiers -- every callable takes etree.Element and
            returns new etree.Element with desired modification.
        string load_key -- key of a call from which stdout can be cib taken
        string instead -- key of call instead of which this new call is to be
            placed
        dict modifier_shortcuts -- a new modifier is generated from each
            modifier shortcut.
            As key there can be keys of MODIFIER_GENERATORS.
            Value is passed into appropriate generator from MODIFIER_GENERATORS.
            For details see pcs.test.tools.fixture_cib (mainly the variable
            MODIFIER_GENERATORS - please refer it when you are adding params
            here)
        """
        cib = modify_cib(
            self.__calls.get(load_key).stdout,
            modifiers,
            **modifier_shortcuts
        )
        self.__calls.place(
            name,
            RunnerCall(
                "cibadmin --replace --verbose --xml-pipe --scope configuration",
                stderr=stderr,
                returncode=returncode,
                check_stdin=create_check_stdin_xml(cib),
            ),
            instead=instead,
        )
Esempio n. 18
0
    def load_agent(
        self,
        name="runner.pcmk.load_agent",
        agent_name="ocf:heartbeat:Dummy",
        agent_filename=None,
        instead=None,
    ):
        """
        Create call for loading resource agent metadata.

        string name -- key of the call
        string agent_name
        string agent_filename -- points to file with the agent metadata in the
            content
        string instead -- key of call instead of which this new call is to be
            placed
        """

        if agent_filename:
            agent_metadata_filename = agent_filename
        elif agent_name in AGENT_FILENAME_MAP:
            agent_metadata_filename = AGENT_FILENAME_MAP[agent_name]
        else:
            raise AssertionError((
                "Filename with metadata of agent '{0}' not specified.\n"
                "Please specify file with metadata for agent:\n"
                "  a) explicitly for this test:"
                " config.runner.pcmk.load_agent(agent_name='{0}',"
                " filename='FILENAME_HERE.xml')\n"
                "  b) implicitly for agent '{0}' in 'AGENT_FILENAME_MAP' in"
                " '{1}'\n"
                "Place agent metadata into '{2}FILENAME_HERE.xml'"
            ).format(agent_name, os.path.realpath(__file__), rc("")))

        self.__calls.place(
            name,
            RunnerCall(
                "crm_resource --show-metadata {0}".format(agent_name),
                stdout=open(rc(agent_metadata_filename)).read()
            ),
            instead=instead,
        )
Esempio n. 19
0
 def is_active(self,
               service,
               name="runner_systemctl.is_active",
               is_active=True):
     args = dict(
         stdout="unknown\n",
         returncode=3,
     )
     if is_active:
         args = dict(
             stdout="active\n",
             returncode=0,
         )
     self.__calls.place(
         name,
         RunnerCall(
             "{bin_path} is-active {service}.service".format(
                 bin_path=settings.systemctl_binary,
                 service=service,
             ), **args))
Esempio n. 20
0
    def resource_cleanup(
        self,
        name="runner.pcmk.cleanup",
        instead=None,
        before=None,
        resource=None,
        node=None,
        stdout="",
        stderr="",
        returncode=0
    ):
        """
        Create a call for crm_resource --cleanup

        string name -- the key of this call
        string instead -- the key of a call instead of which this new call is to
            be placed
        string before -- the key of a call before which this new call is to be
            placed
        string resource -- the id of a resource to be cleaned
        string node -- the name of the node where resources should be cleaned
        string stdout -- crm_resource's stdout
        string stderr -- crm_resource's stderr
        int returncode -- crm_resource's returncode
        """
        cmd = ["crm_resource", "--cleanup"]
        if resource:
            cmd.extend(["--resource", resource])
        if node:
            cmd.extend(["--node", node])
        self.__calls.place(
            name,
            RunnerCall(
                " ".join(cmd),
                stdout=stdout,
                stderr=stderr,
                returncode=returncode
            ),
            before=before,
            instead=instead,
        )
Esempio n. 21
0
 def push_diff(self,
               name="runner.cib.push_diff",
               cib_diff="resulting diff",
               stdout="",
               stderr="",
               returncode=0):
     """
     Create a call for pushing a diff of CIBs
     string name -- key of the call
     string cib_diff -- the diff of CIBs
     """
     self.__calls.place(
         name,
         RunnerCall(
             "cibadmin --patch --verbose --xml-pipe",
             check_stdin=create_check_stdin_xml(cib_diff),
             stdout=stdout,
             stderr=stderr,
             returncode=returncode,
         ),
     )
Esempio n. 22
0
    def fence_history_update(
        self, name="runner.pcmk.fence_history_update", stdout="", stderr="",
        returncode=0
    ):
        """
        Create call for updating fencing history.

        string name -- key of the call
        string stdout -- pacemaker's stdout
        string stderr -- pacemaker's stderr
        int returncode -- pacemaker's returncode
        """
        self.__calls.place(
            name,
            RunnerCall(
                "/usr/sbin/stonith_admin --history * --broadcast",
                stdout=stdout,
                stderr=stderr,
                returncode=returncode,
            ),
        )
Esempio n. 23
0
    def load_state(self,
                   name="runner.pcmk.load_state",
                   filename="crm_mon.minimal.xml",
                   resources=None):
        """
        Create call for loading pacemaker state.

        string name -- key of the call
        string filename -- points to file with the status in the content
        string resources -- xml - resources section, will be put to state
        """
        state = etree.fromstring(open(rc(filename)).read())
        if resources:
            state.append(complete_state_resources(etree.fromstring(resources)))

        self.__calls.place(
            name,
            RunnerCall(
                "crm_mon --one-shot --as-xml --inactive",
                stdout=etree_to_str(state),
            ))
Esempio n. 24
0
    def verify(
        self, name="runner.pcmk.verify", cib_tempfile=None, stderr=None,
        verbose=False
    ):
        """
        Create call that checks that wait for idle is supported

        string name -- key of the call
        string before -- key of call before which this new call is to be placed
        """
        self.__calls.place(
            name,
            RunnerCall(
                "crm_verify{0} {1}".format(
                    " -V" if verbose else "",
                    "--xml-file {0}".format(cib_tempfile) if cib_tempfile
                        else "--live-check"
                ),
                stderr=("" if stderr is None else stderr),
                returncode=(0 if stderr is None else 55),
            ),
        )
Esempio n. 25
0
 def qdevice_get_pk12(self,
                      cert_path="cert path",
                      output_path="output_path",
                      stdout=None,
                      stderr="",
                      returncode=0,
                      name="runner.corosync.qdevice_get_pk12"):
     if stdout is not None and output_path is not None:
         raise AssertionError(
             "Cannot specify both 'output_path' and 'stdout'")
     self.__calls.place(
         name,
         RunnerCall("{binary} -M -c {cert_path}".format(
             binary=os.path.join(settings.corosync_binaries,
                                 "corosync-qdevice-net-certutil"),
             cert_path=cert_path,
         ),
                    stdout=(stdout if stdout is not None else
                            f"Certificate stored in {output_path}\n"),
                    stderr=stderr,
                    returncode=returncode),
     )
Esempio n. 26
0
    def fence_history_get(
        self, name="runner.pcmk.fence_history_get", node=None, stdout="",
        stderr="", returncode=0
    ):
        """
        Create call for getting plain text fencing history.

        string name -- key of the call
        string node -- a node to get a history from
        string stdout -- pacemaker's stdout
        string stderr -- pacemaker's stderr
        int returncode -- pacemaker's returncode
        """
        self.__calls.place(
            name,
            RunnerCall(
                "/usr/sbin/stonith_admin --history {0} --verbose".format(node),
                stdout=stdout,
                stderr=stderr,
                returncode=returncode,
            ),
        )
Esempio n. 27
0
    def fence_history_cleanup(
        self, name="runner.pcmk.fence_history_cleanup", node=None, stdout="",
        stderr="", returncode=0
    ):
        """
        Create call for cleaning fencing history up.

        string name -- key of the call
        string node -- a node to clean a history from
        string stdout -- pacemaker's stdout
        string stderr -- pacemaker's stderr
        int returncode -- pacemaker's returncode
        """
        self.__calls.place(
            name,
            RunnerCall(
                "/usr/sbin/stonith_admin --history {0} --cleanup".format(node),
                stdout=stdout,
                stderr=stderr,
                returncode=returncode,
            ),
        )
Esempio n. 28
0
    def load_agent(
        self,
        name="runner.pcmk.load_agent",
        agent_name="ocf:heartbeat:Dummy",
        agent_filename="resource_agent_ocf_heartbeat_dummy.xml",
        instead=None,
    ):
        """
        Create call for loading resource agent metadata.

        string name -- key of the call
        string agent_name
        string agent_filename -- points to file with the agent metadata in the
            content
        string instead -- key of call instead of which this new call is to be
            placed
        """
        self.__calls.place(
            name,
            RunnerCall("crm_resource --show-metadata {0}".format(agent_name),
                       stdout=open(rc(agent_filename)).read()),
            instead=instead,
        )
Esempio n. 29
0
    def push_independent(
        self,
        cib,
        name="runner.cib.push_independent",
        instead=None,
    ):
        """
        Create call for pushing cib.
        Cib is specified as an argument.

        string name -- key of the call
        string cib -- whole cib to push
        string instead -- key of call instead of which this new call is to be
            placed
        """
        self.__calls.place(
            name,
            RunnerCall(
                "cibadmin --replace --verbose --xml-pipe --scope configuration",
                check_stdin=create_check_stdin_xml(cib),
            ),
            instead=instead,
        )
Esempio n. 30
0
 def qdevice_generate_cert(self,
                           cluster_name,
                           cert_req_path="cert_path",
                           stdout=None,
                           stderr="",
                           returncode=0,
                           name="runner.corosync.qdevice_generate_cert"):
     if stdout is not None and cert_req_path is not None:
         raise AssertionError(
             "Cannot specify both 'cert_req_path' and 'stdout'")
     self.__calls.place(
         name,
         RunnerCall(
             "{binary} -r -n {cluster_name}".format(
                 binary=os.path.join(settings.corosync_binaries,
                                     "corosync-qdevice-net-certutil"),
                 cluster_name=cluster_name,
             ),
             stdout=(stdout if stdout is not None else
                     f"Certificate request stored in {cert_req_path}\n"),
             stderr=stderr,
             returncode=returncode),
     )