Revision decd5f45

b/daemons/ganeti-noded
288 288
    return backend.AddOSToInstance(inst, os_disk, swap_disk)
289 289

  
290 290
  @staticmethod
291
  def perspective_instance_run_rename(params):
292
    """Runs the OS rename script for an instance.
293

  
294
    """
295
    inst_s, old_name, os_disk, swap_disk = params
296
    inst = objects.ConfigObject.Loads(inst_s)
297
    return backend.RunRenameInstance(inst, old_name, os_disk, swap_disk)
298

  
299
  @staticmethod
291 300
  def perspective_instance_os_import(params):
292 301
    """Run the import function of an OS onto a given instance.
293 302

  
b/lib/backend.py
416 416
  return True
417 417

  
418 418

  
419
def RunRenameInstance(instance, old_name, os_disk, swap_disk):
420
  """Run the OS rename script for an instance.
421

  
422
  Args:
423
    instance: the instance object
424
    old_name: the old name of the instance
425
    os_disk: the instance-visible name of the os device
426
    swap_disk: the instance-visible name of the swap device
427

  
428
  """
429
  inst_os = OSFromDisk(instance.os)
430

  
431
  script = inst_os.rename_script
432

  
433
  os_device = instance.FindDisk(os_disk)
434
  if os_device is None:
435
    logger.Error("Can't find this device-visible name '%s'" % os_disk)
436
    return False
437

  
438
  swap_device = instance.FindDisk(swap_disk)
439
  if swap_device is None:
440
    logger.Error("Can't find this device-visible name '%s'" % swap_disk)
441
    return False
442

  
443
  real_os_dev = _RecursiveFindBD(os_device)
444
  if real_os_dev is None:
445
    raise errors.BlockDeviceError("Block device '%s' is not set up" %
446
                                  str(os_device))
447
  real_os_dev.Open()
448

  
449
  real_swap_dev = _RecursiveFindBD(swap_device)
450
  if real_swap_dev is None:
451
    raise errors.BlockDeviceError("Block device '%s' is not set up" %
452
                                  str(swap_device))
453
  real_swap_dev.Open()
454

  
455
  logfile = "%s/rename-%s-%s-%s-%d.log" % (constants.LOG_OS_DIR, instance.os,
456
                                           old_name,
457
                                           instance.name, int(time.time()))
458
  if not os.path.exists(constants.LOG_OS_DIR):
459
    os.mkdir(constants.LOG_OS_DIR, 0750)
460

  
461
  command = utils.BuildShellCmd("cd %s && %s -o %s -n %s -b %s -s %s &>%s",
462
                                inst_os.path, script, old_name, instance.name,
463
                                real_os_dev.dev_path, real_swap_dev.dev_path,
464
                                logfile)
465

  
466
  result = utils.RunCmd(command)
467

  
468
  if result.failed:
469
    logger.Error("os create command '%s' returned error: %s"
470
                 " output: %s" %
471
                 (command, result.fail_reason, result.output))
472
    return False
473

  
474
  return True
475

  
476

  
419 477
def _GetVGInfo(vg_name):
420 478
  """Get informations about the volume group.
421 479

  
b/lib/cmdlib.py
2034 2034
      _ShutdownInstanceDisks(inst, self.cfg)
2035 2035

  
2036 2036

  
2037
class LURenameInstance(LogicalUnit):
2038
  """Rename an instance.
2039

  
2040
  """
2041
  HPATH = "instance-rename"
2042
  HTYPE = constants.HTYPE_INSTANCE
2043
  _OP_REQP = ["instance_name", "new_name"]
2044

  
2045
  def BuildHooksEnv(self):
2046
    """Build hooks env.
2047

  
2048
    This runs on master, primary and secondary nodes of the instance.
2049

  
2050
    """
2051
    env = _BuildInstanceHookEnvByObject(self.instance)
2052
    env["INSTANCE_NEW_NAME"] = self.op.new_name
