Revision 364e1664 lib/hypervisor/hv_kvm.py

b/lib/hypervisor/hv_kvm.py
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:

Also available in: Unified diff