Пример #1
0
 def record_iptables(self, label):
     name = ('%s_iptables_%s.txt'
             % (self.__class__.__name__, label))
     output = open(os.path.join(self.parent_subtest.resultsdir, name), 'w+')
     output.write(utils.run('iptables -t filter -L -n -v').stdout)
     output.write('\n\n')
     output.write(utils.run('iptables -t nat -L -n -v').stdout)
Пример #2
0
def build_CA(tmp_dir, certtool="certtool"):
    """
    setup private key and certificate file which are needed to build.
    certificate file for client and server.

    (1).initialization for variables.
    (2).make a private key with certtool command.
    (3).prepare a info file.
    (4).make a certificate file with certtool command.
    """
    # initialize variables
    cakey_path = '%s/tcakey.pem' % tmp_dir
    cainfo_path = '%s/ca.info' % tmp_dir
    cacert_path = '%s/cacert.pem' % tmp_dir

    # make a private key
    cmd = "%s --generate-privkey > %s " % (certtool, cakey_path)
    cmd_result = utils.run(cmd, ignore_status=True, timeout=10)
    if cmd_result.exit_status:
        raise ConnPrivKeyError(cakey_path, cmd_result.stderr)
    # prepare a info file to build certificate file
    cainfo_file = open(cainfo_path, "w")
    cainfo_file.write("cn = AUTOTEST.VIRT\n")
    cainfo_file.write("ca\n")
    cainfo_file.write("cert_signing_key\n")
    cainfo_file.close()

    # make a certificate file to build clientcert and servercert
    cmd = ("%s --generate-self-signed --load-privkey %s\
           --template %s --outfile %s" %
           (certtool, cakey_path, cainfo_path, cacert_path))
    CmdResult = utils.run(cmd, ignore_status=True)
    if CmdResult.exit_status:
        raise ConnCertError(cainfo_path, CmdResult.stderr)
Пример #3
0
    def mk_cgroup_cgcreate(self, pwd=None, cgroup=None):
        """
        Make a cgroup by cgcreate command

        @params: cgroup: Maked cgroup name
        :return: last cgroup index
        """
        try:
            parent_cgroup = self.get_cgroup_name(pwd)
            if cgroup is None:
                range = "abcdefghijklmnopqrstuvwxyz0123456789"
                sub_cgroup = "cgroup-" + "".join(random.sample(range +
                                                 range.upper(), 6))
            else:
                sub_cgroup = cgroup
            if parent_cgroup is None:
                cgroup = sub_cgroup
            else:
                # Parent cgroup:test. Created cgroup:test1.
                # Whole cgroup name is "test/test1"
                cgroup = os.path.join(parent_cgroup, sub_cgroup)
            if self.__get_cgroup_pwd(cgroup) in self.cgroups:
                raise error.TestFail("%s exists!" % cgroup)
            cgcreate_cmd = "cgcreate -g %s:%s" % (self.module, cgroup)
            utils.run(cgcreate_cmd, ignore_status=False)
            pwd = self.__get_cgroup_pwd(cgroup)
            self.cgroups.append(pwd)
            return len(self.cgroups) - 1
        except error.CmdError:
            raise error.TestFail("Make cgroup by cgcreate failed!")
Пример #4
0
def download_test_provider(provider, update=False):
    """
    Download a test provider defined on a .ini file inside test-providers.d.

    This function will only download test providers that are in git repos.
    Local filesystems don't need this functionality.

    :param provider: Test provider name, such as 'io-github-autotest-qemu'.
    """
    provider_info = get_test_provider_info(provider)
    uri = provider_info.get('uri')
    if not uri.startswith('file://'):
        uri = provider_info.get('uri')
        branch = provider_info.get('branch')
        ref = provider_info.get('ref')
        pubkey = provider_info.get('pubkey')
        download_dst = data_dir.get_test_provider_dir(provider)
        repo_downloaded = os.path.isdir(os.path.join(download_dst, '.git'))
        if not repo_downloaded or update:
            download_dst = git.get_repo(uri=uri, branch=branch, commit=ref,
                                        destination_dir=download_dst)
            os.chdir(download_dst)
            try:
                utils.run('git remote add origin %s' % uri)
            except error.CmdError:
                pass
            utils.run('git pull origin %s' % branch)
        os.chdir(download_dst)
        utils.system('git log -1')
Пример #5
0
    def clone_image(params, vm_name, image_name, root_dir):
        """
        Clone master image to vm specific file.

        :param params: Dictionary containing the test parameters.
        :param vm_name: Vm name.
        :param image_name: Master image name.
        :param root_dir: Base directory for relative filenames.
        """
        if not params.get("image_name_%s_%s" % (image_name, vm_name)):
            m_image_name = params.get("image_name", "image")
            vm_image_name = "%s_%s" % (m_image_name, vm_name)
            if params.get("clone_master", "yes") == "yes":
                image_params = params.object_params(image_name)
                image_params["image_name"] = vm_image_name

                m_image_fn = get_image_filename(params, root_dir)
                image_fn = get_image_filename(image_params, root_dir)

                force_clone = params.get("force_image_clone", "no")
                if not os.path.exists(image_fn) or force_clone == "yes":
                    logging.info("Clone master image for vms.")
                    utils.run(params.get("image_clone_command") % (m_image_fn,
                                                                   image_fn))

            params["image_name_%s_%s" % (image_name, vm_name)] = vm_image_name
Пример #6
0
    def prepare_gluster_disk(disk_img, disk_format):
        """
        Setup glusterfs and prepare disk image.
        """
        # Get the image path and name from parameters
        data_path = data_dir.get_data_dir()
        image_name = params.get("image_name")
        image_format = params.get("image_format")
        image_source = os.path.join(data_path,
                                    image_name + '.' + image_format)

        # Setup gluster.
        host_ip = libvirt.setup_or_cleanup_gluster(True, vol_name,
                                                   brick_path, pool_name)
        logging.debug("host ip: %s ", host_ip)
        image_info = utils_misc.get_image_info(image_source)
        if image_info["format"] == disk_format:
            disk_cmd = ("cp -f %s /mnt/%s" % (image_source, disk_img))
        else:
            # Convert the disk format
            disk_cmd = ("qemu-img convert -f %s -O %s %s /mnt/%s" %
                        (image_info["format"], disk_format, image_source, disk_img))

        # Mount the gluster disk and create the image.
        utils.run("mount -t glusterfs %s:%s /mnt;"
                  " %s; chmod a+rw /mnt/%s; umount /mnt"
                  % (host_ip, vol_name, disk_cmd, disk_img))

        return host_ip
Пример #7
0
def uncompress_asset(asset_info, force=False):
    destination = asset_info['destination']
    uncompress_cmd = asset_info['uncompress_cmd']
    destination_uncompressed = asset_info['destination_uncompressed']

    archive_re = re.compile(r".*\.(gz|xz|7z|bz2)$")
    if destination_uncompressed is not None:
        if uncompress_cmd is None:
            match = archive_re.match(destination)
            if match:
                if match.group(1) == 'gz':
                    uncompress_cmd = ('gzip -cd %s > %s' %
                                      (destination, destination_uncompressed))
                elif match.group(1) == 'xz':
                    uncompress_cmd = ('xz -cd %s > %s' %
                                      (destination, destination_uncompressed))
                elif match.group(1) == 'bz2':
                    uncompress_cmd = ('bzip2 -cd %s > %s' %
                                      (destination, destination_uncompressed))
                elif match.group(1) == '7z':
                    uncompress_cmd = '7za -y e %s' % destination
        else:
            uncompress_cmd = "%s %s" % (uncompress_cmd, destination)

    if uncompress_cmd is not None:
        uncompressed_file_exists = os.path.exists(destination_uncompressed)
        force = (force or not uncompressed_file_exists)

        if os.path.isfile(destination) and force:
            os.chdir(os.path.dirname(destination_uncompressed))
            utils.run(uncompress_cmd)
Пример #8
0
def lv_take_snapshot(vg_name, lv_name,
                     lv_snapshot_name, lv_snapshot_size):
    """
    Take a snapshot of the original logical volume.
    """
    error.context("Taking snapshot from original logical volume",
                  logging.info)

    if not vg_check(vg_name):
        raise error.TestError("Volume group could not be found")
    if lv_check(vg_name, lv_snapshot_name):
        raise error.TestError("Snapshot already exists")
    if not lv_check(vg_name, lv_name):
        raise error.TestError("Snapshot's origin could not be found")

    cmd = ("lvcreate --size %s --snapshot --name %s /dev/%s/%s" %
           (lv_snapshot_size, lv_snapshot_name, vg_name, lv_name))
    try:
        result = utils.run(cmd)
    except error.CmdError, ex:
        if ('Logical volume "%s" already exists in volume group "%s"' %
            (lv_snapshot_name, vg_name) in ex.result_obj.stderr and
            re.search(re.escape(lv_snapshot_name + " [active]"),
                      utils.run("lvdisplay").stdout)):
            # the above conditions detect if merge of snapshot was postponed
            logging.warning(("Logical volume %s is still active! " +
                             "Attempting to deactivate..."), lv_name)
            lv_reactivate(vg_name, lv_name)
            result = utils.run(cmd)
        else:
            raise ex
Пример #9
0
    def run_ip_test(session, ip_ver):
        """
        Check iptables on host and ipv6 address on guest
        """
        if ip_ver == "ipv6":
            # Clean up iptables rules for guest to get ipv6 address
            session.cmd_status("ip6tables -F")

        # It may take some time to get the ip address
        def get_ip_func():
            return utils_net.get_guest_ip_addr(session, iface_mac,
                                               ip_version=ip_ver)
        utils_misc.wait_for(get_ip_func, 5)
        if not get_ip_func():
            utils_net.restart_guest_network(session, iface_mac,
                                            ip_version=ip_ver)
            utils_misc.wait_for(get_ip_func, 5)
        vm_ip = get_ip_func()
        logging.debug("Guest has ip: %s", vm_ip)
        if not vm_ip:
            raise error.TestFail("Can't find ip address on guest")
        ip_gateway = net_ip_address
        if ip_ver == "ipv6":
            ip_gateway = net_ipv6_address
            # Cleanup ip6talbes on host for ping6 test
            utils.run("ip6tables -F")
        if ip_gateway and not routes:
            ping_s, _ = ping(dest=ip_gateway, count=5,
                             timeout=10, session=session)
            if ping_s:
                raise error.TestFail("Failed to ping gateway address: %s"
                                     % ip_gateway)
Пример #10
0
def vg_ramdisk(vg_name, ramdisk_vg_size,
               ramdisk_basedir, ramdisk_sparse_filename):
    """
    Create vg on top of ram memory to speed up lv performance.
    """
    error.context("Creating virtual group on top of ram memory",
                  logging.info)
    vg_size = ramdisk_vg_size
    vg_ramdisk_dir = os.path.join(ramdisk_basedir, vg_name)
    ramdisk_filename = os.path.join(vg_ramdisk_dir,
                                    ramdisk_sparse_filename)

    vg_ramdisk_cleanup(ramdisk_filename, vg_ramdisk_dir, vg_name)
    result = ""
    if not os.path.exists(vg_ramdisk_dir):
        os.mkdir(vg_ramdisk_dir)
    try:
        logging.info("Mounting tmpfs")
        result = utils.run("mount -t tmpfs tmpfs %s" % vg_ramdisk_dir)

        logging.info("Converting and copying /dev/zero")
        cmd = ("dd if=/dev/zero of=%s bs=1M count=1 seek=%s" %
               (ramdisk_filename, vg_size))
        result = utils.run(cmd, verbose=True)

        logging.info("Finding free loop device")
        result = utils.run("losetup --find", verbose=True)
    except error.CmdError, ex:
        logging.error(ex)
        vg_ramdisk_cleanup(ramdisk_filename, vg_ramdisk_dir, vg_name)
        raise ex
Пример #11
0
    def preseed_initrd(self):
        """
        Puts a preseed file inside a gz compressed initrd file.

        Debian and Ubuntu use preseed as the OEM install mechanism. The only
        way to get fully automated setup without resorting to kernel params
        is to add a preseed.cfg file at the root of the initrd image.
        """
        logging.debug("Remastering initrd.gz file with preseed file")
        dest_fname = 'preseed.cfg'
        remaster_path = os.path.join(self.image_path, "initrd_remaster")
        if not os.path.isdir(remaster_path):
            os.makedirs(remaster_path)

        base_initrd = os.path.basename(self.initrd)
        os.chdir(remaster_path)
        utils.run("gzip -d < ../%s | cpio --extract --make-directories "
                  "--no-absolute-filenames" % base_initrd, verbose=DEBUG)
        utils.run("cp %s %s" % (self.unattended_file, dest_fname),
                  verbose=DEBUG)

        if self.params.get("vm_type") == "libvirt":
            utils.run("find . | cpio -H newc --create > ../%s.img" %
                      base_initrd.rstrip(".gz"), verbose=DEBUG)
        else:
            utils.run("find . | cpio -H newc --create | gzip -9 > ../%s" %
                      base_initrd, verbose=DEBUG)

        os.chdir(self.image_path)
        utils.run("rm -rf initrd_remaster", verbose=DEBUG)
        contents = open(self.unattended_file).read()

        logging.debug("Unattended install contents:")
        for line in contents.splitlines():
            logging.debug(line)
Пример #12
0
 def cleanup_pool(self, pool_name, pool_type, pool_target, emulated_image):
     """
     Delete vols, destroy the created pool and restore the env
     """
     sp = libvirt_storage.StoragePool()
     pv = libvirt_storage.PoolVolume(pool_name)
     if pool_type in ["dir", "netfs"]:
         vols = pv.list_volumes()
         for vol in vols:
             # Ignore failed deletion here for deleting pool
             pv.delete_volume(vol)
     try:
         if not sp.delete_pool(pool_name):
             raise error.TestFail("Delete pool %s failed" % pool_name)
     finally:
         if pool_type == "netfs":
             nfs_server_dir = self.params.get("nfs_server_dir", "nfs-server")
             nfs_path = os.path.join(self.tmpdir, nfs_server_dir)
             setup_or_cleanup_nfs(is_setup=False, mount_dir=nfs_path)
             if os.path.exists(nfs_path):
                 shutil.rmtree(nfs_path)
         if pool_type == "logical":
             cmd = "pvs |grep vg_logical|awk '{print $1}'"
             pv = utils.system_output(cmd)
             # Cleanup logical volume anyway
             utils.run("vgremove -f vg_logical", ignore_status=True)
             utils.run("pvremove %s" % pv, ignore_status=True)
         # These types used iscsi device
         if pool_type in ["logical", "iscsi", "fs", "disk", "scsi"]:
             setup_or_cleanup_iscsi(is_setup=False,
                                    emulated_image=emulated_image)
         if pool_type == "dir":
             pool_target = os.path.join(self.tmpdir, pool_target)
             if os.path.exists(pool_target):
                 shutil.rmtree(pool_target)
Пример #13
0
    def initialize(self):
        super(volume_mount, self).initialize()

        vol = "v_" + utils.generate_random_string(8)
        subargs = ["create", "--name", vol]
        mustpass(DockerCmd(self, "volume", subargs).execute())
        self.sub_stuff["volume_name"] = vol

        # First container: bind-mounts new volume, then unpacks two
        # tarballs into it. I don't know why it has to be two tarballs
        # and not one, but the tar thing (vs plain copy) has to do
        # with pivot_root. Whatever that is.
        c1 = DockerContainers(self).get_unique_name(prefix="c1_")
        # Path is not configurable because it's hardcoded in the tarballs
        vol_binding = vol + ":/.imagebuilder-transient-mount"
        subargs = ["--name", c1, "-v", vol_binding, "busybox"]
        mustpass(DockerCmd(self, "create", subargs).execute())
        self.sub_stuff["container1"] = c1
        for ab in ["a", "b"]:
            tar_file = "cp_volume_mount_data_%s.tar" % ab
            tar_path = os.path.join(self.parent_subtest.bindir, tar_file)
            # Failure mode only happens if cp is via redirected stdin.
            docker_path = self.config["docker_path"]
            utils.run("%s cp - %s:/ < %s" % (docker_path, c1, tar_path))

        # Second container also bind-mounts the volume, but directly
        # through the host filesystem.
        subargs = ["inspect", "-f", '"{{ .Mountpoint }}"', vol]
        inspect_cmd = mustpass(DockerCmd(self, "volume", subargs).execute())
        mp = inspect_cmd.stdout.strip()

        c2 = DockerContainers(self).get_unique_name(prefix="c2_")
        subargs = ["--name", c2, "-v", mp + "/0:/mountdir", "-v", mp + "/1:/mountfile", "busybox", "cat", "/mountfile"]
        mustpass(DockerCmd(self, "create", subargs).execute())
        self.sub_stuff["container2"] = c2
Пример #14
0
    def setup_url(self):
        """
        Download the vmlinuz and initrd.img from URL.
        """
        # it's only necessary to download kernel/initrd if running bare qemu
        if self.vm_type == 'kvm':
            error.context("downloading vmlinuz/initrd.img from %s" % self.url)
            os.chdir(self.image_path)
            kernel_cmd = "wget -q %s/%s/%s" % (self.url,
                                               self.boot_path,
                                               os.path.basename(self.kernel))
            initrd_cmd = "wget -q %s/%s/%s" % (self.url,
                                               self.boot_path,
                                               os.path.basename(self.initrd))

            if os.path.exists(self.kernel):
                os.remove(self.kernel)
            if os.path.exists(self.initrd):
                os.remove(self.initrd)

            utils.run(kernel_cmd, verbose=DEBUG)
            utils.run(initrd_cmd, verbose=DEBUG)

        elif self.vm_type == 'libvirt':
            logging.info("Not downloading vmlinuz/initrd.img from %s, "
                         "letting virt-install do it instead")

        else:
            logging.info("No action defined/needed for the current virt "
                         "type: '%s'" % self.vm_type)
Пример #15
0
 def _create_user():
     """
     Create a "vdsm_fake" in 'qemu' group for test
     """
     logging.debug("create a user 'vdsm_fake' in 'qemu' group")
     cmd = "useradd vdsm_fake -G qemu -s /sbin/nologin"
     utils.run(cmd, ignore_status=False)
Пример #16
0
def run_enospc(test, params, env):
    """
    ENOSPC test

    1) Create a virtual disk on lvm
    2) Boot up guest with two disks
    3) Continually write data to second disk
    4) Check images and extend second disk when no space
    5) Continue paused guest
    6) Repeat step 3~5 several times

    @param test: KVM test object.
    @param params: Dictionary with the test parameters.
    @param env: Dictionary with test environment.
    """
    enospc_config = EnospcConfig(test, params)
    enospc_config.setup()
    vm = env.get_vm(params["main_vm"])
    vm.create()
    login_timeout = int(params.get("login_timeout", 360))
    session_serial = vm.wait_for_serial_login(timeout=login_timeout)

    vgtest_name = params.get("vgtest_name")
    lvtest_name = params.get("lvtest_name")
    logical_volume = "/dev/%s/%s" % (vgtest_name, lvtest_name)

    drive_format = params.get("drive_format")
    if drive_format == "virtio":
        devname = "/dev/vdb"
    elif drive_format == "ide":
        output = session_serial.cmd_output("dir /dev")
        devname = "/dev/" + re.findall("([sh]db)\s", output)[0]
    elif drive_format == "scsi":
        devname = "/dev/sdb"
    cmd = params.get("background_cmd")
    cmd %= devname
    logging.info("Sending background cmd '%s'", cmd)
    session_serial.sendline(cmd)

    iterations = int(params.get("repeat_time", 40))
    i = 0
    pause_n = 0
    while i < iterations:
        if vm.monitor.verify_status("paused"):
            pause_n += 1
            logging.info("Checking all images in use by the VM")
            for image_name in vm.params.objects("images"):
                image_params = vm.params.object_params(image_name)
                try:
                    image = kvm_storage.QemuImg(image_params, test.bindir,
                                               image_name)
                    image.check_image(image_params, test.bindir)
                except (virt_vm.VMError, error.TestWarn), e:
                    logging.error(e)
            logging.info("Guest paused, extending Logical Volume size")
            try:
                utils.run("lvextend -L +200M %s" % logical_volume)
            except error.CmdError, e:
                logging.debug(e.result_obj.stdout)
            vm.resume()
Пример #17
0
def check_vmcore(vm, session, timeout):
    """
    Check the vmcore file after triggering a crash

    :param session: A shell session object or None.
    :param timeout: Timeout in seconds
    """
    vmcore_path = vm.params.get("vmcore_path", "/var/crash")
    vmcore_chk_cmd = vm.params.get("vmcore_chk_cmd", "ls -R %s | grep vmcore")
    vmcore_chk_cmd = vmcore_chk_cmd % vmcore_path

    if not utils_misc.wait_for(lambda: not session.is_responsive(), 240, 0, 1):
        raise error.TestFail("Could not trigger crash.")

    error.context("Waiting for kernel crash dump to complete", logging.info)
    session = vm.wait_for_login(timeout=timeout)

    error.context("Probing vmcore file...", logging.info)
    try:
        if vm.params.get("kdump_method") == "ssh":
            logging.info("Checking vmcore file on host")
            utils.run(vmcore_chk_cmd)
        else:
            logging.info("Checking vmcore file on guest")
            session.cmd(vmcore_chk_cmd)
    except Exception:
        postprocess_kdump(vm, timeout)
        raise error.TestFail("Could not found vmcore file.")

    logging.info("Found vmcore.")
Пример #18
0
def create_local_disk(disk_type, path=None,
                      size="10", disk_format="raw",
                      vgname=None, lvname=None):
    if disk_type != "lvm" and path is None:
        raise error.TestError("Path is needed for creating local disk")
    if path:
        utils.run("mkdir -p %s" % os.path.dirname(path))
    try:
        size = str(float(size)) + "G"
    except ValueError:
        pass
    cmd = ""
    if disk_type == "file":
        cmd = "qemu-img create -f %s %s %s" % (disk_format, path, size)
    elif disk_type == "floppy":
        cmd = "dd if=/dev/zero of=%s count=1024 bs=1024" % path
    elif disk_type == "iso":
        cmd = "mkisofs -o %s /root/*.*" % path
    elif disk_type == "lvm":
        if vgname is None or lvname is None:
            raise error.TestError("Both VG name and LV name are needed")
        lv_utils.lv_create(vgname, lvname, size)
        path = "/dev/%s/%s" % (vgname, lvname)
    else:
        raise error.TestError("Unknown disk type %s" % disk_type)
    if cmd:
        utils.run(cmd, ignore_status=True)
    return path
Пример #19
0
 def check_status_with_value(action_list, file_name):
     """
     Check the status of khugepaged when set value to specify file.
     """
     for (a, r) in action_list:
         logging.info("Writing path %s: %s, expected khugepage rc: %s ",
                      file_name, a, r)
         try:
             file_object = open(file_name, "w")
             file_object.write(a)
             file_object.close()
         except IOError, error_detail:
             logging.info("IO Operation on path %s failed: %s",
                          file_name, error_detail)
         time.sleep(5)
         try:
             utils.run('pgrep khugepaged', verbose=False)
             if r != 0:
                 raise THPKhugepagedError("Khugepaged still alive when"
                                          "transparent huge page is "
                                          "disabled")
         except error.CmdError:
             if r == 0:
                 raise THPKhugepagedError("Khugepaged could not be set to"
                                          "status %s" % a)
Пример #20
0
def crash_test(vm, vcpu, crash_cmd, timeout):
    """
    Trigger a crash dump through sysrq-trigger

    :param vcpu: vcpu which is used to trigger a crash
    :param crash_cmd: crash_cmd which is triggered crash command
    :param timeout: Timeout in seconds
    """
    vmcore_path = vm.params.get("vmcore_path", "/var/crash")
    kdump_method = vm.params.get("kdump_method", "basic")
    vmcore_rm_cmd = vm.params.get("vmcore_rm_cmd", "rm -rf %s/*")
    vmcore_rm_cmd = vmcore_rm_cmd % vmcore_path
    kdump_restart_cmd = vm.params.get("kdump_restart_cmd",
                                      "service kdump restart")

    session = vm.wait_for_login(timeout=timeout)

    logging.info("Delete the vmcore file.")
    if kdump_method == "ssh":
        utils.run(vmcore_rm_cmd)
    else:
        session.cmd_output(vmcore_rm_cmd)

    session.cmd(kdump_restart_cmd, timeout=120)

    try:
        if crash_cmd == "nmi":
            logging.info("Triggering crash with 'nmi' interrupt")
            session.cmd("echo 1 > /proc/sys/kernel/unknown_nmi_panic")
            vm.monitor.nmi()
        else:
            logging.info("Triggering crash on vcpu %d ...", vcpu)
            session.sendline("taskset -c %d %s" % (vcpu, crash_cmd))
    except Exception:
        postprocess_kdump(vm, timeout)
Пример #21
0
    def initialize(self, **dargs):
        """
        Gets path of kvm_stat and verifies if debugfs needs to be mounted.
        """
        self.is_enabled = False

        kvm_stat_installed = False
        try:
            self.stat_path = os_dep.command('kvm_stat')
            kvm_stat_installed = True
        except ValueError:
            logging.error('Command kvm_stat not present')

        if kvm_stat_installed:
            try:
                utils.run("%s --batch" % self.stat_path)
                self.is_enabled = True
            except error.CmdError, e:
                if 'debugfs' in str(e):
                    try:
                        utils.run('mount -t debugfs debugfs /sys/kernel/debug')
                    except error.CmdError, e:
                        logging.error('Failed to mount debugfs:\n%s', str(e))
                else:
                    logging.error('Failed to execute kvm_stat:\n%s', str(e))
Пример #22
0
    def setup_url(self):
        """
        Download the vmlinuz and initrd.img from URL.
        """
        # it's only necessary to download kernel/initrd if running bare qemu
        if self.vm_type == "qemu":
            error.context("downloading vmlinuz/initrd.img from %s" % self.url)
            if not os.path.exists(self.image_path):
                os.mkdir(self.image_path)
            os.chdir(self.image_path)
            kernel_cmd = "wget -q %s/%s/%s" % (self.url, self.boot_path, os.path.basename(self.kernel))
            initrd_cmd = "wget -q %s/%s/%s" % (self.url, self.boot_path, os.path.basename(self.initrd))

            if os.path.exists(self.kernel):
                os.remove(self.kernel)
            if os.path.exists(self.initrd):
                os.remove(self.initrd)

            utils.run(kernel_cmd, verbose=DEBUG)
            utils.run(initrd_cmd, verbose=DEBUG)

            if "repo=cdrom" in self.kernel_params:
                # Red Hat
                self.kernel_params = re.sub("repo\=[\:\w\d\/]*", "repo=%s" % self.url, self.kernel_params)

        elif self.vm_type == "libvirt":
            logging.info("Not downloading vmlinuz/initrd.img from %s, " "letting virt-install do it instead")

        else:
            logging.info("No action defined/needed for the current virt " "type: '%s'" % self.vm_type)
Пример #23
0
 def attach_hook():
     """
     Check attach hooks.
     """
     # Start a domain with qemu command.
     disk_src = vm.get_first_disk_devices()['source']
     vm_test = "foo"
     prepare_hook_file(hook_script %
                       (vm_test, hook_log))
     qemu_bin = params.get("qemu_bin", "/usr/libexec/qemu-kvm")
     if "ppc" in platform.machine():
         qemu_bin = "%s -machine pseries" % qemu_bin
     qemu_cmd = ("%s -drive file=%s,if=none,bus=0,unit=1"
                 " -monitor unix:/tmp/demo,"
                 "server,nowait -name %s" %
                 (qemu_bin, disk_src, vm_test))
     ret = utils.run("%s &" % qemu_cmd)
     pid = utils.run("ps -ef | grep '%s' | grep -v grep | awk"
                     " '{print $2}'" % qemu_cmd).stdout.strip()
     if not pid:
         raise error.TestFail("Cannot get pid of qemu command")
     ret = virsh.qemu_attach(pid, **virsh_dargs)
     if ret.exit_status:
         utils_misc.kill_process_tree(pid)
         raise error.TestFail("Cannot attach qemu process")
     else:
         virsh.destroy(vm_test)
     hook_str = hook_file + " " + vm_test + " attach begin -"
     if not check_hooks(hook_str):
         raise error.TestFail("Failed to check"
                              " attach hooks")
Пример #24
0
    def setup_gagent_in_host(self, params, vm):
        error.context("Install qemu guest agent package on host", logging.info)
        gagent_host_install_cmd = params["gagent_host_install_cmd"]
        utils.run(gagent_host_install_cmd, params.get("login_timeout", 360))

        error.context("Install dependence packages on host", logging.info)
        gagent_host_dep_install_cmd = params.get("gagent_host_dep_install_cmd",
                                                 "")
        utils.run(gagent_host_dep_install_cmd,
                  params.get("login_timeout", 360))

        error.context("Copy necessary DLLs to guest", logging.info)
        gagent_guest_dir = params["gagent_guest_dir"]
        gagent_remove_service_cmd = params["gagent_remove_service_cmd"]
        gagent_dep_dlls_list = params.get("gagent_dep_dlls", "").split()

        session = self._get_session(params, vm)
        s, o = session.cmd_status_output("mkdir %s" % gagent_guest_dir)
        if bool(s):
            if str(s) == "1":
                # The directory exists, try to remove previous copies
                # of the qemu-ga.exe program, since the rss client
                # can't transfer file if destination exists.
                self._session_cmd_close(session, gagent_remove_service_cmd)
            else:
                raise error.TestError("Could not create qemu-ga directory"
                                      " in VM '%s', detail: '%s'" % (vm.name, o))
        dlls_list = session.cmd("dir %s" % gagent_guest_dir)
        missing_dlls_list = [_ for _ in gagent_dep_dlls_list
                             if os.path.basename(_) not in dlls_list]
        map(lambda f: vm.copy_files_to(f, gagent_guest_dir), missing_dlls_list)

        error.context("Copy qemu guest agent program to guest", logging.info)
        gagent_host_path = params["gagent_host_path"]
        vm.copy_files_to(gagent_host_path, gagent_guest_dir)
Пример #25
0
    def check_ipt_rules(check_ipv4=True, check_ipv6=False):
        """
        Check iptables for network/interface
        """
        br_name = ast.literal_eval(net_bridge)["name"]
        net_forward = ast.literal_eval(params.get("net_forward", "{}"))
        net_ipv4 = params.get("net_ipv4")
        net_ipv6 = params.get("net_ipv6")
        ipt_rules = ("FORWARD -i {0} -o {0} -j ACCEPT".format(br_name),
                     "FORWARD -o %s -j REJECT --reject-with icmp" % br_name,
                     "FORWARD -i %s -j REJECT --reject-with icmp" % br_name)
        net_dev_in = ""
        net_dev_out = ""
        if net_forward.has_key("dev"):
            net_dev_in = " -i %s" % net_forward["dev"]
            net_dev_out = " -o %s" % net_forward["dev"]
        if check_ipv4:
            ipv4_rules = list(ipt_rules)
            ctr_rule = ""
            nat_rules = []
            if net_forward.has_key("mode") and net_forward["mode"] == "nat":
                nat_port = ast.literal_eval(params.get("nat_port"))
                p_start = nat_port["start"]
                p_end = nat_port["end"]
                ctr_rule = " -m .* RELATED,ESTABLISHED"
                nat_rules = [("POSTROUTING -s {0} ! -d {0} -p tcp -j MASQUERADE"
                              " --to-ports {1}-{2}".format(net_ipv4, p_start, p_end)),
                             ("POSTROUTING -s {0} ! -d {0} -p udp -j MASQUERADE"
                              " --to-ports {1}-{2}".format(net_ipv4, p_start, p_end)),
                             ("POSTROUTING -s {0} ! -d {0} -p udp"
                              " -j MASQUERADE".format(net_ipv4))]
            if nat_rules:
                ipv4_rules.extend(nat_rules)
            if (net_ipv4 and net_forward.has_key("mode") and
                    net_forward["mode"] in ["nat", "route"]):
                rules = [("FORWARD -d %s%s -o %s%s -j ACCEPT"
                          % (net_ipv4, net_dev_in, br_name, ctr_rule)),
                         ("FORWARD -s %s -i %s%s -j ACCEPT"
                          % (net_ipv4, br_name, net_dev_out))]
                ipv4_rules.extend(rules)

            output = utils.run("iptables-save").stdout.strip()
            logging.debug("iptables: %s", output)
            for ipt in ipv4_rules:
                if not re.findall(r"%s" % ipt, output, re.M):
                    raise error.TestFail("Can't find iptable rule:\n%s" % ipt)
        if check_ipv6:
            ipv6_rules = list(ipt_rules)
            if (net_ipv6 and net_forward.has_key("mode") and
                    net_forward["mode"] in ["nat", "route"]):
                rules = [("FORWARD -d %s%s -o %s -j ACCEPT"
                          % (net_ipv6, net_dev_in, br_name)),
                         ("FORWARD -s %s -i %s%s -j ACCEPT"
                          % (net_ipv6, br_name, net_dev_out))]
                ipv6_rules.extend(rules)
            output = utils.run("ip6tables-save").stdout.strip()
            logging.debug("iptables: %s", output)
            for ipt in ipv6_rules:
                if not output.count(ipt):
                    raise error.TestFail("Can't find ipbtable rule:\n%s" % ipt)
Пример #26
0
    def _vg_ramdisk(self, vg_name):
        """
        Create vg on top of ram memory to speed up lv performance.
        """
        error.context("Creating virtual group on top of ram memory",
                      logging.info)
        vg_size = RAMDISK_VG_SIZE
        vg_ramdisk_dir = os.path.join(RAMDISK_BASEDIR, vg_name)
        ramdisk_filename = os.path.join(vg_ramdisk_dir,
                                        RAMDISK_SPARSE_FILENAME)

        self._vg_ramdisk_cleanup(ramdisk_filename,
                                 vg_ramdisk_dir, vg_name, "")
        result = ""
        if not os.path.exists(vg_ramdisk_dir):
            os.mkdir(vg_ramdisk_dir)
        try:
            logging.info("Mounting tmpfs")
            result = utils.run("mount -t tmpfs tmpfs " + vg_ramdisk_dir)

            logging.info("Converting and copying /dev/zero")
            cmd = ("dd if=/dev/zero of=" + ramdisk_filename +
                   " bs=1M count=1 seek=" + vg_size)
            result = utils.run(cmd, verbose=True)

            logging.info("Finding free loop device")
            result = utils.run("losetup --find", verbose=True)
        except error.CmdError, ex:
            logging.error(ex)
            self._vg_ramdisk_cleanup(ramdisk_filename,
                                     vg_ramdisk_dir, vg_name, "")
            raise ex
Пример #27
0
 def check_qemu_cmd():
     """
     Check qemu command line options.
     """
     cmd = ("ps -ef | grep %s | grep -v grep " % vm_name)
     if max_mem_rt:
         cmd += (" | grep 'slots=%s,maxmem=%sk'"
                 % (max_mem_slots, max_mem_rt))
     if tg_size:
         size = int(tg_size) * 1024
         cmd += (" | grep 'memory-backend-ram,id=memdimm0,size=%s"
                 % size)
         if pg_size:
             cmd += ",host-nodes=%s" % node_mask
             if numa_memnode:
                 for node in numa_memnode:
                     if ('nodeset' in node and
                             node['nodeset'] in node_mask):
                         cmd += ",policy=%s" % node['mode']
             cmd += ".*pc-dimm,node=%s" % tg_node
         if mem_addr:
             cmd += (".*slot=%s,addr=%s" %
                     (mem_addr['slot'], int(mem_addr['base'], 16)))
         cmd += "'"
     # Run the command
     utils.run(cmd)
Пример #28
0
def get_defcon(local=False):
    """
    Return list of dictionaries containing SELinux default file context types

    :param local: Only return locally modified default contexts
    :return: list of dictionaries of default context attributes
    """
    if local:
        result = utils.run("semanage fcontext --list -C", ignore_status=True)
    else:
        result = utils.run("semanage fcontext --list", ignore_status=True)
    _no_semanage(result)
    if result.exit_status != 0:
        raise SeCmdError("semanage", result.stderr)
    result_list = result.stdout.strip().split("\n")
    # Need to process top-down instead of bottom-up
    result_list.reverse()
    first_line = result_list.pop()
    # First column name has a space in it
    column_names = [name.strip().lower().replace(" ", "_") for name in first_line.split("  ") if len(name) > 0]
    # Shorten first column name
    column_names[0] = column_names[0].replace("selinux_", "")
    fcontexts = []
    for line in result_list:
        if len(line) < 1:  # skip blank lines
            continue
        column_data = [name.strip() for name in line.split("  ") if len(name) > 0]
        # Enumerating data raises exception if no column_names match
        fcontext = dict([(column_names[idx], data) for idx, data in enumerate(column_data)])
        # find/set functions only accept type, not full context string
        fcontext["context"] = get_type_from_context(fcontext["context"])
        fcontexts.append(fcontext)
    return fcontexts
Пример #29
0
def uncompress_asset(asset_info, force=False):
    destination = asset_info["destination"]
    uncompress_cmd = asset_info["uncompress_cmd"]
    destination_uncompressed = asset_info["destination_uncompressed"]

    archive_re = re.compile(r".*\.(gz|xz|7z|bz2)$")
    if destination_uncompressed is not None:
        if uncompress_cmd is None:
            match = archive_re.match(destination)
            if match:
                if match.group(1) == "gz":
                    uncompress_cmd = "gzip -cd %s > %s" % (destination, destination_uncompressed)
                elif match.group(1) == "xz":
                    uncompress_cmd = "xz -cd %s > %s" % (destination, destination_uncompressed)
                elif match.group(1) == "bz2":
                    uncompress_cmd = "bzip2 -cd %s > %s" % (destination, destination_uncompressed)
                elif match.group(1) == "7z":
                    uncompress_cmd = "7za -y e %s" % destination
        else:
            uncompress_cmd = "%s %s" % (uncompress_cmd, destination)

    if uncompress_cmd is not None:
        uncompressed_file_exists = os.path.exists(destination_uncompressed)
        force = force or not uncompressed_file_exists

        if os.path.isfile(destination) and force:
            os.chdir(os.path.dirname(destination_uncompressed))
            utils.run(uncompress_cmd)
Пример #30
0
def create_disk_xml(xml_file, device_type, source_file, target_dev, policy):
    """
    Create a disk xml file for attaching to a domain.

    :prams xml_file: path/file to save the disk XML
    :source_file: disk's source file
    :device_type: CD-ROM or floppy
    """
    if device_type == "cdrom":
        target_bus = "ide"
        image_size = "100M"
    elif device_type == "floppy":
        target_bus = "fdc"
        image_size = "1.44M"
    else:
        error.TestNAError("Unsupport device type in this test: " + device_type)
    utils.run("qemu-img create %s %s" % (source_file, image_size))
    disk_class = vm_xml.VMXML.get_device_class('disk')
    disk = disk_class(type_name='file')
    disk.device = device_type
    disk.driver = dict(name='qemu')
    disk.source = disk.new_disk_source(attrs={'file': source_file, 'startupPolicy': policy})
    disk.target = dict(bus=target_bus, dev=target_dev)
    disk.xmltreefile.write()
    shutil.copyfile(disk.xml, xml_file)
