Revision 6c0af70e

b/daemons/ganeti-noded
338 338
    """Run the import function of an OS onto a given instance.
339 339

  
340 340
    """
341
    inst_s, os_disk, swap_disk, src_node, src_image, cluster_name = params
341
    inst_s, src_node, src_images, cluster_name = params
342 342
    inst = objects.Instance.FromDict(inst_s)
343
    return backend.ImportOSIntoInstance(inst, os_disk, swap_disk,
344
                                        src_node, src_image, cluster_name)
343
    return backend.ImportOSIntoInstance(inst, src_node, src_images,
344
                                        cluster_name)
345 345

  
346 346
  @staticmethod
347 347
  def perspective_instance_shutdown(params):
b/lib/backend.py
1477 1477
  return config
1478 1478

  
1479 1479

  
1480
def ImportOSIntoInstance(instance, os_disk, swap_disk, src_node, src_image,
1481
                         cluster_name):
1480
def ImportOSIntoInstance(instance, src_node, src_images, cluster_name):
1482 1481
  """Import an os image into an instance.
1483 1482

  
1484
  Args:
1485
    instance: the instance object
1486
    os_disk: the instance-visible name of the os device
1487
    swap_disk: the instance-visible name of the swap device
1488
    src_node: node holding the source image
1489
    src_image: path to the source image on src_node
1490

  
1491
  Returns:
1492
    False in case of error, True otherwise.
1483
  @type instance: L{objects.instance}
1484
  @param instance: instance to import the disks into
1485
  @type src_node: string
1486
  @param src_node: source node for the disk images
1487
  @type src_images: list of string
1488
  @param src_images: absolute paths of the disk images
1489
  @rtype: list of boolean
1490
  @return: each boolean represent the success of importing the n-th disk
1493 1491

  
1494 1492
  """
1495
  # TODO(ultrotter): Import/Export still to be converted to OS API 10
1496
  logging.error("Import/Export still to be converted to OS API 10")
1497
  return False
1498

  
1493
  import_env = OSEnvironment(instance)
1499 1494
  inst_os = OSFromDisk(instance.os)
1500 1495
  import_script = inst_os.import_script
1501 1496

  
1502
  os_device = instance.FindDisk(os_disk)
1503
  if os_device is None:
1504
    logging.error("Can't find this device-visible name '%s'", os_disk)
1505
    return False
1506

  
1507
  swap_device = instance.FindDisk(swap_disk)
1508
  if swap_device is None:
1509
    logging.error("Can't find this device-visible name '%s'", swap_disk)
1510
    return False
1511

  
1512
  real_os_dev = _RecursiveFindBD(os_device)
1513
  if real_os_dev is None:
1514
    raise errors.BlockDeviceError("Block device '%s' is not set up" %
1515
                                  str(os_device))
1516
  real_os_dev.Open()
1517

  
1518
  real_swap_dev = _RecursiveFindBD(swap_device)
1519
  if real_swap_dev is None:
1520
    raise errors.BlockDeviceError("Block device '%s' is not set up" %
1521
                                  str(swap_device))
1522
  real_swap_dev.Open()
1523

  
1524 1497
  logfile = "%s/import-%s-%s-%s.log" % (constants.LOG_OS_DIR, instance.os,
1525 1498
                                        instance.name, int(time.time()))
1526 1499
  if not os.path.exists(constants.LOG_OS_DIR):
1527 1500
    os.mkdir(constants.LOG_OS_DIR, 0750)
1528 1501

  
1529
  destcmd = utils.BuildShellCmd('cat %s', src_image)
1530
  remotecmd = _GetSshRunner(cluster_name).BuildCmd(src_node,
1531
                                                   constants.GANETI_RUNAS,
1532
                                                   destcmd)
1533

  
1534 1502
  comprcmd = "gunzip"
1535
  impcmd = utils.BuildShellCmd("(cd %s; %s -i %s -b %s -s %s &>%s)",
1536
                               inst_os.path, import_script, instance.name,
1537
                               real_os_dev.dev_path, real_swap_dev.dev_path,
1503
  impcmd = utils.BuildShellCmd("(cd %s; %s &>%s)", inst_os.path, import_script,
1538 1504
                               logfile)
1539 1505

  
1540
  command = '|'.join([utils.ShellQuoteArgs(remotecmd), comprcmd, impcmd])
1541
  env = {'HYPERVISOR': instance.hypervisor}
1542

  
1543
  result = utils.RunCmd(command, env=env)
1544

  
1545
  if result.failed:
1546
    logging.error("os import command '%s' returned error: %s"
1547
                  " output: %s", command, result.fail_reason, result.output)
1548
    return False
1506
  final_result = []
1507
  for idx, image in enumerate(src_images):
1508
    if image:
1509
      destcmd = utils.BuildShellCmd('cat %s', image)
1510
      remotecmd = _GetSshRunner(cluster_name).BuildCmd(src_node,
1511
                                                       constants.GANETI_RUNAS,
1512
                                                       destcmd)
1513
      command = '|'.join([utils.ShellQuoteArgs(remotecmd), comprcmd, impcmd])
1514
      import_env['IMPORT_DEVICE'] = import_env['DISK_%d_PATH' % idx]
1515
      result = utils.RunCmd(command, env=import_env)
1516
      if result.failed:
1517
        logging.error("disk import command '%s' returned error: %s"
1518
                      " output: %s", command, result.fail_reason, result.output)
1519
        final_result.append(False)
1520
      else:
1521
        final_result.append(True)
1522
    else:
1523
      final_result.append(True)
1549 1524

  
1550
  return True
1525
  return final_result
1551 1526

  
1552 1527

  
1553 1528
def ListExports():
b/lib/cmdlib.py
3701 3701
        src_node = self.op.src_node
3702 3702
        src_image = self.src_image
3703 3703
        cluster_name = self.cfg.GetClusterName()
3704
        if not self.rpc.call_instance_os_import(pnode_name, iobj, "sda", "sdb",
3705
                                                src_node, src_image,
3706
                                                cluster_name):
3707
          raise errors.OpExecError("Could not import os for instance"
3704
        import_result = self.rpc.call_instance_os_import(pnode_name, iobj,
3705
                                                         src_node, [src_image],
3706
                                                         cluster_name)
3707
        if import_result[0]:
3708
          raise errors.OpExecError("Could not import disks for instance"
3708 3709
                                   " %s on node %s" %
3709 3710
                                   (instance, pnode_name))
3710 3711
      else:
b/lib/rpc.py
831 831
      return result
832 832
    return objects.SerializableConfigParser.Loads(str(result))
833 833

  
834
  def call_instance_os_import(self, node, inst, osdev, swapdev,
835
                              src_node, src_image, cluster_name):
834
  def call_instance_os_import(self, node, inst, src_node, src_images,
835
                              cluster_name):
836 836
    """Request the import of a backup into an instance.
837 837

  
838 838
    This is a single-node call.
839 839

  
840 840
    """
841
    params = [self._InstDict(inst), osdev, swapdev,
842
              src_node, src_image, cluster_name]
841
    params = [self._InstDict(inst), src_node, src_images, cluster_name]
843 842
    c = Client("instance_os_import", params)
844 843
    self._ConnectNode(c, node)
845 844
    c.Run()

Also available in: Unified diff