file_names = ssconf.SimpleStore().GetFileList()
file_names.append(constants.SSL_CERT_FILE)
+ file_names.append(constants.RAPI_CERT_FILE)
file_names.extend(master_files)
local_checksums = utils.FingerprintFiles(file_names)
feedback_fn("* Gathering data (%d nodes)" % len(nodelist))
node_verify_param = {
constants.NV_FILELIST: file_names,
- constants.NV_NODELIST: nodelist,
+ constants.NV_NODELIST: [node.name for node in nodeinfo
+ if not node.offline],
constants.NV_HYPERVISOR: hypervisors,
constants.NV_NODENETTEST: [(node.name, node.primary_ip,
- node.secondary_ip) for node in nodeinfo],
+ node.secondary_ip) for node in nodeinfo
+ if not node.offline],
constants.NV_LVLIST: vg_name,
constants.NV_INSTANCELIST: hypervisors,
constants.NV_VGLIST: None,
"""
node_list = self.acquired_locks[locking.LEVEL_NODE]
- node_data = self.rpc.call_os_diagnose(node_list)
+ valid_nodes = [node for node in self.cfg.GetOnlineNodeList()
+ if node in node_list]
+ node_data = self.rpc.call_os_diagnose(valid_nodes)
if node_data == False:
raise errors.OpExecError("Can't gather the list of OSes")
- pol = self._DiagnoseByOS(node_list, node_data)
+ pol = self._DiagnoseByOS(valid_nodes, node_data)
output = []
for os_name, os_data in pol.iteritems():
row = []
" based ping to noded port")
cp_size = self.cfg.GetClusterInfo().candidate_pool_size
- node_info = self.cfg.GetAllNodesInfo().values()
mc_now, _ = self.cfg.GetMasterCandidateStats()
master_candidate = mc_now < cp_size
raise errors.OpPrereqError("The master node has to be a"
" master candidate and online")
cp_size = self.cfg.GetClusterInfo().candidate_pool_size
- node_info = self.cfg.GetAllNodesInfo().values()
num_candidates, _ = self.cfg.GetMasterCandidateStats()
if num_candidates <= cp_size:
msg = ("Not enough master candidates (desired"
self.instance = self.cfg.GetInstanceInfo(self.op.instance_name)
assert self.instance is not None, \
"Cannot retrieve locked instance %s" % self.op.instance_name
- _CheckNodeOnline(self, instance.primary_node)
+ _CheckNodeOnline(self, self.instance.primary_node)
def Exec(self, feedback_fn):
"""Activate the disks.
" (is_primary=True, pass=2)",
inst_disk.iv_name, node)
disks_ok = False
- device_info.append((instance.primary_node, inst_disk.iv_name, result))
+ device_info.append((instance.primary_node, inst_disk.iv_name, result.data))
# leave the disks configured for the primary node
# this is a workaround that would be fixed better by
return result
-def _CheckNodeFreeMemory(lu, node, reason, requested, hypervisor):
+def _CheckNodeFreeMemory(lu, node, reason, requested, hypervisor_name):
"""Checks if a node has enough free memory.
This function check if a given node has the needed amount of free
@param reason: string to use in the error message
@type requested: C{int}
@param requested: the amount of memory in MiB to check for
- @type hypervisor: C{str}
- @param hypervisor: the hypervisor to ask for memory stats
+ @type hypervisor_name: C{str}
+ @param hypervisor_name: the hypervisor to ask for memory stats
@raise errors.OpPrereqError: if the node doesn't have enough memory, or
we cannot check the node
"""
- nodeinfo = lu.rpc.call_node_info([node], lu.cfg.GetVGName(), hypervisor)
+ nodeinfo = lu.rpc.call_node_info([node], lu.cfg.GetVGName(), hypervisor_name)
nodeinfo[node].Raise()
free_mem = nodeinfo[node].data.get('memory_free')
if not isinstance(free_mem, int):
self.instance = self.cfg.GetInstanceInfo(self.op.instance_name)
assert self.instance is not None, \
"Cannot retrieve locked instance %s" % self.op.instance_name
- _CheckNodeOnline(self, instance.primary_node)
+ _CheckNodeOnline(self, self.instance.primary_node)
def Exec(self, feedback_fn):
"""Shutdown the instance.
self.instance = self.cfg.GetInstanceInfo(self.op.instance_name)
assert self.instance is not None, \
"Cannot retrieve locked instance %s" % self.op.instance_name
- _CheckNodeOnline(self, self.op.primary_node)
+ _CheckNodeOnline(self, self.instance.primary_node)
def Exec(self, feedback_fn):
"""Connect to the console of an instance
_OP_REQP = ["instance_name", "mode", "disks"]
REQ_BGL = False
- def ExpandNames(self):
- self._ExpandAndLockInstance()
-
+ def CheckArguments(self):
if not hasattr(self.op, "remote_node"):
self.op.remote_node = None
-
- ia_name = getattr(self.op, "iallocator", None)
- if ia_name is not None:
- if self.op.remote_node is not None:
+ if not hasattr(self.op, "iallocator"):
+ self.op.iallocator = None
+
+ # check for valid parameter combination
+ cnt = [self.op.remote_node, self.op.iallocator].count(None)
+ if self.op.mode == constants.REPLACE_DISK_CHG:
+ if cnt == 2:
+ raise errors.OpPrereqError("When changing the secondary either an"
+ " iallocator script must be used or the"
+ " new node given")
+ elif cnt == 0:
raise errors.OpPrereqError("Give either the iallocator or the new"
" secondary, not both")
+ else: # not replacing the secondary
+ if cnt != 2:
+ raise errors.OpPrereqError("The iallocator and new node options can"
+ " be used only when changing the"
+ " secondary node")
+
+ def ExpandNames(self):
+ self._ExpandAndLockInstance()
+
+ if self.op.iallocator is not None:
self.needed_locks[locking.LEVEL_NODE] = locking.ALL_SET
elif self.op.remote_node is not None:
remote_node = self.cfg.ExpandNodeName(self.op.remote_node)
"Cannot retrieve locked instance %s" % self.op.instance_name
self.instance = instance
- if instance.disk_template not in constants.DTS_NET_MIRROR:
- raise errors.OpPrereqError("Instance's disk layout is not"
- " network mirrored.")
+ if instance.disk_template != constants.DT_DRBD8:
+ raise errors.OpPrereqError("Can only run replace disks for DRBD8-based"
+ " instances")
if len(instance.secondary_nodes) != 1:
raise errors.OpPrereqError("The instance has a strange layout,"
self.sec_node = instance.secondary_nodes[0]
- ia_name = getattr(self.op, "iallocator", None)
- if ia_name is not None:
+ if self.op.iallocator is not None:
self._RunAllocator()
remote_node = self.op.remote_node
raise errors.OpPrereqError("The specified node is the primary node of"
" the instance.")
elif remote_node == self.sec_node:
- if self.op.mode == constants.REPLACE_DISK_SEC:
- # this is for DRBD8, where we can't execute the same mode of
- # replacement as for drbd7 (no different port allocated)
- raise errors.OpPrereqError("Same secondary given, cannot execute"
- " replacement")
- if instance.disk_template == constants.DT_DRBD8:
- if (self.op.mode == constants.REPLACE_DISK_ALL and
- remote_node is not None):
- # switch to replace secondary mode
- self.op.mode = constants.REPLACE_DISK_SEC
-
- if self.op.mode == constants.REPLACE_DISK_ALL:
- raise errors.OpPrereqError("Template 'drbd' only allows primary or"
- " secondary disk replacement, not"
- " both at once")
- elif self.op.mode == constants.REPLACE_DISK_PRI:
- if remote_node is not None:
- raise errors.OpPrereqError("Template 'drbd' does not allow changing"
- " the secondary while doing a primary"
- " node disk replacement")
- self.tgt_node = instance.primary_node
- self.oth_node = instance.secondary_nodes[0]
- _CheckNodeOnline(self, self.tgt_node)
- _CheckNodeOnline(self, self.oth_node)
- elif self.op.mode == constants.REPLACE_DISK_SEC:
- self.new_node = remote_node # this can be None, in which case
- # we don't change the secondary
- self.tgt_node = instance.secondary_nodes[0]
- self.oth_node = instance.primary_node
- _CheckNodeOnline(self, self.oth_node)
- if self.new_node is not None:
- _CheckNodeOnline(self, self.new_node)
- else:
- _CheckNodeOnline(self, self.tgt_node)
- else:
- raise errors.ProgrammerError("Unhandled disk replace mode")
+ raise errors.OpPrereqError("The specified node is already the"
+ " secondary node of the instance.")
+
+ if self.op.mode == constants.REPLACE_DISK_PRI:
+ n1 = self.tgt_node = instance.primary_node
+ n2 = self.oth_node = self.sec_node
+ elif self.op.mode == constants.REPLACE_DISK_SEC:
+ n1 = self.tgt_node = self.sec_node
+ n2 = self.oth_node = instance.primary_node
+ elif self.op.mode == constants.REPLACE_DISK_CHG:
+ n1 = self.new_node = remote_node
+ n2 = self.oth_node = instance.primary_node
+ self.tgt_node = self.sec_node
+ else:
+ raise errors.ProgrammerError("Unhandled disk replace mode")
+
+ _CheckNodeOnline(self, n1)
+ _CheckNodeOnline(self, n2)
if not self.op.disks:
self.op.disks = range(len(instance.disks))
# now that the new lvs have the old name, we can add them to the device
info("adding new mirror component on %s" % tgt_node)
- result =self.rpc.call_blockdev_addchildren(tgt_node, dev, new_lvs)
+ result = self.rpc.call_blockdev_addchildren(tgt_node, dev, new_lvs)
if result.failed or not result.data:
for new_lv in new_lvs:
result = self.rpc.call_blockdev_remove(tgt_node, new_lv)
warning, info = (self.proc.LogWarning, self.proc.LogInfo)
instance = self.instance
iv_names = {}
- vgname = self.cfg.GetVGName()
# start of work
cfg = self.cfg
old_node = self.tgt_node
# Step: create new storage
self.proc.LogStep(3, steps_total, "allocate new storage")
for idx, dev in enumerate(instance.disks):
- size = dev.size
info("adding new local storage on %s for disk/%d" %
(new_node, idx))
# since we *always* want to create this LV, we use the
# and now perform the drbd attach
info("attaching primary drbds to new secondary (standalone => connected)")
- failures = []
for idx, dev in enumerate(instance.disks):
info("attaching primary drbd for disk/%d to new secondary node" % idx)
# since the attach is smart, it's enough to 'find' the device,
if instance.status == "down":
_StartInstanceDisks(self, instance, True)
- if instance.disk_template == constants.DT_DRBD8:
- if self.op.remote_node is None:
- fn = self._ExecD8DiskOnly
- else:
- fn = self._ExecD8Secondary
+ if self.op.mode == constants.REPLACE_DISK_CHG:
+ fn = self._ExecD8Secondary
else:
- raise errors.ProgrammerError("Unhandled disk replacement case")
+ fn = self._ExecD8DiskOnly
ret = fn(feedback_fn)
self.instance = self.cfg.GetInstanceInfo(instance_name)
assert self.instance is not None, \
"Cannot retrieve locked instance %s" % self.op.instance_name
- _CheckNodeOnline(self, instance.primary_node)
+ _CheckNodeOnline(self, self.instance.primary_node)
self.dst_node = self.cfg.GetNodeInfo(
self.cfg.ExpandNodeName(self.op.target_node))
self.name = name
self.mem_size = self.disks = self.disk_template = None
self.os = self.tags = self.nics = self.vcpus = None
+ self.hypervisor = None
self.relocate_from = None
# computed fields
self.required_nodes = None
node_list = cfg.GetNodeList()
if self.mode == constants.IALLOCATOR_MODE_ALLOC:
- hypervisor = self.hypervisor
+ hypervisor_name = self.hypervisor
elif self.mode == constants.IALLOCATOR_MODE_RELOC:
- hypervisor = cfg.GetInstanceInfo(self.name).hypervisor
+ hypervisor_name = cfg.GetInstanceInfo(self.name).hypervisor
node_data = self.lu.rpc.call_node_info(node_list, cfg.GetVGName(),
- hypervisor)
+ hypervisor_name)
node_iinfo = self.lu.rpc.call_all_instances_info(node_list,
cluster_info.enabled_hypervisors)
for nname in node_list: