Commit 4c06a2d0 authored by Iustin Pop's avatar Iustin Pop
Browse files

Merge branch 'stable-2.1' into devel-2.1



* stable-2.1:
  TLReplaceDisks: Delay iallocator when evacuating node
  Implement debug level across OS-related RPC calls
  Second try to fix LUVerifyCluster
  LUVerifyCluster: Fix bug with offline nodes
  utils: Fix retry delay calculator
  Bump RPC protocol version to 30
Signed-off-by: default avatarIustin Pop <iustin@google.com>
Reviewed-by: default avatarMichael Hanselmann <hansmi@google.com>
parents 9f53d9ce 94a1b377
......@@ -345,8 +345,9 @@ class NodeHttpServer(http.server.HttpServer):
instance = objects.Instance.FromDict(params[2])
cluster_name = params[3]
dev_idx = params[4]
debug = params[5]
return backend.ExportSnapshot(disk, dest_node, instance,
cluster_name, dev_idx)
cluster_name, dev_idx, debug)
@staticmethod
def perspective_finalize_export(params):
......@@ -451,26 +452,27 @@ class NodeHttpServer(http.server.HttpServer):
inst_s = params[0]
inst = objects.Instance.FromDict(inst_s)
reinstall = params[1]
return backend.InstanceOsAdd(inst, reinstall)
debug = params[2]
return backend.InstanceOsAdd(inst, reinstall, debug)
@staticmethod
def perspective_instance_run_rename(params):
"""Runs the OS rename script for an instance.
"""
inst_s, old_name = params
inst_s, old_name, debug = params
inst = objects.Instance.FromDict(inst_s)
return backend.RunRenameInstance(inst, old_name)
return backend.RunRenameInstance(inst, old_name, debug)
@staticmethod
def perspective_instance_os_import(params):
"""Run the import function of an OS onto a given instance.
"""
inst_s, src_node, src_images, cluster_name = params
inst_s, src_node, src_images, cluster_name, debug = params
inst = objects.Instance.FromDict(inst_s)
return backend.ImportOSIntoInstance(inst, src_node, src_images,
cluster_name)
cluster_name, debug)
@staticmethod
def perspective_instance_shutdown(params):
......
......@@ -789,19 +789,21 @@ def GetAllInstancesInfo(hypervisor_list):
return output
def InstanceOsAdd(instance, reinstall):
def InstanceOsAdd(instance, reinstall, debug):
"""Add an OS to an instance.
@type instance: L{objects.Instance}
@param instance: Instance whose OS is to be installed
@type reinstall: boolean
@param reinstall: whether this is an instance reinstall
@type debug: integer
@param debug: debug level, passed to the OS scripts
@rtype: None
"""
inst_os = OSFromDisk(instance.os)
create_env = OSEnvironment(instance, inst_os)
create_env = OSEnvironment(instance, inst_os, debug)
if reinstall:
create_env['INSTANCE_REINSTALL'] = "1"
......@@ -820,20 +822,22 @@ def InstanceOsAdd(instance, reinstall):
" log file:\n%s", result.fail_reason, "\n".join(lines), log=False)
def RunRenameInstance(instance, old_name):
def RunRenameInstance(instance, old_name, debug):
"""Run the OS rename script for an instance.
@type instance: L{objects.Instance}
@param instance: Instance whose OS is to be installed
@type old_name: string
@param old_name: previous instance name
@type debug: integer
@param debug: debug level, passed to the OS scripts
@rtype: boolean
@return: the success of the operation
"""
inst_os = OSFromDisk(instance.os)
rename_env = OSEnvironment(instance, inst_os)
rename_env = OSEnvironment(instance, inst_os, debug)
rename_env['OLD_INSTANCE_NAME'] = old_name
logfile = "%s/rename-%s-%s-%s-%d.log" % (constants.LOG_OS_DIR, instance.os,
......@@ -1944,7 +1948,7 @@ def BlockdevSnapshot(disk):
disk.unique_id, disk.dev_type)
def ExportSnapshot(disk, dest_node, instance, cluster_name, idx):
def ExportSnapshot(disk, dest_node, instance, cluster_name, idx, debug):
"""Export a block device snapshot to a remote node.
@type disk: L{objects.Disk}
......@@ -1958,11 +1962,13 @@ def ExportSnapshot(disk, dest_node, instance, cluster_name, idx):
@type idx: int
@param idx: the index of the disk in the instance's disk list,
used to export to the OS scripts environment
@type debug: integer
@param debug: debug level, passed to the OS scripts
@rtype: None
"""
inst_os = OSFromDisk(instance.os)
export_env = OSEnvironment(instance, inst_os)
export_env = OSEnvironment(instance, inst_os, debug)
export_script = inst_os.export_script
......@@ -2092,7 +2098,7 @@ def ExportInfo(dest):
return config.Dumps()
def ImportOSIntoInstance(instance, src_node, src_images, cluster_name):
def ImportOSIntoInstance(instance, src_node, src_images, cluster_name, debug):
"""Import an os image into an instance.
@type instance: L{objects.Instance}
......@@ -2101,12 +2107,14 @@ def ImportOSIntoInstance(instance, src_node, src_images, cluster_name):
@param src_node: source node for the disk images
@type src_images: list of string
@param src_images: absolute paths of the disk images
@type debug: integer
@param debug: debug level, passed to the OS scripts
@rtype: list of boolean
@return: each boolean represent the success of importing the n-th disk
"""
inst_os = OSFromDisk(instance.os)
import_env = OSEnvironment(instance, inst_os)
import_env = OSEnvironment(instance, inst_os, debug)
import_script = inst_os.import_script
logfile = "%s/import-%s-%s-%s.log" % (constants.LOG_OS_DIR, instance.os,
......
......@@ -1603,7 +1603,8 @@ class LUVerifyCluster(LogicalUnit):
test = msg and not res.offline
self._ErrorIf(test, self.ENODEHOOKS, node_name,
"Communication failure in hooks execution: %s", msg)
if test:
if res.offline or msg:
# No need to investigate payload if node is offline or gave an error.
# override manually lu_result here as _ErrorIf only
# overrides self.bad
lu_result = 1
......@@ -3992,7 +3993,8 @@ class LUReinstallInstance(LogicalUnit):
_StartInstanceDisks(self, inst, None)
try:
feedback_fn("Running the instance OS create scripts...")
result = self.rpc.call_instance_os_add(inst.primary_node, inst, True)
# FIXME: pass debug option from opcode to backend
result = self.rpc.call_instance_os_add(inst.primary_node, inst, True, 0)
result.Raise("Could not install OS for instance %s on node %s" %
(inst.name, inst.primary_node))
finally:
......@@ -4176,7 +4178,7 @@ class LURenameInstance(LogicalUnit):
_StartInstanceDisks(self, inst, None)
try:
result = self.rpc.call_instance_run_rename(inst.primary_node, inst,
old_name)
old_name, 0)
msg = result.fail_msg
if msg:
msg = ("Could not run OS rename script for instance %s on node %s"
......@@ -6229,7 +6231,8 @@ class LUCreateInstance(LogicalUnit):
if iobj.disk_template != constants.DT_DISKLESS:
if self.op.mode == constants.INSTANCE_CREATE:
feedback_fn("* running the instance OS create scripts...")
result = self.rpc.call_instance_os_add(pnode_name, iobj, False)
# FIXME: pass debug option from opcode to backend
result = self.rpc.call_instance_os_add(pnode_name, iobj, False, 0)
result.Raise("Could not add os for instance %s"
" on node %s" % (instance, pnode_name))
......@@ -6238,9 +6241,10 @@ class LUCreateInstance(LogicalUnit):
src_node = self.op.src_node
src_images = self.src_images
cluster_name = self.cfg.GetClusterName()
# FIXME: pass debug option from opcode to backend
import_result = self.rpc.call_instance_os_import(pnode_name, iobj,
src_node, src_images,
cluster_name)
cluster_name, 0)
msg = import_result.fail_msg
if msg:
self.LogWarning("Error while importing the disk images for instance"
......@@ -6359,7 +6363,7 @@ class LUReplaceDisks(LogicalUnit):
self.replacer = TLReplaceDisks(self, self.op.instance_name, self.op.mode,
self.op.iallocator, self.op.remote_node,
self.op.disks)
self.op.disks, False)
self.tasklets = [self.replacer]
......@@ -6451,7 +6455,8 @@ class LUEvacuateNode(LogicalUnit):
names.append(inst.name)
replacer = TLReplaceDisks(self, inst.name, constants.REPLACE_DISK_CHG,
self.op.iallocator, self.op.remote_node, [])
self.op.iallocator, self.op.remote_node, [],
True)
tasklets.append(replacer)
self.tasklets = tasklets
......@@ -6493,7 +6498,7 @@ class TLReplaceDisks(Tasklet):
"""
def __init__(self, lu, instance_name, mode, iallocator_name, remote_node,
disks):
disks, delay_iallocator):
"""Initializes this class.
"""
......@@ -6505,6 +6510,7 @@ class TLReplaceDisks(Tasklet):
self.iallocator_name = iallocator_name
self.remote_node = remote_node
self.disks = disks
self.delay_iallocator = delay_iallocator
# Runtime data
self.instance = None
......@@ -6591,6 +6597,19 @@ class TLReplaceDisks(Tasklet):
len(instance.secondary_nodes),
errors.ECODE_FAULT)
if not self.delay_iallocator:
self._CheckPrereq2()
def _CheckPrereq2(self):
"""Check prerequisites, second part.
This function should always be part of CheckPrereq. It was separated and is
now called from Exec because during node evacuation iallocator was only
called with an unmodified cluster model, not taking planned changes into
account.
"""
instance = self.instance
secondary_node = instance.secondary_nodes[0]
if self.iallocator_name is None:
......@@ -6694,6 +6713,9 @@ class TLReplaceDisks(Tasklet):
This dispatches the disk replacement to the appropriate handler.
"""
if self.delay_iallocator:
self._CheckPrereq2()
if not self.disks:
feedback_fn("No disks need replacement")
return
......@@ -8148,8 +8170,10 @@ class LUExportInstance(LogicalUnit):
feedback_fn("Exporting snapshot %s from %s to %s" %
(idx, src_node, dst_node.name))
if dev:
# FIXME: pass debug from opcode to backend
result = self.rpc.call_snapshot_export(src_node, dev, dst_node.name,
instance, cluster_name, idx)
instance, cluster_name,
idx, 0)
msg = result.fail_msg
if msg:
self.LogWarning("Could not export disk/%s from node %s to"
......
......@@ -26,7 +26,7 @@ import re
from ganeti import _autoconf
# various versions
PROTOCOL_VERSION = 20
PROTOCOL_VERSION = 30
RELEASE_VERSION = _autoconf.PACKAGE_VERSION
OS_API_V10 = 10
OS_API_V15 = 15
......
......@@ -576,23 +576,23 @@ class RpcRunner(object):
[self._InstDict(inst), reboot_type,
shutdown_timeout])
def call_instance_os_add(self, node, inst, reinstall):
def call_instance_os_add(self, node, inst, reinstall, debug):
"""Installs an OS on the given instance.
This is a single-node call.
"""
return self._SingleNodeCall(node, "instance_os_add",
[self._InstDict(inst), reinstall])
[self._InstDict(inst), reinstall, debug])
def call_instance_run_rename(self, node, inst, old_name):
def call_instance_run_rename(self, node, inst, old_name, debug):
"""Run the OS rename script for an instance.
This is a single-node call.
"""
return self._SingleNodeCall(node, "instance_run_rename",
[self._InstDict(inst), old_name])
[self._InstDict(inst), old_name, debug])
def call_instance_info(self, node, instance, hname):
"""Returns information about a single instance.
......@@ -988,7 +988,7 @@ class RpcRunner(object):
return self._SingleNodeCall(node, "blockdev_snapshot", [cf_bdev.ToDict()])
def call_snapshot_export(self, node, snap_bdev, dest_node, instance,
cluster_name, idx):
cluster_name, idx, debug):
"""Request the export of a given snapshot.
This is a single-node call.
......@@ -996,7 +996,8 @@ class RpcRunner(object):
"""
return self._SingleNodeCall(node, "snapshot_export",
[snap_bdev.ToDict(), dest_node,
self._InstDict(instance), cluster_name, idx])
self._InstDict(instance), cluster_name,
idx, debug])
def call_finalize_export(self, node, instance, snap_disks):
"""Request the completion of an export operation.
......@@ -1025,7 +1026,7 @@ class RpcRunner(object):
return self._SingleNodeCall(node, "export_info", [path])
def call_instance_os_import(self, node, inst, src_node, src_images,
cluster_name):
cluster_name, debug):
"""Request the import of a backup into an instance.
This is a single-node call.
......@@ -1033,7 +1034,7 @@ class RpcRunner(object):
"""
return self._SingleNodeCall(node, "instance_os_import",
[self._InstDict(inst), src_node, src_images,
cluster_name])
cluster_name, debug])
def call_export_list(self, node_list):
"""Gets the stored exports list.
......
......@@ -2172,7 +2172,7 @@ class _RetryDelayCalculator(object):
# Update for next run
if self._limit is None or self._next < self._limit:
self._next = max(self._limit, self._next * self._factor)
self._next = min(self._limit, self._next * self._factor)
return current
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment