319 |
319 |
return (ifname, tapfd)
|
320 |
320 |
|
321 |
321 |
|
|
322 |
class HeadRequest(urllib2.Request):
|
|
323 |
def get_method(self):
|
|
324 |
return "HEAD"
|
|
325 |
|
|
326 |
|
322 |
327 |
def _CheckUrl(url):
|
323 |
328 |
"""Check if a given URL exists on the server
|
324 |
329 |
|
325 |
330 |
"""
|
326 |
|
req = urllib2.Request(url)
|
327 |
|
|
328 |
|
# XXX: ugly but true
|
329 |
|
req.get_method = lambda: "HEAD"
|
330 |
|
|
331 |
331 |
try:
|
332 |
|
resp = urllib2.urlopen(req)
|
|
332 |
urllib2.urlopen(HeadRequest(url))
|
|
333 |
return True
|
333 |
334 |
except urllib2.URLError:
|
334 |
335 |
return False
|
335 |
336 |
|
336 |
|
del resp
|
337 |
|
return True
|
338 |
|
|
339 |
337 |
|
340 |
338 |
class QmpMessage:
|
341 |
339 |
"""QEMU Messaging Protocol (QMP) message.
|
... | ... | |
698 |
696 |
constants.HV_KVM_SPICE_USE_VDAGENT: hv_base.NO_CHECK,
|
699 |
697 |
constants.HV_KVM_FLOPPY_IMAGE_PATH: hv_base.OPT_FILE_CHECK,
|
700 |
698 |
constants.HV_CDROM_IMAGE_PATH: hv_base.OPT_FILE_OR_URL_CHECK,
|
701 |
|
constants.HV_KVM_CDROM2_IMAGE_PATH: hv_base.OPT_FILE_CHECK,
|
|
699 |
constants.HV_KVM_CDROM2_IMAGE_PATH: hv_base.OPT_FILE_OR_URL_CHECK,
|
702 |
700 |
constants.HV_BOOT_ORDER:
|
703 |
701 |
hv_base.ParamInSet(True, constants.HT_KVM_VALID_BO_TYPES),
|
704 |
702 |
constants.HV_NIC_TYPE:
|
... | ... | |
1352 |
1350 |
|
1353 |
1351 |
return dev_opts
|
1354 |
1352 |
|
|
1353 |
@staticmethod
|
|
1354 |
def CdromOption(kvm_cmd, cdrom_disk_type, cdrom_image, cdrom_boot,
|
|
1355 |
needs_boot_flag):
|
|
1356 |
"""Extends L{kvm_cmd} with the '-drive' option for a cdrom, and
|
|
1357 |
optionally the '-boot' option.
|
|
1358 |
|
|
1359 |
Example: -drive file=cdrom.iso,media=cdrom,format=raw,if=ide -boot d
|
|
1360 |
|
|
1361 |
Example: -drive file=cdrom.iso,media=cdrom,format=raw,if=ide,boot=on
|
|
1362 |
|
|
1363 |
Example: -drive file=http://hostname.com/cdrom.iso,media=cdrom
|
|
1364 |
|
|
1365 |
@type kvm_cmd: string
|
|
1366 |
@param kvm_cmd: KVM command line
|
|
1367 |
|
|
1368 |
@type cdrom_disk_type:
|
|
1369 |
@param cdrom_disk_type:
|
|
1370 |
|
|
1371 |
@type cdrom_image:
|
|
1372 |
@param cdrom_image:
|
|
1373 |
|
|
1374 |
@type cdrom_boot:
|
|
1375 |
@param cdrom_boot:
|
|
1376 |
|
|
1377 |
@type needs_boot_flag:
|
|
1378 |
@param needs_boot_flag:
|
|
1379 |
|
|
1380 |
"""
|
|
1381 |
# Check that the ISO image is accessible
|
|
1382 |
# See https://bugs.launchpad.net/qemu/+bug/597575
|
|
1383 |
if utils.IsUrl(cdrom_image) and not _CheckUrl(cdrom_image):
|
|
1384 |
raise errors.HypervisorError("Cdrom ISO image '%s' is not accessible" %
|
|
1385 |
cdrom_image)
|
|
1386 |
|
|
1387 |
# set cdrom 'media' and 'format', if needed
|
|
1388 |
if utils.IsUrl(cdrom_image):
|
|
1389 |
options = ",media=cdrom"
|
|
1390 |
else:
|
|
1391 |
options = ",media=cdrom,format=raw"
|
|
1392 |
|
|
1393 |
# set cdrom 'if' type
|
|
1394 |
if cdrom_boot:
|
|
1395 |
if_val = ",if=" + constants.HT_DISK_IDE
|
|
1396 |
elif cdrom_disk_type == constants.HT_DISK_PARAVIRTUAL:
|
|
1397 |
if_val = ",if=virtio"
|
|
1398 |
else:
|
|
1399 |
if_val = ",if=" + cdrom_disk_type
|
|
1400 |
|
|
1401 |
# set boot flag, if needed
|
|
1402 |
boot_val = ""
|
|
1403 |
if cdrom_boot:
|
|
1404 |
kvm_cmd.extend(["-boot", "d"])
|
|
1405 |
|
|
1406 |
# whether this is an older KVM version that requires the 'boot=on' flag
|
|
1407 |
# on devices
|
|
1408 |
if needs_boot_flag:
|
|
1409 |
boot_val = ",boot=on"
|
|
1410 |
|
|
1411 |
# build '-drive' option
|
|
1412 |
drive_val = "file=%s%s%s%s" % (cdrom_image, options, if_val, boot_val)
|
|
1413 |
kvm_cmd.extend(["-drive", drive_val])
|
|
1414 |
|
1355 |
1415 |
def _GenerateKVMRuntime(self, instance, block_devices, startup_paused,
|
1356 |
1416 |
kvmhelp):
|
1357 |
1417 |
"""Generate KVM information to start an instance.
|
... | ... | |
1432 |
1492 |
if boot_network:
|
1433 |
1493 |
kvm_cmd.extend(["-boot", "n"])
|
1434 |
1494 |
|
1435 |
|
# whether this is an older KVM version that uses the boot=on flag
|
1436 |
|
# on devices
|
1437 |
|
needs_boot_flag = self._BOOT_RE.search(kvmhelp)
|
1438 |
|
|
1439 |
1495 |
disk_type = hvp[constants.HV_DISK_TYPE]
|
1440 |
1496 |
|
1441 |
|
#Now we can specify a different device type for CDROM devices.
|
|
1497 |
# Now we can specify a different device type for CDROM devices.
|
1442 |
1498 |
cdrom_disk_type = hvp[constants.HV_KVM_CDROM_DISK_TYPE]
|
1443 |
1499 |
if not cdrom_disk_type:
|
1444 |
1500 |
cdrom_disk_type = disk_type
|
1445 |
1501 |
|
1446 |
|
iso_image = hvp[constants.HV_CDROM_IMAGE_PATH]
|
1447 |
|
if iso_image:
|
1448 |
|
options = ",media=cdrom"
|
1449 |
|
if re.match(r'(https?|ftps?)://', iso_image):
|
1450 |
|
# Check that the iso image is really there
|
1451 |
|
# See https://bugs.launchpad.net/qemu/+bug/597575
|
1452 |
|
if not _CheckUrl(iso_image):
|
1453 |
|
raise errors.HypervisorError("ISO image %s is not accessible" %
|
1454 |
|
iso_image)
|
1455 |
|
else:
|
1456 |
|
options = "%s,format=raw" % options
|
1457 |
|
# set cdrom 'if' type
|
1458 |
|
if boot_cdrom:
|
1459 |
|
actual_cdrom_type = constants.HT_DISK_IDE
|
1460 |
|
elif cdrom_disk_type == constants.HT_DISK_PARAVIRTUAL:
|
1461 |
|
actual_cdrom_type = "virtio"
|
1462 |
|
else:
|
1463 |
|
actual_cdrom_type = cdrom_disk_type
|
1464 |
|
if_val = ",if=%s" % actual_cdrom_type
|
1465 |
|
# set boot flag, if needed
|
1466 |
|
boot_val = ""
|
1467 |
|
if boot_cdrom:
|
1468 |
|
kvm_cmd.extend(["-boot", "d"])
|
1469 |
|
if needs_boot_flag:
|
1470 |
|
boot_val = ",boot=on"
|
1471 |
|
# and finally build the entire '-drive' value
|
1472 |
|
drive_val = "file=%s%s%s%s" % (iso_image, options, if_val, boot_val)
|
1473 |
|
kvm_cmd.extend(["-drive", drive_val])
|
|
1502 |
cdrom_image1 = hvp[constants.HV_CDROM_IMAGE_PATH]
|
|
1503 |
if cdrom_image1:
|
|
1504 |
needs_boot_flag = self._BOOT_RE.search(kvmhelp)
|
|
1505 |
self.CdromOption(kvm_cmd, cdrom_disk_type, cdrom_image1, boot_cdrom,
|
|
1506 |
needs_boot_flag)
|
1474 |
1507 |
|
1475 |
|
iso_image2 = hvp[constants.HV_KVM_CDROM2_IMAGE_PATH]
|
1476 |
|
if iso_image2:
|
1477 |
|
options = ",format=raw,media=cdrom"
|
1478 |
|
if cdrom_disk_type == constants.HT_DISK_PARAVIRTUAL:
|
1479 |
|
if_val = ",if=virtio"
|
1480 |
|
else:
|
1481 |
|
if_val = ",if=%s" % cdrom_disk_type
|
1482 |
|
drive_val = "file=%s%s%s" % (iso_image2, options, if_val)
|
1483 |
|
kvm_cmd.extend(["-drive", drive_val])
|
|
1508 |
cdrom_image2 = hvp[constants.HV_KVM_CDROM2_IMAGE_PATH]
|
|
1509 |
if cdrom_image2:
|
|
1510 |
self.CdromOption(kvm_cmd, cdrom_disk_type, cdrom_image2, False, False)
|
1484 |
1511 |
|
1485 |
1512 |
floppy_image = hvp[constants.HV_KVM_FLOPPY_IMAGE_PATH]
|
1486 |
1513 |
if floppy_image:
|