def run(test, params, env):
    """
    Ansible playbook basic test:
    1) Check ansible package exists
    2) Launch the guest
    3) Clone an ansible playbook repo
    4) Generate the ansible-playbook command
    5) Execute the playbook and verify the return status

    :param test: QEMU test object.
    :param params: Dictionary with the test parameters.
    :param env: Dictionary with test environment.
    """

    guest_user = params["username"]
    guest_passwd = params["password"]
    step_time = params.get_numeric("step_time", 60)
    ansible_callback_plugin = params.get("ansible_callback_plugin")
    ansible_addl_opts = params.get("ansible_addl_opts", "")
    ansible_ssh_extra_args = params["ansible_ssh_extra_args"]
    ansible_extra_vars = params.get("ansible_extra_vars", "{}")
    playbook_repo = params["playbook_repo"]
    playbook_timeout = params.get_numeric("playbook_timeout")
    playbook_dir = params.get("playbook_dir",
                              os.path.join(test.workdir, "ansible_playbook"))
    toplevel_playbook = os.path.join(playbook_dir, params["toplevel_playbook"])
    # Use this directory to copy some logs back from the guest
    test_harness_log_dir = test.logdir

    # Responsive migration specific parameters
    mq_listen_port = params.get_numeric("mq_listen_port", find_free_port())
    wait_response_timeout = params.get_numeric("wait_response_timeout", 600)

    vms = env.get_all_vms()
    guest_ip_list = []
    for vm in vms:
        vm.verify_alive()
        vm.wait_for_login()
        guest_ip_list.append(vm.get_address())

    logging.info("Cloning %s", playbook_repo)
    process.run("git clone {src} {dst}".format(src=playbook_repo,
                                               dst=playbook_dir), verbose=False)

    error_context.base_context("Generate playbook related options.",
                               logging.info)
    extra_vars = {"ansible_ssh_extra_args": ansible_ssh_extra_args,
                  "ansible_ssh_pass": guest_passwd,
                  "mq_port": mq_listen_port,
                  "test_harness_log_dir": test_harness_log_dir}
    extra_vars.update(json.loads(ansible_extra_vars))

    error_context.context("Execute the ansible playbook.", logging.info)
    playbook_executor = ansible.PlaybookExecutor(
        inventory="{},".format(",".join(guest_ip_list)),
        site_yml=toplevel_playbook,
        remote_user=guest_user,
        extra_vars=json.dumps(extra_vars),
        callback_plugin=ansible_callback_plugin,
        addl_opts=ansible_addl_opts
    )

    mq_publisher = message_queuing.MQPublisher(mq_listen_port)
    try:
        error_context.base_context('Confirm remote subscriber has accessed to '
                                   'activate migrating guests.', logging.info)
        try:
            mq_publisher.confirm_access(wait_response_timeout)
        except message_queuing.MessageNotFoundError as err:
            logging.error(err)
            test.fail("Failed to capture the 'ACCESS' message.")
        logging.info("Already captured the 'ACCESS' message.")

        error_context.context("Migrate guests after subscriber accessed.",
                              logging.info)
        for vm in vms:
            vm.migrate()
    except VMMigrateFailedError:
        error_context.context("Send the 'ALERT' message to notify the remote "
                              "subscriber to stop the test.", logging.info)
        mq_publisher.alert()
        raise
    else:
        error_context.context("Send the 'APPROVE' message to notify the remote "
                              "subscriber to continue the test.", logging.info)
        mq_publisher.approve()
    finally:
        ansible_log = "ansible_playbook.log"
        try:
            playbook_executor.wait_for_completed(playbook_timeout, step_time)
        except ansible.ExecutorTimeoutError as err:
            test.error(str(err))
        else:
            if playbook_executor.get_status() != 0:
                test.fail("Ansible playbook execution failed, please check the "
                          "{} for details.".format(ansible_log))
            logging.info("Ansible playbook execution passed.")
        finally:
            playbook_executor.store_playbook_log(test_harness_log_dir,
                                                 ansible_log)
            playbook_executor.close()
            mq_publisher.close()
