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

Side by Side Diff: client/virt/virt_env_process.py

Issue 6883246: Merge autotest upstream from @5318 ~ @5336 (Closed) Base URL: ssh://gitrw.chromium.org:9222/autotest.git@master
Patch Set: patch Created 9 years, 7 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « client/virt/tests/yum_update.py ('k') | client/virt/virt_installer.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 import os, time, commands, re, logging, glob, threading, shutil 1 import os, time, commands, re, logging, glob, threading, shutil
2 from autotest_lib.client.bin import utils 2 from autotest_lib.client.bin import utils
3 from autotest_lib.client.common_lib import error 3 from autotest_lib.client.common_lib import error
4 import kvm_vm, kvm_utils, kvm_subprocess, kvm_monitor, ppm_utils, test_setup 4 import aexpect, virt_utils, kvm_monitor, ppm_utils, virt_test_setup
5 import virt_vm, kvm_vm
5 try: 6 try:
6 import PIL.Image 7 import PIL.Image
7 except ImportError: 8 except ImportError:
8 logging.warning('No python imaging library installed. PPM image ' 9 logging.warning('No python imaging library installed. PPM image '
9 'conversion to JPEG disabled. In order to enable it, ' 10 'conversion to JPEG disabled. In order to enable it, '
10 'please install python-imaging or the equivalent for your ' 11 'please install python-imaging or the equivalent for your '
11 'distro.') 12 'distro.')
12 13
13 14
14 _screendump_thread = None 15 _screendump_thread = None
15 _screendump_thread_termination_event = None 16 _screendump_thread_termination_event = None
16 17
17 18
18 def preprocess_image(test, params): 19 def preprocess_image(test, params):
19 """ 20 """
20 Preprocess a single QEMU image according to the instructions in params. 21 Preprocess a single QEMU image according to the instructions in params.
21 22
22 @param test: Autotest test object. 23 @param test: Autotest test object.
23 @param params: A dict containing image preprocessing parameters. 24 @param params: A dict containing image preprocessing parameters.
24 @note: Currently this function just creates an image if requested. 25 @note: Currently this function just creates an image if requested.
25 """ 26 """
26 image_filename = kvm_vm.get_image_filename(params, test.bindir) 27 image_filename = virt_vm.get_image_filename(params, test.bindir)
27 28
28 create_image = False 29 create_image = False
29 30
30 if params.get("force_create_image") == "yes": 31 if params.get("force_create_image") == "yes":
31 logging.debug("'force_create_image' specified; creating image...") 32 logging.debug("'force_create_image' specified; creating image...")
32 create_image = True 33 create_image = True
33 elif (params.get("create_image") == "yes" and not 34 elif (params.get("create_image") == "yes" and not
34 os.path.exists(image_filename)): 35 os.path.exists(image_filename)):
35 logging.debug("Creating image...") 36 logging.debug("Creating image...")
36 create_image = True 37 create_image = True
37 38
38 if create_image and not kvm_vm.create_image(params, test.bindir): 39 if create_image and not virt_vm.create_image(params, test.bindir):
39 raise error.TestError("Could not create image") 40 raise error.TestError("Could not create image")
40 41
41 42
42 def preprocess_vm(test, params, env, name): 43 def preprocess_vm(test, params, env, name):
43 """ 44 """
44 Preprocess a single VM object according to the instructions in params. 45 Preprocess a single VM object according to the instructions in params.
45 Start the VM if requested and get a screendump. 46 Start the VM if requested and get a screendump.
46 47
47 @param test: An Autotest test object. 48 @param test: An Autotest test object.
48 @param params: A dict containing VM preprocessing parameters. 49 @param params: A dict containing VM preprocessing parameters.
49 @param env: The environment (a dict-like object). 50 @param env: The environment (a dict-like object).
50 @param name: The name of the VM object. 51 @param name: The name of the VM object.
51 """ 52 """
52 logging.debug("Preprocessing VM '%s'..." % name) 53 logging.debug("Preprocessing VM '%s'..." % name)
53 vm = env.get_vm(name) 54 vm = env.get_vm(name)
54 if not vm: 55 if not vm:
55 logging.debug("VM object does not exist; creating it") 56 logging.debug("VM object does not exist; creating it")
56 vm = kvm_vm.VM(name, params, test.bindir, env.get("address_cache")) 57 vm_type = params.get('vm_type')
58 if vm_type == 'kvm':
59 vm = kvm_vm.VM(name, params, test.bindir, env.get("address_cache"))
57 env.register_vm(name, vm) 60 env.register_vm(name, vm)
58 61
59 start_vm = False 62 start_vm = False
60 63
61 if params.get("restart_vm") == "yes": 64 if params.get("restart_vm") == "yes":
62 logging.debug("'restart_vm' specified; (re)starting VM...") 65 logging.debug("'restart_vm' specified; (re)starting VM...")
63 start_vm = True 66 start_vm = True
64 elif params.get("migration_mode"): 67 elif params.get("migration_mode"):
65 logging.debug("Starting VM in incoming migration mode...") 68 logging.debug("Starting VM in incoming migration mode...")
66 start_vm = True 69 start_vm = True
67 elif params.get("start_vm") == "yes": 70 elif params.get("start_vm") == "yes":
68 if not vm.is_alive(): 71 if not vm.is_alive():
69 logging.debug("VM is not alive; starting it...") 72 logging.debug("VM is not alive; starting it...")
70 start_vm = True 73 start_vm = True
71 elif vm.make_qemu_command() != vm.make_qemu_command(name, params, 74 if vm.needs_restart(name=name, params=params, basedir=test.bindir):
72 test.bindir): 75 logging.debug("Current VM specs differ from requested one; "
73 logging.debug("VM's qemu command differs from requested one; "
74 "restarting it...") 76 "restarting it...")
75 start_vm = True 77 start_vm = True
76 78
77 if start_vm: 79 if start_vm:
78 # Start the VM (or restart it if it's already up) 80 # Start the VM (or restart it if it's already up)
79 vm.create(name, params, test.bindir, 81 vm.create(name, params, test.bindir,
80 migration_mode=params.get("migration_mode")) 82 migration_mode=params.get("migration_mode"))
81 else: 83 else:
82 # Don't start the VM, just update its params 84 # Don't start the VM, just update its params
83 vm.params = params 85 vm.params = params
84 86
85 scrdump_filename = os.path.join(test.debugdir, "pre_%s.ppm" % name) 87 scrdump_filename = os.path.join(test.debugdir, "pre_%s.ppm" % name)
86 try: 88 try:
87 if vm.monitor: 89 if vm.monitor:
88 vm.monitor.screendump(scrdump_filename, debug=False) 90 vm.monitor.screendump(scrdump_filename, debug=False)
89 except kvm_monitor.MonitorError, e: 91 except kvm_monitor.MonitorError, e:
90 logging.warn(e) 92 logging.warn(e)
91 93
92 94
93 def postprocess_image(test, params): 95 def postprocess_image(test, params):
94 """ 96 """
95 Postprocess a single QEMU image according to the instructions in params. 97 Postprocess a single QEMU image according to the instructions in params.
96 98
97 @param test: An Autotest test object. 99 @param test: An Autotest test object.
98 @param params: A dict containing image postprocessing parameters. 100 @param params: A dict containing image postprocessing parameters.
99 """ 101 """
100 if params.get("check_image") == "yes": 102 if params.get("check_image") == "yes":
101 kvm_vm.check_image(params, test.bindir) 103 virt_vm.check_image(params, test.bindir)
102 if params.get("remove_image") == "yes": 104 if params.get("remove_image") == "yes":
103 kvm_vm.remove_image(params, test.bindir) 105 virt_vm.remove_image(params, test.bindir)
104 106
105 107
106 def postprocess_vm(test, params, env, name): 108 def postprocess_vm(test, params, env, name):
107 """ 109 """
108 Postprocess a single VM object according to the instructions in params. 110 Postprocess a single VM object according to the instructions in params.
109 Kill the VM if requested and get a screendump. 111 Kill the VM if requested and get a screendump.
110 112
111 @param test: An Autotest test object. 113 @param test: An Autotest test object.
112 @param params: A dict containing VM postprocessing parameters. 114 @param params: A dict containing VM postprocessing parameters.
113 @param env: The environment (a dict-like object). 115 @param env: The environment (a dict-like object).
114 @param name: The name of the VM object. 116 @param name: The name of the VM object.
115 """ 117 """
116 logging.debug("Postprocessing VM '%s'..." % name) 118 logging.debug("Postprocessing VM '%s'..." % name)
117 vm = env.get_vm(name) 119 vm = env.get_vm(name)
118 if not vm: 120 if not vm:
119 return 121 return
120 122
121 scrdump_filename = os.path.join(test.debugdir, "post_%s.ppm" % name) 123 scrdump_filename = os.path.join(test.debugdir, "post_%s.ppm" % name)
122 try: 124 try:
123 if vm.monitor: 125 if vm.monitor:
124 vm.monitor.screendump(scrdump_filename, debug=False) 126 vm.monitor.screendump(scrdump_filename, debug=False)
125 except kvm_monitor.MonitorError, e: 127 except kvm_monitor.MonitorError, e:
126 logging.warn(e) 128 logging.warn(e)
127 129
128 if params.get("kill_vm") == "yes": 130 if params.get("kill_vm") == "yes":
129 kill_vm_timeout = float(params.get("kill_vm_timeout", 0)) 131 kill_vm_timeout = float(params.get("kill_vm_timeout", 0))
130 if kill_vm_timeout: 132 if kill_vm_timeout:
131 logging.debug("'kill_vm' specified; waiting for VM to shut down " 133 logging.debug("'kill_vm' specified; waiting for VM to shut down "
132 "before killing it...") 134 "before killing it...")
133 kvm_utils.wait_for(vm.is_dead, kill_vm_timeout, 0, 1) 135 virt_utils.wait_for(vm.is_dead, kill_vm_timeout, 0, 1)
134 else: 136 else:
135 logging.debug("'kill_vm' specified; killing VM...") 137 logging.debug("'kill_vm' specified; killing VM...")
136 vm.destroy(gracefully = params.get("kill_vm_gracefully") == "yes") 138 vm.destroy(gracefully = params.get("kill_vm_gracefully") == "yes")
137 139
138 140
139 def process_command(test, params, env, command, command_timeout, 141 def process_command(test, params, env, command, command_timeout,
140 command_noncritical): 142 command_noncritical):
141 """ 143 """
142 Pre- or post- custom commands to be executed before/after a test is run 144 Pre- or post- custom commands to be executed before/after a test is run
143 145
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
194 @param env: The environment (a dict-like object). 196 @param env: The environment (a dict-like object).
195 """ 197 """
196 error.context("preprocessing") 198 error.context("preprocessing")
197 # Start tcpdump if it isn't already running 199 # Start tcpdump if it isn't already running
198 if "address_cache" not in env: 200 if "address_cache" not in env:
199 env["address_cache"] = {} 201 env["address_cache"] = {}
200 if "tcpdump" in env and not env["tcpdump"].is_alive(): 202 if "tcpdump" in env and not env["tcpdump"].is_alive():
201 env["tcpdump"].close() 203 env["tcpdump"].close()
202 del env["tcpdump"] 204 del env["tcpdump"]
203 if "tcpdump" not in env and params.get("run_tcpdump", "yes") == "yes": 205 if "tcpdump" not in env and params.get("run_tcpdump", "yes") == "yes":
204 cmd = "%s -npvi any 'dst port 68'" % kvm_utils.find_command("tcpdump") 206 cmd = "%s -npvi any 'dst port 68'" % virt_utils.find_command("tcpdump")
205 logging.debug("Starting tcpdump (%s)...", cmd) 207 logging.debug("Starting tcpdump (%s)...", cmd)
206 env["tcpdump"] = kvm_subprocess.Tail( 208 env["tcpdump"] = aexpect.Tail(
207 command=cmd, 209 command=cmd,
208 output_func=_update_address_cache, 210 output_func=_update_address_cache,
209 output_params=(env["address_cache"],)) 211 output_params=(env["address_cache"],))
210 if kvm_utils.wait_for(lambda: not env["tcpdump"].is_alive(), 212 if virt_utils.wait_for(lambda: not env["tcpdump"].is_alive(),
211 0.1, 0.1, 1.0): 213 0.1, 0.1, 1.0):
212 logging.warn("Could not start tcpdump") 214 logging.warn("Could not start tcpdump")
213 logging.warn("Status: %s" % env["tcpdump"].get_status()) 215 logging.warn("Status: %s" % env["tcpdump"].get_status())
214 logging.warn("Output:" + kvm_utils.format_str_for_message( 216 logging.warn("Output:" + virt_utils.format_str_for_message(
215 env["tcpdump"].get_output())) 217 env["tcpdump"].get_output()))
216 218
217 # Destroy and remove VMs that are no longer needed in the environment 219 # Destroy and remove VMs that are no longer needed in the environment
218 requested_vms = params.objects("vms") 220 requested_vms = params.objects("vms")
219 for key in env.keys(): 221 for key in env.keys():
220 vm = env[key] 222 vm = env[key]
221 if not kvm_utils.is_vm(vm): 223 if not virt_utils.is_vm(vm):
222 continue 224 continue
223 if not vm.name in requested_vms: 225 if not vm.name in requested_vms:
224 logging.debug("VM '%s' found in environment but not required for " 226 logging.debug("VM '%s' found in environment but not required for "
225 "test; removing it..." % vm.name) 227 "test; removing it..." % vm.name)
226 vm.destroy() 228 vm.destroy()
227 del env[key] 229 del env[key]
228 230
229 # Get the KVM kernel module version and write it as a keyval 231 # Get the KVM kernel module version and write it as a keyval
230 logging.debug("Fetching KVM module version...") 232 logging.debug("Fetching KVM module version...")
231 if os.path.exists("/dev/kvm"): 233 if os.path.exists("/dev/kvm"):
232 try: 234 try:
233 kvm_version = open("/sys/module/kvm/version").read().strip() 235 kvm_version = open("/sys/module/kvm/version").read().strip()
234 except: 236 except:
235 kvm_version = os.uname()[2] 237 kvm_version = os.uname()[2]
236 else: 238 else:
237 kvm_version = "Unknown" 239 kvm_version = "Unknown"
238 logging.debug("KVM module not loaded") 240 logging.debug("KVM module not loaded")
239 logging.debug("KVM version: %s" % kvm_version) 241 logging.debug("KVM version: %s" % kvm_version)
240 test.write_test_keyval({"kvm_version": kvm_version}) 242 test.write_test_keyval({"kvm_version": kvm_version})
241 243
242 # Get the KVM userspace version and write it as a keyval 244 # Get the KVM userspace version and write it as a keyval
243 logging.debug("Fetching KVM userspace version...") 245 logging.debug("Fetching KVM userspace version...")
244 qemu_path = kvm_utils.get_path(test.bindir, params.get("qemu_binary", 246 qemu_path = virt_utils.get_path(test.bindir, params.get("qemu_binary",
245 "qemu")) 247 "qemu"))
246 version_line = commands.getoutput("%s -help | head -n 1" % qemu_path) 248 version_line = commands.getoutput("%s -help | head -n 1" % qemu_path)
247 matches = re.findall("[Vv]ersion .*?,", version_line) 249 matches = re.findall("[Vv]ersion .*?,", version_line)
248 if matches: 250 if matches:
249 kvm_userspace_version = " ".join(matches[0].split()[1:]).strip(",") 251 kvm_userspace_version = " ".join(matches[0].split()[1:]).strip(",")
250 else: 252 else:
251 kvm_userspace_version = "Unknown" 253 kvm_userspace_version = "Unknown"
252 logging.debug("Could not fetch KVM userspace version") 254 logging.debug("Could not fetch KVM userspace version")
253 logging.debug("KVM userspace version: %s" % kvm_userspace_version) 255 logging.debug("KVM userspace version: %s" % kvm_userspace_version)
254 test.write_test_keyval({"kvm_userspace_version": kvm_userspace_version}) 256 test.write_test_keyval({"kvm_userspace_version": kvm_userspace_version})
255 257
256 if params.get("setup_hugepages") == "yes": 258 if params.get("setup_hugepages") == "yes":
257 h = test_setup.HugePageConfig(params) 259 h = virt_test_setup.HugePageConfig(params)
258 h.setup() 260 h.setup()
259 261
260 # Execute any pre_commands 262 # Execute any pre_commands
261 if params.get("pre_command"): 263 if params.get("pre_command"):
262 process_command(test, params, env, params.get("pre_command"), 264 process_command(test, params, env, params.get("pre_command"),
263 int(params.get("pre_command_timeout", "600")), 265 int(params.get("pre_command_timeout", "600")),
264 params.get("pre_command_noncritical") == "yes") 266 params.get("pre_command_noncritical") == "yes")
265 267
266 # Preprocess all VMs and images 268 # Preprocess all VMs and images
267 process(test, params, env, preprocess_image, preprocess_vm) 269 process(test, params, env, preprocess_image, preprocess_vm)
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
333 335
334 # Kill all unresponsive VMs 336 # Kill all unresponsive VMs
335 if params.get("kill_unresponsive_vms") == "yes": 337 if params.get("kill_unresponsive_vms") == "yes":
336 logging.debug("'kill_unresponsive_vms' specified; killing all VMs " 338 logging.debug("'kill_unresponsive_vms' specified; killing all VMs "
337 "that fail to respond to a remote login request...") 339 "that fail to respond to a remote login request...")
338 for vm in env.get_all_vms(): 340 for vm in env.get_all_vms():
339 if vm.is_alive(): 341 if vm.is_alive():
340 try: 342 try:
341 session = vm.login() 343 session = vm.login()
342 session.close() 344 session.close()
343 except (kvm_utils.LoginError, kvm_vm.VMError), e: 345 except (virt_utils.LoginError, virt_vm.VMError), e:
344 logging.warn(e) 346 logging.warn(e)
345 vm.destroy(gracefully=False) 347 vm.destroy(gracefully=False)
346 348
347 # Kill all kvm_subprocess tail threads 349 # Kill all aexpect tail threads
348 kvm_subprocess.kill_tail_threads() 350 aexpect.kill_tail_threads()
349 351
350 # Terminate tcpdump if no VMs are alive 352 # Terminate tcpdump if no VMs are alive
351 living_vms = [vm for vm in env.get_all_vms() if vm.is_alive()] 353 living_vms = [vm for vm in env.get_all_vms() if vm.is_alive()]
352 if not living_vms and "tcpdump" in env: 354 if not living_vms and "tcpdump" in env:
353 env["tcpdump"].close() 355 env["tcpdump"].close()
354 del env["tcpdump"] 356 del env["tcpdump"]
355 357
356 if params.get("setup_hugepages") == "yes": 358 if params.get("setup_hugepages") == "yes":
357 h = test_setup.HugePageConfig(params) 359 h = virt_test_setup.HugePageConfig(params)
358 h.cleanup() 360 h.cleanup()
359 361
360 # Execute any post_commands 362 # Execute any post_commands
361 if params.get("post_command"): 363 if params.get("post_command"):
362 process_command(test, params, env, params.get("post_command"), 364 process_command(test, params, env, params.get("post_command"),
363 int(params.get("post_command_timeout", "600")), 365 int(params.get("post_command_timeout", "600")),
364 params.get("post_command_noncritical") == "yes") 366 params.get("post_command_noncritical") == "yes")
365 367
366 368
367 def postprocess_on_error(test, params, env): 369 def postprocess_on_error(test, params, env):
(...skipping 21 matching lines...) Expand all
389 mac_address, address_cache.get("last_seen")) 391 mac_address, address_cache.get("last_seen"))
390 address_cache[mac_address] = address_cache.get("last_seen") 392 address_cache[mac_address] = address_cache.get("last_seen")
391 address_cache["time_%s" % mac_address] = time.time() 393 address_cache["time_%s" % mac_address] = time.time()
392 del address_cache["last_seen"] 394 del address_cache["last_seen"]
393 395
394 396
395 def _take_screendumps(test, params, env): 397 def _take_screendumps(test, params, env):
396 global _screendump_thread_termination_event 398 global _screendump_thread_termination_event
397 temp_dir = test.debugdir 399 temp_dir = test.debugdir
398 if params.get("screendump_temp_dir"): 400 if params.get("screendump_temp_dir"):
399 temp_dir = kvm_utils.get_path(test.bindir, 401 temp_dir = virt_utils.get_path(test.bindir,
400 params.get("screendump_temp_dir")) 402 params.get("screendump_temp_dir"))
401 try: 403 try:
402 os.makedirs(temp_dir) 404 os.makedirs(temp_dir)
403 except OSError: 405 except OSError:
404 pass 406 pass
405 temp_filename = os.path.join(temp_dir, "scrdump-%s.ppm" % 407 temp_filename = os.path.join(temp_dir, "scrdump-%s.ppm" %
406 kvm_utils.generate_random_string(6)) 408 virt_utils.generate_random_string(6))
407 delay = float(params.get("screendump_delay", 5)) 409 delay = float(params.get("screendump_delay", 5))
408 quality = int(params.get("screendump_quality", 30)) 410 quality = int(params.get("screendump_quality", 30))
409 411
410 cache = {} 412 cache = {}
411 413
412 while True: 414 while True:
413 for vm in env.get_all_vms(): 415 for vm in env.get_all_vms():
414 if not vm.is_alive(): 416 if not vm.is_alive():
415 continue 417 continue
416 try: 418 try:
(...skipping 28 matching lines...) Expand all
445 image = PIL.Image.open(temp_filename) 447 image = PIL.Image.open(temp_filename)
446 image.save(screendump_filename, format="JPEG", quality=quali ty) 448 image.save(screendump_filename, format="JPEG", quality=quali ty)
447 cache[hash] = screendump_filename 449 cache[hash] = screendump_filename
448 except NameError: 450 except NameError:
449 pass 451 pass
450 os.unlink(temp_filename) 452 os.unlink(temp_filename)
451 if _screendump_thread_termination_event.isSet(): 453 if _screendump_thread_termination_event.isSet():
452 _screendump_thread_termination_event = None 454 _screendump_thread_termination_event = None
453 break 455 break
454 _screendump_thread_termination_event.wait(delay) 456 _screendump_thread_termination_event.wait(delay)
OLDNEW
« no previous file with comments | « client/virt/tests/yum_update.py ('k') | client/virt/virt_installer.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698