2053
    nl = ([self.sstore.GetMasterNode(), self.instance.primary_node] +
2054
          list(self.instance.secondary_nodes))
2055
    return env, nl, nl
2056

  
2057
  def CheckPrereq(self):
2058
    """Check prerequisites.
2059

  
2060
    This checks that the instance is in the cluster and is not running.
2061

  
2062
    """
2063
    instance = self.cfg.GetInstanceInfo(
2064
      self.cfg.ExpandInstanceName(self.op.instance_name))
2065
    if instance is None:
2066
      raise errors.OpPrereqError("Instance '%s' not known" %
2067
                                 self.op.instance_name)
2068
    if instance.status != "down":
2069
      raise errors.OpPrereqError("Instance '%s' is marked to be up" %
2070
                                 self.op.instance_name)
2071
    remote_info = rpc.call_instance_info(instance.primary_node, instance.name)
2072
    if remote_info:
2073
      raise errors.OpPrereqError("Instance '%s' is running on the node %s" %
2074
                                 (self.op.instance_name,
2075
                                  instance.primary_node))
2076
    self.instance = instance
2077

  
2078
    # new name verification
2079
    hostname1 = utils.LookupHostname(self.op.new_name)
2080
    if not hostname1:
2081
      raise errors.OpPrereqError("New instance name '%s' not found in dns" %
2082
                                 self.op.new_name)
2083

  
2084
    self.op.new_name = new_name = hostname1['hostname']
2085
    if not getattr(self.op, "ignore_ip", False):
2086
      command = ["fping", "-q", hostname1['ip']]
2087
      result = utils.RunCmd(command)
2088
      if not result.failed:
2089
        raise errors.OpPrereqError("IP %s of instance %s already in use" %
2090
                                   (hostname1['ip'], new_name))
2091

  
2092

  
2093
  def Exec(self, feedback_fn):
2094
    """Reinstall the instance.
2095

  
2096
    """
2097
    inst = self.instance
2098
    old_name = inst.name
2099

  
2100
    self.cfg.RenameInstance(inst.name, self.op.new_name)
2101

  
2102
    # re-read the instance from the configuration after rename
2103
    inst = self.cfg.GetInstanceInfo(self.op.new_name)
2104

  
2105
    _StartInstanceDisks(self.cfg, inst, None)
2106
    try:
2107
      if not rpc.call_instance_run_rename(inst.primary_node, inst, old_name,
2108
                                          "sda", "sdb"):
2109
        msg = ("Could run OS rename script for instance %s\n"
2110
               "on node %s\n"
2111
               "(but the instance has been renamed in Ganeti)" %
2112
               (inst.name, inst.primary_node))
2113
        logger.Error(msg)
2114
    finally:
2115
      _ShutdownInstanceDisks(inst, self.cfg)
2116

  
2117

  
2037 2118
class LURemoveInstance(LogicalUnit):
2038 2119
  """Remove an instance.
2039 2120

  
b/lib/mcpu.py
58 58
    opcodes.OpCreateInstance: cmdlib.LUCreateInstance,
59 59
    opcodes.OpReinstallInstance: cmdlib.LUReinstallInstance,
60 60
    opcodes.OpRemoveInstance: cmdlib.LURemoveInstance,
61
    opcodes.OpRenameInstance: cmdlib.LURenameInstance,
61 62
    opcodes.OpActivateInstanceDisks: cmdlib.LUActivateInstanceDisks,
62 63
    opcodes.OpShutdownInstance: cmdlib.LUShutdownInstance,
63 64
    opcodes.OpStartupInstance: cmdlib.LUStartupInstance,
b/lib/opcodes.py
145 145
  __slots__ = ["instance_name"]
146 146

  
147 147

  
148
class OpRenameInstance(OpCode):
149
  """Rename an instance."""
150
  OP_ID = "OP_INSTANCE_RENAME"
151
  __slots__ = ["instance_name", "ignore_ip", "new_name"]
152

  
153

  
148 154
class OpStartupInstance(OpCode):
149 155
  """Startup an instance."""
150 156
  OP_ID = "OP_INSTANCE_STARTUP"
b/lib/rpc.py
324 324
  return c.getresult().get(node, False)
325 325

  
326 326

  
327
def call_instance_run_rename(node, inst, old_name, osdev, swapdev):
328
  """Run the OS rename script for an instance.