Пример #31
0
def run(test, params, env):
    """
    Transfer a file back and forth between host and guest.

    1) Boot up a VM.
    2) Create a large file by dd on host.
    3) Copy this file from host to guest.
    4) Copy this file from guest to host.
    5) Check if file transfers ended good.

    :param test: QEMU test object.
    :param params: Dictionary with the test parameters.
    :param env: Dictionary with test environment.
    """
    @error.context_aware
    def do_file_copy(src_file, guest_file, dst_file, transfer_timeout):
        error.context(
            "Transferring file host -> guest,"
            " timeout: %ss" % transfer_timeout, logging.info)
        vm.copy_files_to(src_file, guest_file, timeout=transfer_timeout)
        error.context(
            "Transferring file guest -> host,"
            " timeout: %ss" % transfer_timeout, logging.info)
        vm.copy_files_from(guest_file, dst_file, timeout=transfer_timeout)
        error.context(
            "Compare md5sum between original file and"
            " transferred file", logging.info)

        if (utils.hash_file(src_file, method="md5") != utils.hash_file(
                dst_file, method="md5")):
            raise error.TestFail("File changed after transfer host -> guest "
                                 "and guest -> host")

    login_timeout = int(params.get("login_timeout", 360))
    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    error.context("Login to guest", logging.info)
    session = vm.wait_for_login(timeout=login_timeout)

    dir_name = data_dir.get_tmp_dir()
    tmp_dir = params.get("tmp_dir", "/var/tmp/")
    clean_cmd = params.get("clean_cmd", "rm -f")
    scp_sessions = int(params.get("scp_para_sessions", 1))
    filesize = float(params.get("filesize", 4000))
    transfer_timeout = float(params.get("transfer_timeout", 600))

    src_path = []
    dst_path = []
    guest_path = []
    for _ in range(scp_sessions):
        random_file_name = utils_misc.generate_random_string(8)
        src_path.append(os.path.join(dir_name, "h-src-%s" % random_file_name))
        guest_path.append(tmp_dir + "g-tmp-%s" % random_file_name)
        dst_path.append(os.path.join(dir_name, "h-dst-%s" % random_file_name))

    cmd = "dd if=/dev/zero of=%s bs=1M count=%d"
    try:
        for src_file in src_path:
            error.context("Create %dMB file on host" % filesize, logging.info)
            utils.run(cmd % (src_file, filesize))

        stress_timeout = float(params.get("stress_timeout", "3600"))

        error.context("Do file transfer between host and guest", logging.info)
        start_time = time.time()
        stop_time = start_time + stress_timeout
        # here when set a run flag, when other case call this case as a
        # subprocess backgroundly, can set this run flag to False to stop
        # the stress test.
        env["file_transfer_run"] = True
        while (env["file_transfer_run"] and time.time() < stop_time):
            scp_threads = []
            for index in range(scp_sessions):
                scp_threads.append(
                    (do_file_copy, (src_path[index], guest_path[index],
                                    dst_path[index], transfer_timeout)))
            utils_misc.parallel(scp_threads)

    finally:
        env["file_transfer_run"] = False
        logging.info('Cleaning temp file on host and guest')
        for del_file in guest_path:
            session.cmd("%s %s" % (clean_cmd, del_file),
                        ignore_all_errors=True)
        for del_file in src_path + dst_path:
            utils.system("%s %s" % (clean_cmd, del_file), ignore_status=True)

        if session:
            session.close()
Пример #32
0
    def check_ipt_rules(check_ipv4=True, check_ipv6=False):
        """
        Check iptables for network/interface
        """
        br_name = ast.literal_eval(net_bridge)["name"]
        net_forward = ast.literal_eval(params.get("net_forward", "{}"))
        net_ipv4 = params.get("net_ipv4")
        net_ipv6 = params.get("net_ipv6")
        ipt_rules = ("FORWARD -i {0} -o {0} -j ACCEPT".format(br_name),
                     "FORWARD -o %s -j REJECT --reject-with icmp" % br_name,
                     "FORWARD -i %s -j REJECT --reject-with icmp" % br_name)
        net_dev_in = ""
        net_dev_out = ""
        if net_forward.has_key("dev"):
            net_dev_in = " -i %s" % net_forward["dev"]
            net_dev_out = " -o %s" % net_forward["dev"]
        if check_ipv4:
            ipv4_rules = list(ipt_rules)
            ctr_rule = ""
            nat_rules = []
            if net_forward.has_key("mode") and net_forward["mode"] == "nat":
                nat_port = ast.literal_eval(params.get("nat_port"))
                p_start = nat_port["start"]
                p_end = nat_port["end"]
                ctr_rule = " -m .* RELATED,ESTABLISHED"
                nat_rules = [
                    ("POSTROUTING -s {0} ! -d {0} -p tcp -j MASQUERADE"
                     " --to-ports {1}-{2}".format(net_ipv4, p_start, p_end)),
                    ("POSTROUTING -s {0} ! -d {0} -p udp -j MASQUERADE"
                     " --to-ports {1}-{2}".format(net_ipv4, p_start, p_end)),
                    ("POSTROUTING -s {0} ! -d {0} -p udp"
                     " -j MASQUERADE".format(net_ipv4))
                ]
            if nat_rules:
                ipv4_rules.extend(nat_rules)
            if (net_ipv4 and net_forward.has_key("mode")
                    and net_forward["mode"] in ["nat", "route"]):
                rules = [("FORWARD -d %s%s -o %s%s -j ACCEPT" %
                          (net_ipv4, net_dev_in, br_name, ctr_rule)),
                         ("FORWARD -s %s -i %s%s -j ACCEPT" %
                          (net_ipv4, br_name, net_dev_out))]
                ipv4_rules.extend(rules)

            output = utils.run("iptables-save").stdout.strip()
            logging.debug("iptables: %s", output)
            for ipt in ipv4_rules:
                if not re.findall(r"%s" % ipt, output, re.M):
                    raise error.TestFail("Can't find iptable rule:\n%s" % ipt)
        if check_ipv6:
            ipv6_rules = list(ipt_rules)
            if (net_ipv6 and net_forward.has_key("mode")
                    and net_forward["mode"] in ["nat", "route"]):
                rules = [("FORWARD -d %s%s -o %s -j ACCEPT" %
                          (net_ipv6, net_dev_in, br_name)),
                         ("FORWARD -s %s -i %s%s -j ACCEPT" %
                          (net_ipv6, br_name, net_dev_out))]
                ipv6_rules.extend(rules)
            output = utils.run("ip6tables-save").stdout.strip()
            logging.debug("iptables: %s", output)
            for ipt in ipv6_rules:
                if not output.count(ipt):
                    raise error.TestFail("Can't find ipbtable rule:\n%s" % ipt)
    def netload_kill_problem(session_serial):
        netperf_dir = os.path.join(os.environ['AUTODIR'], "tests/netperf2")
        setup_cmd = params.get("setup_cmd")
        clean_cmd = params.get("clean_cmd")
        firewall_flush = "iptables -F"

        try:
            utils.run(firewall_flush)
        except Exception:
            logging.warning("Could not flush firewall rules on host")

        try:
            session_serial.cmd(firewall_flush)
        except aexpect.ShellError:
            logging.warning("Could not flush firewall rules on guest")

        for i in params.get("netperf_files").split():
            vm.copy_files_to(os.path.join(netperf_dir, i), "/tmp")

        guest_ip = vm.get_address(0)
        server_ip = get_corespond_ip(guest_ip)

        logging.info("Setup and run netperf on host and guest")
        session_serial.cmd(setup_cmd % "/tmp", timeout=200)
        utils.run(setup_cmd % netperf_dir)

        try:
            session_serial.cmd(clean_cmd)
        except Exception:
            pass
        session_serial.cmd(params.get("netserver_cmd") % "/tmp")

        utils.run(clean_cmd, ignore_status=True)
        utils.run(params.get("netserver_cmd") % netperf_dir)

        server_netperf_cmd = params.get("netperf_cmd") % (
            netperf_dir, "TCP_STREAM", guest_ip,
            params.get("packet_size", "1500"))
        guest_netperf_cmd = params.get("netperf_cmd") % (
            "/tmp", "TCP_STREAM", server_ip, params.get("packet_size", "1500"))

        tcpdump = env.get("tcpdump")
        pid = None
        if tcpdump:
            # Stop the background tcpdump process
            try:
                pid = int(utils.system_output("pidof tcpdump"))
                logging.debug("Stopping the background tcpdump")
                os.kill(pid, signal.SIGSTOP)
            except Exception:
                pass

        try:
            logging.info("Start heavy network load host <=> guest.")
            session_serial.sendline(guest_netperf_cmd)
            utils.BgJob(server_netperf_cmd)

            # Wait for create big network usage.
            time.sleep(10)
            kill_and_check(vm)

        finally:
            utils.run(clean_cmd, ignore_status=True)
            if tcpdump and pid:
                logging.debug("Resuming the background tcpdump")
                logging.info("pid is %s" % pid)
                os.kill(pid, signal.SIGCONT)
Пример #34
0
    def create(self, params, ignore_errors=False):
        """
        Create an image using qemu_img or dd.

        @param params: Dictionary containing the test parameters.
        @param ignore_errors: Whether to ignore errors on the image creation
                cmd.

        @note: params should contain:
               image_name -- the name of the image file, without extension
               image_format -- the format of the image (qcow2, raw etc)
               image_cluster_size (optional) -- the cluster size for the image
               image_size -- the requested size of the image (a string
                   qemu-img can understand, such as '10G')
               create_with_dd -- use dd to create the image (raw format only)
               base_image(optional) -- the base image name when create
                   snapshot
               base_format(optional) -- the format of base image
               encrypted(optional) -- if the image is encrypted, allowed
               values: on and off. Default is "off"
               preallocated(optional) -- if preallocation when create image,
               allowed values: off, metadata. Default is "off"

        @return: tuple (path to the image created, utils.CmdResult object
                containing the result of the creation command).
        """
        if params.get(
                "create_with_dd") == "yes" and self.image_format == "raw":
            # maps K,M,G,T => (count, bs)
            human = {
                'K': (1, 1),
                'M': (1, 1024),
                'G': (1024, 1024),
                'T': (1024, 1048576),
            }
            if human.has_key(self.size[-1]):
                block_size = human[self.size[-1]][1]
                size = int(self.size[:-1]) * human[self.size[-1]][0]
            qemu_img_cmd = ("dd if=/dev/zero of=%s count=%s bs=%sK" %
                            (self.image_filename, size, block_size))
        else:
            qemu_img_cmd = self.image_cmd
            qemu_img_cmd += " create"

            qemu_img_cmd += " -f %s" % self.image_format

            image_cluster_size = params.get("image_cluster_size", None)
            preallocated = params.get("preallocated", "off")
            encrypted = params.get("encrypted", "off")
            image_extra_params = params.get("image_extra_params", "")

            qemu_img_cmd += " -o "
            if preallocated != "off":
                qemu_img_cmd += "preallocation=%s," % preallocated

            if encrypted != "off":
                qemu_img_cmd += "encrypted=%s," % encrypted

            if image_cluster_size is not None:
                qemu_img_cmd += "cluster_size=%s," % image_cluster_size

            if image_extra_params:
                qemu_img_cmd += "%s," % image_extra_params
            qemu_img_cmd = qemu_img_cmd.rstrip(" -o")
            qemu_img_cmd = qemu_img_cmd.rstrip(",")

            if self.base_tag:
                qemu_img_cmd += " -b %s" % self.base_image_filename
                if self.base_format:
                    qemu_img_cmd += " -F %s" % self.base_format

            qemu_img_cmd += " %s" % self.image_filename

            qemu_img_cmd += " %s" % self.size

        image_dirname = os.path.dirname(self.image_filename)
        if not os.path.isdir(image_dirname):
            e_msg = ("Parent directory of the image file %s does "
                     "not exist" % self.image_filename)
            logging.error(e_msg)
            logging.error("This usually means a serious setup error.")
            logging.error("Please verify if your data dir contains the "
                          "expected directory structure")
            logging.error("Backing data dir: %s",
                          data_dir.get_backing_data_dir())
            logging.error("Directory structure:")
            for root, _, _ in os.walk(data_dir.get_backing_data_dir()):
                logging.error(root)

            logging.warning("We'll try to proceed by creating the dir. "
                            "Other errors may ensue")
            os.makedirs(image_dirname)

        msg = "Create image by command: %s" % qemu_img_cmd
        error.context(msg, logging.info)
        cmd_result = utils.run(qemu_img_cmd, verbose=False, ignore_status=True)
        if cmd_result.exit_status != 0 and not ignore_errors:
            raise error.TestError("Failed to create image %s" %
                                  self.image_filename)

        return self.image_filename, cmd_result
Пример #35
0
    def check_image(self, params, root_dir):
        """
        Check an image using the appropriate tools for each virt backend.

        @param params: Dictionary containing the test parameters.
        @param root_dir: Base directory for relative filenames.

        @note: params should contain:
               image_name -- the name of the image file, without extension
               image_format -- the format of the image (qcow2, raw etc)

        @raise VMImageCheckError: In case qemu-img check fails on the image.
        """
        image_filename = self.image_filename
        logging.debug("Checking image file %s", image_filename)
        qemu_img_cmd = self.image_cmd
        image_is_qcow2 = self.image_format == 'qcow2'
        if os.path.exists(image_filename) and image_is_qcow2:
            # Verifying if qemu-img supports 'check'
            q_result = utils.run(qemu_img_cmd,
                                 ignore_status=True,
                                 verbose=False)
            q_output = q_result.stdout
            check_img = True
            if not "check" in q_output:
                logging.error("qemu-img does not support 'check', "
                              "skipping check")
                check_img = False
            if not "info" in q_output:
                logging.error("qemu-img does not support 'info', "
                              "skipping check")
                check_img = False
            if check_img:
                try:
                    utils.run("%s info %s" % (qemu_img_cmd, image_filename),
                              verbose=False)
                except error.CmdError:
                    logging.error("Error getting info from image %s",
                                  image_filename)

                cmd_result = utils.run("%s check %s" %
                                       (qemu_img_cmd, image_filename),
                                       ignore_status=True,
                                       verbose=False)
                # Error check, large chances of a non-fatal problem.
                # There are chances that bad data was skipped though
                if cmd_result.exit_status == 1:
                    for e_line in cmd_result.stdout.splitlines():
                        logging.error("[stdout] %s", e_line)
                    for e_line in cmd_result.stderr.splitlines():
                        logging.error("[stderr] %s", e_line)
                    chk = params.get("backup_image_on_check_error", "no")
                    if chk == "yes":
                        self.backup_image(params, root_dir, "backup", False)
                    raise error.TestWarn("qemu-img check error. Some bad "
                                         "data in the image may have gone"
                                         " unnoticed")
                # Exit status 2 is data corruption for sure,
                # so fail the test
                elif cmd_result.exit_status == 2:
                    for e_line in cmd_result.stdout.splitlines():
                        logging.error("[stdout] %s", e_line)
                    for e_line in cmd_result.stderr.splitlines():
                        logging.error("[stderr] %s", e_line)
                    chk = params.get("backup_image_on_check_error", "no")
                    if chk == "yes":
                        self.backup_image(params, root_dir, "backup", False)
                    raise virt_vm.VMImageCheckError(image_filename)
                # Leaked clusters, they are known to be harmless to data
                # integrity
                elif cmd_result.exit_status == 3:
                    raise error.TestWarn("Leaked clusters were noticed"
                                         " during image check. No data "
                                         "integrity problem was found "
                                         "though.")

                # Just handle normal operation
                if params.get("backup_image", "no") == "yes":
                    self.backup_image(params, root_dir, "backup", True)
        else:
            if not os.path.exists(image_filename):
                logging.debug("Image file %s not found, skipping check",
                              image_filename)
            elif not image_is_qcow2:
                logging.debug("Image file %s not qcow2, skipping check",
                              image_filename)
 def wait_func():
     return not utils.run(
         "service libvirt-guests status"
         " | grep 'Resuming guest'",
         ignore_status=True).exit_status
            libvirtd.stop()
        if autostart_bypass_cache:
            ret = virsh.autostart(vm_name, "", ignore_status=True)
            libvirt.check_exit_status(ret)
            qemu_config.auto_start_bypass_cache = autostart_bypass_cache
            libvirtd.restart()
        if security_driver:
            qemu_config.security_driver = [security_driver]
        if test_libvirt_guests:
            if multi_guests:
                start_delay = params.get("start_delay", "20")
                libvirt_guests_config.START_DELAY = start_delay
            if check_flags:
                libvirt_guests_config.BYPASS_CACHE = "1"
            # The config file format should be "x=y" instead of "x = y"
            utils.run("sed -i -e 's/ = /=/g' " "/etc/sysconfig/libvirt-guests")
            libvirt_guests.restart()

        # Change domain xml.
        if cpu_mode:
            build_vm_xml(vm_name, cpu_mode=True)
        if security_driver:
            build_vm_xml(vm_name, sec_driver=True)

        # Turn VM into certain state.
        if pre_vm_state == "transient":
            logging.info("Creating %s..." % vm_name)
            vmxml_for_test = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name)
            if vm.is_alive():
                vm.destroy(gracefully=False)
            vm.undefine()
Пример #38
0
        logging.debug("Readonly mode test")

    # Run virsh cmd
    try:
        cmd_result = virsh.find_storage_pool_sources(source_type,
                                                     srcSpec.name,
                                                     ignore_status=True,
                                                     debug=True,
                                                     readonly=ro_flag)
        output = cmd_result.stdout.strip()
        err = cmd_result.stderr.strip()
        status = cmd_result.exit_status
        if not status_error:
            if status:
                raise error.TestFail(err)
            else:
                logging.debug("Command output:\n%s", output)
        elif status_error and status == 0:
            raise error.TestFail("Expect fail, but run successfully")
    finally:
        # Clean up
        if cleanup_logical:
            cmd = "pvs |grep %s |awk '{print $1}'" % vg_name
            pv_name = utils.system_output(cmd)
            lv_utils.vg_remove(vg_name)
            utils.run("pvremove %s" % pv_name)
        if cleanup_iscsi:
            utils_test.libvirt.setup_or_cleanup_iscsi(False)
        if cleanup_nfs:
            utils_test.libvirt.setup_or_cleanup_nfs(False)
Пример #39
0
 def stop_service(self):
     """
     Stops the NFS server.
     """
     utils.run(self.stop_cmd)
Пример #40
0
    def run_once(self):
        """
        Run each benchmark twice, with different number of threads.

        A sanity check is made on each benchmark executed:
        The ratio between the times
        time_ratio = time_one_thrd / time_full_thrds

        Has to be contained inside an envelope:
        upper_bound = full_thrds * (1 + (1/n_cpus))
        lower_bound = full_thrds * (1 - (1/n_cpus))

        Otherwise, we throw an exception (this test might be running under a
        virtual machine and sanity check failure might mean bugs on smp
        implementation).
        """
        os.chdir(self.srcdir)

        # get the tests to run
        test_list = self.tests.split()

        if len(test_list) == 0:
            raise error.TestError('No tests (benchmarks) provided. Exit.')

        for itest in test_list:
            itest_cmd = os.path.join('NPB3.3-OMP/bin/', itest)
            try:
                itest = utils.run(itest_cmd)
            except Exception, e:
                logging.error('NPB benchmark %s has failed. Output: %s',
                              itest_cmd, e)
                self.n_fail += 1
                continue
            logging.debug(itest.stdout)

            # Get the number of threads that the test ran
            # (which is supposed to be equal to the number of system cores)
            m = re.search('Total threads\s*=\s*(.*)\n', itest.stdout)

            # Gather benchmark results
            ts = re.search('Time in seconds\s*=\s*(.*)\n', itest.stdout)
            mt = re.search('Mop/s total\s*=\s*(.*)\n', itest.stdout)
            mp = re.search('Mop/s/thread\s*=\s*(.*)\n', itest.stdout)

            time_seconds = float(ts.groups()[0])
            mops_total = float(mt.groups()[0])
            mops_per_thread = float(mp.groups()[0])

            logging.info('Test: %s', itest_cmd)
            logging.info('Time (s): %s', time_seconds)
            logging.info('Total operations executed (mops/s): %s', mops_total)
            logging.info('Total operations per thread (mops/s/thread): %s',
                         mops_per_thread)

            self.write_test_keyval({'test': itest_cmd})
            self.write_test_keyval({'time_seconds': time_seconds})
            self.write_test_keyval({'mops_total': mops_total})
            self.write_test_keyval({'mops_per_thread': mops_per_thread})

            # A little extra sanity check comes handy
            if int(m.groups()[0]) != utils.count_cpus():
                raise error.TestError("NPB test suite evaluated the number "
                                      "of threads incorrectly: System appears "
                                      "to have %s cores, but %s threads were "
                                      "executed.")

            # We will use this integer with float point vars later.
            full_thrds = float(m.groups()[0])

            # get duration for full_threads running.
            m = re.search('Time in seconds\s*=\s*(.*)\n', itest.stdout)
            time_full_thrds = float(m.groups()[0])

            # repeat the execution with single thread.
            itest_single_cmd = ''.join(['OMP_NUM_THREADS=1 ', itest_cmd])
            try:
                itest_single = utils.run(itest_single_cmd)
            except Exception, e:
                logging.error(
                    'NPB benchmark single thread %s has failed. '
                    'Output: %s', itest_single_cmd, e)
                self.n_fail += 1
                continue