def run(test, params, env):
    """
    QEMU nested block resize test

    1) Boot the main vm as L1, attach scsi data disk
    2) Pass-through L1 data disk to L2
    3) Run io on the data disk in L2.
    4) Execute block_resize for data disk image on host.
    5) Check L1 status should keep running.
    6) Check L2 status should keep running.

    :param test: QEMU test object.
    :param params: Dictionary with the test parameters.
    :param env: Dictionary with test environment.
    """
    def _on_exit(obj, msg):
        logging.info("Receive exit msg:%s", msg)
        obj.set_msg_loop(False)
        status = msg.split(":")[1]
        if status != "0":
            test.fail("Get L2 guest unexpected exit message")

    def _on_resize(obj, msg):
        logging.info("Receive resize msg:%s", msg)
        data_image_params = params.object_params("stg0")
        data_image_size = params.get_numeric("new_image_size_stg0")
        data_image_filename = storage.get_image_filename(
            data_image_params, data_dir.get_data_dir())
        data_image_dev = vm.get_block({'file': data_image_filename})
        args = (None, data_image_size, data_image_dev)

        vm.monitor.block_resize(*args)
        time.sleep(2)
        vm.verify_status("running")
        guest_cmd_output = session.cmd("lsblk -dn", timeout=60).strip()
        logging.debug("Guest cmd output: '%s'", guest_cmd_output)
        obj.send_message("status-req")
        logging.info("Finish handle on_resize")

    def _on_status(obj, msg):
        logging.info("Receive status msg:%s", msg)
        status = msg.split(":")[1]
        # Notify L2 exit
        obj.send_message("exit")
        if status != "running":
            test.fail("Get unexpected status of L2 guest " + status)
        logging.info("Finish handle on_status")

    # Error contexts are used to give more info on what was
    # going on when one exception happened executing test code.
    error_context.context("Get the main VM", logging.info)
    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    session = vm.wait_for_login()
    # Handle nested ENV
    guest_user = params["username"]
    guest_passwd = params["password"]
    step_time = params.get_numeric("step_time", 60)
    ansible_callback_plugin = params.get("ansible_callback_plugin")
    ansible_addl_opts = params.get("ansible_addl_opts", "")
    ansible_ssh_extra_args = params["ansible_ssh_extra_args"]
    ansible_extra_vars = params.get("ansible_extra_vars", "{}")
    playbook_repo = params["playbook_repo"]
    playbook_timeout = params.get_numeric("playbook_timeout")
    playbook_dir = params.get("playbook_dir",
                              os.path.join(test.workdir, "ansible_playbook"))
    toplevel_playbook = os.path.join(playbook_dir, params["toplevel_playbook"])
    # Use this directory to copy some logs back from the guest
    test_harness_log_dir = test.logdir

    mq_listen_port = params.get_numeric("mq_listen_port", 5000)
    guest_ip_list = [vm.get_address()]

    logging.info("Cloning %s", playbook_repo)
    process.run("git clone {src} {dst}".format(src=playbook_repo,
                                               dst=playbook_dir),
                verbose=False)

    error_context.base_context("Generate playbook related options.",
                               logging.info)
    extra_vars = {
        "ansible_ssh_extra_args": ansible_ssh_extra_args,
        "ansible_ssh_pass": guest_passwd,
        "mq_port": mq_listen_port,
        "test_harness_log_dir": test_harness_log_dir
    }
    extra_vars.update(json.loads(ansible_extra_vars))

    error_context.context("Execute the ansible playbook.", logging.info)
    playbook_executor = ansible.PlaybookExecutor(
        inventory="{},".format(",".join(guest_ip_list)),
        site_yml=toplevel_playbook,
        remote_user=guest_user,
        extra_vars=json.dumps(extra_vars),
        callback_plugin=ansible_callback_plugin,
        addl_opts=ansible_addl_opts)

    # Handle cases

    mq_port = params.get("mq_port", 5000)
    wait_response_timeout = params.get_numeric("wait_response_timeout", 1800)

    mq_publisher = message_queuing.MQPublisher(mq_port,
                                               other_options="--broker")

    host = "127.0.0.1"

    logging.info("host:{} port:{}".format(host, mq_port))
    client = message_queuing.MQClient(host, mq_port)
    time.sleep(2)

    client.register_msg("resize", _on_resize)
    client.register_msg("status-rsp:", _on_status)
    client.register_msg("exit:", _on_exit)

    try:
        client.msg_loop(timeout=wait_response_timeout)
        logging.debug("Finish msg_loop")
    finally:
        ansible_log = "ansible_playbook.log"
        try:
            playbook_executor.wait_for_completed(playbook_timeout, step_time)
        except ansible.ExecutorTimeoutError as err:
            test.error(str(err))
        else:
            if playbook_executor.get_status() != 0:
                test.fail(
                    "Ansible playbook execution failed, please check the "
                    "{} for details.".format(ansible_log))
            logging.info("Ansible playbook execution passed.")
        finally:
            playbook_executor.store_playbook_log(test_harness_log_dir,
                                                 ansible_log)
            playbook_executor.close()
            client.close()
            mq_publisher.close()
            logging.debug("MQ closed")