329

  
330
  This is a single-node call.
331

  
332
  """
333
  params = [inst.Dumps(), old_name, osdev, swapdev]
334
  c = Client("instance_run_rename", params)
335
  c.connect(node)
336
  c.run()
337
  return c.getresult().get(node, False)
338

  
339

  
327 340
def call_instance_info(node, instance):
328 341
  """Returns information about a single instance.
329 342

  
b/man/gnt-instance.sgml
413 413
        </para>
414 414
      </refsect3>
415 415

  
416
      <refsect3>
417
        <title>RENAME</title>
418

  
419
        <cmdsynopsis>
420
          <command>rename</command>
421
          <arg>--no-ip-check</arg>
422
          <arg choice="req"><replaceable>instance</replaceable></arg>
423
          <arg choice="req"><replaceable>new_name</replaceable></arg>
424
        </cmdsynopsis>
425

  
426
        <para>
427
          Renames the given instance. The instance must be stopped
428
          when running this command. The requirements for the new name
429
          are the same as for adding an instance: the new name must be
430
          resolvable and the IP it resolves to must not be reachable
431
          (in order to prevent duplicate IPs the next time the
432
          instance is started). The IP test can be skipped if the
433
          <option>--no-ip-check</option> option is passed.
434
        </para>
435
      </refsect3>
436

  
416 437
    </refsect2>
417 438

  
418 439
    <refsect2>
b/scripts/gnt-instance
239 239
  return 0
240 240

  
241 241

  
242
def RenameInstance(opts, args):
243
  """Reinstall an instance.
244

  
245
  Args:
246
    opts - class with options as members
247
    args - list containing two elements, the instance name and the new name
248

  
249
  """
250
  op = opcodes.OpRenameInstance(instance_name=args[0],
251
                                new_name=args[1],
252
                                ignore_ip=opts.ignore_ip)
253
  SubmitOpCode(op)
254

  
255
  return 0
256

  
257

  
242 258
def ActivateDisks(opts, args):
243 259
  """Activate an instance's disks.
244 260

  
......
270 286

  
271 287

  
272 288
def StartupInstance(opts, args):
273
  """Shutdown an instance.
289
  """Startup an instance.
274 290

  
275 291
  Args:
276 292
    opts - class with options as members
......
634 650
                    ],
635 651
                   "-b disk -p port <instance>",
636 652
                   "Removes a mirror from the instance"),
653
  'rename': (RenameInstance, ARGS_FIXED(2),
654
             [DEBUG_OPT,
655
              make_option("--no-ip-check", dest="ignore_ip",
656
                          help="Do not check that the IP of the new name"
657
                          " is alive",
658
                          default=False, action="store_true"),
659
              ],
660
             "<instance> <new_name>", "Rename the instance"),
637 661
  'replace-disks': (ReplaceDisks, ARGS_ONE,
638 662
                    [DEBUG_OPT,
639 663
                     make_option("-n", "--new-secondary", dest="new_secondary",
......
655 679
                          default=None, type="string", metavar="<ADDRESS>"),
656 680
              make_option("-b", "--bridge", dest="bridge",
657 681
                          help="Bridge to connect this instance to",
658
                          default=None, type="string", metavar="<bridge>")
682
                          default=None, type="string", metavar="<bridge>"),
659 683
              ],
660 684
             "<instance>", "Alters the parameters of an instance"),
661 685
  'shutdown': (ShutdownInstance, ARGS_ANY,

Also available in: Unified diff