Пример #41
0
 def cleanup(self, force_stop=False):
     error.context("Cleaning up test NFS share")
     utils.run("umount %s" % self.mnt_dir)
     utils.run("exportfs -u localhost:%s" % self.nfs_dir)
     if force_stop:
         self.stop_service()
Пример #42
0
 def start_service(self):
     """
     Starts the NFS server.
     """
     utils.run(self.start_cmd)
Пример #43
0
def run(test, params, env):
    """
    Start, restart, reload and stop libvirt daemon with all possible
    init scripts.
    """
    def service_avail(cmd):
        """
        Check the availability of three init services.

        :param cmd: service name. Can be initctl, systemctl or initscripts
        :return: True if init system avaiable or False if not.
        """
        if cmd in ['initctl', 'systemctl']:
            try:
                os_dep.command(cmd)
                return True
            except ValueError:
                return False
        elif cmd == 'initscripts':
            return os.path.exists('/etc/rc.d/init.d/libvirtd')

    def service_check(cmd):
        """
        Check the availability of libvirtd init scripts.

        :param cmd: service name. Can be initctl, systemctl or initscripts
        """
        if cmd == 'systemctl':
            res = utils.run('systemctl list-unit-files')
            for ufile in [
                    "libvirt-guests.service", "libvirtd.service",
                    "libvirtd.socket"
            ]:
                if ufile not in res.stdout:
                    raise error.TestFail('Missing systemd unit file %s' %
                                         ufile)
        elif cmd == 'initctl':
            script = glob.glob('/usr/share/doc/*/libvirtd.upstart')
            if not script:
                raise error.TestFail('Cannot find libvirtd.upstart script')
            if not os.path.exists('/etc/init/libvirtd.conf'):
                shutil.copyfile(script[0], '/etc/init/libvirtd.conf')

    def service_call(cmd, action, expected_exit_code=0, user=None):
        """
        Call a specific action using different init system and check
        the exit code against expectation.

        :param cmd: service name. Can be initctl, systemctl or initscripts
        :param action: action name. Such as start, stop or restart
        :param expected_exit_code: Expected return code of the command
        :param user: username service call to run as. None if run as root
        :return: CmdResult instance
        """
        logging.debug("%s libvirtd using %s" % (action, cmd))
        if cmd in ['initctl', 'systemctl']:
            cmdline = "%s %s libvirtd" % (cmd, action)
        elif cmd == 'initscripts':
            cmdline = "/etc/rc.d/init.d/libvirtd %s" % action

        if user:
            cmdline = 'su - %s -c "%s"' % (user, cmdline)

        res = utils.run(cmdline, ignore_status=True)
        logging.debug(res)

        if res.exit_status != expected_exit_code:
            raise error.TestFail("Expected exit status is %s, but got %s." %
                                 (expected_exit_code, res.exit_status))
        return res

    commands = ['initctl', 'initscripts', 'systemctl']
    avail_commands = []
    for command in commands:
        if service_avail(command):
            avail_commands.append(command)
    logging.debug("Available commands: %s" % avail_commands)

    libvirtd = utils_libvirtd.Libvirtd()
    libvirtd.stop()

    username = '******'
    utils.run('useradd %s' % username, ignore_status=True)
    try:
        for command in avail_commands:
            if command == 'systemctl':
                service_call(command,
                             'start',
                             user=username,
                             expected_exit_code=4)
            service_call(command, 'start')
            service_call(command, 'status')

            if command == 'systemctl':
                service_call(command,
                             'reload',
                             user=username,
                             expected_exit_code=4)
            service_call(command, 'reload')
            service_call(command, 'status')

            if command == 'systemctl':
                service_call(command,
                             'restart',
                             user=username,
                             expected_exit_code=4)
            service_call(command, 'restart')
            service_call(command, 'status')

            if command == 'systemctl':
                service_call(command,
                             'stop',
                             user=username,
                             expected_exit_code=4)
            service_call(command, 'stop')
            if command == 'initctl':
                service_call(command, 'status')
            else:
                service_call(command, 'status', expected_exit_code=3)
    finally:
        utils.run('userdel -r virt-test', ignore_status=True)
        libvirtd.restart()
Пример #44
0
 def restart_service(self):
     """
     Restarts the NFS server.
     """
     utils.run(self.restart_cmd)
Пример #45
0
def local_runner(cmd, timeout=None):
    return utils.run(cmd, verbose=False, timeout=timeout).stdout
Пример #46
0
def local_runner_status(cmd, timeout=None):
    return utils.run(cmd, verbose=False, timeout=timeout).exit_status
Пример #47
0
def run(test, params, env):
    """
    Test snapshot-create-as command
    Make sure that the clean repo can be used because qemu-guest-agent need to
    be installed in guest

    The command create a snapshot (disk and RAM) from arguments which including
    the following point
    * virsh snapshot-create-as --print-xml --diskspec --name --description
    * virsh snapshot-create-as --print-xml with multi --diskspec
    * virsh snapshot-create-as --print-xml --memspec
    * virsh snapshot-create-as --description
    * virsh snapshot-create-as --no-metadata
    * virsh snapshot-create-as --no-metadata --print-xml (negative test)
    * virsh snapshot-create-as --atomic --disk-only
    * virsh snapshot-create-as --quiesce --disk-only (positive and negative)
    * virsh snapshot-create-as --reuse-external
    * virsh snapshot-create-as --disk-only --diskspec
    * virsh snapshot-create-as --memspec --reuse-external --atomic(negative)
    * virsh snapshot-create-as --disk-only and --memspec (negative)
    * Create multi snapshots with snapshot-create-as
    * Create snapshot with name a--a a--a--snap1
    """

    if not virsh.has_help_command('snapshot-create-as'):
        raise error.TestNAError("This version of libvirt does not support "
                                "the snapshot-create-as test")

    vm_name = params.get("main_vm")
    status_error = params.get("status_error", "no")
    options = params.get("snap_createas_opts")
    multi_num = params.get("multi_num", "1")
    diskspec_num = params.get("diskspec_num", "1")
    bad_disk = params.get("bad_disk")
    reuse_external = "yes" == params.get("reuse_external", "no")
    start_ga = params.get("start_ga", "yes")
    domain_state = params.get("domain_state")
    memspec_opts = params.get("memspec_opts")
    config_format = "yes" == params.get("config_format", "no")
    snapshot_image_format = params.get("snapshot_image_format")
    diskspec_opts = params.get("diskspec_opts")
    create_autodestroy = 'yes' == params.get("create_autodestroy", "no")
    unix_channel = "yes" == params.get("unix_channel", "yes")
    dac_denial = "yes" == params.get("dac_denial", "no")
    check_json_no_savevm = "yes" == params.get("check_json_no_savevm", "no")
    disk_snapshot_attr = params.get('disk_snapshot_attr', 'external')
    set_snapshot_attr = "yes" == params.get("set_snapshot_attr", "no")

    # gluster related params
    replace_vm_disk = "yes" == params.get("replace_vm_disk", "no")
    disk_src_protocol = params.get("disk_source_protocol")
    restart_tgtd = params.get("restart_tgtd", "no")
    vol_name = params.get("vol_name")
    tmp_dir = data_dir.get_tmp_dir()
    pool_name = params.get("pool_name", "gluster-pool")
    brick_path = os.path.join(tmp_dir, pool_name)

    uri = params.get("virsh_uri")
    usr = params.get('unprivileged_user')
    if usr:
        if usr.count('EXAMPLE'):
            usr = '******'

    if disk_src_protocol == 'iscsi':
        if not libvirt_version.version_compare(1, 0, 4):
            raise error.TestNAError("'iscsi' disk doesn't support in"
                                    " current libvirt version.")

    if not libvirt_version.version_compare(1, 1, 1):
        if params.get('setup_libvirt_polkit') == 'yes':
            raise error.TestNAError("API acl test not supported in current"
                                    " libvirt version.")

    if not libvirt_version.version_compare(1, 2, 7):
        # As bug 1017289 closed as WONTFIX, the support only
        # exist on 1.2.7 and higher
        if disk_src_protocol == 'gluster':
            raise error.TestNAError("Snapshot on glusterfs not support in "
                                    "current version. Check more info with "
                                    "https://bugzilla.redhat.com/buglist.cgi?"
                                    "bug_id=1017289,1032370")

    opt_names = locals()
    if memspec_opts is not None:
        mem_options = compose_disk_options(test, params, memspec_opts)
        # if the parameters have the disk without "file=" then we only need to
        # add testdir for it.
        if mem_options is None:
            mem_options = os.path.join(test.tmpdir, memspec_opts)
        options += " --memspec " + mem_options

    tag_diskspec = 0
    dnum = int(diskspec_num)
    if diskspec_opts is not None:
        tag_diskspec = 1
        opt_names['diskopts_1'] = diskspec_opts

    # diskspec_opts[n] is used in cfg when more than 1 --diskspec is used
    if dnum > 1:
        tag_diskspec = 1
        for i in range(1, dnum + 1):
            opt_names["diskopts_%s" % i] = params.get("diskspec_opts%s" % i)

    if tag_diskspec == 1:
        for i in range(1, dnum + 1):
            disk_options = compose_disk_options(test, params,
                                                opt_names["diskopts_%s" % i])
            options += " --diskspec " + disk_options

    logging.debug("options are %s", options)

    vm = env.get_vm(vm_name)
    option_dict = {}
    option_dict = utils_misc.valued_option_dict(options, r' --(?!-)')
    logging.debug("option_dict is %s", option_dict)

    # A backup of original vm
    vmxml_backup = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name)
    logging.debug("original xml is %s", vmxml_backup)

    # Generate empty image for negative test
    if bad_disk is not None:
        bad_disk = os.path.join(test.tmpdir, bad_disk)
        os.open(bad_disk, os.O_RDWR | os.O_CREAT)

    # Generate external disk
    if reuse_external:
        disk_path = ''
        for i in range(dnum):
            external_disk = "external_disk%s" % i
            if params.get(external_disk):
                disk_path = os.path.join(test.tmpdir,
                                         params.get(external_disk))
                utils.run("qemu-img create -f qcow2 %s 1G" % disk_path)
        # Only chmod of the last external disk for negative case
        if dac_denial:
            utils.run("chmod 500 %s" % disk_path)

    qemu_conf = None
    libvirtd_conf = None
    libvirtd_log_path = None
    libvirtd = utils_libvirtd.Libvirtd()
    try:
        # Config "snapshot_image_format" option in qemu.conf
        if config_format:
            qemu_conf = utils_config.LibvirtQemuConfig()
            qemu_conf.snapshot_image_format = snapshot_image_format
            logging.debug("the qemu config file content is:\n %s" % qemu_conf)
            libvirtd.restart()

        if check_json_no_savevm:
            libvirtd_conf = utils_config.LibvirtdConfig()
            libvirtd_conf["log_level"] = '1'
            libvirtd_conf["log_filters"] = '"1:json 3:remote 4:event"'
            libvirtd_log_path = os.path.join(test.tmpdir, "libvirtd.log")
            libvirtd_conf["log_outputs"] = '"1:file:%s"' % libvirtd_log_path
            logging.debug("the libvirtd config file content is:\n %s" %
                          libvirtd_conf)
            libvirtd.restart()

        if replace_vm_disk:
            libvirt.set_vm_disk(vm, params, tmp_dir)

        if set_snapshot_attr:
            if vm.is_alive():
                vm.destroy(gracefully=False)
            vmxml_new = vm_xml.VMXML.new_from_dumpxml(vm_name)
            disk_xml = vmxml_backup.get_devices(device_type="disk")[0]
            vmxml_new.del_device(disk_xml)
            # set snapshot attribute in disk xml
            disk_xml.snapshot = disk_snapshot_attr
            new_disk = disk.Disk(type_name='file')
            new_disk.xmltreefile = disk_xml.xmltreefile
            vmxml_new.add_device(new_disk)
            logging.debug("The vm xml now is: %s" % vmxml_new.xmltreefile)
            vmxml_new.sync()
            vm.start()

        # Start qemu-ga on guest if have --quiesce
        if unix_channel and options.find("quiesce") >= 0:
            vm.prepare_guest_agent()
            session = vm.wait_for_login()
            if start_ga == "no":
                # The qemu-ga could be running and should be killed
                session.cmd("kill -9 `pidof qemu-ga`")
                # Check if the qemu-ga get killed
                stat_ps = session.cmd_status("ps aux |grep [q]emu-ga")
                if not stat_ps:
                    # As managed by systemd and set as autostart, qemu-ga
                    # could be restarted, so use systemctl to stop it.
                    session.cmd("systemctl stop qemu-guest-agent")
                    stat_ps = session.cmd_status("ps aux |grep [q]emu-ga")
                    if not stat_ps:
                        raise error.TestNAError("Fail to stop agent in "
                                                "guest")

            if domain_state == "paused":
                virsh.suspend(vm_name)
        else:
            # Remove channel if exist
            if vm.is_alive():
                vm.destroy(gracefully=False)
            xml_inst = vm_xml.VMXML.new_from_dumpxml(vm_name)
            xml_inst.remove_agent_channels()
            vm.start()

        # Record the previous snapshot-list
        snaps_before = virsh.snapshot_list(vm_name)

        # Attach disk before create snapshot if not print xml and multi disks
        # specified in cfg
        if dnum > 1 and "--print-xml" not in options:
            for i in range(1, dnum):
                disk_path = os.path.join(test.tmpdir, 'disk%s.qcow2' % i)
                utils.run("qemu-img create -f qcow2 %s 200M" % disk_path)
                virsh.attach_disk(vm_name, disk_path,
                                  'vd%s' % list(string.lowercase)[i],
                                  debug=True)

        # Run virsh command
        # May create several snapshots, according to configuration
        for count in range(int(multi_num)):
            if create_autodestroy:
                # Run virsh command in interactive mode
                vmxml_backup.undefine()
                vp = virsh.VirshPersistent()
                vp.create(vmxml_backup['xml'], '--autodestroy')
                cmd_result = vp.snapshot_create_as(vm_name, options,
                                                   ignore_status=True,
                                                   debug=True)
                vp.close_session()
                vmxml_backup.define()
            else:
                cmd_result = virsh.snapshot_create_as(vm_name, options,
                                                      unprivileged_user=usr,
                                                      uri=uri,
                                                      ignore_status=True,
                                                      debug=True)
                # for multi snapshots without specific snapshot name, the
                # snapshot name is using time string with 1 second
                # incremental, to avoid get snapshot failure with same name,
                # sleep 1 second here.
                if int(multi_num) > 1:
                    time.sleep(1.1)
            output = cmd_result.stdout.strip()
            status = cmd_result.exit_status

            # check status_error
            if status_error == "yes":
                if status == 0:
                    raise error.TestFail("Run successfully with wrong command!")
                else:
                    # Check memspec file should be removed if failed
                    if (options.find("memspec") >= 0 and
                            options.find("atomic") >= 0):
                        if os.path.isfile(option_dict['memspec']):
                            os.remove(option_dict['memspec'])
                            raise error.TestFail("Run failed but file %s exist"
                                                 % option_dict['memspec'])
                        else:
                            logging.info("Run failed as expected and memspec"
                                         " file already been removed")
                    # Check domain xml is not updated if reuse external fail
                    elif reuse_external and dac_denial:
                        output = virsh.dumpxml(vm_name).stdout.strip()
                        if "reuse_external" in output:
                            raise error.TestFail("Domain xml should not be "
                                                 "updated with snapshot image")
                    else:
                        logging.info("Run failed as expected")

            elif status_error == "no":
                if status != 0:
                    raise error.TestFail("Run failed with right command: %s"
                                         % output)
                else:
                    # Check the special options
                    snaps_list = virsh.snapshot_list(vm_name)
                    logging.debug("snaps_list is %s", snaps_list)

                    check_snapslist(vm_name, options, option_dict, output,
                                    snaps_before, snaps_list)

                    # For cover bug 872292
                    if check_json_no_savevm:
                        pattern = "The command savevm has not been found"
                        with open(libvirtd_log_path) as f:
                            for line in f:
                                if pattern in line and "error" in line:
                                    raise error.TestFail("'%s' was found: %s"
                                                         % (pattern, line))

    finally:
        if vm.is_alive():
            vm.destroy()
        # recover domain xml
        xml_recover(vmxml_backup)
        path = "/var/lib/libvirt/qemu/snapshot/" + vm_name
        if os.path.isfile(path):
            raise error.TestFail("Still can find snapshot metadata")

        if disk_src_protocol == 'gluster':
            libvirt.setup_or_cleanup_gluster(False, vol_name, brick_path)
            libvirtd.restart()

        if disk_src_protocol == 'iscsi':
            libvirt.setup_or_cleanup_iscsi(False, restart_tgtd=restart_tgtd)

        # rm bad disks
        if bad_disk is not None:
            os.remove(bad_disk)
        # rm attach disks and reuse external disks
        if dnum > 1 and "--print-xml" not in options:
            for i in range(dnum):
                disk_path = os.path.join(test.tmpdir, 'disk%s.qcow2' % i)
                if os.path.exists(disk_path):
                    os.unlink(disk_path)
                if reuse_external:
                    external_disk = "external_disk%s" % i
                    disk_path = os.path.join(test.tmpdir,
                                             params.get(external_disk))
                    if os.path.exists(disk_path):
                        os.unlink(disk_path)

        # restore config
        if config_format and qemu_conf:
            qemu_conf.restore()

        if libvirtd_conf:
            libvirtd_conf.restore()

        if libvirtd_conf or (config_format and qemu_conf):
            libvirtd.restart()

        if libvirtd_log_path and os.path.exists(libvirtd_log_path):
            os.unlink(libvirtd_log_path)
Пример #48
0
 cellno = params.get("freepages_cellno")
 cellno_list = []
 get_node_num = "numactl -H|awk '/available:/ {print $2}'"
 host_cells = utils.run(get_node_num).stdout.strip()
 try:
     host_cells = int(host_cells)
 except (TypeError, ValueError), e:
     raise error.TestError("Fail to get host nodes number: %s" % e)
 if cellno == "AUTO":
     cellno_list = range(0, host_cells)
 elif cellno == "OUT_OF_RANGE":
     cellno_list.append(host_cells)
 else:
     cellno_list.append(cellno)
 pagesize = params.get("freepages_page_size")
 default_pagesize = utils.run("getconf PAGE_SIZE").stdout.strip()
 try:
     default_pagesize = int(default_pagesize) / 1024
 except (TypeError, ValueError), e:
     raise error.TestError("Fail to get default page size: %s" % e)
 default_huge_pagesize = utils_memory.get_huge_page_size()
 pagesize_list = []
 if pagesize == "AUTO":
     pagesize_list.append(default_pagesize)
     pagesize_list.append(default_huge_pagesize)
 else:
     pagesize_list.append(pagesize)
 huge_pages = params.get("huge_pages")
 if huge_pages and not status_error:
     try:
         huge_pages = int(huge_pages)
