Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(69)

Unified Diff: client/tests/kvm/kvm_vm.py

Issue 6124004: Revert "Merge remote branch 'cros/upstream' into autotest-rebase" (Closed) Base URL: ssh://git@gitrw.chromium.org:9222/autotest.git@master
Patch Set: Created 9 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « client/tests/kvm/kvm_utils.py ('k') | client/tests/kvm/migration_control.srv » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: client/tests/kvm/kvm_vm.py
diff --git a/client/tests/kvm/kvm_vm.py b/client/tests/kvm/kvm_vm.py
index f6f168486e6178b1de61b1d3ba72a27c1bbe80d2..a860437f6ea41e92d8f069b8bdc6e3a61d45e7f6 100755
--- a/client/tests/kvm/kvm_vm.py
+++ b/client/tests/kvm/kvm_vm.py
@@ -24,8 +24,6 @@ def get_image_filename(params, root_dir):
"""
image_name = params.get("image_name", "image")
image_format = params.get("image_format", "qcow2")
- if params.get("image_raw_device") == "yes":
- return image_name
image_filename = "%s.%s" % (image_name, image_format)
image_filename = kvm_utils.get_path(root_dir, image_filename)
return image_filename
@@ -97,7 +95,7 @@ class VM:
This class handles all basic VM operations.
"""
- def __init__(self, name, params, root_dir, address_cache, state=None):
+ def __init__(self, name, params, root_dir, address_cache):
"""
Initialize the object and set a few attributes.
@@ -106,35 +104,30 @@ class VM:
(see method make_qemu_command for a full description)
@param root_dir: Base directory for relative filenames
@param address_cache: A dict that maps MAC addresses to IP addresses
- @param state: If provided, use this as self.__dict__
"""
- if state:
- self.__dict__ = state
- else:
- self.process = None
- self.serial_console = None
- self.redirs = {}
- self.vnc_port = 5900
- self.monitors = []
- self.pci_assignable = None
- self.netdev_id = []
- self.uuid = None
-
- # Find a unique identifier for this VM
- while True:
- self.instance = (time.strftime("%Y%m%d-%H%M%S-") +
- kvm_utils.generate_random_string(4))
- if not glob.glob("/tmp/*%s" % self.instance):
- break
+ self.process = None
+ self.serial_console = None
+ self.redirs = {}
+ self.vnc_port = 5900
+ self.monitors = []
+ self.pci_assignable = None
+ self.netdev_id = []
+ self.uuid = None
self.name = name
self.params = params
self.root_dir = root_dir
self.address_cache = address_cache
+ # Find a unique identifier for this VM
+ while True:
+ self.instance = (time.strftime("%Y%m%d-%H%M%S-") +
+ kvm_utils.generate_random_string(4))
+ if not glob.glob("/tmp/*%s" % self.instance):
+ break
- def clone(self, name=None, params=None, root_dir=None, address_cache=None,
- copy_state=False):
+
+ def clone(self, name=None, params=None, root_dir=None, address_cache=None):
"""
Return a clone of the VM object with optionally modified parameters.
The clone is initially not alive and needs to be started using create().
@@ -145,8 +138,6 @@ class VM:
@param params: Optional new VM creation parameters
@param root_dir: Optional new base directory for relative filenames
@param address_cache: A dict that maps MAC addresses to IP addresses
- @param copy_state: If True, copy the original VM's state to the clone.
- Mainly useful for make_qemu_command().
"""
if name is None:
name = self.name
@@ -156,11 +147,7 @@ class VM:
root_dir = self.root_dir
if address_cache is None:
address_cache = self.address_cache
- if copy_state:
- state = self.__dict__.copy()
- else:
- state = None
- return VM(name, params, root_dir, address_cache, state)
+ return VM(name, params, root_dir, address_cache)
def make_qemu_command(self, name=None, params=None, root_dir=None):
@@ -249,22 +236,25 @@ class VM:
def add_nic(help, vlan, model=None, mac=None, netdev_id=None,
nic_extra_params=None):
- if has_option(help, "netdev"):
- netdev_vlan_str = ",netdev=%s" % netdev_id
- else:
- netdev_vlan_str = ",vlan=%d" % vlan
if has_option(help, "device"):
+ if model == "virtio":
+ model="virtio-net-pci"
if not model:
- model = "rtl8139"
- elif model == "virtio":
- model = "virtio-net-pci"
- cmd = " -device %s" % model + netdev_vlan_str
+ model= "rtl8139"
+ cmd = " -device %s" % model
if mac:
- cmd += ",mac='%s'" % mac
+ cmd += ",mac=%s" % mac
+ if has_option(help, "netdev"):
+ cmd += ",netdev=%s" % netdev_id
+ else:
+ cmd += "vlan=%d," % vlan
if nic_extra_params:
cmd += ",%s" % nic_extra_params
else:
- cmd = " -net nic" + netdev_vlan_str
+ if has_option(help, "netdev"):
+ cmd = " -net nic,netdev=%s" % netdev_id
+ else:
+ cmd = " -net nic,vlan=%d" % vlan
if model:
cmd += ",model=%s" % model
if mac:
@@ -273,11 +263,11 @@ class VM:
def add_net(help, vlan, mode, ifname=None, script=None,
downscript=None, tftp=None, bootfile=None, hostfwd=[],
- netdev_id=None, netdev_extra_params=None):
+ netdev_id=None, vhost=False):
if has_option(help, "netdev"):
cmd = " -netdev %s,id=%s" % (mode, netdev_id)
- if netdev_extra_params:
- cmd += ",%s" % netdev_extra_params
+ if vhost:
+ cmd +=",vhost=on"
else:
cmd = " -net %s,vlan=%d" % (mode, vlan)
if mode == "tap":
@@ -361,9 +351,6 @@ class VM:
if params is None: params = self.params
if root_dir is None: root_dir = self.root_dir
- # Clone this VM using the new params
- vm = self.clone(name, params, root_dir, copy_state=True)
-
qemu_binary = kvm_utils.get_path(root_dir, params.get("qemu_binary",
"qemu"))
# Get the output of 'qemu -help' (log a message in case this call never
@@ -381,19 +368,19 @@ class VM:
# Add the VM's name
qemu_cmd += add_name(help, name)
# Add monitors
- for monitor_name in params.objects("monitors"):
- monitor_params = params.object_params(monitor_name)
- monitor_filename = vm.get_monitor_filename(monitor_name)
+ for monitor_name in kvm_utils.get_sub_dict_names(params, "monitors"):
+ monitor_params = kvm_utils.get_sub_dict(params, monitor_name)
+ monitor_filename = self.get_monitor_filename(monitor_name)
if monitor_params.get("monitor_type") == "qmp":
qemu_cmd += add_qmp_monitor(help, monitor_filename)
else:
qemu_cmd += add_human_monitor(help, monitor_filename)
# Add serial console redirection
- qemu_cmd += add_serial(help, vm.get_serial_console_filename())
+ qemu_cmd += add_serial(help, self.get_serial_console_filename())
- for image_name in params.objects("images"):
- image_params = params.object_params(image_name)
+ for image_name in kvm_utils.get_sub_dict_names(params, "images"):
+ image_params = kvm_utils.get_sub_dict(params, image_name)
if image_params.get("boot_drive") == "no":
continue
qemu_cmd += add_drive(help,
@@ -407,23 +394,20 @@ class VM:
image_params.get("image_boot") == "yes")
redirs = []
- for redir_name in params.objects("redirs"):
- redir_params = params.object_params(redir_name)
+ for redir_name in kvm_utils.get_sub_dict_names(params, "redirs"):
+ redir_params = kvm_utils.get_sub_dict(params, redir_name)
guest_port = int(redir_params.get("guest_port"))
- host_port = vm.redirs.get(guest_port)
+ host_port = self.redirs.get(guest_port)
redirs += [(host_port, guest_port)]
vlan = 0
- for nic_name in params.objects("nics"):
- nic_params = params.object_params(nic_name)
- try:
- netdev_id = vm.netdev_id[vlan]
- except IndexError:
- netdev_id = None
+ for nic_name in kvm_utils.get_sub_dict_names(params, "nics"):
+ nic_params = kvm_utils.get_sub_dict(params, nic_name)
# Handle the '-net nic' part
- mac = vm.get_mac_address(vlan)
+ mac = self.get_mac_address(vlan)
qemu_cmd += add_nic(help, vlan, nic_params.get("nic_model"), mac,
- netdev_id, nic_params.get("nic_extra_params"))
+ self.netdev_id[vlan],
+ nic_params.get("nic_extra_params"))
# Handle the '-net tap' or '-net user' part
script = nic_params.get("nic_script")
downscript = nic_params.get("nic_downscript")
@@ -435,10 +419,11 @@ class VM:
if tftp:
tftp = kvm_utils.get_path(root_dir, tftp)
qemu_cmd += add_net(help, vlan, nic_params.get("nic_mode", "user"),
- vm.get_ifname(vlan),
+ self.get_ifname(vlan),
script, downscript, tftp,
- nic_params.get("bootp"), redirs, netdev_id,
- nic_params.get("netdev_extra_params"))
+ nic_params.get("bootp"), redirs,
+ self.netdev_id[vlan],
+ nic_params.get("vhost")=="yes")
# Proceed to next NIC
vlan += 1
@@ -450,8 +435,9 @@ class VM:
if smp:
qemu_cmd += add_smp(help, smp)
- for cdrom in params.objects("cdroms"):
- cdrom_params = params.object_params(cdrom)
+ cdroms = kvm_utils.get_sub_dict_names(params, "cdroms")
+ for cdrom in cdroms:
+ cdrom_params = kvm_utils.get_sub_dict(params, cdrom)
iso = cdrom_params.get("cdrom")
if iso:
qemu_cmd += add_cdrom(help, kvm_utils.get_path(root_dir, iso),
@@ -491,27 +477,27 @@ class VM:
qemu_cmd += add_tcp_redir(help, host_port, guest_port)
if params.get("display") == "vnc":
- qemu_cmd += add_vnc(help, vm.vnc_port)
+ qemu_cmd += add_vnc(help, self.vnc_port)
elif params.get("display") == "sdl":
qemu_cmd += add_sdl(help)
elif params.get("display") == "nographic":
qemu_cmd += add_nographic(help)
if params.get("uuid") == "random":
- qemu_cmd += add_uuid(help, vm.uuid)
+ qemu_cmd += add_uuid(help, self.uuid)
elif params.get("uuid"):
qemu_cmd += add_uuid(help, params.get("uuid"))
if params.get("testdev") == "yes":
- qemu_cmd += add_testdev(help, vm.get_testlog_filename())
+ qemu_cmd += add_testdev(help, self.get_testlog_filename())
if params.get("disable_hpet") == "yes":
qemu_cmd += add_no_hpet(help)
# If the PCI assignment step went OK, add each one of the PCI assigned
# devices to the qemu command line.
- if vm.pci_assignable:
- for pci_id in vm.pa_pci_ids:
+ if self.pci_assignable:
+ for pci_id in self.pa_pci_ids:
qemu_cmd += add_pcidevice(help, pci_id)
extra_params = params.get("extra_params")
@@ -522,7 +508,7 @@ class VM:
def create(self, name=None, params=None, root_dir=None, timeout=5.0,
- migration_mode=None, mac_source=None):
+ migration_mode=None, migration_exec_cmd=None, mac_source=None):
"""
Start the VM by running a qemu command.
All parameters are optional. If name, params or root_dir are not
@@ -550,40 +536,38 @@ class VM:
params = self.params
root_dir = self.root_dir
- # Verify the md5sum of the ISO images
- for cdrom in params.objects("cdroms"):
- cdrom_params = params.object_params(cdrom)
- iso = cdrom_params.get("cdrom")
- if iso:
- iso = kvm_utils.get_path(root_dir, iso)
- if not os.path.exists(iso):
- logging.error("ISO file not found: %s" % iso)
+ # Verify the md5sum of the ISO image
+ iso = params.get("cdrom")
+ if iso:
+ iso = kvm_utils.get_path(root_dir, iso)
+ if not os.path.exists(iso):
+ logging.error("ISO file not found: %s" % iso)
+ return False
+ compare = False
+ if params.get("md5sum_1m"):
+ logging.debug("Comparing expected MD5 sum with MD5 sum of "
+ "first MB of ISO file...")
+ actual_hash = utils.hash_file(iso, 1048576, method="md5")
+ expected_hash = params.get("md5sum_1m")
+ compare = True
+ elif params.get("md5sum"):
+ logging.debug("Comparing expected MD5 sum with MD5 sum of ISO "
+ "file...")
+ actual_hash = utils.hash_file(iso, method="md5")
+ expected_hash = params.get("md5sum")
+ compare = True
+ elif params.get("sha1sum"):
+ logging.debug("Comparing expected SHA1 sum with SHA1 sum of "
+ "ISO file...")
+ actual_hash = utils.hash_file(iso, method="sha1")
+ expected_hash = params.get("sha1sum")
+ compare = True
+ if compare:
+ if actual_hash == expected_hash:
+ logging.debug("Hashes match")
+ else:
+ logging.error("Actual hash differs from expected one")
return False
- compare = False
- if cdrom_params.get("md5sum_1m"):
- logging.debug("Comparing expected MD5 sum with MD5 sum of "
- "first MB of ISO file...")
- actual_hash = utils.hash_file(iso, 1048576, method="md5")
- expected_hash = cdrom_params.get("md5sum_1m")
- compare = True
- elif cdrom_params.get("md5sum"):
- logging.debug("Comparing expected MD5 sum with MD5 sum of "
- "ISO file...")
- actual_hash = utils.hash_file(iso, method="md5")
- expected_hash = cdrom_params.get("md5sum")
- compare = True
- elif cdrom_params.get("sha1sum"):
- logging.debug("Comparing expected SHA1 sum with SHA1 sum "
- "of ISO file...")
- actual_hash = utils.hash_file(iso, method="sha1")
- expected_hash = cdrom_params.get("sha1sum")
- compare = True
- if compare:
- if actual_hash == expected_hash:
- logging.debug("Hashes match")
- else:
- logging.error("Actual hash differs from expected one")
- return False
# Make sure the following code is not executed by more than one thread
# at the same time
@@ -592,17 +576,15 @@ class VM:
try:
# Handle port redirections
- redir_names = params.objects("redirs")
+ redir_names = kvm_utils.get_sub_dict_names(params, "redirs")
host_ports = kvm_utils.find_free_ports(5000, 6000, len(redir_names))
self.redirs = {}
for i in range(len(redir_names)):
- redir_params = params.object_params(redir_names[i])
+ redir_params = kvm_utils.get_sub_dict(params, redir_names[i])
guest_port = int(redir_params.get("guest_port"))
self.redirs[guest_port] = host_ports[i]
- # Generate netdev IDs for all NICs
- self.netdev_id = []
- for nic in params.objects("nics"):
+ for nic in kvm_utils.get_sub_dict_names(params, "nics"):
self.netdev_id.append(kvm_utils.generate_random_id())
# Find available VNC port, if needed
@@ -616,19 +598,13 @@ class VM:
f.close()
# Generate or copy MAC addresses for all NICs
- num_nics = len(params.objects("nics"))
+ num_nics = len(kvm_utils.get_sub_dict_names(params, "nics"))
for vlan in range(num_nics):
- nic_name = params.objects("nics")[vlan]
- nic_params = params.object_params(nic_name)
- if nic_params.get("nic_mac", None):
- mac = nic_params.get("nic_mac")
+ mac = mac_source and mac_source.get_mac_address(vlan)
+ if mac:
kvm_utils.set_mac_address(self.instance, vlan, mac)
else:
- mac = mac_source and mac_source.get_mac_address(vlan)
- if mac:
- kvm_utils.set_mac_address(self.instance, vlan, mac)
- else:
- kvm_utils.generate_mac_address(self.instance, vlan)
+ kvm_utils.generate_mac_address(self.instance, vlan)
# Assign a PCI assignable device
self.pci_assignable = None
@@ -684,9 +660,7 @@ class VM:
self.migration_file = "/tmp/migration-unix-%s" % self.instance
qemu_command += " -incoming unix:%s" % self.migration_file
elif migration_mode == "exec":
- self.migration_port = kvm_utils.find_free_port(5200, 6000)
- qemu_command += (' -incoming "exec:nc -l %s"' %
- self.migration_port)
+ qemu_command += ' -incoming "exec:%s"' % migration_exec_cmd
logging.debug("Running qemu command:\n%s", qemu_command)
self.process = kvm_subprocess.run_bg(qemu_command, None,
@@ -704,8 +678,9 @@ class VM:
# Establish monitor connections
self.monitors = []
- for monitor_name in params.objects("monitors"):
- monitor_params = params.object_params(monitor_name)
+ for monitor_name in kvm_utils.get_sub_dict_names(params,
+ "monitors"):
+ monitor_params = kvm_utils.get_sub_dict(params, monitor_name)
# Wait for monitor connection to succeed
end_time = time.time() + timeout
while time.time() < end_time:
@@ -758,7 +733,7 @@ class VM:
# Establish a session with the serial console -- requires a version
# of netcat that supports -U
- self.serial_console = kvm_subprocess.ShellSession(
+ self.serial_console = kvm_subprocess.kvm_shell_session(
"nc -U %s" % self.get_serial_console_filename(),
auto_close=False,
output_func=kvm_utils.log_line,
@@ -851,7 +826,7 @@ class VM:
os.unlink(self.migration_file)
except OSError:
pass
- num_nics = len(self.params.objects("nics"))
+ num_nics = len(kvm_utils.get_sub_dict_names(self.params, "nics"))
for vlan in range(num_nics):
self.free_mac_address(vlan)
@@ -910,7 +885,7 @@ class VM:
params).
"""
return [self.get_monitor_filename(m) for m in
- self.params.objects("monitors")]
+ kvm_utils.get_sub_dict_names(self.params, "monitors")]
def get_serial_console_filename(self):
@@ -936,9 +911,9 @@ class VM:
@param index: Index of the NIC whose address is requested.
"""
- nics = self.params.objects("nics")
+ nics = kvm_utils.get_sub_dict_names(self.params, "nics")
nic_name = nics[index]
- nic_params = self.params.object_params(nic_name)
+ nic_params = kvm_utils.get_sub_dict(self.params, nic_name)
if nic_params.get("nic_mode") == "tap":
mac = self.get_mac_address(index)
if not mac:
@@ -971,8 +946,8 @@ class VM:
@return: If port redirection is used, return the host port redirected
to guest port port. Otherwise return port.
"""
- nic_name = self.params.objects("nics")[nic_index]
- nic_params = self.params.object_params(nic_name)
+ nic_name = kvm_utils.get_sub_dict_names(self.params, "nics")[nic_index]
+ nic_params = kvm_utils.get_sub_dict(self.params, nic_name)
if nic_params.get("nic_mode") == "tap":
return port
else:
@@ -988,9 +963,9 @@ class VM:
@param nic_index: Index of the NIC
"""
- nics = self.params.objects("nics")
+ nics = kvm_utils.get_sub_dict_names(self.params, "nics")
nic_name = nics[nic_index]
- nic_params = self.params.object_params(nic_name)
+ nic_params = kvm_utils.get_sub_dict(self.params, nic_name)
if nic_params.get("nic_ifname"):
return nic_params.get("nic_ifname")
else:
@@ -1065,7 +1040,7 @@ class VM:
@param nic_index: The index of the NIC to connect to.
@param timeout: Time (seconds) before giving up logging into the
guest.
- @return: ShellSession object on success and None on failure.
+ @return: kvm_spawn object on success and None on failure.
"""
username = self.params.get("username", "")
password = self.params.get("password", "")
@@ -1093,7 +1068,7 @@ class VM:
def copy_files_to(self, local_path, remote_path, nic_index=0, timeout=600):
"""
- Transfer files to the remote host(guest).
+ Transfer files to the guest.
@param local_path: Host path
@param remote_path: Guest path
@@ -1107,12 +1082,21 @@ class VM:
address = self.get_address(nic_index)
port = self.get_port(int(self.params.get("file_transfer_port")))
- log_filename = ("transfer-%s-to-%s-%s.log" %
- (self.name, address,
- kvm_utils.generate_random_string(4)))
- return kvm_utils.copy_files_to(address, client, username, password,
- port, local_path, remote_path,
- log_filename, timeout)
+ if not address or not port:
+ logging.debug("IP address or port unavailable")
+ return None
+
+ if client == "scp":
+ log_filename = ("scp-%s-%s.log" %
+ (self.name, kvm_utils.generate_random_string(4)))
+ return kvm_utils.scp_to_remote(address, port, username, password,
+ local_path, remote_path,
+ log_filename, timeout)
+ elif client == "rss":
+ c = rss_file_transfer.FileUploadClient(address, port)
+ c.upload(local_path, remote_path, timeout)
+ c.close()
+ return True
def copy_files_from(self, remote_path, local_path, nic_index=0, timeout=600):
@@ -1131,11 +1115,21 @@ class VM:
address = self.get_address(nic_index)
port = self.get_port(int(self.params.get("file_transfer_port")))
- log_filename = ("transfer-%s-from-%s-%s.log" %
- (self.name, address,
- kvm_utils.generate_random_string(4)))
- return kvm_utils.copy_files_from(address, client, username, password,
- port, local_path, remote_path, log_filename, timeout)
+ if not address or not port:
+ logging.debug("IP address or port unavailable")
+ return None
+
+ if client == "scp":
+ log_filename = ("scp-%s-%s.log" %
+ (self.name, kvm_utils.generate_random_string(4)))
+ return kvm_utils.scp_from_remote(address, port, username, password,
+ remote_path, local_path,
+ log_filename, timeout)
+ elif client == "rss":
+ c = rss_file_transfer.FileDownloadClient(address, port)
+ c.download(remote_path, local_path, timeout)
+ c.close()
+ return True
def serial_login(self, timeout=10):
@@ -1145,7 +1139,7 @@ class VM:
password prompt or a shell prompt) -- fail.
@param timeout: Time (seconds) before giving up logging into the guest.
- @return: ShellSession object on success and None on failure.
+ @return: kvm_spawn object on success and None on failure.
"""
username = self.params.get("username", "")
password = self.params.get("password", "")
@@ -1219,7 +1213,11 @@ class VM:
if not session:
return None
try:
- return int(session.cmd(self.params.get("cpu_chk_cmd")))
+ cmd = self.params.get("cpu_chk_cmd")
+ s, count = session.get_command_status_output(cmd)
+ if s == 0:
+ return int(count)
+ return None
finally:
session.close()
@@ -1237,7 +1235,9 @@ class VM:
try:
if not cmd:
cmd = self.params.get("mem_chk_cmd")
- mem_str = session.cmd(cmd)
+ s, mem_str = session.get_command_status_output(cmd)
+ if s != 0:
+ return None
mem = re.findall("([0-9]+)", mem_str)
mem_size = 0
for m in mem:
@@ -1259,14 +1259,3 @@ class VM:
"""
cmd = self.params.get("mem_chk_cur_cmd")
return self.get_memory_size(cmd)
-
-
- def save_to_file(self, path):
- """
- Save the state of virtual machine to a file through migrate to
- exec
- """
- # Make sure we only get one iteration
- self.monitor.cmd("migrate_set_speed 1000g")
- self.monitor.cmd("migrate_set_downtime 100000000")
- self.monitor.migrate('"exec:cat>%s"' % path)
« no previous file with comments | « client/tests/kvm/kvm_utils.py ('k') | client/tests/kvm/migration_control.srv » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698