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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « client/tests/kvm/kvm_utils.py ('k') | client/tests/kvm/migration_control.srv » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/python 1 #!/usr/bin/python
2 """ 2 """
3 Utility classes and functions to handle Virtual Machine creation using qemu. 3 Utility classes and functions to handle Virtual Machine creation using qemu.
4 4
5 @copyright: 2008-2009 Red Hat Inc. 5 @copyright: 2008-2009 Red Hat Inc.
6 """ 6 """
7 7
8 import time, socket, os, logging, fcntl, re, commands, shelve, glob 8 import time, socket, os, logging, fcntl, re, commands, shelve, glob
9 import kvm_utils, kvm_subprocess, kvm_monitor, rss_file_transfer 9 import kvm_utils, kvm_subprocess, kvm_monitor, rss_file_transfer
10 from autotest_lib.client.common_lib import error 10 from autotest_lib.client.common_lib import error
11 from autotest_lib.client.bin import utils 11 from autotest_lib.client.bin import utils
12 12
13 13
14 def get_image_filename(params, root_dir): 14 def get_image_filename(params, root_dir):
15 """ 15 """
16 Generate an image path from params and root_dir. 16 Generate an image path from params and root_dir.
17 17
18 @param params: Dictionary containing the test parameters. 18 @param params: Dictionary containing the test parameters.
19 @param root_dir: Base directory for relative filenames. 19 @param root_dir: Base directory for relative filenames.
20 20
21 @note: params should contain: 21 @note: params should contain:
22 image_name -- the name of the image file, without extension 22 image_name -- the name of the image file, without extension
23 image_format -- the format of the image (qcow2, raw etc) 23 image_format -- the format of the image (qcow2, raw etc)
24 """ 24 """
25 image_name = params.get("image_name", "image") 25 image_name = params.get("image_name", "image")
26 image_format = params.get("image_format", "qcow2") 26 image_format = params.get("image_format", "qcow2")
27 if params.get("image_raw_device") == "yes":
28 return image_name
29 image_filename = "%s.%s" % (image_name, image_format) 27 image_filename = "%s.%s" % (image_name, image_format)
30 image_filename = kvm_utils.get_path(root_dir, image_filename) 28 image_filename = kvm_utils.get_path(root_dir, image_filename)
31 return image_filename 29 return image_filename
32 30
33 31
34 def create_image(params, root_dir): 32 def create_image(params, root_dir):
35 """ 33 """
36 Create an image using qemu_image. 34 Create an image using qemu_image.
37 35
38 @param params: Dictionary containing the test parameters. 36 @param params: Dictionary containing the test parameters.
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
90 os.unlink(image_filename) 88 os.unlink(image_filename)
91 else: 89 else:
92 logging.debug("Image file %s not found") 90 logging.debug("Image file %s not found")
93 91
94 92
95 class VM: 93 class VM:
96 """ 94 """
97 This class handles all basic VM operations. 95 This class handles all basic VM operations.
98 """ 96 """
99 97
100 def __init__(self, name, params, root_dir, address_cache, state=None): 98 def __init__(self, name, params, root_dir, address_cache):
101 """ 99 """
102 Initialize the object and set a few attributes. 100 Initialize the object and set a few attributes.
103 101
104 @param name: The name of the object 102 @param name: The name of the object
105 @param params: A dict containing VM params 103 @param params: A dict containing VM params
106 (see method make_qemu_command for a full description) 104 (see method make_qemu_command for a full description)
107 @param root_dir: Base directory for relative filenames 105 @param root_dir: Base directory for relative filenames
108 @param address_cache: A dict that maps MAC addresses to IP addresses 106 @param address_cache: A dict that maps MAC addresses to IP addresses
109 @param state: If provided, use this as self.__dict__
110 """ 107 """
111 if state: 108 self.process = None
112 self.__dict__ = state 109 self.serial_console = None
113 else: 110 self.redirs = {}
114 self.process = None 111 self.vnc_port = 5900
115 self.serial_console = None 112 self.monitors = []
116 self.redirs = {} 113 self.pci_assignable = None
117 self.vnc_port = 5900 114 self.netdev_id = []
118 self.monitors = [] 115 self.uuid = None
119 self.pci_assignable = None
120 self.netdev_id = []
121 self.uuid = None
122
123 # Find a unique identifier for this VM
124 while True:
125 self.instance = (time.strftime("%Y%m%d-%H%M%S-") +
126 kvm_utils.generate_random_string(4))
127 if not glob.glob("/tmp/*%s" % self.instance):
128 break
129 116
130 self.name = name 117 self.name = name
131 self.params = params 118 self.params = params
132 self.root_dir = root_dir 119 self.root_dir = root_dir
133 self.address_cache = address_cache 120 self.address_cache = address_cache
134 121
122 # Find a unique identifier for this VM
123 while True:
124 self.instance = (time.strftime("%Y%m%d-%H%M%S-") +
125 kvm_utils.generate_random_string(4))
126 if not glob.glob("/tmp/*%s" % self.instance):
127 break
135 128
136 def clone(self, name=None, params=None, root_dir=None, address_cache=None, 129
137 copy_state=False): 130 def clone(self, name=None, params=None, root_dir=None, address_cache=None):
138 """ 131 """
139 Return a clone of the VM object with optionally modified parameters. 132 Return a clone of the VM object with optionally modified parameters.
140 The clone is initially not alive and needs to be started using create(). 133 The clone is initially not alive and needs to be started using create().
141 Any parameters not passed to this function are copied from the source 134 Any parameters not passed to this function are copied from the source
142 VM. 135 VM.
143 136
144 @param name: Optional new VM name 137 @param name: Optional new VM name
145 @param params: Optional new VM creation parameters 138 @param params: Optional new VM creation parameters
146 @param root_dir: Optional new base directory for relative filenames 139 @param root_dir: Optional new base directory for relative filenames
147 @param address_cache: A dict that maps MAC addresses to IP addresses 140 @param address_cache: A dict that maps MAC addresses to IP addresses
148 @param copy_state: If True, copy the original VM's state to the clone.
149 Mainly useful for make_qemu_command().
150 """ 141 """
151 if name is None: 142 if name is None:
152 name = self.name 143 name = self.name
153 if params is None: 144 if params is None:
154 params = self.params.copy() 145 params = self.params.copy()
155 if root_dir is None: 146 if root_dir is None:
156 root_dir = self.root_dir 147 root_dir = self.root_dir
157 if address_cache is None: 148 if address_cache is None:
158 address_cache = self.address_cache 149 address_cache = self.address_cache
159 if copy_state: 150 return VM(name, params, root_dir, address_cache)
160 state = self.__dict__.copy()
161 else:
162 state = None
163 return VM(name, params, root_dir, address_cache, state)
164 151
165 152
166 def make_qemu_command(self, name=None, params=None, root_dir=None): 153 def make_qemu_command(self, name=None, params=None, root_dir=None):
167 """ 154 """
168 Generate a qemu command line. All parameters are optional. If a 155 Generate a qemu command line. All parameters are optional. If a
169 parameter is not supplied, the corresponding value stored in the 156 parameter is not supplied, the corresponding value stored in the
170 class attributes is used. 157 class attributes is used.
171 158
172 @param name: The name of the object 159 @param name: The name of the object
173 @param params: A dict containing VM params 160 @param params: A dict containing VM params
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
242 if format: cmd += ",if=%s" % format 229 if format: cmd += ",if=%s" % format
243 if cache: cmd += ",cache=%s" % cache 230 if cache: cmd += ",cache=%s" % cache
244 if werror: cmd += ",werror=%s" % werror 231 if werror: cmd += ",werror=%s" % werror
245 if serial: cmd += ",serial='%s'" % serial 232 if serial: cmd += ",serial='%s'" % serial
246 if snapshot: cmd += ",snapshot=on" 233 if snapshot: cmd += ",snapshot=on"
247 if boot: cmd += ",boot=on" 234 if boot: cmd += ",boot=on"
248 return cmd 235 return cmd
249 236
250 def add_nic(help, vlan, model=None, mac=None, netdev_id=None, 237 def add_nic(help, vlan, model=None, mac=None, netdev_id=None,
251 nic_extra_params=None): 238 nic_extra_params=None):
252 if has_option(help, "netdev"):
253 netdev_vlan_str = ",netdev=%s" % netdev_id
254 else:
255 netdev_vlan_str = ",vlan=%d" % vlan
256 if has_option(help, "device"): 239 if has_option(help, "device"):
240 if model == "virtio":
241 model="virtio-net-pci"
257 if not model: 242 if not model:
258 model = "rtl8139" 243 model= "rtl8139"
259 elif model == "virtio": 244 cmd = " -device %s" % model
260 model = "virtio-net-pci"
261 cmd = " -device %s" % model + netdev_vlan_str
262 if mac: 245 if mac:
263 cmd += ",mac='%s'" % mac 246 cmd += ",mac=%s" % mac
247 if has_option(help, "netdev"):
248 cmd += ",netdev=%s" % netdev_id
249 else:
250 cmd += "vlan=%d," % vlan
264 if nic_extra_params: 251 if nic_extra_params:
265 cmd += ",%s" % nic_extra_params 252 cmd += ",%s" % nic_extra_params
266 else: 253 else:
267 cmd = " -net nic" + netdev_vlan_str 254 if has_option(help, "netdev"):
255 cmd = " -net nic,netdev=%s" % netdev_id
256 else:
257 cmd = " -net nic,vlan=%d" % vlan
268 if model: 258 if model:
269 cmd += ",model=%s" % model 259 cmd += ",model=%s" % model
270 if mac: 260 if mac:
271 cmd += ",macaddr='%s'" % mac 261 cmd += ",macaddr='%s'" % mac
272 return cmd 262 return cmd
273 263
274 def add_net(help, vlan, mode, ifname=None, script=None, 264 def add_net(help, vlan, mode, ifname=None, script=None,
275 downscript=None, tftp=None, bootfile=None, hostfwd=[], 265 downscript=None, tftp=None, bootfile=None, hostfwd=[],
276 netdev_id=None, netdev_extra_params=None): 266 netdev_id=None, vhost=False):
277 if has_option(help, "netdev"): 267 if has_option(help, "netdev"):
278 cmd = " -netdev %s,id=%s" % (mode, netdev_id) 268 cmd = " -netdev %s,id=%s" % (mode, netdev_id)
279 if netdev_extra_params: 269 if vhost:
280 cmd += ",%s" % netdev_extra_params 270 cmd +=",vhost=on"
281 else: 271 else:
282 cmd = " -net %s,vlan=%d" % (mode, vlan) 272 cmd = " -net %s,vlan=%d" % (mode, vlan)
283 if mode == "tap": 273 if mode == "tap":
284 if ifname: cmd += ",ifname='%s'" % ifname 274 if ifname: cmd += ",ifname='%s'" % ifname
285 if script: cmd += ",script='%s'" % script 275 if script: cmd += ",script='%s'" % script
286 cmd += ",downscript='%s'" % (downscript or "no") 276 cmd += ",downscript='%s'" % (downscript or "no")
287 elif mode == "user": 277 elif mode == "user":
288 if tftp and "[,tftp=" in help: 278 if tftp and "[,tftp=" in help:
289 cmd += ",tftp='%s'" % tftp 279 cmd += ",tftp='%s'" % tftp
290 if bootfile and "[,bootfile=" in help: 280 if bootfile and "[,bootfile=" in help:
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
354 return " -no-hpet" 344 return " -no-hpet"
355 else: 345 else:
356 return "" 346 return ""
357 347
358 # End of command line option wrappers 348 # End of command line option wrappers
359 349
360 if name is None: name = self.name 350 if name is None: name = self.name
361 if params is None: params = self.params 351 if params is None: params = self.params
362 if root_dir is None: root_dir = self.root_dir 352 if root_dir is None: root_dir = self.root_dir
363 353
364 # Clone this VM using the new params
365 vm = self.clone(name, params, root_dir, copy_state=True)
366
367 qemu_binary = kvm_utils.get_path(root_dir, params.get("qemu_binary", 354 qemu_binary = kvm_utils.get_path(root_dir, params.get("qemu_binary",
368 "qemu")) 355 "qemu"))
369 # Get the output of 'qemu -help' (log a message in case this call never 356 # Get the output of 'qemu -help' (log a message in case this call never
370 # returns or causes some other kind of trouble) 357 # returns or causes some other kind of trouble)
371 logging.debug("Getting output of 'qemu -help'") 358 logging.debug("Getting output of 'qemu -help'")
372 help = commands.getoutput("%s -help" % qemu_binary) 359 help = commands.getoutput("%s -help" % qemu_binary)
373 360
374 # Start constructing the qemu command 361 # Start constructing the qemu command
375 qemu_cmd = "" 362 qemu_cmd = ""
376 # Set the X11 display parameter if requested 363 # Set the X11 display parameter if requested
377 if params.get("x11_display"): 364 if params.get("x11_display"):
378 qemu_cmd += "DISPLAY=%s " % params.get("x11_display") 365 qemu_cmd += "DISPLAY=%s " % params.get("x11_display")
379 # Add the qemu binary 366 # Add the qemu binary
380 qemu_cmd += qemu_binary 367 qemu_cmd += qemu_binary
381 # Add the VM's name 368 # Add the VM's name
382 qemu_cmd += add_name(help, name) 369 qemu_cmd += add_name(help, name)
383 # Add monitors 370 # Add monitors
384 for monitor_name in params.objects("monitors"): 371 for monitor_name in kvm_utils.get_sub_dict_names(params, "monitors"):
385 monitor_params = params.object_params(monitor_name) 372 monitor_params = kvm_utils.get_sub_dict(params, monitor_name)
386 monitor_filename = vm.get_monitor_filename(monitor_name) 373 monitor_filename = self.get_monitor_filename(monitor_name)
387 if monitor_params.get("monitor_type") == "qmp": 374 if monitor_params.get("monitor_type") == "qmp":
388 qemu_cmd += add_qmp_monitor(help, monitor_filename) 375 qemu_cmd += add_qmp_monitor(help, monitor_filename)
389 else: 376 else:
390 qemu_cmd += add_human_monitor(help, monitor_filename) 377 qemu_cmd += add_human_monitor(help, monitor_filename)
391 378
392 # Add serial console redirection 379 # Add serial console redirection
393 qemu_cmd += add_serial(help, vm.get_serial_console_filename()) 380 qemu_cmd += add_serial(help, self.get_serial_console_filename())
394 381
395 for image_name in params.objects("images"): 382 for image_name in kvm_utils.get_sub_dict_names(params, "images"):
396 image_params = params.object_params(image_name) 383 image_params = kvm_utils.get_sub_dict(params, image_name)
397 if image_params.get("boot_drive") == "no": 384 if image_params.get("boot_drive") == "no":
398 continue 385 continue
399 qemu_cmd += add_drive(help, 386 qemu_cmd += add_drive(help,
400 get_image_filename(image_params, root_dir), 387 get_image_filename(image_params, root_dir),
401 image_params.get("drive_index"), 388 image_params.get("drive_index"),
402 image_params.get("drive_format"), 389 image_params.get("drive_format"),
403 image_params.get("drive_cache"), 390 image_params.get("drive_cache"),
404 image_params.get("drive_werror"), 391 image_params.get("drive_werror"),
405 image_params.get("drive_serial"), 392 image_params.get("drive_serial"),
406 image_params.get("image_snapshot") == "yes", 393 image_params.get("image_snapshot") == "yes",
407 image_params.get("image_boot") == "yes") 394 image_params.get("image_boot") == "yes")
408 395
409 redirs = [] 396 redirs = []
410 for redir_name in params.objects("redirs"): 397 for redir_name in kvm_utils.get_sub_dict_names(params, "redirs"):
411 redir_params = params.object_params(redir_name) 398 redir_params = kvm_utils.get_sub_dict(params, redir_name)
412 guest_port = int(redir_params.get("guest_port")) 399 guest_port = int(redir_params.get("guest_port"))
413 host_port = vm.redirs.get(guest_port) 400 host_port = self.redirs.get(guest_port)
414 redirs += [(host_port, guest_port)] 401 redirs += [(host_port, guest_port)]
415 402
416 vlan = 0 403 vlan = 0
417 for nic_name in params.objects("nics"): 404 for nic_name in kvm_utils.get_sub_dict_names(params, "nics"):
418 nic_params = params.object_params(nic_name) 405 nic_params = kvm_utils.get_sub_dict(params, nic_name)
419 try:
420 netdev_id = vm.netdev_id[vlan]
421 except IndexError:
422 netdev_id = None
423 # Handle the '-net nic' part 406 # Handle the '-net nic' part
424 mac = vm.get_mac_address(vlan) 407 mac = self.get_mac_address(vlan)
425 qemu_cmd += add_nic(help, vlan, nic_params.get("nic_model"), mac, 408 qemu_cmd += add_nic(help, vlan, nic_params.get("nic_model"), mac,
426 netdev_id, nic_params.get("nic_extra_params")) 409 self.netdev_id[vlan],
410 nic_params.get("nic_extra_params"))
427 # Handle the '-net tap' or '-net user' part 411 # Handle the '-net tap' or '-net user' part
428 script = nic_params.get("nic_script") 412 script = nic_params.get("nic_script")
429 downscript = nic_params.get("nic_downscript") 413 downscript = nic_params.get("nic_downscript")
430 tftp = nic_params.get("tftp") 414 tftp = nic_params.get("tftp")
431 if script: 415 if script:
432 script = kvm_utils.get_path(root_dir, script) 416 script = kvm_utils.get_path(root_dir, script)
433 if downscript: 417 if downscript:
434 downscript = kvm_utils.get_path(root_dir, downscript) 418 downscript = kvm_utils.get_path(root_dir, downscript)
435 if tftp: 419 if tftp:
436 tftp = kvm_utils.get_path(root_dir, tftp) 420 tftp = kvm_utils.get_path(root_dir, tftp)
437 qemu_cmd += add_net(help, vlan, nic_params.get("nic_mode", "user"), 421 qemu_cmd += add_net(help, vlan, nic_params.get("nic_mode", "user"),
438 vm.get_ifname(vlan), 422 self.get_ifname(vlan),
439 script, downscript, tftp, 423 script, downscript, tftp,
440 nic_params.get("bootp"), redirs, netdev_id, 424 nic_params.get("bootp"), redirs,
441 nic_params.get("netdev_extra_params")) 425 self.netdev_id[vlan],
426 nic_params.get("vhost")=="yes")
442 # Proceed to next NIC 427 # Proceed to next NIC
443 vlan += 1 428 vlan += 1
444 429
445 mem = params.get("mem") 430 mem = params.get("mem")
446 if mem: 431 if mem:
447 qemu_cmd += add_mem(help, mem) 432 qemu_cmd += add_mem(help, mem)
448 433
449 smp = params.get("smp") 434 smp = params.get("smp")
450 if smp: 435 if smp:
451 qemu_cmd += add_smp(help, smp) 436 qemu_cmd += add_smp(help, smp)
452 437
453 for cdrom in params.objects("cdroms"): 438 cdroms = kvm_utils.get_sub_dict_names(params, "cdroms")
454 cdrom_params = params.object_params(cdrom) 439 for cdrom in cdroms:
440 cdrom_params = kvm_utils.get_sub_dict(params, cdrom)
455 iso = cdrom_params.get("cdrom") 441 iso = cdrom_params.get("cdrom")
456 if iso: 442 if iso:
457 qemu_cmd += add_cdrom(help, kvm_utils.get_path(root_dir, iso), 443 qemu_cmd += add_cdrom(help, kvm_utils.get_path(root_dir, iso),
458 cdrom_params.get("drive_index")) 444 cdrom_params.get("drive_index"))
459 445
460 # We may want to add {floppy_otps} parameter for -fda 446 # We may want to add {floppy_otps} parameter for -fda
461 # {fat:floppy:}/path/. However vvfat is not usually recommended. 447 # {fat:floppy:}/path/. However vvfat is not usually recommended.
462 floppy = params.get("floppy") 448 floppy = params.get("floppy")
463 if floppy: 449 if floppy:
464 floppy = kvm_utils.get_path(root_dir, floppy) 450 floppy = kvm_utils.get_path(root_dir, floppy)
(...skipping 19 matching lines...) Expand all
484 470
485 initrd = params.get("initrd") 471 initrd = params.get("initrd")
486 if initrd: 472 if initrd:
487 initrd = kvm_utils.get_path(root_dir, initrd) 473 initrd = kvm_utils.get_path(root_dir, initrd)
488 qemu_cmd += add_initrd(help, initrd) 474 qemu_cmd += add_initrd(help, initrd)
489 475
490 for host_port, guest_port in redirs: 476 for host_port, guest_port in redirs:
491 qemu_cmd += add_tcp_redir(help, host_port, guest_port) 477 qemu_cmd += add_tcp_redir(help, host_port, guest_port)
492 478
493 if params.get("display") == "vnc": 479 if params.get("display") == "vnc":
494 qemu_cmd += add_vnc(help, vm.vnc_port) 480 qemu_cmd += add_vnc(help, self.vnc_port)
495 elif params.get("display") == "sdl": 481 elif params.get("display") == "sdl":
496 qemu_cmd += add_sdl(help) 482 qemu_cmd += add_sdl(help)
497 elif params.get("display") == "nographic": 483 elif params.get("display") == "nographic":
498 qemu_cmd += add_nographic(help) 484 qemu_cmd += add_nographic(help)
499 485
500 if params.get("uuid") == "random": 486 if params.get("uuid") == "random":
501 qemu_cmd += add_uuid(help, vm.uuid) 487 qemu_cmd += add_uuid(help, self.uuid)
502 elif params.get("uuid"): 488 elif params.get("uuid"):
503 qemu_cmd += add_uuid(help, params.get("uuid")) 489 qemu_cmd += add_uuid(help, params.get("uuid"))
504 490
505 if params.get("testdev") == "yes": 491 if params.get("testdev") == "yes":
506 qemu_cmd += add_testdev(help, vm.get_testlog_filename()) 492 qemu_cmd += add_testdev(help, self.get_testlog_filename())
507 493
508 if params.get("disable_hpet") == "yes": 494 if params.get("disable_hpet") == "yes":
509 qemu_cmd += add_no_hpet(help) 495 qemu_cmd += add_no_hpet(help)
510 496
511 # If the PCI assignment step went OK, add each one of the PCI assigned 497 # If the PCI assignment step went OK, add each one of the PCI assigned
512 # devices to the qemu command line. 498 # devices to the qemu command line.
513 if vm.pci_assignable: 499 if self.pci_assignable:
514 for pci_id in vm.pa_pci_ids: 500 for pci_id in self.pa_pci_ids:
515 qemu_cmd += add_pcidevice(help, pci_id) 501 qemu_cmd += add_pcidevice(help, pci_id)
516 502
517 extra_params = params.get("extra_params") 503 extra_params = params.get("extra_params")
518 if extra_params: 504 if extra_params:
519 qemu_cmd += " %s" % extra_params 505 qemu_cmd += " %s" % extra_params
520 506
521 return qemu_cmd 507 return qemu_cmd
522 508
523 509
524 def create(self, name=None, params=None, root_dir=None, timeout=5.0, 510 def create(self, name=None, params=None, root_dir=None, timeout=5.0,
525 migration_mode=None, mac_source=None): 511 migration_mode=None, migration_exec_cmd=None, mac_source=None):
526 """ 512 """
527 Start the VM by running a qemu command. 513 Start the VM by running a qemu command.
528 All parameters are optional. If name, params or root_dir are not 514 All parameters are optional. If name, params or root_dir are not
529 supplied, the respective values stored as class attributes are used. 515 supplied, the respective values stored as class attributes are used.
530 516
531 @param name: The name of the object 517 @param name: The name of the object
532 @param params: A dict containing VM params 518 @param params: A dict containing VM params
533 @param root_dir: Base directory for relative filenames 519 @param root_dir: Base directory for relative filenames
534 @param migration_mode: If supplied, start VM for incoming migration 520 @param migration_mode: If supplied, start VM for incoming migration
535 using this protocol (either 'tcp', 'unix' or 'exec') 521 using this protocol (either 'tcp', 'unix' or 'exec')
536 @param migration_exec_cmd: Command to embed in '-incoming "exec: ..."' 522 @param migration_exec_cmd: Command to embed in '-incoming "exec: ..."'
537 (e.g. 'gzip -c -d filename') if migration_mode is 'exec' 523 (e.g. 'gzip -c -d filename') if migration_mode is 'exec'
538 @param mac_source: A VM object from which to copy MAC addresses. If not 524 @param mac_source: A VM object from which to copy MAC addresses. If not
539 specified, new addresses will be generated. 525 specified, new addresses will be generated.
540 """ 526 """
541 self.destroy() 527 self.destroy()
542 528
543 if name is not None: 529 if name is not None:
544 self.name = name 530 self.name = name
545 if params is not None: 531 if params is not None:
546 self.params = params 532 self.params = params
547 if root_dir is not None: 533 if root_dir is not None:
548 self.root_dir = root_dir 534 self.root_dir = root_dir
549 name = self.name 535 name = self.name
550 params = self.params 536 params = self.params
551 root_dir = self.root_dir 537 root_dir = self.root_dir
552 538
553 # Verify the md5sum of the ISO images 539 # Verify the md5sum of the ISO image
554 for cdrom in params.objects("cdroms"): 540 iso = params.get("cdrom")
555 cdrom_params = params.object_params(cdrom) 541 if iso:
556 iso = cdrom_params.get("cdrom") 542 iso = kvm_utils.get_path(root_dir, iso)
557 if iso: 543 if not os.path.exists(iso):
558 iso = kvm_utils.get_path(root_dir, iso) 544 logging.error("ISO file not found: %s" % iso)
559 if not os.path.exists(iso): 545 return False
560 logging.error("ISO file not found: %s" % iso) 546 compare = False
547 if params.get("md5sum_1m"):
548 logging.debug("Comparing expected MD5 sum with MD5 sum of "
549 "first MB of ISO file...")
550 actual_hash = utils.hash_file(iso, 1048576, method="md5")
551 expected_hash = params.get("md5sum_1m")
552 compare = True
553 elif params.get("md5sum"):
554 logging.debug("Comparing expected MD5 sum with MD5 sum of ISO "
555 "file...")
556 actual_hash = utils.hash_file(iso, method="md5")
557 expected_hash = params.get("md5sum")
558 compare = True
559 elif params.get("sha1sum"):
560 logging.debug("Comparing expected SHA1 sum with SHA1 sum of "
561 "ISO file...")
562 actual_hash = utils.hash_file(iso, method="sha1")
563 expected_hash = params.get("sha1sum")
564 compare = True
565 if compare:
566 if actual_hash == expected_hash:
567 logging.debug("Hashes match")
568 else:
569 logging.error("Actual hash differs from expected one")
561 return False 570 return False
562 compare = False
563 if cdrom_params.get("md5sum_1m"):
564 logging.debug("Comparing expected MD5 sum with MD5 sum of "
565 "first MB of ISO file...")
566 actual_hash = utils.hash_file(iso, 1048576, method="md5")
567 expected_hash = cdrom_params.get("md5sum_1m")
568 compare = True
569 elif cdrom_params.get("md5sum"):
570 logging.debug("Comparing expected MD5 sum with MD5 sum of "
571 "ISO file...")
572 actual_hash = utils.hash_file(iso, method="md5")
573 expected_hash = cdrom_params.get("md5sum")
574 compare = True
575 elif cdrom_params.get("sha1sum"):
576 logging.debug("Comparing expected SHA1 sum with SHA1 sum "
577 "of ISO file...")
578 actual_hash = utils.hash_file(iso, method="sha1")
579 expected_hash = cdrom_params.get("sha1sum")
580 compare = True
581 if compare:
582 if actual_hash == expected_hash:
583 logging.debug("Hashes match")
584 else:
585 logging.error("Actual hash differs from expected one")
586 return False
587 571
588 # Make sure the following code is not executed by more than one thread 572 # Make sure the following code is not executed by more than one thread
589 # at the same time 573 # at the same time
590 lockfile = open("/tmp/kvm-autotest-vm-create.lock", "w+") 574 lockfile = open("/tmp/kvm-autotest-vm-create.lock", "w+")
591 fcntl.lockf(lockfile, fcntl.LOCK_EX) 575 fcntl.lockf(lockfile, fcntl.LOCK_EX)
592 576
593 try: 577 try:
594 # Handle port redirections 578 # Handle port redirections
595 redir_names = params.objects("redirs") 579 redir_names = kvm_utils.get_sub_dict_names(params, "redirs")
596 host_ports = kvm_utils.find_free_ports(5000, 6000, len(redir_names)) 580 host_ports = kvm_utils.find_free_ports(5000, 6000, len(redir_names))
597 self.redirs = {} 581 self.redirs = {}
598 for i in range(len(redir_names)): 582 for i in range(len(redir_names)):
599 redir_params = params.object_params(redir_names[i]) 583 redir_params = kvm_utils.get_sub_dict(params, redir_names[i])
600 guest_port = int(redir_params.get("guest_port")) 584 guest_port = int(redir_params.get("guest_port"))
601 self.redirs[guest_port] = host_ports[i] 585 self.redirs[guest_port] = host_ports[i]
602 586
603 # Generate netdev IDs for all NICs 587 for nic in kvm_utils.get_sub_dict_names(params, "nics"):
604 self.netdev_id = []
605 for nic in params.objects("nics"):
606 self.netdev_id.append(kvm_utils.generate_random_id()) 588 self.netdev_id.append(kvm_utils.generate_random_id())
607 589
608 # Find available VNC port, if needed 590 # Find available VNC port, if needed
609 if params.get("display") == "vnc": 591 if params.get("display") == "vnc":
610 self.vnc_port = kvm_utils.find_free_port(5900, 6100) 592 self.vnc_port = kvm_utils.find_free_port(5900, 6100)
611 593
612 # Find random UUID if specified 'uuid = random' in config file 594 # Find random UUID if specified 'uuid = random' in config file
613 if params.get("uuid") == "random": 595 if params.get("uuid") == "random":
614 f = open("/proc/sys/kernel/random/uuid") 596 f = open("/proc/sys/kernel/random/uuid")
615 self.uuid = f.read().strip() 597 self.uuid = f.read().strip()
616 f.close() 598 f.close()
617 599
618 # Generate or copy MAC addresses for all NICs 600 # Generate or copy MAC addresses for all NICs
619 num_nics = len(params.objects("nics")) 601 num_nics = len(kvm_utils.get_sub_dict_names(params, "nics"))
620 for vlan in range(num_nics): 602 for vlan in range(num_nics):
621 nic_name = params.objects("nics")[vlan] 603 mac = mac_source and mac_source.get_mac_address(vlan)
622 nic_params = params.object_params(nic_name) 604 if mac:
623 if nic_params.get("nic_mac", None):
624 mac = nic_params.get("nic_mac")
625 kvm_utils.set_mac_address(self.instance, vlan, mac) 605 kvm_utils.set_mac_address(self.instance, vlan, mac)
626 else: 606 else:
627 mac = mac_source and mac_source.get_mac_address(vlan) 607 kvm_utils.generate_mac_address(self.instance, vlan)
628 if mac:
629 kvm_utils.set_mac_address(self.instance, vlan, mac)
630 else:
631 kvm_utils.generate_mac_address(self.instance, vlan)
632 608
633 # Assign a PCI assignable device 609 # Assign a PCI assignable device
634 self.pci_assignable = None 610 self.pci_assignable = None
635 pa_type = params.get("pci_assignable") 611 pa_type = params.get("pci_assignable")
636 if pa_type in ["vf", "pf", "mixed"]: 612 if pa_type in ["vf", "pf", "mixed"]:
637 pa_devices_requested = params.get("devices_requested") 613 pa_devices_requested = params.get("devices_requested")
638 614
639 # Virtual Functions (VF) assignable devices 615 # Virtual Functions (VF) assignable devices
640 if pa_type == "vf": 616 if pa_type == "vf":
641 self.pci_assignable = kvm_utils.PciAssignable( 617 self.pci_assignable = kvm_utils.PciAssignable(
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
677 qemu_command = self.make_qemu_command() 653 qemu_command = self.make_qemu_command()
678 654
679 # Add migration parameters if required 655 # Add migration parameters if required
680 if migration_mode == "tcp": 656 if migration_mode == "tcp":
681 self.migration_port = kvm_utils.find_free_port(5200, 6000) 657 self.migration_port = kvm_utils.find_free_port(5200, 6000)
682 qemu_command += " -incoming tcp:0:%d" % self.migration_port 658 qemu_command += " -incoming tcp:0:%d" % self.migration_port
683 elif migration_mode == "unix": 659 elif migration_mode == "unix":
684 self.migration_file = "/tmp/migration-unix-%s" % self.instance 660 self.migration_file = "/tmp/migration-unix-%s" % self.instance
685 qemu_command += " -incoming unix:%s" % self.migration_file 661 qemu_command += " -incoming unix:%s" % self.migration_file
686 elif migration_mode == "exec": 662 elif migration_mode == "exec":
687 self.migration_port = kvm_utils.find_free_port(5200, 6000) 663 qemu_command += ' -incoming "exec:%s"' % migration_exec_cmd
688 qemu_command += (' -incoming "exec:nc -l %s"' %
689 self.migration_port)
690 664
691 logging.debug("Running qemu command:\n%s", qemu_command) 665 logging.debug("Running qemu command:\n%s", qemu_command)
692 self.process = kvm_subprocess.run_bg(qemu_command, None, 666 self.process = kvm_subprocess.run_bg(qemu_command, None,
693 logging.debug, "(qemu) ") 667 logging.debug, "(qemu) ")
694 668
695 # Make sure the process was started successfully 669 # Make sure the process was started successfully
696 if not self.process.is_alive(): 670 if not self.process.is_alive():
697 logging.error("VM could not be created; " 671 logging.error("VM could not be created; "
698 "qemu command failed:\n%s" % qemu_command) 672 "qemu command failed:\n%s" % qemu_command)
699 logging.error("Status: %s" % self.process.get_status()) 673 logging.error("Status: %s" % self.process.get_status())
700 logging.error("Output:" + kvm_utils.format_str_for_message( 674 logging.error("Output:" + kvm_utils.format_str_for_message(
701 self.process.get_output())) 675 self.process.get_output()))
702 self.destroy() 676 self.destroy()
703 return False 677 return False
704 678
705 # Establish monitor connections 679 # Establish monitor connections
706 self.monitors = [] 680 self.monitors = []
707 for monitor_name in params.objects("monitors"): 681 for monitor_name in kvm_utils.get_sub_dict_names(params,
708 monitor_params = params.object_params(monitor_name) 682 "monitors"):
683 monitor_params = kvm_utils.get_sub_dict(params, monitor_name)
709 # Wait for monitor connection to succeed 684 # Wait for monitor connection to succeed
710 end_time = time.time() + timeout 685 end_time = time.time() + timeout
711 while time.time() < end_time: 686 while time.time() < end_time:
712 try: 687 try:
713 if monitor_params.get("monitor_type") == "qmp": 688 if monitor_params.get("monitor_type") == "qmp":
714 # Add a QMP monitor 689 # Add a QMP monitor
715 monitor = kvm_monitor.QMPMonitor( 690 monitor = kvm_monitor.QMPMonitor(
716 monitor_name, 691 monitor_name,
717 self.get_monitor_filename(monitor_name)) 692 self.get_monitor_filename(monitor_name))
718 else: 693 else:
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
751 "qemu command:\n%s" % qemu_command) 726 "qemu command:\n%s" % qemu_command)
752 logging.error("Output:" + kvm_utils.format_str_for_message( 727 logging.error("Output:" + kvm_utils.format_str_for_message(
753 self.process.get_output())) 728 self.process.get_output()))
754 self.destroy() 729 self.destroy()
755 return False 730 return False
756 731
757 logging.debug("VM appears to be alive with PID %s", self.get_pid()) 732 logging.debug("VM appears to be alive with PID %s", self.get_pid())
758 733
759 # Establish a session with the serial console -- requires a version 734 # Establish a session with the serial console -- requires a version
760 # of netcat that supports -U 735 # of netcat that supports -U
761 self.serial_console = kvm_subprocess.ShellSession( 736 self.serial_console = kvm_subprocess.kvm_shell_session(
762 "nc -U %s" % self.get_serial_console_filename(), 737 "nc -U %s" % self.get_serial_console_filename(),
763 auto_close=False, 738 auto_close=False,
764 output_func=kvm_utils.log_line, 739 output_func=kvm_utils.log_line,
765 output_params=("serial-%s.log" % name,)) 740 output_params=("serial-%s.log" % name,))
766 741
767 return True 742 return True
768 743
769 finally: 744 finally:
770 fcntl.lockf(lockfile, fcntl.LOCK_UN) 745 fcntl.lockf(lockfile, fcntl.LOCK_UN)
771 lockfile.close() 746 lockfile.close()
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
844 self.get_monitor_filenames()): 819 self.get_monitor_filenames()):
845 try: 820 try:
846 os.unlink(f) 821 os.unlink(f)
847 except OSError: 822 except OSError:
848 pass 823 pass
849 if hasattr(self, "migration_file"): 824 if hasattr(self, "migration_file"):
850 try: 825 try:
851 os.unlink(self.migration_file) 826 os.unlink(self.migration_file)
852 except OSError: 827 except OSError:
853 pass 828 pass
854 num_nics = len(self.params.objects("nics")) 829 num_nics = len(kvm_utils.get_sub_dict_names(self.params, "nics"))
855 for vlan in range(num_nics): 830 for vlan in range(num_nics):
856 self.free_mac_address(vlan) 831 self.free_mac_address(vlan)
857 832
858 833
859 @property 834 @property
860 def monitor(self): 835 def monitor(self):
861 """ 836 """
862 Return the main monitor object, selected by the parameter main_monitor. 837 Return the main monitor object, selected by the parameter main_monitor.
863 If main_monitor isn't defined, return the first monitor. 838 If main_monitor isn't defined, return the first monitor.
864 If no monitors exist, or if main_monitor refers to a nonexistent 839 If no monitors exist, or if main_monitor refers to a nonexistent
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
903 """ 878 """
904 return "/tmp/monitor-%s-%s" % (monitor_name, self.instance) 879 return "/tmp/monitor-%s-%s" % (monitor_name, self.instance)
905 880
906 881
907 def get_monitor_filenames(self): 882 def get_monitor_filenames(self):
908 """ 883 """
909 Return a list of all monitor filenames (as specified in the VM's 884 Return a list of all monitor filenames (as specified in the VM's
910 params). 885 params).
911 """ 886 """
912 return [self.get_monitor_filename(m) for m in 887 return [self.get_monitor_filename(m) for m in
913 self.params.objects("monitors")] 888 kvm_utils.get_sub_dict_names(self.params, "monitors")]
914 889
915 890
916 def get_serial_console_filename(self): 891 def get_serial_console_filename(self):
917 """ 892 """
918 Return the serial console filename. 893 Return the serial console filename.
919 """ 894 """
920 return "/tmp/serial-%s" % self.instance 895 return "/tmp/serial-%s" % self.instance
921 896
922 897
923 def get_testlog_filename(self): 898 def get_testlog_filename(self):
924 """ 899 """
925 Return the testlog filename. 900 Return the testlog filename.
926 """ 901 """
927 return "/tmp/testlog-%s" % self.instance 902 return "/tmp/testlog-%s" % self.instance
928 903
929 904
930 def get_address(self, index=0): 905 def get_address(self, index=0):
931 """ 906 """
932 Return the address of a NIC of the guest, in host space. 907 Return the address of a NIC of the guest, in host space.
933 908
934 If port redirection is used, return 'localhost' (the NIC has no IP 909 If port redirection is used, return 'localhost' (the NIC has no IP
935 address of its own). Otherwise return the NIC's IP address. 910 address of its own). Otherwise return the NIC's IP address.
936 911
937 @param index: Index of the NIC whose address is requested. 912 @param index: Index of the NIC whose address is requested.
938 """ 913 """
939 nics = self.params.objects("nics") 914 nics = kvm_utils.get_sub_dict_names(self.params, "nics")
940 nic_name = nics[index] 915 nic_name = nics[index]
941 nic_params = self.params.object_params(nic_name) 916 nic_params = kvm_utils.get_sub_dict(self.params, nic_name)
942 if nic_params.get("nic_mode") == "tap": 917 if nic_params.get("nic_mode") == "tap":
943 mac = self.get_mac_address(index) 918 mac = self.get_mac_address(index)
944 if not mac: 919 if not mac:
945 logging.debug("MAC address unavailable") 920 logging.debug("MAC address unavailable")
946 return None 921 return None
947 mac = mac.lower() 922 mac = mac.lower()
948 # Get the IP address from the cache 923 # Get the IP address from the cache
949 ip = self.address_cache.get(mac) 924 ip = self.address_cache.get(mac)
950 if not ip: 925 if not ip:
951 logging.debug("Could not find IP address for MAC address: %s" % 926 logging.debug("Could not find IP address for MAC address: %s" %
(...skipping 12 matching lines...) Expand all
964 939
965 def get_port(self, port, nic_index=0): 940 def get_port(self, port, nic_index=0):
966 """ 941 """
967 Return the port in host space corresponding to port in guest space. 942 Return the port in host space corresponding to port in guest space.
968 943
969 @param port: Port number in host space. 944 @param port: Port number in host space.
970 @param nic_index: Index of the NIC. 945 @param nic_index: Index of the NIC.
971 @return: If port redirection is used, return the host port redirected 946 @return: If port redirection is used, return the host port redirected
972 to guest port port. Otherwise return port. 947 to guest port port. Otherwise return port.
973 """ 948 """
974 nic_name = self.params.objects("nics")[nic_index] 949 nic_name = kvm_utils.get_sub_dict_names(self.params, "nics")[nic_index]
975 nic_params = self.params.object_params(nic_name) 950 nic_params = kvm_utils.get_sub_dict(self.params, nic_name)
976 if nic_params.get("nic_mode") == "tap": 951 if nic_params.get("nic_mode") == "tap":
977 return port 952 return port
978 else: 953 else:
979 if not self.redirs.has_key(port): 954 if not self.redirs.has_key(port):
980 logging.warn("Warning: guest port %s requested but not " 955 logging.warn("Warning: guest port %s requested but not "
981 "redirected" % port) 956 "redirected" % port)
982 return self.redirs.get(port) 957 return self.redirs.get(port)
983 958
984 959
985 def get_ifname(self, nic_index=0): 960 def get_ifname(self, nic_index=0):
986 """ 961 """
987 Return the ifname of a tap device associated with a NIC. 962 Return the ifname of a tap device associated with a NIC.
988 963
989 @param nic_index: Index of the NIC 964 @param nic_index: Index of the NIC
990 """ 965 """
991 nics = self.params.objects("nics") 966 nics = kvm_utils.get_sub_dict_names(self.params, "nics")
992 nic_name = nics[nic_index] 967 nic_name = nics[nic_index]
993 nic_params = self.params.object_params(nic_name) 968 nic_params = kvm_utils.get_sub_dict(self.params, nic_name)
994 if nic_params.get("nic_ifname"): 969 if nic_params.get("nic_ifname"):
995 return nic_params.get("nic_ifname") 970 return nic_params.get("nic_ifname")
996 else: 971 else:
997 return "t%d-%s" % (nic_index, self.instance[-11:]) 972 return "t%d-%s" % (nic_index, self.instance[-11:])
998 973
999 974
1000 def get_mac_address(self, nic_index=0): 975 def get_mac_address(self, nic_index=0):
1001 """ 976 """
1002 Return the MAC address of a NIC. 977 Return the MAC address of a NIC.
1003 978
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
1058 1033
1059 def remote_login(self, nic_index=0, timeout=10): 1034 def remote_login(self, nic_index=0, timeout=10):
1060 """ 1035 """
1061 Log into the guest via SSH/Telnet/Netcat. 1036 Log into the guest via SSH/Telnet/Netcat.
1062 If timeout expires while waiting for output from the guest (e.g. a 1037 If timeout expires while waiting for output from the guest (e.g. a
1063 password prompt or a shell prompt) -- fail. 1038 password prompt or a shell prompt) -- fail.
1064 1039
1065 @param nic_index: The index of the NIC to connect to. 1040 @param nic_index: The index of the NIC to connect to.
1066 @param timeout: Time (seconds) before giving up logging into the 1041 @param timeout: Time (seconds) before giving up logging into the
1067 guest. 1042 guest.
1068 @return: ShellSession object on success and None on failure. 1043 @return: kvm_spawn object on success and None on failure.
1069 """ 1044 """
1070 username = self.params.get("username", "") 1045 username = self.params.get("username", "")
1071 password = self.params.get("password", "") 1046 password = self.params.get("password", "")
1072 prompt = self.params.get("shell_prompt", "[\#\$]") 1047 prompt = self.params.get("shell_prompt", "[\#\$]")
1073 linesep = eval("'%s'" % self.params.get("shell_linesep", r"\n")) 1048 linesep = eval("'%s'" % self.params.get("shell_linesep", r"\n"))
1074 client = self.params.get("shell_client") 1049 client = self.params.get("shell_client")
1075 address = self.get_address(nic_index) 1050 address = self.get_address(nic_index)
1076 port = self.get_port(int(self.params.get("shell_port"))) 1051 port = self.get_port(int(self.params.get("shell_port")))
1077 log_filename = ("session-%s-%s.log" % 1052 log_filename = ("session-%s-%s.log" %
1078 (self.name, kvm_utils.generate_random_string(4))) 1053 (self.name, kvm_utils.generate_random_string(4)))
1079 1054
1080 if not address or not port: 1055 if not address or not port:
1081 logging.debug("IP address or port unavailable") 1056 logging.debug("IP address or port unavailable")
1082 return None 1057 return None
1083 1058
1084 session = kvm_utils.remote_login(client, address, port, username, 1059 session = kvm_utils.remote_login(client, address, port, username,
1085 password, prompt, linesep, 1060 password, prompt, linesep,
1086 log_filename, timeout) 1061 log_filename, timeout)
1087 1062
1088 if session: 1063 if session:
1089 session.set_status_test_command(self.params.get("status_test_" 1064 session.set_status_test_command(self.params.get("status_test_"
1090 "command", "")) 1065 "command", ""))
1091 return session 1066 return session
1092 1067
1093 1068
1094 def copy_files_to(self, local_path, remote_path, nic_index=0, timeout=600): 1069 def copy_files_to(self, local_path, remote_path, nic_index=0, timeout=600):
1095 """ 1070 """
1096 Transfer files to the remote host(guest). 1071 Transfer files to the guest.
1097 1072
1098 @param local_path: Host path 1073 @param local_path: Host path
1099 @param remote_path: Guest path 1074 @param remote_path: Guest path
1100 @param nic_index: The index of the NIC to connect to. 1075 @param nic_index: The index of the NIC to connect to.
1101 @param timeout: Time (seconds) before giving up on doing the remote 1076 @param timeout: Time (seconds) before giving up on doing the remote
1102 copy. 1077 copy.
1103 """ 1078 """
1104 username = self.params.get("username", "") 1079 username = self.params.get("username", "")
1105 password = self.params.get("password", "") 1080 password = self.params.get("password", "")
1106 client = self.params.get("file_transfer_client") 1081 client = self.params.get("file_transfer_client")
1107 address = self.get_address(nic_index) 1082 address = self.get_address(nic_index)
1108 port = self.get_port(int(self.params.get("file_transfer_port"))) 1083 port = self.get_port(int(self.params.get("file_transfer_port")))
1109 1084
1110 log_filename = ("transfer-%s-to-%s-%s.log" % 1085 if not address or not port:
1111 (self.name, address, 1086 logging.debug("IP address or port unavailable")
1112 kvm_utils.generate_random_string(4))) 1087 return None
1113 return kvm_utils.copy_files_to(address, client, username, password, 1088
1114 port, local_path, remote_path, 1089 if client == "scp":
1115 log_filename, timeout) 1090 log_filename = ("scp-%s-%s.log" %
1091 (self.name, kvm_utils.generate_random_string(4)))
1092 return kvm_utils.scp_to_remote(address, port, username, password,
1093 local_path, remote_path,
1094 log_filename, timeout)
1095 elif client == "rss":
1096 c = rss_file_transfer.FileUploadClient(address, port)
1097 c.upload(local_path, remote_path, timeout)
1098 c.close()
1099 return True
1116 1100
1117 1101
1118 def copy_files_from(self, remote_path, local_path, nic_index=0, timeout=600) : 1102 def copy_files_from(self, remote_path, local_path, nic_index=0, timeout=600) :
1119 """ 1103 """
1120 Transfer files from the guest. 1104 Transfer files from the guest.
1121 1105
1122 @param local_path: Guest path 1106 @param local_path: Guest path
1123 @param remote_path: Host path 1107 @param remote_path: Host path
1124 @param nic_index: The index of the NIC to connect to. 1108 @param nic_index: The index of the NIC to connect to.
1125 @param timeout: Time (seconds) before giving up on doing the remote 1109 @param timeout: Time (seconds) before giving up on doing the remote
1126 copy. 1110 copy.
1127 """ 1111 """
1128 username = self.params.get("username", "") 1112 username = self.params.get("username", "")
1129 password = self.params.get("password", "") 1113 password = self.params.get("password", "")
1130 client = self.params.get("file_transfer_client") 1114 client = self.params.get("file_transfer_client")
1131 address = self.get_address(nic_index) 1115 address = self.get_address(nic_index)
1132 port = self.get_port(int(self.params.get("file_transfer_port"))) 1116 port = self.get_port(int(self.params.get("file_transfer_port")))
1133 1117
1134 log_filename = ("transfer-%s-from-%s-%s.log" % 1118 if not address or not port:
1135 (self.name, address, 1119 logging.debug("IP address or port unavailable")
1136 kvm_utils.generate_random_string(4))) 1120 return None
1137 return kvm_utils.copy_files_from(address, client, username, password, 1121
1138 port, local_path, remote_path, log_filename, timeout) 1122 if client == "scp":
1123 log_filename = ("scp-%s-%s.log" %
1124 (self.name, kvm_utils.generate_random_string(4)))
1125 return kvm_utils.scp_from_remote(address, port, username, password,
1126 remote_path, local_path,
1127 log_filename, timeout)
1128 elif client == "rss":
1129 c = rss_file_transfer.FileDownloadClient(address, port)
1130 c.download(remote_path, local_path, timeout)
1131 c.close()
1132 return True
1139 1133
1140 1134
1141 def serial_login(self, timeout=10): 1135 def serial_login(self, timeout=10):
1142 """ 1136 """
1143 Log into the guest via the serial console. 1137 Log into the guest via the serial console.
1144 If timeout expires while waiting for output from the guest (e.g. a 1138 If timeout expires while waiting for output from the guest (e.g. a
1145 password prompt or a shell prompt) -- fail. 1139 password prompt or a shell prompt) -- fail.
1146 1140
1147 @param timeout: Time (seconds) before giving up logging into the guest. 1141 @param timeout: Time (seconds) before giving up logging into the guest.
1148 @return: ShellSession object on success and None on failure. 1142 @return: kvm_spawn object on success and None on failure.
1149 """ 1143 """
1150 username = self.params.get("username", "") 1144 username = self.params.get("username", "")
1151 password = self.params.get("password", "") 1145 password = self.params.get("password", "")
1152 prompt = self.params.get("shell_prompt", "[\#\$]") 1146 prompt = self.params.get("shell_prompt", "[\#\$]")
1153 linesep = eval("'%s'" % self.params.get("shell_linesep", r"\n")) 1147 linesep = eval("'%s'" % self.params.get("shell_linesep", r"\n"))
1154 status_test_command = self.params.get("status_test_command", "") 1148 status_test_command = self.params.get("status_test_command", "")
1155 1149
1156 if self.serial_console: 1150 if self.serial_console:
1157 self.serial_console.set_linesep(linesep) 1151 self.serial_console.set_linesep(linesep)
1158 self.serial_console.set_status_test_command(status_test_command) 1152 self.serial_console.set_status_test_command(status_test_command)
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1212 1206
1213 1207
1214 def get_cpu_count(self): 1208 def get_cpu_count(self):
1215 """ 1209 """
1216 Get the cpu count of the VM. 1210 Get the cpu count of the VM.
1217 """ 1211 """
1218 session = self.remote_login() 1212 session = self.remote_login()
1219 if not session: 1213 if not session:
1220 return None 1214 return None
1221 try: 1215 try:
1222 return int(session.cmd(self.params.get("cpu_chk_cmd"))) 1216 cmd = self.params.get("cpu_chk_cmd")
1217 s, count = session.get_command_status_output(cmd)
1218 if s == 0:
1219 return int(count)
1220 return None
1223 finally: 1221 finally:
1224 session.close() 1222 session.close()
1225 1223
1226 1224
1227 def get_memory_size(self, cmd=None): 1225 def get_memory_size(self, cmd=None):
1228 """ 1226 """
1229 Get bootup memory size of the VM. 1227 Get bootup memory size of the VM.
1230 1228
1231 @param check_cmd: Command used to check memory. If not provided, 1229 @param check_cmd: Command used to check memory. If not provided,
1232 self.params.get("mem_chk_cmd") will be used. 1230 self.params.get("mem_chk_cmd") will be used.
1233 """ 1231 """
1234 session = self.remote_login() 1232 session = self.remote_login()
1235 if not session: 1233 if not session:
1236 return None 1234 return None
1237 try: 1235 try:
1238 if not cmd: 1236 if not cmd:
1239 cmd = self.params.get("mem_chk_cmd") 1237 cmd = self.params.get("mem_chk_cmd")
1240 mem_str = session.cmd(cmd) 1238 s, mem_str = session.get_command_status_output(cmd)
1239 if s != 0:
1240 return None
1241 mem = re.findall("([0-9]+)", mem_str) 1241 mem = re.findall("([0-9]+)", mem_str)
1242 mem_size = 0 1242 mem_size = 0
1243 for m in mem: 1243 for m in mem:
1244 mem_size += int(m) 1244 mem_size += int(m)
1245 if "GB" in mem_str: 1245 if "GB" in mem_str:
1246 mem_size *= 1024 1246 mem_size *= 1024
1247 elif "MB" in mem_str: 1247 elif "MB" in mem_str:
1248 pass 1248 pass
1249 else: 1249 else:
1250 mem_size /= 1024 1250 mem_size /= 1024
1251 return int(mem_size) 1251 return int(mem_size)
1252 finally: 1252 finally:
1253 session.close() 1253 session.close()
1254 1254
1255 1255
1256 def get_current_memory_size(self): 1256 def get_current_memory_size(self):
1257 """ 1257 """
1258 Get current memory size of the VM, rather than bootup memory. 1258 Get current memory size of the VM, rather than bootup memory.
1259 """ 1259 """
1260 cmd = self.params.get("mem_chk_cur_cmd") 1260 cmd = self.params.get("mem_chk_cur_cmd")
1261 return self.get_memory_size(cmd) 1261 return self.get_memory_size(cmd)
1262
1263
1264 def save_to_file(self, path):
1265 """
1266 Save the state of virtual machine to a file through migrate to
1267 exec
1268 """
1269 # Make sure we only get one iteration
1270 self.monitor.cmd("migrate_set_speed 1000g")
1271 self.monitor.cmd("migrate_set_downtime 100000000")
1272 self.monitor.migrate('"exec:cat>%s"' % path)
OLDNEW
« 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