Пример #49
0
        cmd = ("dd if=/dev/zero of=" + ramdisk_filename +
               " bs=1M count=1 seek=" + vg_size)
        result = utils.run(cmd, verbose=True)

        logging.info("Finding free loop device")
        result = utils.run("losetup --find", verbose=True)
    except error.CmdError, ex:
        logging.error(ex)
        vg_ramdisk_cleanup(ramdisk_filename, vg_ramdisk_dir, vg_name, "")
        raise ex

    loop_device = result.stdout.rstrip()

    try:
        logging.info("Creating loop device")
        result = utils.run("losetup " + loop_device + " " + ramdisk_filename)
        logging.info("Creating physical volume %s", loop_device)
        result = utils.run("pvcreate " + loop_device)
        logging.info("Creating volume group %s", vg_name)
        result = utils.run("vgcreate " + vg_name + " " + loop_device)
    except error.CmdError, ex:
        logging.error(ex)
        vg_ramdisk_cleanup(ramdisk_filename, vg_ramdisk_dir, vg_name,
                           loop_device)
        raise ex

    logging.info(result.stdout.rstrip())


def vg_ramdisk_cleanup(ramdisk_filename, vg_ramdisk_dir, vg_name, loop_device):
    """
Пример #50
0
def run(test, params, env):
    """
    Test domfstrim command, make sure that all supported options work well

    Test scenaries:
    1. fstrim without options
    2. fstrim with --minimum with large options
    3. fstrim with --minimum with small options

    Note: --mountpoint still not supported so will not test here
    """
    def recompose_xml(vm_name, scsi_disk):
        """
        Add scsi disk, guest agent and scsi controller for guest
        :param: vm_name: Name of domain
        :param: scsi_disk: scsi_debug disk name
        """

        vmxml = vm_xml.VMXML.new_from_dumpxml(vm_name)
        disk_path = scsi_disk
        # Add scsi disk xml
        scsi_disk = Disk(type_name="block")
        scsi_disk.device = "lun"
        scsi_disk.source = scsi_disk.new_disk_source(
            **{'attrs': {
                'dev': disk_path
            }})
        scsi_disk.target = {'dev': "sdb", 'bus': "scsi"}
        find_scsi = "no"
        controllers = vmxml.xmltreefile.findall("devices/controller")
        for controller in controllers:
            if controller.get("type") == "scsi":
                find_scsi = "yes"
        vmxml.add_device(scsi_disk)

        # Add scsi disk controller
        if find_scsi == "no":
            scsi_controller = Controller("controller")
            scsi_controller.type = "scsi"
            scsi_controller.index = "0"
            scsi_controller.model = "virtio-scsi"
            vmxml.add_device(scsi_controller)

        # Redefine guest
        vmxml.sync()

    if not virsh.has_help_command('domfstrim'):
        raise error.TestNAError("This version of libvirt does not support "
                                "the domfstrim test")

    try:
        utils_path.find_command("lsscsi")
    except utils_path.CmdNotFoundError:
        raise error.TestNAError("Command 'lsscsi' is missing. You must "
                                "install it.")

    vm_name = params.get("main_vm", "avocado-vt-vm1")
    status_error = ("yes" == params.get("status_error", "no"))
    minimum = params.get("domfstrim_minimum")
    mountpoint = params.get("domfstrim_mountpoint")
    options = params.get("domfstrim_options", "")
    is_fulltrim = ("yes" == params.get("is_fulltrim", "yes"))
    uri = params.get("virsh_uri")
    unprivileged_user = params.get('unprivileged_user')
    has_qemu_ga = not ("yes" == params.get("no_qemu_ga", "no"))
    start_qemu_ga = not ("yes" == params.get("no_start_qemu_ga", "no"))
    if unprivileged_user:
        if unprivileged_user.count('EXAMPLE'):
            unprivileged_user = '******'

    if not libvirt_version.version_compare(1, 1, 1):
        if params.get('setup_libvirt_polkit') == 'yes':
            raise error.TestNAError("API acl test not supported in current"
                                    " libvirt version.")

    # Do backup for origin xml
    xml_backup = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name)
    try:
        vm = env.get_vm(vm_name)
        if not vm.is_alive():
            vm.start()
        session = vm.wait_for_login()
        bef_list = session.cmd_output("fdisk -l|grep ^/dev|"
                                      "cut -d' ' -f1").split("\n")
        session.close()
        vm.destroy()

        # Load module and get scsi disk name
        utils.load_module("scsi_debug lbpu=1 lbpws=1")
        scsi_disk = utils.run("lsscsi|grep scsi_debug|"
                              "awk '{print $6}'").stdout.strip()
        # Create partition
        open("/tmp/fdisk-cmd", "w").write("n\np\n\n\n\nw\n")
        output = utils.run("fdisk %s < /tmp/fdisk-cmd" %
                           scsi_disk).stdout.strip()
        logging.debug("fdisk output %s", output)
        os.remove("/tmp/fdisk-cmd")
        # Format disk
        output = utils.run("mkfs.ext3 %s1" % scsi_disk).stdout.strip()
        logging.debug("output %s", output)
        # Add scsi disk in guest
        recompose_xml(vm_name, scsi_disk)

        # Prepare guest agent and start guest
        if has_qemu_ga:
            vm.prepare_guest_agent(start=start_qemu_ga)
        else:
            # Remove qemu-ga channel
            vm.prepare_guest_agent(channel=has_qemu_ga, start=False)

        guest_session = vm.wait_for_login()
        # Get new generated disk
        af_list = guest_session.cmd_output("fdisk -l|grep ^/dev|"
                                           "cut -d' ' -f1").split('\n')
        new_disk = "".join(list(set(bef_list) ^ set(af_list)))
        # Mount disk in guest
        guest_session.cmd("mkdir -p /home/test && mount %s /home/test" %
                          new_disk)

        # Do first fstrim before all to get original map for compare
        cmd_result = virsh.domfstrim(vm_name)
        if cmd_result.exit_status != 0:
            if not status_error:
                raise error.TestFail("Fail to do virsh domfstrim, error %s" %
                                     cmd_result.stderr)

        def get_diskmap_size():
            """
            Collect size from disk map
            :return: disk size
            """
            map_cmd = "cat /sys/bus/pseudo/drivers/scsi_debug/map"
            diskmap = utils.run(map_cmd).stdout.strip('\n\x00')
            logging.debug("disk map is %s", diskmap)
            sum = 0
            for i in diskmap.split(","):
                sum = sum + int(i.split("-")[1]) - int(i.split("-")[0])
            return sum

        ori_size = get_diskmap_size()

        # Write date in disk
        dd_cmd = "dd if=/dev/zero of=/home/test/file bs=1048576 count=5"
        guest_session.cmd(dd_cmd)

        def _full_mapped():
            """
            Do full map check
            :return: True or False
            """
            full_size = get_diskmap_size()
            return (ori_size < full_size)

        if not utils_misc.wait_for(_full_mapped, timeout=30):
            raise error.TestError("Scsi map is not updated after dd command.")

        full_size = get_diskmap_size()

        # Remove disk content in guest
        guest_session.cmd("rm -rf /home/test/*")
        guest_session.close()

        def _trim_completed():
            """
            Do empty fstrim check
            :return: True of False
            """
            cmd_result = virsh.domfstrim(vm_name,
                                         minimum,
                                         mountpoint,
                                         options,
                                         unprivileged_user=unprivileged_user,
                                         uri=uri)
            if cmd_result.exit_status != 0:
                if not status_error:
                    raise error.TestFail(
                        "Fail to do virsh domfstrim, error %s" %
                        cmd_result.stderr)
                else:
                    logging.info("Fail to do virsh domfstrim as expected: %s",
                                 cmd_result.stderr)
                    return True

            empty_size = get_diskmap_size()

            if is_fulltrim:
                return empty_size <= ori_size
            else:
                # For partly trim will check later
                return False

        if not utils_misc.wait_for(_trim_completed, timeout=30):
            # Get result again to check partly fstrim
            empty_size = get_diskmap_size()
            if not is_fulltrim:
                if ori_size < empty_size <= full_size:
                    logging.info("Success to do fstrim partly")
                    return True
            raise error.TestFail("Fail to do fstrim. (orignal size: %s), "
                                 "(current size: %s), (full size: %s)" %
                                 (ori_size, empty_size, full_size))
        logging.info("Success to do fstrim")

    finally:
        # Do domain recovery
        vm.shutdown()
        xml_backup.sync()
        utils.unload_module("scsi_debug")
Пример #51
0
def run(test, params, env):
    """
    Test suspend commands in qemu guest agent.

    :param test: kvm test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environmen.
    """
    clock_server = params.get("clock_server", "clock.redhat.com")
    ntputil_install = params.get("ntputil_install", "yum install -y ntpdate")
    login_timeout = int(params.get("login_timeout", "240"))
    date_time_command = params.get(
        "date_time_command", r"date -u +'TIME: %a %m/%d/%Y %H:%M:%S.%N'")
    date_time_filter_re = params.get("date_time_filter_re",
                                     r"(?:TIME: \w\w\w )(.{19})(.+)")
    date_time_format = params.get("date_time_format", "%m/%d/%Y %H:%M:%S")

    tolerance = float(params.get("time_diff_tolerance", "0.5"))

    sub_work = params["sub_work"]
    test_type = params["timedrift_sub_work"]

    vm_name = params.get("vms")
    vm = env.get_vm(vm_name)
    error.context("Check if ntp utils are host in system.", logging.info)
    try:
        utils.find_command("ntpdate")
    except ValueError:
        error.context("Install ntp utils `%s`." % (ntputil_install),
                      logging.info)
        utils.run(ntputil_install)
    error.context("Sync host machine with clock server %s" % (clock_server),
                  logging.info)
    utils.run("ntpdate %s" % (clock_server))

    session = vm.wait_for_login(timeout=login_timeout)
    error.context("Get clock from host and guest VM using `date`",
                  logging.info)

    before_date = utils_test.get_time(session, date_time_command,
                                      date_time_filter_re, date_time_format)
    logging.debug("date: host time=%ss guest time=%ss", *before_date)

    session.close()

    if sub_work in globals():  # Try to find sub work function.
        globals()[sub_work](params, vm, session)
    else:
        raise error.TestNAError("Unable to found subwork %s in %s test file." %
                                (sub_work, __file__))

    vm = env.get_vm(vm_name)
    session = vm.wait_for_login(timeout=login_timeout)
    error.context("Get clock from host and guest VM using `date`",
                  logging.info)
    after_date = utils_test.get_time(session, date_time_command,
                                     date_time_filter_re, date_time_format)
    logging.debug("date: host time=%ss guest time=%ss", *after_date)

    if test_type == 'guest_suspend':
        date_diff = time_diff(before_date, after_date)
        if date_diff > tolerance:
            raise error.TestFail("date %ss difference is"
                                 "'guest_diff_time != host_diff_time'"
                                 " out of tolerance %ss" %
                                 (date_diff[1], tolerance))
    elif test_type == "guest_pause_resume":
        date_diff = time_diff_host_guest(before_date, after_date)
        if date_diff[1] > tolerance:
            raise error.TestFail("date %ss difference is "
                                 "'guest_time_after-guest_time_before'"
                                 " out of tolerance %ss" %
                                 (date_diff[1], tolerance))
Пример #52
0
def run(test, params, env):
    """
    Test set/get secret value for a volume

    1) Positive testing
       1.1) define or undefine a private or public secret
       1.2) get the public secret value
       1.3) set the private or public secret value
    2) Negative testing
       2.1) get private secret
       2.2) get secret without setting secret value
       2.3) get or set secret with invalid options
       2.4) set secret with doesn't exist UUID
    """

    # Run test case
    uuid = ""
    no_specified_uuid = False

    usage_volume = params.get("secret_usage_volume")
    define_secret = params.get("secret_define", "no")
    change_parameters = params.get("secret_change_parameters", "no")

    # If storage volume doesn't exist then create it
    if usage_volume and not os.path.isfile(usage_volume):
        utils.run("dd if=/dev/zero of=%s bs=1 count=1 seek=1M" % usage_volume)

    # Define secret based on storage volume
    if usage_volume and define_secret == "yes":
        create_secret_volume(params)

    # Get secret UUID from secret list
    if not no_specified_uuid:
        output = virsh.secret_list(ignore_status=False).stdout.strip()
        sec_list = re.findall(r"\n(.+\S+)\ +\S+\ +(.+\S+)", output)
        logging.debug("Secret list is %s", sec_list)
        if usage_volume and sec_list:
            for sec in sec_list:
                if usage_volume in sec[1]:
                    uuid = sec[0].lstrip()
                    no_specified_uuid = True
            logging.debug("Secret uuid is %s", uuid)

    uuid = params.get("secret_uuid", uuid)

    # Update parameters dictionary with automatically generated UUID
    if no_specified_uuid:
        params['secret_uuid'] = uuid

    # If only define secret then don't need to run the following cases

    # positive and negative testing #########

    if define_secret == "no":
        if change_parameters == "no":
            try:
                try:
                    get_secret_value(params)
                except error.TestFail, detail:
                    raise error.TestFail("Failed to get secret value.\n"
                                         "Detail: %s." % detail)
            finally:
                cleanup(params)
        else:
            try:
                try:
                    set_secret_value(params)
                except error.TestFail, detail:
                    raise error.TestFail("Failed to set secret value.\n"
                                         "Detail: %s." % detail)
            finally:
                cleanup(params)
Пример #53
0
def run_multi_vms_file_transfer(test, params, env):
    """
    Transfer a file back and forth between multi VMs for long time.

    1) Boot up two VMs .
    2) Create a large file by dd on host.
    3) Copy this file to VM1.
    4) Compare copied file's md5 with original file.
    5) Copy this file from VM1 to VM2.
    6) Compare copied file's md5 with original file.
    7) Copy this file from VM2 to VM1.
    8) Compare copied file's md5 with original file.
    9) Repeat step 5-8

    :param test: KVM test object.
    :param params: Dictionary with the test parameters.
    :param env: Dictionary with test environment.
    """
    def md5_check(session, orig_md5):
        msg = "Compare copied file's md5 with original file."
        error.context(msg, logging.info)
        md5_cmd = "md5sum %s | awk '{print $1}'" % guest_path
        s, o = session.cmd_status_output(md5_cmd)
        if s:
            msg = "Fail to get md5 value from guest. Output is %s" % o
            raise error.TestError(msg)
        new_md5 = o.splitlines()[-1]
        if new_md5 != orig_md5:
            msg = "File changed after transfer host -> VM1. Original md5 value"
            msg += " is %s. Current md5 value is %s" % (orig_md5, new_md5)
            raise error.TestFail(msg)

    vm1 = env.get_vm(params["main_vm"])
    vm1.verify_alive()
    login_timeout = int(params.get("login_timeout", 360))
    vm2 = env.get_vm(params["vms"].split()[-1])
    vm2.verify_alive()

    session_vm1 = vm1.wait_for_login(timeout=login_timeout)
    session_vm2 = vm2.wait_for_login(timeout=login_timeout)

    transfer_timeout = int(params.get("transfer_timeout", 1000))
    username = params["username"]
    password = params["password"]
    port = int(params["file_transfer_port"])
    tmp_dir = params.get("tmp_dir", "/tmp/")
    repeat_time = int(params.get("repeat_time", "10"))
    clean_cmd = params.get("clean_cmd", "rm -f")
    filesize = int(params.get("filesize", 4000))
    count = int(filesize / 10)
    if count == 0:
        count = 1

    host_path = os.path.join(tmp_dir,
                             "tmp-%s" % utils_misc.generate_random_string(8))
    cmd = "dd if=/dev/zero of=%s bs=10M count=%d" % (host_path, count)
    guest_path = (tmp_dir +
                  "file_transfer-%s" % utils_misc.generate_random_string(8))
    try:
        error.context("Creating %dMB file on host" % filesize, logging.info)
        utils.run(cmd)
        orig_md5 = utils.hash_file(host_path, method="md5")
        error.context(
            "Transferring file host -> VM1, timeout: %ss" % transfer_timeout,
            logging.info)
        t_begin = time.time()
        vm1.copy_files_to(host_path, guest_path, timeout=transfer_timeout)
        t_end = time.time()
        throughput = filesize / (t_end - t_begin)
        logging.info(
            "File transfer host -> VM1 succeed, "
            "estimated throughput: %.2fMB/s", throughput)
        md5_check(session_vm1, orig_md5)

        ip_vm1 = vm1.get_address()
        ip_vm2 = vm2.get_address()
        for i in range(repeat_time):
            log_vm1 = os.path.join(test.debugdir,
                                   "remote_scp_to_vm1_%s.log" % i)
            log_vm2 = os.path.join(test.debugdir,
                                   "remote_scp_to_vm2_%s.log" % i)

            msg = "Transferring file VM1 -> VM2, timeout: %ss." % transfer_timeout
            msg += " Repeat: %s/%s" % (i + 1, repeat_time)
            error.context(msg, logging.info)
            t_begin = time.time()
            s = remote.scp_between_remotes(src=ip_vm1,
                                           dst=ip_vm2,
                                           port=port,
                                           s_passwd=password,
                                           d_passwd=password,
                                           s_name=username,
                                           d_name=username,
                                           s_path=guest_path,
                                           d_path=guest_path,
                                           timeout=transfer_timeout,
                                           log_filename=log_vm2)
            t_end = time.time()
            throughput = filesize / (t_end - t_begin)
            logging.info(
                "File transfer VM1 -> VM2 succeed, "
                "estimated throughput: %.2fMB/s", throughput)
            md5_check(session_vm2, orig_md5)
            session_vm1.cmd("rm -rf %s" % guest_path)

            msg = "Transferring file VM2 -> VM1, timeout: %ss." % transfer_timeout
            msg += " Repeat: %s/%s" % (i + 1, repeat_time)

            error.context(msg, logging.info)
            t_begin = time.time()
            remote.scp_between_remotes(src=ip_vm2,
                                       dst=ip_vm1,
                                       port=port,
                                       s_passwd=password,
                                       d_passwd=password,
                                       s_name=username,
                                       d_name=username,
                                       s_path=guest_path,
                                       d_path=guest_path,
                                       timeout=transfer_timeout,
                                       log_filename=log_vm1)
            t_end = time.time()
            throughput = filesize / (t_end - t_begin)
            logging.info(
                "File transfer VM2 -> VM1 succeed, "
                "estimated throughput: %.2fMB/s", throughput)
            md5_check(session_vm1, orig_md5)
            session_vm2.cmd("%s %s" % (clean_cmd, guest_path))

    finally:
        try:
            session_vm1.cmd("%s %s" % (clean_cmd, guest_path))
        except Exception:
            pass
        try:
            session_vm2.cmd("%s %s" % (clean_cmd, guest_path))
        except Exception:
            pass
        try:
            os.remove(host_path)
        except OSError:
            pass
        if session_vm1:
            session_vm1.close()
        if session_vm2:
            session_vm2.close()
Пример #54
0
 def record_iptables(self, label):
     name = ('%s_iptables_%s.txt' % (self.__class__.__name__, label))
     output = open(os.path.join(self.parent_subtest.resultsdir, name), 'w+')
     output.write(utils.run('iptables -t filter -L -n -v').stdout)
     output.write('\n\n')
     output.write(utils.run('iptables -t nat -L -n -v').stdout)
Пример #55
0
def run_jumbo(test, params, env):
    """
    Test the RX jumbo frame function of vnics:

    1) Boot the VM.
    2) Change the MTU of guest nics and host taps depending on the NIC model.
    3) Add the static ARP entry for guest NIC.
    4) Wait for the MTU ok.
    5) Verify the path MTU using ping.
    6) Ping the guest with large frames.
    7) Increment size ping.
    8) Flood ping the guest with large frames.
    9) Verify the path MTU.
    10) Recover the MTU.

    @param test: KVM test object.
    @param params: Dictionary with the test parameters.
    @param env: Dictionary with test environment.
    """
    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    session = vm.wait_for_login(timeout=int(params.get("login_timeout", 360)))
    mtu = params.get("mtu", "1500")
    flood_time = params.get("flood_time", "300")
    max_icmp_pkt_size = int(mtu) - 28

    ifname = vm.get_ifname(0)
    ip = vm.get_address(0)
    if ip is None:
        raise error.TestError("Could not get the IP address")

    try:
        # Environment preparation
        ethname = utils_test.get_linux_ifname(session, vm.get_mac_address(0))

        logging.info("Changing the MTU of guest ...")
        guest_mtu_cmd = "ifconfig %s mtu %s" % (ethname , mtu)
        session.cmd(guest_mtu_cmd)

        logging.info("Chaning the MTU of host tap ...")
        host_mtu_cmd = "ifconfig %s mtu %s" % (ifname, mtu)
        utils.run(host_mtu_cmd)

        logging.info("Add a temporary static ARP entry ...")
        arp_add_cmd = "arp -s %s %s -i %s" % (ip, vm.get_mac_address(0), ifname)
        utils.run(arp_add_cmd)

        def is_mtu_ok():
            s, _ = utils_test.ping(ip, 1, interface=ifname,
                                       packetsize=max_icmp_pkt_size,
                                       hint="do", timeout=2)
            return s == 0

        def verify_mtu():
            logging.info("Verify the path MTU")
            s, o = utils_test.ping(ip, 10, interface=ifname,
                                       packetsize=max_icmp_pkt_size,
                                       hint="do", timeout=15)
            if s != 0 :
                logging.error(o)
                raise error.TestFail("Path MTU is not as expected")
            if utils_test.get_loss_ratio(o) != 0:
                logging.error(o)
                raise error.TestFail("Packet loss ratio during MTU "
                                     "verification is not zero")

        def flood_ping():
            logging.info("Flood with large frames")
            utils_test.ping(ip, interface=ifname,
                                packetsize=max_icmp_pkt_size,
                                flood=True, timeout=float(flood_time))

        def large_frame_ping(count=100):
            logging.info("Large frame ping")
            _, o = utils_test.ping(ip, count, interface=ifname,
                                       packetsize=max_icmp_pkt_size,
                                       timeout=float(count) * 2)
            ratio = utils_test.get_loss_ratio(o)
            if ratio != 0:
                raise error.TestFail("Loss ratio of large frame ping is %s" %
                                     ratio)

        def size_increase_ping(step=random.randrange(90, 110)):
            logging.info("Size increase ping")
            for size in range(0, max_icmp_pkt_size + 1, step):
                logging.info("Ping %s with size %s", ip, size)
                s, o = utils_test.ping(ip, 1, interface=ifname,
                                           packetsize=size,
                                           hint="do", timeout=1)
                if s != 0:
                    s, o = utils_test.ping(ip, 10, interface=ifname,
                                               packetsize=size,
                                               adaptive=True, hint="do",
                                               timeout=20)

                    if utils_test.get_loss_ratio(o) > int(params.get(
                                                      "fail_ratio", 50)):
                        raise error.TestFail("Ping loss ratio is greater "
                                             "than 50% for size %s" % size)

        logging.info("Waiting for the MTU to be OK")
        wait_mtu_ok = 10
        if not utils_misc.wait_for(is_mtu_ok, wait_mtu_ok, 0, 1):
            logging.debug(commands.getoutput("ifconfig -a"))
            raise error.TestError("MTU is not as expected even after %s "
                                  "seconds" % wait_mtu_ok)

        # Functional Test
        verify_mtu()
        large_frame_ping()
        size_increase_ping()

        # Stress test
        flood_ping()
        verify_mtu()

    finally:
        # Environment clean
        session.close()
        logging.info("Removing the temporary ARP entry")
        utils.run("arp -d %s -i %s" % (ip, ifname))
Пример #56
0
def run(test, params, env):
    """
    Test the virsh pool commands

    (1) Define a given type pool
    (2) List pool with '--inactive --type' options
    (3) Dumpxml for the pool
    (4) Undefine the pool
    (5) Define pool by using the XML file in step (3)
    (6) Build the pool(except 'disk' type pool
        For 'fs' type pool, cover --overwrite and --no-overwrite options
    (7) Start the pool
    (8) List pool with '--persistent --type' options
    (9) Mark pool autostart
    (10) List pool with '--autostart --type' options
    (11) Restart libvirtd and list pool with '--autostart --persistent' options
    (12) Destroy the pool
    (13) Unmark pool autostart
    (14) Repeat step (11)
    (15) Start the pool
    (16) Get pool info
    (17) Get pool uuid by name
    (18) Get pool name by uuid
    (19) Refresh the pool
         For 'dir' type pool, touch a file under target path and refresh again
         to make the new file show in vol-list.
    (20) Destroy the pool
    (21) Delete pool for 'dir' type pool. After the command, the pool object
         will still exist but target path will be deleted
    (22) Undefine the pool
    """

    # Initialize the variables
    pool_name = params.get("pool_name", "temp_pool_1")
    pool_type = params.get("pool_type", "dir")
    pool_target = params.get("pool_target", "")
    # The file for dumped pool xml
    pool_xml = os.path.join(test.tmpdir, "pool.xml.tmp")
    if os.path.dirname(pool_target) is "":
        pool_target = os.path.join(test.tmpdir, pool_target)
    vol_name = params.get("vol_name", "temp_vol_1")
    # Use pool name as VG name
    vg_name = pool_name
    status_error = "yes" == params.get("status_error", "no")
    vol_path = os.path.join(pool_target, vol_name)
    # Clean up flags:
    # cleanup_env[0] for nfs, cleanup_env[1] for iscsi, cleanup_env[2] for lvm
    # cleanup_env[3] for selinux backup status.
    cleanup_env = [False, False, False, ""]

    def check_exit_status(result, expect_error=False):
        """
        Check the exit status of virsh commands.

        :param result: Virsh command result object
        :param expect_error: Boolean value, expect command success or fail
        """
        if not expect_error:
            if result.exit_status != 0:
                raise error.TestFail(result.stderr)
            else:
                logging.debug("Command output:\n%s", result.stdout.strip())
        elif expect_error and result.exit_status == 0:
            raise error.TestFail("Expect fail, but run successfully.")

    def check_pool_list(pool_name, option="--all", expect_error=False):
        """
        Check pool by running pool-list command with given option.

        :param pool_name: Name of the pool
        :param option: option for pool-list command
        :param expect_error: Boolean value, expect command success or fail
        """
        found = False
        # Get the list stored in a variable
        result = virsh.pool_list(option, ignore_status=True)
        check_exit_status(result, False)
        output = re.findall(r"(\S+)\ +(\S+)\ +(\S+)[\ +\n]",
                            str(result.stdout))
        for item in output:
            if pool_name in item[0]:
                found = True
                break
        if found:
            logging.debug("Find pool '%s' in pool list.", pool_name)
        else:
            logging.debug("Not find pool %s in pool list.", pool_name)
        if expect_error and found:
            raise error.TestFail("Unexpect pool '%s' exist." % pool_name)
        if not expect_error and not found:
            raise error.TestFail("Expect pool '%s' doesn't exist." % pool_name)

    def check_vol_list(vol_name, pool_name):
        """
        Check volume from the list

        :param vol_name: Name of the volume
        :param pool_name: Name of the pool
        """
        found = False
        # Get the volume list stored in a variable
        result = virsh.vol_list(pool_name, ignore_status=True)
        check_exit_status(result)

        output = re.findall(r"(\S+)\ +(\S+)[\ +\n]", str(result.stdout))
        for item in output:
            if vol_name in item[0]:
                found = True
                break
        if found:
            logging.debug(
                "Find volume '%s' in pool '%s'.", vol_name, pool_name)
        else:
            raise error.TestFail(
                "Not find volume '%s' in pool '%s'." %
                (vol_name, pool_name))

    def check_pool_info(pool_info, check_point, value):
        """
        Check the pool name, uuid, etc.

        :param pool_info: A dict include pool's information
        :param key: Key of pool info dict, available value: Name, UUID, State
                    Persistent, Autostart, Capacity, Allocation, Available
        :param value: Expect value of pool_info[key]
        """
        if pool_info is None:
            raise error.TestFail("Pool info dictionary is needed.")
        if pool_info[check_point] == value:
            logging.debug("Pool '%s' is '%s'.", check_point, value)
        else:
            raise error.TestFail("Pool '%s' isn't '%s'." % (check_point,
                                                            value))

    # Run Testcase
    try:
        _pool = libvirt_storage.StoragePool()
        # Step (1)
        # Pool define
        result = utils_test.libvirt.define_pool(pool_name, pool_type,
                                                pool_target, cleanup_env)
        check_exit_status(result, status_error)

        # Step (2)
        # Pool list
        option = "--inactive --type %s" % pool_type
        check_pool_list(pool_name, option)

        # Step (3)
        # Pool dumpxml
        xml = virsh.pool_dumpxml(pool_name, to_file=pool_xml)
        logging.debug("Pool '%s' XML:\n%s", pool_name, xml)

        # Step (4)
        # Undefine pool
        result = virsh.pool_undefine(pool_name, ignore_status=True)
        check_exit_status(result)
        check_pool_list(pool_name, "--all", True)

        # Step (5)
        # Define pool from XML file
        result = virsh.pool_define(pool_xml)
        check_exit_status(result, status_error)

        # Step (6)
        # Buid pool, this step may fail for 'disk' and 'logical' types pool
        if pool_type not in ["disk", "logical"]:
            option = ""
        # Options --overwrite and --no-overwrite can only be used to
        # build a filesystem pool, but it will fail for now
            # if pool_type == "fs":
            #    option = '--overwrite'
            result = virsh.pool_build(pool_name, option, ignore_status=True)
            check_exit_status(result)

        # Step (7)
        # Pool start
        result = virsh.pool_start(pool_name, ignore_status=True)
        check_exit_status(result)

        # Step (8)
        # Pool list
        option = "--persistent --type %s" % pool_type
        check_pool_list(pool_name, option)

        # Step (9)
        # Pool autostart
        result = virsh.pool_autostart(pool_name, ignore_status=True)
        check_exit_status(result)

        # Step (10)
        # Pool list
        option = "--autostart --type %s" % pool_type
        check_pool_list(pool_name, option)

        # Step (11)
        # Restart libvirtd and check the autostart pool
        utils_libvirtd.libvirtd_restart()
        option = "--autostart --persistent"
        check_pool_list(pool_name, option)

        # Step (12)
        # Pool destroy
        if virsh.pool_destroy(pool_name):
            logging.debug("Pool %s destroyed.", pool_name)
        else:
            raise error.TestFail("Destroy pool % failed." % pool_name)

        # Step (13)
        # Pool autostart disable
        result = virsh.pool_autostart(pool_name, "--disable",
                                      ignore_status=True)
        check_exit_status(result)

        # Step (14)
        # Repeat step (11)
        utils_libvirtd.libvirtd_restart()
        option = "--autostart"
        check_pool_list(pool_name, option, True)

        # Step (15)
        # Pool start
        # If the filesystem cntaining the directory is mounted, then the
        # directory will show as running, which means the local 'dir' pool
        # don't need start after restart libvirtd
        if pool_type != "dir":
            result = virsh.pool_start(pool_name, ignore_status=True)
            check_exit_status(result)

        # Step (16)
        # Pool info
        pool_info = _pool.pool_info(pool_name)
        logging.debug("Pool '%s' info:\n%s", pool_name, pool_info)

        # Step (17)
        # Pool UUID
        result = virsh.pool_uuid(pool_info["Name"], ignore_status=True)
        check_exit_status(result)
        check_pool_info(pool_info, "UUID", result.stdout.strip())

        # Step (18)
        # Pool Name
        result = virsh.pool_name(pool_info["UUID"], ignore_status=True)
        check_exit_status(result)
        check_pool_info(pool_info, "Name", result.stdout.strip())

        # Step (19)
        # Pool refresh for 'dir' type pool
        if pool_type == "dir":
            os.mknod(vol_path)
            result = virsh.pool_refresh(pool_name)
            check_exit_status(result)
            check_vol_list(vol_name, pool_name)

        # Step(20)
        # Pool destroy
        if virsh.pool_destroy(pool_name):
            logging.debug("Pool %s destroyed.", pool_name)
        else:
            raise error.TestFail("Destroy pool % failed." % pool_name)

        # Step (21)
        # Pool delete for 'dir' type pool
        if pool_type == "dir":
            if os.path.exists(vol_path):
                os.remove(vol_path)
            result = virsh.pool_delete(pool_name, ignore_status=True)
            check_exit_status(result)
            option = "--inactive --type %s" % pool_type
            check_pool_list(pool_name, option)
            if os.path.exists(pool_target):
                raise error.TestFail("The target path '%s' still exist." %
                                     pool_target)
            result = virsh.pool_start(pool_name, ignore_status=True)
            check_exit_status(result, True)

        # Step (22)
        # Pool undefine
        result = virsh.pool_undefine(pool_name, ignore_status=True)
        check_exit_status(result)
        check_pool_list(pool_name, "--all", True)
    finally:
        # Clean up
        if os.path.exists(pool_xml):
            os.remove(pool_xml)
        if not _pool.delete_pool(pool_name):
            logging.error("Can't delete pool: %s", pool_name)
        if cleanup_env[2]:
            cmd = "pvs |grep %s |awk '{print $1}'" % vg_name
            pv_name = utils.system_output(cmd)
            lv_utils.vg_remove(vg_name)
            utils.run("pvremove %s" % pv_name)
        if cleanup_env[1]:
            utils_test.libvirt.setup_or_cleanup_iscsi(False)
        if cleanup_env[0]:
            utils_test.libvirt.setup_or_cleanup_nfs(
                False, restore_selinux=cleanup_env[3])
Пример #57
0
 def setup(self, tarball='lhcs_regression-1.6.tgz'):
     tarball = utils.unmap_url(self.bindir, tarball, self.tmpdir)
     utils.extract_tarball_to_dir(tarball, self.srcdir)
     os.chdir(self.srcdir)
     utils.run('patch -p1 < %s/0001-LHCS-Cleanups-and-bugfixes.patch'
               % self.bindir)
Пример #58
0
def preprocess(test, params, env):
    """
    Preprocess all VMs and images according to the instructions in params.
    Also, collect some host information, such as the KVM version.

    @param test: An Autotest test object.
    @param params: A dict containing all VM and image parameters.
    @param env: The environment (a dict-like object).
    """
    error.context("preprocessing")
    # First, let's verify if this test does require root or not. If it
    # does and the test suite is running as a regular user, we shall just
    # throw a TestNAError exception, which will skip the test.
    if params.get('requires_root', 'no') == 'yes':
        utils_misc.verify_running_as_root()

    port = params.get('shell_port')
    prompt = params.get('shell_prompt')
    address = params.get('ovirt_node_address')
    username = params.get('ovirt_node_user')
    password = params.get('ovirt_node_password')

    setup_pb = False
    for nic in params.get('nics', "").split():
        nic_params = params.object_params(nic)
        if nic_params.get('netdst') == 'private':
            setup_pb = True
            params_pb = nic_params
            params['netdst_%s' % nic] = nic_params.get("priv_brname", 'atbr0')

    if setup_pb:
        brcfg = test_setup.PrivateBridgeConfig(params_pb)
        brcfg.setup()

    base_dir = data_dir.get_data_dir()
    if params.get("storage_type") == "iscsi":
        iscsidev = qemu_storage.Iscsidev(params, base_dir, "iscsi")
        params["image_name"] = iscsidev.setup()
        params["image_raw_device"] = "yes"

    # Start tcpdump if it isn't already running
    if "address_cache" not in env:
        env["address_cache"] = {}
    if "tcpdump" in env and not env["tcpdump"].is_alive():
        env["tcpdump"].close()
        del env["tcpdump"]
    if "tcpdump" not in env and params.get("run_tcpdump", "yes") == "yes":
        cmd = "%s -npvi any 'port 68'" % utils_misc.find_command("tcpdump")
        if params.get("remote_preprocess") == "yes":
            login_cmd = ("ssh -o UserKnownHostsFile=/dev/null -o \
                         PreferredAuthentications=password -p %s %s@%s" %
                         (port, username, address))
            env["tcpdump"] = aexpect.ShellSession(
                login_cmd,
                output_func=_update_address_cache,
                output_params=(env["address_cache"],))
            remote.handle_prompts(env["tcpdump"], username, password, prompt)
            env["tcpdump"].sendline(cmd)
        else:
            env["tcpdump"] = aexpect.Tail(
                command=cmd,
                output_func=_tcpdump_handler,
                output_params=(env["address_cache"], "tcpdump.log",))

        if utils_misc.wait_for(lambda: not env["tcpdump"].is_alive(),
                              0.1, 0.1, 1.0):
            logging.warn("Could not start tcpdump")
            logging.warn("Status: %s" % env["tcpdump"].get_status())
            logging.warn("Output:" + utils_misc.format_str_for_message(
                env["tcpdump"].get_output()))

    # Destroy and remove VMs that are no longer needed in the environment
    requested_vms = params.objects("vms")
    for key in env.keys():
        vm = env[key]
        if not isinstance(vm, virt_vm.BaseVM):
            continue
        if not vm.name in requested_vms:
            vm.destroy()
            del env[key]

    if (params.get("auto_cpu_model") == "yes" and
        params.get("vm_type") == "qemu"):
        if not env.get("cpu_model"):
            env["cpu_model"] = utils_misc.get_qemu_best_cpu_model(params)
        params["cpu_model"] = env.get("cpu_model")

    kvm_ver_cmd = params.get("kvm_ver_cmd", "")

    if kvm_ver_cmd:
        try:
            cmd_result = utils.run(kvm_ver_cmd)
            kvm_version = cmd_result.stdout.strip()
        except error.CmdError:
            kvm_version = "Unknown"
    else:
        # Get the KVM kernel module version and write it as a keyval
        if os.path.exists("/dev/kvm"):
            try:
                kvm_version = open("/sys/module/kvm/version").read().strip()
            except Exception:
                kvm_version = os.uname()[2]
        else:
            logging.warning("KVM module not loaded")
            kvm_version = "Unknown"

    logging.debug("KVM version: %s" % kvm_version)
    test.write_test_keyval({"kvm_version": kvm_version})

    # Get the KVM userspace version and write it as a keyval
    kvm_userspace_ver_cmd = params.get("kvm_userspace_ver_cmd", "")

    if kvm_userspace_ver_cmd:
        try:
            cmd_result = utils.run(kvm_userspace_ver_cmd)
            kvm_userspace_version = cmd_result.stdout.strip()
        except error.CmdError:
            kvm_userspace_version = "Unknown"
    else:
        qemu_path = utils_misc.get_qemu_binary(params)
        version_line = commands.getoutput("%s -help | head -n 1" % qemu_path)
        matches = re.findall("[Vv]ersion .*?,", version_line)
        if matches:
            kvm_userspace_version = " ".join(matches[0].split()[1:]).strip(",")
        else:
            kvm_userspace_version = "Unknown"

    logging.debug("KVM userspace version: %s" % kvm_userspace_version)
    test.write_test_keyval({"kvm_userspace_version": kvm_userspace_version})

    if params.get("setup_hugepages") == "yes":
        h = test_setup.HugePageConfig(params)
        h.setup()
        if params.get("vm_type") == "libvirt":
            utils_libvirtd.libvirtd_restart()

    if params.get("setup_thp") == "yes":
        thp = test_setup.TransparentHugePageConfig(test, params)
        thp.setup()


    if params.get("setup_ksm") == "yes":
        ksm = test_setup.KSMConfig(params, env)
        ksm.setup(env)

    # Execute any pre_commands
    if params.get("pre_command"):
        process_command(test, params, env, params.get("pre_command"),
                        int(params.get("pre_command_timeout", "600")),
                        params.get("pre_command_noncritical") == "yes")


    # if you want set "pci=nomsi" before test, set "disable_pci_msi = yes"
    # and pci_msi_sensitive = "yes"
    if params.get("pci_msi_sensitive", "no") == "yes":
        disable_pci_msi = params.get("disable_pci_msi", "no")
        image_filename = storage.get_image_filename(params,
                                                    data_dir.get_data_dir())
        grub_file = params.get("grub_file", "/boot/grub2/grub.cfg")
        kernel_cfg_pos_reg = params.get("kernel_cfg_pos_reg",
                                         r".*vmlinuz-\d+.*")
        msi_keyword = params.get("msi_keyword", " pci=nomsi")

        disk_obj = utils_disk.GuestFSModiDisk(image_filename)
        kernel_config_ori = disk_obj.read_file(grub_file)
        kernel_config = re.findall(kernel_cfg_pos_reg, kernel_config_ori)
        if not kernel_config:
            raise error.TestError("Cannot find the kernel config, reg is %s" %
                                  kernel_cfg_pos_reg)
        kernel_config_line = kernel_config[0]

        kernel_need_modify = False
        if disable_pci_msi == "yes":
            if not re.findall(msi_keyword, kernel_config_line):
                kernel_config_set = kernel_config_line + msi_keyword
                kernel_need_modify = True
        else:
            if re.findall(msi_keyword, kernel_config_line):
                kernel_config_set = re.sub(msi_keyword, "", kernel_config_line)
                kernel_need_modify = True

        if kernel_need_modify:
            for vm in env.get_all_vms():
                if vm:
                    vm.destroy()
                    env.unregister_vm(vm.name)
            disk_obj.replace_image_file_content(grub_file, kernel_config_line,
                                                kernel_config_set)
        logging.debug("Guest cmdline 'pci=nomsi' setting is: [ %s ]" %
                       disable_pci_msi)

    # Clone master image from vms.
    base_dir = data_dir.get_data_dir()
    if params.get("master_images_clone"):
        for vm_name in params.get("vms").split():
            vm = env.get_vm(vm_name)
            if vm:
                vm.destroy(free_mac_addresses=False)
                env.unregister_vm(vm_name)

            vm_params = params.object_params(vm_name)
            for image in vm_params.get("master_images_clone").split():
                image_obj = qemu_storage.QemuImg(params, base_dir, image)
                image_obj.clone_image(params, vm_name, image, base_dir)

    # Preprocess all VMs and images
    if params.get("not_preprocess", "no") == "no":
        process(test, params, env, preprocess_image, preprocess_vm)

    # Start the screendump thread
    if params.get("take_regular_screendumps") == "yes":
        global _screendump_thread, _screendump_thread_termination_event
        _screendump_thread_termination_event = threading.Event()
        _screendump_thread = threading.Thread(target=_take_screendumps,
                                              name='ScreenDump',
                                              args=(test, params, env))
        _screendump_thread.start()

    return params
Пример #59
0
def run(test, params, env):
    """
    Test interafce xml options.

    1.Prepare test environment,destroy or suspend a VM.
    2.Edit xml and start the domain.
    3.Perform test operation.
    4.Recover test environment.
    5.Confirm the test result.
    """
    vm_name = params.get("main_vm")
    vm = env.get_vm(vm_name)

    def prepare_pxe_boot():
        """
        Prepare tftp server and pxe boot files
        """
        pkg_list = [
            "syslinux", "tftp-server", "tftp", "ipxe-roms-qemu", "wget"
        ]
        # Try to install required packages
        if not utils_misc.yum_install(pkg_list):
            raise error.TestError("Failed ot install " "required packages")
        boot_initrd = params.get("boot_initrd", "EXAMPLE_INITRD")
        boot_vmlinuz = params.get("boot_vmlinuz", "EXAMPLE_VMLINUZ")
        if boot_initrd.count("EXAMPLE") or boot_vmlinuz.count("EXAMPLE"):
            raise error.TestNAError("Please provide initrd/vmlinuz URL")
        # Download pxe boot images
        utils.run("wget %s -O %s/initrd.img" % (boot_initrd, tftp_root))
        utils.run("wget %s -O %s/vmlinuz" % (boot_vmlinuz, tftp_root))
        utils.run("cp -f /usr/share/syslinux/pxelinux.0 {0};"
                  " mkdir -m 777 -p {0}/pxelinux.cfg".format(tftp_root))
        pxe_file = "%s/pxelinux.cfg/default" % tftp_root
        boot_txt = """
DISPLAY boot.txt
DEFAULT rhel
LABEL rhel
        kernel vmlinuz
        append initrd=initrd.img
PROMPT 1
TIMEOUT 3"""
        with open(pxe_file, 'w') as p_file:
            p_file.write(boot_txt)

    def modify_iface_xml():
        """
        Modify interface xml options
        """
        vmxml = vm_xml.VMXML.new_from_dumpxml(vm_name)
        if pxe_boot:
            # Config boot console for pxe boot
            osxml = vm_xml.VMOSXML()
            osxml.type = vmxml.os.type
            osxml.arch = vmxml.os.arch
            osxml.machine = vmxml.os.machine
            osxml.loader = "/usr/share/seabios/bios.bin"
            osxml.bios_useserial = "yes"
            osxml.bios_reboot_timeout = "-1"
            osxml.boots = ['network']
            del vmxml.os
            vmxml.os = osxml

        xml_devices = vmxml.devices
        iface_index = xml_devices.index(
            xml_devices.by_device_tag("interface")[0])
        iface = xml_devices[iface_index]
        iface_bandwidth = {}
        iface_inbound = ast.literal_eval(iface_bandwidth_inbound)
        iface_outbound = ast.literal_eval(iface_bandwidth_outbound)
        if iface_inbound:
            iface_bandwidth["inbound"] = iface_inbound
        if iface_outbound:
            iface_bandwidth["outbound"] = iface_outbound
        if iface_bandwidth:
            bandwidth = iface.new_bandwidth(**iface_bandwidth)
            iface.bandwidth = bandwidth

        iface_type = params.get("iface_type", "network")
        iface.type_name = iface_type
        source = ast.literal_eval(iface_source)
        if not source:
            source = {"network": "default"}
        net_ifs = utils_net.get_net_if(state="UP")
        # Check source device is valid or not,
        # if it's not in host interface list, try to set
        # source device to first active interface of host
        if (iface.type_name == "direct" and source.has_key('dev')
                and source['dev'] not in net_ifs):
            logging.warn(
                "Source device %s is not a interface"
                " of host, reset to %s", source['dev'], net_ifs[0])
            source['dev'] = net_ifs[0]
        del iface.source
        iface.source = source
        iface_model = params.get("iface_model", "virtio")
        iface.model = iface_model
        logging.debug("New interface xml file: %s", iface)
        vmxml.devices = xml_devices
        vmxml.xmltreefile.write()
        vmxml.sync()

    def run_dnsmasq_default_test(key, value=None, exists=True):
        """
        Test dnsmasq configuration.
        """
        conf_file = "/var/lib/libvirt/dnsmasq/default.conf"
        if not os.path.exists(conf_file):
            raise error.TestNAError("Can't find default.conf file")

        configs = ""
        with open(conf_file) as f:
            configs = f.read()
        logging.debug("configs in file %s: %s", conf_file, configs)
        if value:
            config = "%s=%s" % (key, value)
        else:
            config = key

        if not configs.count(config):
            if exists:
                raise error.TestFail("Can't find %s=%s in configuration"
                                     " file" % (key, value))
        else:
            if not exists:
                raise error.TestFail("Found %s=%s in configuration"
                                     " file" % (key, value))

    def run_dnsmasq_addnhosts_test(hostip, hostnames):
        """
        Test host ip and names configuration
        """
        conf_file = "/var/lib/libvirt/dnsmasq/default.addnhosts"
        hosts_re = ".*".join(hostnames)
        configs = ""
        with open(conf_file) as f:
            configs = f.read()
        logging.debug("configs in file %s: %s", conf_file, configs)
        if not re.search(r"%s.*%s" % (hostip, hosts_re), configs, re.M):
            raise error.TestFail("Can't find '%s' in configuration"
                                 " file" % hostip)

    def run_dnsmasq_host_test(iface_mac, guest_ip, guest_name):
        """
        Test host name and ip configuration for dnsmasq
        """
        conf_file = "/var/lib/libvirt/dnsmasq/default.hostsfile"
        config = "%s,%s,%s" % (iface_mac, guest_ip, guest_name)
        configs = ""
        with open(conf_file) as f:
            configs = f.read()
        logging.debug("configs in file %s: %s", conf_file, configs)
        if not configs.count(config):
            raise error.TestFail("Can't find host configuration"
                                 " in file %s" % conf_file)

    def check_class_rules(ifname, rule_id, bandwidth):
        """
        Check bandwidth settings via 'tc class' output
        """
        cmd = "tc class show dev %s" % ifname
        class_output = utils.run(cmd).stdout
        logging.debug("Bandwidth class output: %s", class_output)
        class_pattern = (r"class htb %s.*rate (\d+)Kbit ceil"
                         " (\d+)Kbit burst (\d+)(K?M?)b.*" % rule_id)
        se = re.search(class_pattern, class_output, re.M)
        if not se:
            raise error.TestFail("Can't find outbound setting"
                                 " for htb %s" % rule_id)
        logging.debug("bandwidth from tc output:%s" % str(se.groups()))
        ceil = None
        if bandwidth.has_key("floor"):
            ceil = int(bandwidth["floor"]) * 8
        elif bandwidth.has_key("average"):
            ceil = int(bandwidth["average"]) * 8
        if ceil:
            assert int(se.group(1)) == ceil
        if bandwidth.has_key("peak"):
            assert int(se.group(2)) == int(bandwidth["peak"]) * 8
        if bandwidth.has_key("burst"):
            if se.group(4) == 'M':
                tc_burst = int(se.group(3)) * 1024
            else:
                tc_burst = int(se.group(3))
            assert tc_burst == int(bandwidth["burst"])

    def check_filter_rules(ifname, bandwidth):
        """
        Check bandwidth settings via 'tc filter' output
        """
        cmd = "tc -d filter show dev %s parent ffff:" % ifname
        filter_output = utils.run(cmd).stdout
        logging.debug("Bandwidth filter output: %s", filter_output)
        if not filter_output.count("filter protocol all pref"):
            raise error.TestFail("Can't find 'protocol all' settings"
                                 " in filter rules")
        filter_pattern = ".*police.*rate (\d+)Kbit burst (\d+)(K?M?)b.*"
        se = re.search(r"%s" % filter_pattern, filter_output, re.M)
        if not se:
            raise error.TestFail("Can't find any filter policy")
        logging.debug("bandwidth from tc output:%s" % str(se.groups()))
        logging.debug("bandwidth from setting:%s" % str(bandwidth))
        if bandwidth.has_key("average"):
            assert int(se.group(1)) == int(bandwidth["average"]) * 8
        if bandwidth.has_key("burst"):
            if se.group(3) == 'M':
                tc_burst = int(se.group(2)) * 1024
            else:
                tc_burst = int(se.group(2))
            assert tc_burst == int(bandwidth["burst"])

    def check_host_routes():
        """
        Check network routes on host
        """
        for rt in routes:
            try:
                route = ast.literal_eval(rt)
                addr = "%s/%s" % (route["address"], route["prefix"])
                cmd = "ip route list %s" % addr
                if route.has_key("family") and route["family"] == "ipv6":
                    cmd = "ip -6 route list %s" % addr
                output = utils.run(cmd).stdout
                match_obj = re.search(r"via (\S+).*metric (\d+)", output)
                if match_obj:
                    via_addr = match_obj.group(1)
                    metric = match_obj.group(2)
                    logging.debug("via address %s for %s, matric is %s" %
                                  (via_addr, addr, metric))
                    assert via_addr == route["gateway"]
                    if route.has_key("metric"):
                        assert metric == route["metric"]
            except KeyError:
                pass

    def run_bandwidth_test(check_net=False, check_iface=False):
        """
        Test bandwidth option for network or interface by tc command.
        """
        iface_inbound = ast.literal_eval(iface_bandwidth_inbound)
        iface_outbound = ast.literal_eval(iface_bandwidth_outbound)
        net_inbound = ast.literal_eval(net_bandwidth_inbound)
        net_outbound = ast.literal_eval(net_bandwidth_outbound)
        net_bridge_name = ast.literal_eval(net_bridge)["name"]
        iface_name = libvirt.get_ifname_host(vm_name, iface_mac)

        try:
            if check_net and net_inbound:
                # Check qdisc rules
                cmd = "tc -d qdisc show dev %s" % net_bridge_name
                qdisc_output = utils.run(cmd).stdout
                logging.debug("Bandwidth qdisc output: %s", qdisc_output)
                if not qdisc_output.count("qdisc ingress ffff:"):
                    raise error.TestFail("Can't find ingress setting")
                check_class_rules(net_bridge_name, "1:1", {
                    "average": net_inbound["average"],
                    "peak": net_inbound["peak"]
                })
                check_class_rules(net_bridge_name, "1:2", net_inbound)

            # Check filter rules on bridge interface
            if check_net and net_outbound:
                check_filter_rules(net_bridge_name, net_outbound)

            # Check class rules on interface inbound settings
            if check_iface and iface_inbound:
                check_class_rules(
                    iface_name, "1:1", {
                        'average': iface_inbound['average'],
                        'peak': iface_inbound['peak'],
                        'burst': iface_inbound['burst']
                    })
                if iface_inbound.has_key("floor"):
                    if not libvirt_version.version_compare(1, 0, 1):
                        raise error.TestNAError("Not supported Qos"
                                                " options 'floor'")

                    check_class_rules(net_bridge_name, "1:3",
                                      {'floor': iface_inbound["floor"]})

            # Check filter rules on interface outbound settings
            if check_iface and iface_outbound:
                check_filter_rules(iface_name, iface_outbound)
        except AssertionError:
            utils.log_last_traceback()
            raise error.TestFail("Failed to check network bandwidth")

    def check_name_ip(session):
        """
        Check dns resolving on guest
        """
        # Check if bind-utils is installed
        if not utils_misc.yum_install(['bind-utils'], session):
            raise error.TestError("Failed to install bind-utils" " on guest")
        # Run host command to check if hostname can be resolved
        if not guest_ipv4 and not guest_ipv6:
            raise error.TestFail("No ip address found from parameters")
        guest_ip = guest_ipv4 if guest_ipv4 else guest_ipv6
        cmd = "host %s | grep %s" % (guest_name, guest_ip)
        if session.cmd_status(cmd):
            raise error.TestFail("Can't resolve name %s on guest" % guest_name)

    def check_ipt_rules(check_ipv4=True, check_ipv6=False):
        """
        Check iptables for network/interface
        """
        br_name = ast.literal_eval(net_bridge)["name"]
        net_forward = ast.literal_eval(params.get("net_forward", "{}"))
        net_ipv4 = params.get("net_ipv4")
        net_ipv6 = params.get("net_ipv6")
        ipt_rules = ("FORWARD -i {0} -o {0} -j ACCEPT".format(br_name),
                     "FORWARD -o %s -j REJECT --reject-with icmp" % br_name,
                     "FORWARD -i %s -j REJECT --reject-with icmp" % br_name)
        net_dev_in = ""
        net_dev_out = ""
        if net_forward.has_key("dev"):
            net_dev_in = " -i %s" % net_forward["dev"]
            net_dev_out = " -o %s" % net_forward["dev"]
        if check_ipv4:
            ipv4_rules = list(ipt_rules)
            ctr_rule = ""
            nat_rules = []
            if net_forward.has_key("mode") and net_forward["mode"] == "nat":
                nat_port = ast.literal_eval(params.get("nat_port"))
                p_start = nat_port["start"]
                p_end = nat_port["end"]
                ctr_rule = " -m .* RELATED,ESTABLISHED"
                nat_rules = [
                    ("POSTROUTING -s {0} ! -d {0} -p tcp -j MASQUERADE"
                     " --to-ports {1}-{2}".format(net_ipv4, p_start, p_end)),
                    ("POSTROUTING -s {0} ! -d {0} -p udp -j MASQUERADE"
                     " --to-ports {1}-{2}".format(net_ipv4, p_start, p_end)),
                    ("POSTROUTING -s {0} ! -d {0} -p udp"
                     " -j MASQUERADE".format(net_ipv4))
                ]
            if nat_rules:
                ipv4_rules.extend(nat_rules)
            if (net_ipv4 and net_forward.has_key("mode")
                    and net_forward["mode"] in ["nat", "route"]):
                rules = [("FORWARD -d %s%s -o %s%s -j ACCEPT" %
                          (net_ipv4, net_dev_in, br_name, ctr_rule)),
                         ("FORWARD -s %s -i %s%s -j ACCEPT" %
                          (net_ipv4, br_name, net_dev_out))]
                ipv4_rules.extend(rules)

            output = utils.run("iptables-save").stdout.strip()
            logging.debug("iptables: %s", output)
            for ipt in ipv4_rules:
                if not re.findall(r"%s" % ipt, output, re.M):
                    raise error.TestFail("Can't find iptable rule:\n%s" % ipt)
        if check_ipv6:
            ipv6_rules = list(ipt_rules)
            if (net_ipv6 and net_forward.has_key("mode")
                    and net_forward["mode"] in ["nat", "route"]):
                rules = [("FORWARD -d %s%s -o %s -j ACCEPT" %
                          (net_ipv6, net_dev_in, br_name)),
                         ("FORWARD -s %s -i %s%s -j ACCEPT" %
                          (net_ipv6, br_name, net_dev_out))]
                ipv6_rules.extend(rules)
            output = utils.run("ip6tables-save").stdout.strip()
            logging.debug("iptables: %s", output)
            for ipt in ipv6_rules:
                if not output.count(ipt):
                    raise error.TestFail("Can't find ipbtable rule:\n%s" % ipt)

    def run_ip_test(session, ip_ver):
        """
        Check iptables on host and ipv6 address on guest
        """
        if ip_ver == "ipv6":
            # Clean up iptables rules for guest to get ipv6 address
            session.cmd_status("ip6tables -F")

        # It may take some time to get the ip address
        def get_ip_func():
            return utils_net.get_guest_ip_addr(session,
                                               iface_mac,
                                               ip_version=ip_ver)

        utils_misc.wait_for(get_ip_func, 5)
        if not get_ip_func():
            utils_net.restart_guest_network(session,
                                            iface_mac,
                                            ip_version=ip_ver)
            utils_misc.wait_for(get_ip_func, 5)
        vm_ip = get_ip_func()
        logging.debug("Guest has ip: %s", vm_ip)
        if not vm_ip:
            raise error.TestFail("Can't find ip address on guest")
        ip_gateway = net_ip_address
        if ip_ver == "ipv6":
            ip_gateway = net_ipv6_address
            # Cleanup ip6talbes on host for ping6 test
            utils.run("ip6tables -F")
        if ip_gateway and not routes:
            ping_s, _ = ping(dest=ip_gateway,
                             count=5,
                             timeout=10,
                             session=session)
            if ping_s:
                raise error.TestFail("Failed to ping gateway address: %s" %
                                     ip_gateway)

    def run_guest_libvirt(session):
        """
        Check guest libvirt network
        """
        # Try to install required packages
        if not utils_misc.yum_install(['libvirt'], session):
            raise error.TestError("Failed ot install libvirt"
                                  " package on guest")
        result = True
        # Try to load tun module first
        session.cmd("lsmod | grep tun || modprobe  tun")
        # Check network state on guest
        cmd = ("service libvirtd restart; virsh net-info default"
               " | grep 'Active:.*no'")
        if session.cmd_status(cmd):
            result = False
            logging.error("Default network isn't in inactive state")
        # Try to start default network on guest, check error messages
        if result:
            cmd = "virsh net-start default"
            status, output = session.cmd_status_output(cmd)
            logging.debug("Run command on guest exit %s, output %s" %
                          (status, output))
            if not status or not output.count("already in use"):
                result = False
                logging.error("Failed to see network messges on guest")
        if session.cmd_status("yum -y remove libvirt*"):
            logging.error("Failed to remove libvirt packages on guest")

        if not result:
            raise error.TestFail("Check libvirt network on guest failed")

    start_error = "yes" == params.get("start_error", "no")
    define_error = "yes" == params.get("define_error", "no")
    restart_error = "yes" == params.get("restart_error", "no")

    # network specific attributes.
    net_name = params.get("net_name", "default")
    net_bridge = params.get("net_bridge", "{'name':'virbr0'}")
    net_domain = params.get("net_domain")
    net_ip_address = params.get("net_ip_address")
    net_ipv6_address = params.get("net_ipv6_address")
    net_dns_forward = params.get("net_dns_forward")
    net_dns_txt = params.get("net_dns_txt")
    net_dns_srv = params.get("net_dns_srv")
    net_dns_hostip = params.get("net_dns_hostip")
    net_dns_hostnames = params.get("net_dns_hostnames", "").split()
    dhcp_start_ipv4 = params.get("dhcp_start_ipv4")
    dhcp_end_ipv4 = params.get("dhcp_end_ipv4")
    guest_name = params.get("guest_name")
    guest_ipv4 = params.get("guest_ipv4")
    guest_ipv6 = params.get("guest_ipv6")
    tftp_root = params.get("tftp_root")
    pxe_boot = "yes" == params.get("pxe_boot", "no")
    routes = params.get("routes", "").split()
    net_bandwidth_inbound = params.get("net_bandwidth_inbound", "{}")
    net_bandwidth_outbound = params.get("net_bandwidth_outbound", "{}")
    iface_bandwidth_inbound = params.get("iface_bandwidth_inbound", "{}")
    iface_bandwidth_outbound = params.get("iface_bandwidth_outbound", "{}")
    iface_num = params.get("iface_num", "1")
    iface_source = params.get("iface_source", "{}")
    multiple_guests = params.get("multiple_guests")
    create_network = "yes" == params.get("create_network", "no")
    attach_iface = "yes" == params.get("attach_iface", "no")
    serial_login = "******" == params.get("serial_login", "no")
    change_iface_option = "yes" == params.get("change_iface_option", "no")
    test_bridge = "yes" == params.get("test_bridge", "no")
    test_dnsmasq = "yes" == params.get("test_dnsmasq", "no")
    test_dhcp_range = "yes" == params.get("test_dhcp_range", "no")
    test_dns_host = "yes" == params.get("test_dns_host", "no")
    test_qos_bandwidth = "yes" == params.get("test_qos_bandwidth", "no")
    test_pg_bandwidth = "yes" == params.get("test_portgroup_bandwidth", "no")
    test_qos_remove = "yes" == params.get("test_qos_remove", "no")
    test_ipv4_address = "yes" == params.get("test_ipv4_address", "no")
    test_ipv6_address = "yes" == params.get("test_ipv6_address", "no")
    test_guest_libvirt = "yes" == params.get("test_guest_libvirt", "no")
    username = params.get("username")
    password = params.get("password")

    # Destroy VM first
    if vm.is_alive():
        vm.destroy(gracefully=False)

    # Back up xml file.
    netxml_backup = NetworkXML.new_from_net_dumpxml("default")
    iface_mac = vm_xml.VMXML.get_first_mac_by_name(vm_name)
    params["guest_mac"] = iface_mac
    vmxml_backup = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name)
    vms_list = []
    if "floor" in ast.literal_eval(iface_bandwidth_inbound):
        if not libvirt_version.version_compare(1, 0, 1):
            raise error.TestNAError("Not supported Qos" " options 'floor'")

    # Build the xml and run test.
    try:
        if test_dnsmasq:
            # Check the settings before modifying network xml
            if net_dns_forward == "no":
                run_dnsmasq_default_test("domain-needed", exists=False)
                run_dnsmasq_default_test("local", "//", exists=False)
            if net_domain:
                run_dnsmasq_default_test("domain", net_domain, exists=False)
                run_dnsmasq_default_test("expand-hosts", exists=False)

        # Prepare pxe boot directory
        if pxe_boot:
            prepare_pxe_boot()
        # Edit the network xml or create a new one.
        if create_network:
            net_ifs = utils_net.get_net_if(state="UP")
            # Check forward device is valid or not,
            # if it's not in host interface list, try to set
            # forward device to first active interface of host
            forward = ast.literal_eval(params.get("net_forward", "{}"))
            if (forward.has_key('mode') and forward['mode']
                    in ['passthrough', 'private', 'bridge', 'macvtap']
                    and forward.has_key('dev')
                    and forward['dev'] not in net_ifs):
                logging.warn(
                    "Forward device %s is not a interface"
                    " of host, reset to %s", forward['dev'], net_ifs[0])
                forward['dev'] = net_ifs[0]
                params["net_forward"] = str(forward)
            forward_iface = params.get("forward_iface")
            if forward_iface:
                interface = [x for x in forward_iface.split()]
                # The guest will use first interface of the list,
                # check if it's valid or not, if it's not in host
                # interface list, try to set forward interface to
                # first active interface of host.
                if interface[0] not in net_ifs:
                    logging.warn(
                        "Forward interface %s is not a "
                        " interface of host, reset to %s", interface[0],
                        net_ifs[0])
                    interface[0] = net_ifs[0]
                    params["forward_iface"] = " ".join(interface)

            netxml = libvirt.create_net_xml(net_name, params)
            try:
                netxml.sync()
            except xcepts.LibvirtXMLError, details:
                logging.info(str(details))
                if define_error:
                    pass
                else:
                    raise error.TestFail("Failed to define network")
        # Edit the interface xml.
        if change_iface_option:
            modify_iface_xml()
        # Attach interface if needed
        if attach_iface:
            iface_type = params.get("iface_type", "network")
            iface_model = params.get("iface_model", "virtio")
            for i in range(int(iface_num)):
                logging.info("Try to attach interface loop %s" % i)
                options = ("%s %s --model %s --config" %
                           (iface_type, net_name, iface_model))
                ret = virsh.attach_interface(vm_name,
                                             options,
                                             ignore_status=True)
                if ret.exit_status:
                    logging.error("Command output %s" % ret.stdout.strip())
                    raise error.TestFail("Failed to attach-interface")

        if multiple_guests:
            # Clone more vms for testing
            for i in range(int(multiple_guests)):
                guest_name = "%s_%s" % (vm_name, i)
                timeout = params.get("clone_timeout", 360)
                utils_libguestfs.virt_clone_cmd(vm_name,
                                                guest_name,
                                                True,
                                                timeout=timeout)
                vms_list.append(vm.clone(guest_name))

        if test_bridge:
            bridge = ast.literal_eval(net_bridge)
            br_if = utils_net.Interface(bridge['name'])
            if not br_if.is_up():
                raise error.TestFail("Bridge interface isn't up")
        if test_dnsmasq:
            # Check the settings in dnsmasq config file
            if net_dns_forward == "no":
                run_dnsmasq_default_test("domain-needed")
                run_dnsmasq_default_test("local", "//")
            if net_domain:
                run_dnsmasq_default_test("domain", net_domain)
                run_dnsmasq_default_test("expand-hosts")
            if net_bridge:
                bridge = ast.literal_eval(net_bridge)
                run_dnsmasq_default_test("interface", bridge['name'])
                if bridge.has_key('stp') and bridge['stp'] == 'on':
                    if bridge.has_key('delay'):
                        br_delay = float(bridge['delay'])
                        cmd = (
                            "brctl showstp %s | grep 'bridge forward delay'" %
                            bridge['name'])
                        out = utils.run(cmd,
                                        ignore_status=False).stdout.strip()
                        logging.debug("brctl showstp output: %s", out)
                        pattern = (r"\s*forward delay\s+(\d+.\d+)\s+bridge"
                                   " forward delay\s+(\d+.\d+)")
                        match_obj = re.search(pattern, out, re.M)
                        if not match_obj or len(match_obj.groups()) != 2:
                            raise error.TestFail("Can't see forward delay"
                                                 " messages from command")
                        elif (float(match_obj.groups()[0]) != br_delay
                              or float(match_obj.groups()[1]) != br_delay):
                            raise error.TestFail("Foward delay setting"
                                                 " can't take effect")
            if dhcp_start_ipv4 and dhcp_end_ipv4:
                run_dnsmasq_default_test(
                    "dhcp-range", "%s,%s" % (dhcp_start_ipv4, dhcp_end_ipv4))
            if guest_name and guest_ipv4:
                run_dnsmasq_host_test(iface_mac, guest_ipv4, guest_name)

        if test_dns_host:
            if net_dns_txt:
                dns_txt = ast.literal_eval(net_dns_txt)
                run_dnsmasq_default_test(
                    "txt-record",
                    "%s,%s" % (dns_txt["name"], dns_txt["value"]))
            if net_dns_srv:
                dns_srv = ast.literal_eval(net_dns_srv)
                run_dnsmasq_default_test(
                    "srv-host", "_%s._%s.%s,%s,%s,%s,%s" %
                    (dns_srv["service"], dns_srv["protocol"],
                     dns_srv["domain"], dns_srv["target"], dns_srv["port"],
                     dns_srv["priority"], dns_srv["weight"]))
            if net_dns_hostip and net_dns_hostnames:
                run_dnsmasq_addnhosts_test(net_dns_hostip, net_dns_hostnames)

        # Run bandwidth test for network
        if test_qos_bandwidth:
            run_bandwidth_test(check_net=True)
        # Check routes if needed
        if routes:
            check_host_routes()

        try:
            # Start the VM.
            vm.start()
            if start_error:
                raise error.TestFail("VM started unexpectedly")
            if pxe_boot:
                # Just check network boot messages here
                vm.serial_console.read_until_output_matches(
                    ["Loading vmlinuz", "Loading initrd.img"],
                    utils_misc.strip_console_codes)
                output = vm.serial_console.get_stripped_output()
                logging.debug("Boot messages: %s", output)

            else:
                if serial_login:
                    session = vm.wait_for_serial_login(username=username,
                                                       password=password)
                else:
                    session = vm.wait_for_login()

                if test_dhcp_range:
                    dhcp_range = int(params.get("dhcp_range", "252"))
                    utils_net.restart_guest_network(session, iface_mac)
                    vm_ip = utils_net.get_guest_ip_addr(session, iface_mac)
                    logging.debug("Guest has ip: %s", vm_ip)
                    if not vm_ip and dhcp_range:
                        raise error.TestFail("Guest has invalid ip address")
                    elif vm_ip and not dhcp_range:
                        raise error.TestFail("Guest has ip address: %s" %
                                             vm_ip)
                    dhcp_range = dhcp_range - 1
                    for vms in vms_list:
                        # Start other VMs.
                        vms.start()
                        sess = vms.wait_for_serial_login()
                        vms_mac = vms.get_virsh_mac_address()
                        # restart guest network to get ip addr
                        utils_net.restart_guest_network(sess, vms_mac)
                        vms_ip = utils_net.get_guest_ip_addr(sess, vms_mac)
                        if not vms_ip and dhcp_range:
                            raise error.TestFail(
                                "Guest has invalid ip address")
                        elif vms_ip and not dhcp_range:
                            # Get IP address on guest should return Null
                            # if it exceeds the dhcp range
                            raise error.TestFail("Guest has ip address: %s" %
                                                 vms_ip)
                        dhcp_range = dhcp_range - 1
                        if vms_ip:
                            ping_s, _ = ping(dest=vm_ip,
                                             count=5,
                                             timeout=10,
                                             session=sess)
                            if ping_s:
                                raise error.TestFail(
                                    "Failed to ping, src: %s, "
                                    "dst: %s" % (vms_ip, vm_ip))
                        sess.close()

                # Check dnsmasq settings if take affect in guest
                if guest_ipv4:
                    check_name_ip(session)

                # Run bandwidth test for interface
                if test_qos_bandwidth:
                    run_bandwidth_test(check_iface=True)
                # Run bandwidth test for portgroup
                if test_pg_bandwidth:
                    pg_bandwidth_inbound = params.get(
                        "portgroup_bandwidth_inbound", "").split()
                    pg_bandwidth_outbound = params.get(
                        "portgroup_bandwidth_outbound", "").split()
                    pg_name = params.get("portgroup_name", "").split()
                    pg_default = params.get("portgroup_default", "").split()
                    iface_inbound = ast.literal_eval(iface_bandwidth_inbound)
                    iface_outbound = ast.literal_eval(iface_bandwidth_outbound)
                    iface_name = libvirt.get_ifname_host(vm_name, iface_mac)
                    if_source = ast.literal_eval(iface_source)
                    if if_source.has_key("portgroup"):
                        pg = if_source["portgroup"]
                    else:
                        pg = "default"
                    for (name, df, bw_ib,
                         bw_ob) in zip(pg_name, pg_default,
                                       pg_bandwidth_inbound,
                                       pg_bandwidth_outbound):
                        if pg == name:
                            inbound = ast.literal_eval(bw_ib)
                            outbound = ast.literal_eval(bw_ob)
                        elif pg == "default" and df == "yes":
                            inbound = ast.literal_eval(bw_ib)
                            outbound = ast.literal_eval(bw_ob)
                        else:
                            continue
                        # Interface bandwidth settings will
                        # overwriting portgroup settings
                        if iface_inbound:
                            inbound = iface_inbound
                        if iface_outbound:
                            outbound = iface_outbound
                        check_class_rules(iface_name, "1:1", inbound)
                        check_filter_rules(iface_name, outbound)
                if test_qos_remove:
                    # Remove the bandwidth settings in network xml
                    logging.debug("Removing network bandwidth settings...")
                    netxml_backup.sync()
                    vm.destroy(gracefully=False)
                    # Should fail to start vm
                    vm.start()
                    if restart_error:
                        raise error.TestFail("VM started unexpectedly")
                if test_ipv6_address:
                    check_ipt_rules(check_ipv6=True)
                    run_ip_test(session, "ipv6")
                if test_ipv4_address:
                    check_ipt_rules(check_ipv4=True)
                    run_ip_test(session, "ipv4")

                if test_guest_libvirt:
                    run_guest_libvirt(session)

                session.close()
        except virt_vm.VMStartError as details:
            logging.info(str(details))
            if not (start_error or restart_error):
                raise error.TestFail('VM failed to start:\n%s' % details)
Пример #60
0
def preprocess(test, params, env):
    """
    Preprocess all VMs and images according to the instructions in params.
    Also, collect some host information, such as the KVM version.

    @param test: An Autotest test object.
    @param params: A dict containing all VM and image parameters.
    @param env: The environment (a dict-like object).
    """
    error.context("preprocessing")
    # First, let's verify if this test does require root or not. If it
    # does and the test suite is running as a regular user, we shall just
    # throw a TestNAError exception, which will skip the test.
    if params.get('requires_root', 'no') == 'yes':
        utils_test.verify_running_as_root()

    port = params.get('shell_port')
    prompt = params.get('shell_prompt')
    address = params.get('ovirt_node_address')
    username = params.get('ovirt_node_user')
    password = params.get('ovirt_node_password')

    # Start tcpdump if it isn't already running
    if "address_cache" not in env:
        env["address_cache"] = {}
    if "tcpdump" in env and not env["tcpdump"].is_alive():
        env["tcpdump"].close()
        del env["tcpdump"]
    if "tcpdump" not in env and params.get("run_tcpdump", "yes") == "yes":
        cmd = "%s -npvi any 'port 68'" % utils_misc.find_command("tcpdump")
        if params.get("remote_preprocess") == "yes":
            login_cmd = ("ssh -o UserKnownHostsFile=/dev/null -o \
                         PreferredAuthentications=password -p %s %s@%s" %
                         (port, username, address))
            env["tcpdump"] = aexpect.ShellSession(
                login_cmd,
                output_func=_update_address_cache,
                output_params=(env["address_cache"], ))
            remote._remote_login(env["tcpdump"], username, password, prompt)
            env["tcpdump"].sendline(cmd)
        else:
            env["tcpdump"] = aexpect.Tail(command=cmd,
                                          output_func=_tcpdump_handler,
                                          output_params=(
                                              env["address_cache"],
                                              "tcpdump.log",
                                          ))

        if utils_misc.wait_for(lambda: not env["tcpdump"].is_alive(), 0.1, 0.1,
                               1.0):
            logging.warn("Could not start tcpdump")
            logging.warn("Status: %s" % env["tcpdump"].get_status())
            logging.warn(
                "Output:" +
                utils_misc.format_str_for_message(env["tcpdump"].get_output()))

    # Destroy and remove VMs that are no longer needed in the environment
    requested_vms = params.objects("vms")
    for key in env.keys():
        vm = env[key]
        if not isinstance(vm, virt_vm.BaseVM):
            continue
        if not vm.name in requested_vms:
            vm.destroy()
            del env[key]

    if (params.get("auto_cpu_model") == "yes"
            and params.get("vm_type") == "qemu"):
        if not env.get("cpu_model"):
            env["cpu_model"] = utils_misc.get_qemu_best_cpu_model(params)
        params["cpu_model"] = env.get("cpu_model")

    kvm_ver_cmd = params.get("kvm_ver_cmd", "")

    if kvm_ver_cmd:
        try:
            cmd_result = utils.run(kvm_ver_cmd)
            kvm_version = cmd_result.stdout.strip()
        except error.CmdError:
            kvm_version = "Unknown"
    else:
        # Get the KVM kernel module version and write it as a keyval
        if os.path.exists("/dev/kvm"):
            try:
                kvm_version = open("/sys/module/kvm/version").read().strip()
            except Exception:
                kvm_version = os.uname()[2]
        else:
            logging.warning("KVM module not loaded")
            kvm_version = "Unknown"

    logging.debug("KVM version: %s" % kvm_version)
    test.write_test_keyval({"kvm_version": kvm_version})

    # Get the KVM userspace version and write it as a keyval
    kvm_userspace_ver_cmd = params.get("kvm_userspace_ver_cmd", "")

    if kvm_userspace_ver_cmd:
        try:
            cmd_result = utils.run(kvm_userspace_ver_cmd)
            kvm_userspace_version = cmd_result.stdout.strip()
        except error.CmdError:
            kvm_userspace_version = "Unknown"
    else:
        qemu_path = utils_misc.get_path(test.bindir,
                                        params.get("qemu_binary", "qemu"))
        version_line = commands.getoutput("%s -help | head -n 1" % qemu_path)
        matches = re.findall("[Vv]ersion .*?,", version_line)
        if matches:
            kvm_userspace_version = " ".join(matches[0].split()[1:]).strip(",")
        else:
            kvm_userspace_version = "Unknown"

    logging.debug("KVM userspace version: %s" % kvm_userspace_version)
    test.write_test_keyval({"kvm_userspace_version": kvm_userspace_version})

    if params.get("setup_hugepages") == "yes":
        h = test_setup.HugePageConfig(params)
        h.setup()
        if params.get("vm_type") == "libvirt":
            libvirt_vm.libvirtd_restart()

    if params.get("setup_thp") == "yes":
        thp = test_setup.TransparentHugePageConfig(test, params)
        thp.setup()

    # Execute any pre_commands
    if params.get("pre_command"):
        process_command(test, params, env, params.get("pre_command"),
                        int(params.get("pre_command_timeout", "600")),
                        params.get("pre_command_noncritical") == "yes")

    #Clone master image from vms.
    base_dir = data_dir.get_data_dir()
    if params.get("master_images_clone"):
        for vm_name in params.get("vms").split():
            vm = env.get_vm(vm_name)
            if vm:
                vm.destroy(free_mac_addresses=False)
                env.unregister_vm(vm_name)

            vm_params = params.object_params(vm_name)
            for image in vm_params.get("master_images_clone").split():
                image_obj = qemu_storage.QemuImg(params, base_dir, image)
                image_obj.clone_image(params, vm_name, image, base_dir)

    # Preprocess all VMs and images
    if params.get("not_preprocess", "no") == "no":
        process(test, params, env, preprocess_image, preprocess_vm)

    # Start the screendump thread
    if params.get("take_regular_screendumps") == "yes":
        global _screendump_thread, _screendump_thread_termination_event
        _screendump_thread_termination_event = threading.Event()
        _screendump_thread = threading.Thread(target=_take_screendumps,
                                              name='ScreenDump',
                                              args=(test, params, env))
        _screendump_thread.start()