Exemple #3
0
def run(test, params, env):
    """
    Ansible playbook basic test:
    1) Check ansible package exists
    2) Launch the guest
    3) Clone an ansible playbook repo
    4) Generate the ansible-playbook command
    5) Execute the playbook and verify the return status

    :param test: QEMU test object.
    :param params: Dictionary with the test parameters.
    :param env: Dictionary with test environment.
    """

    guest_user = params["username"]
    guest_passwd = params["password"]
    step_time = params.get_numeric("step_time", 60)
    ansible_callback_plugin = params.get("ansible_callback_plugin")
    ansible_addl_opts = params.get("ansible_addl_opts", "")
    ansible_ssh_extra_args = params["ansible_ssh_extra_args"]
    ansible_extra_vars = params.get("ansible_extra_vars", "{}")
    playbook_repo = params["playbook_repo"]
    playbook_timeout = params.get_numeric("playbook_timeout")
    playbook_dir = params.get("playbook_dir",
                              os.path.join(test.workdir, "ansible_playbook"))
    toplevel_playbook = os.path.join(playbook_dir, params["toplevel_playbook"])
    # Use this directory to copy some logs back from the guest
    test_harness_log_dir = test.logdir

    vms = env.get_all_vms()
    guest_ip_list = []
    for vm in vms:
        vm.verify_alive()
        vm.wait_for_login()
        guest_ip_list.append(vm.get_address())

    logging.info("Cloning %s", playbook_repo)
    process.run("git clone {src} {dst}".format(src=playbook_repo,
                                               dst=playbook_dir),
                verbose=False)

    error_context.base_context("Generate playbook related options.",
                               logging.info)
    extra_vars = {
        "ansible_ssh_extra_args": ansible_ssh_extra_args,
        "ansible_ssh_pass": guest_passwd,
        "test_harness_log_dir": test_harness_log_dir
    }
    extra_vars.update(json.loads(ansible_extra_vars))

    error_context.context("Execute the ansible playbook.", logging.info)
    playbook_executor = ansible.PlaybookExecutor(
        inventory="{},".format(",".join(guest_ip_list)),
        site_yml=toplevel_playbook,
        remote_user=guest_user,
        extra_vars=json.dumps(extra_vars),
        callback_plugin=ansible_callback_plugin,
        addl_opts=ansible_addl_opts)

    ansible_log = "ansible_playbook.log"
    try:
        playbook_executor.wait_for_completed(playbook_timeout, step_time)
    except ansible.ExecutorTimeoutError as err:
        test.error(str(err))
    else:
        if playbook_executor.get_status() != 0:
            test.fail("Ansible playbook execution failed, please check the {} "
                      "for details.".format(ansible_log))
        logging.info("Ansible playbook execution passed.")
    finally:
        playbook_executor.store_playbook_log(test_harness_log_dir, ansible_log)
        playbook_executor.close()