RedistributeAncillaryFiles, ExpandNodeUuidAndName, ShareAll, SupportsOob, \
CheckInstanceState, INSTANCE_DOWN, GetUpdatedParams, \
AdjustCandidatePool, CheckIAllocatorOrNode, LoadNodeEvacResult, \
- GetWantedNodes, MapInstanceDisksToNodes, RunPostHook, \
+ GetWantedNodes, MapInstanceLvsToNodes, RunPostHook, \
FindFaultyInstanceDisks
Any errors are signaled by raising errors.OpPrereqError.
"""
- cfg = self.cfg
- hostname = self.hostname
- node_name = hostname.name
- primary_ip = self.op.primary_ip = hostname.ip
+ node_name = self.hostname.name
+ self.op.primary_ip = self.hostname.ip
if self.op.secondary_ip is None:
if self.primary_ip_family == netutils.IP6Address.family:
raise errors.OpPrereqError("When using a IPv6 primary address, a valid"
" IPv4 address must be given as secondary",
errors.ECODE_INVAL)
- self.op.secondary_ip = primary_ip
+ self.op.secondary_ip = self.op.primary_ip
secondary_ip = self.op.secondary_ip
if not netutils.IP4Address.IsValid(secondary_ip):
raise errors.OpPrereqError("Secondary IP (%s) needs to be a valid IPv4"
" address" % secondary_ip, errors.ECODE_INVAL)
- existing_node_info = cfg.GetNodeInfoByName(node_name)
+ existing_node_info = self.cfg.GetNodeInfoByName(node_name)
if not self.op.readd and existing_node_info is not None:
raise errors.OpPrereqError("Node %s is already in the configuration" %
node_name, errors.ECODE_EXISTS)
self.changed_primary_ip = False
- for existing_node in cfg.GetAllNodesInfo().values():
+ for existing_node in self.cfg.GetAllNodesInfo().values():
if self.op.readd and node_name == existing_node.name:
if existing_node.secondary_ip != secondary_ip:
raise errors.OpPrereqError("Readded node doesn't have the same IP"
" address configuration as before",
errors.ECODE_INVAL)
- if existing_node.primary_ip != primary_ip:
+ if existing_node.primary_ip != self.op.primary_ip:
self.changed_primary_ip = True
continue
- if (existing_node.primary_ip == primary_ip or
- existing_node.secondary_ip == primary_ip or
+ if (existing_node.primary_ip == self.op.primary_ip or
+ existing_node.secondary_ip == self.op.primary_ip or
existing_node.primary_ip == secondary_ip or
existing_node.secondary_ip == secondary_ip):
raise errors.OpPrereqError("New node ip address(es) conflict with"
setattr(self.op, attr, True)
if self.op.readd and not self.op.vm_capable:
- pri, sec = cfg.GetNodeInstances(existing_node_info.uuid)
+ pri, sec = self.cfg.GetNodeInstances(existing_node_info.uuid)
if pri or sec:
raise errors.OpPrereqError("Node %s being re-added with vm_capable"
" flag set to false, but it already holds"
# check that the type of the node (single versus dual homed) is the
# same as for the master
- myself = cfg.GetNodeInfo(self.cfg.GetMasterNode())
+ myself = self.cfg.GetNodeInfo(self.cfg.GetMasterNode())
master_singlehomed = myself.secondary_ip == myself.primary_ip
- newbie_singlehomed = secondary_ip == primary_ip
+ newbie_singlehomed = secondary_ip == self.op.primary_ip
if master_singlehomed != newbie_singlehomed:
if master_singlehomed:
raise errors.OpPrereqError("The master has no secondary ip but the"
errors.ECODE_INVAL)
# checks reachability
- if not netutils.TcpPing(primary_ip, constants.DEFAULT_NODED_PORT):
+ if not netutils.TcpPing(self.op.primary_ip, constants.DEFAULT_NODED_PORT):
raise errors.OpPrereqError("Node not reachable by ping",
errors.ECODE_ENVIRON)
if self.op.readd:
self.new_node = existing_node_info
else:
- node_group = cfg.LookupNodeGroup(self.op.group)
+ node_group = self.cfg.LookupNodeGroup(self.op.group)
self.new_node = objects.Node(name=node_name,
- primary_ip=primary_ip,
+ primary_ip=self.op.primary_ip,
secondary_ip=secondary_ip,
master_candidate=self.master_candidate,
offline=False, drained=False,
(constants.PROTOCOL_VERSION, result.payload),
errors.ECODE_ENVIRON)
- vg_name = cfg.GetVGName()
+ vg_name = self.cfg.GetVGName()
if vg_name is not None:
vparams = {constants.NV_PVLIST: [vg_name]}
- excl_stor = IsExclusiveStorageEnabledNode(cfg, self.new_node)
+ excl_stor = IsExclusiveStorageEnabledNode(self.cfg, self.new_node)
cname = self.cfg.GetClusterName()
result = rpcrunner.call_node_verify_light(
- [node_name], vparams, cname, cfg.GetClusterInfo().hvparams)[node_name]
+ [node_name], vparams, cname,
+ self.cfg.GetClusterInfo().hvparams)[node_name]
(errmsgs, _) = CheckNodePVs(result.payload, excl_stor)
if errmsgs:
raise errors.OpPrereqError("Checks on node PVs failed: %s" %
"""Adds the new node to the cluster.
"""
- new_node = self.new_node
- node_name = new_node.name
-
assert locking.BGL in self.owned_locks(locking.LEVEL_CLUSTER), \
"Not owning BGL"
# We adding a new node so we assume it's powered
- new_node.powered = True
+ self.new_node.powered = True
# for re-adds, reset the offline/drained/master-candidate flags;
# we need to reset here, otherwise offline would prevent RPC calls
# later in the procedure; this also means that if the re-add
# fails, we are left with a non-offlined, broken node
if self.op.readd:
- new_node.drained = new_node.offline = False # pylint: disable=W0201
+ self.new_node.drained = False
self.LogInfo("Readding a node, the offline/drained flags were reset")
# if we demote the node, we do cleanup later in the procedure
- new_node.master_candidate = self.master_candidate
+ self.new_node.master_candidate = self.master_candidate
if self.changed_primary_ip:
- new_node.primary_ip = self.op.primary_ip
+ self.new_node.primary_ip = self.op.primary_ip
# copy the master/vm_capable flags
for attr in self._NFLAGS:
- setattr(new_node, attr, getattr(self.op, attr))
+ setattr(self.new_node, attr, getattr(self.op, attr))
# notify the user about any possible mc promotion
- if new_node.master_candidate:
+ if self.new_node.master_candidate:
self.LogInfo("Node will be a master candidate")
if self.op.ndparams:
- new_node.ndparams = self.op.ndparams
+ self.new_node.ndparams = self.op.ndparams
else:
- new_node.ndparams = {}
+ self.new_node.ndparams = {}
if self.op.hv_state:
- new_node.hv_state_static = self.new_hv_state
+ self.new_node.hv_state_static = self.new_hv_state
if self.op.disk_state:
- new_node.disk_state_static = self.new_disk_state
+ self.new_node.disk_state_static = self.new_disk_state
# Add node to our /etc/hosts, and add key to known_hosts
if self.cfg.GetClusterInfo().modify_etc_hosts:
self.hostname.ip)
result.Raise("Can't update hosts file with new host data")
- if new_node.secondary_ip != new_node.primary_ip:
- _CheckNodeHasSecondaryIP(self, new_node, new_node.secondary_ip, False)
+ if self.new_node.secondary_ip != self.new_node.primary_ip:
+ _CheckNodeHasSecondaryIP(self, self.new_node, self.new_node.secondary_ip,
+ False)
node_verifier_uuids = [self.cfg.GetMasterNode()]
node_verify_param = {
- constants.NV_NODELIST: ([node_name], {}),
+ constants.NV_NODELIST: ([self.new_node.name], {}),
# TODO: do a node-net-test as well?
}
raise errors.OpExecError("ssh/hostname verification failed")
if self.op.readd:
- self.context.ReaddNode(new_node)
+ self.context.ReaddNode(self.new_node)
RedistributeAncillaryFiles(self)
# make sure we redistribute the config
- self.cfg.Update(new_node, feedback_fn)
+ self.cfg.Update(self.new_node, feedback_fn)
# and make sure the new node will not have old files around
- if not new_node.master_candidate:
- result = self.rpc.call_node_demote_from_mc(new_node.uuid)
+ if not self.new_node.master_candidate:
+ result = self.rpc.call_node_demote_from_mc(self.new_node.uuid)
result.Warn("Node failed to demote itself from master candidate status",
self.LogWarning)
else:
- self.context.AddNode(new_node, self.proc.GetECId())
+ self.context.AddNode(self.new_node, self.proc.GetECId())
RedistributeAncillaryFiles(self)
if self.lock_instances:
self.needed_locks[locking.LEVEL_INSTANCE] = \
- frozenset(self.cfg.GetInstancesInfoByFilter(self._InstanceFilter))
+ self.cfg.GetInstanceNames(
+ self.cfg.GetInstancesInfoByFilter(self._InstanceFilter).keys())
def BuildHooksEnv(self):
"""Build hooks env.
self.cfg.GetInstancesInfoByFilter(self._InstanceFilter)
# Verify instance locks
- owned_instances = self.owned_locks(locking.LEVEL_INSTANCE)
- wanted_instances = frozenset(affected_instances.keys())
- if wanted_instances - owned_instances:
+ owned_instance_names = self.owned_locks(locking.LEVEL_INSTANCE)
+ wanted_instance_names = frozenset([inst.name for inst in
+ affected_instances.values()])
+ if wanted_instance_names - owned_instance_names:
raise errors.OpPrereqError("Instances affected by changing node %s's"
" secondary IP address have changed since"
" locks were acquired, wanted '%s', have"
" '%s'; retry the operation" %
(node.name,
- utils.CommaJoin(wanted_instances),
- utils.CommaJoin(owned_instances)),
+ utils.CommaJoin(wanted_instance_names),
+ utils.CommaJoin(owned_instance_names)),
errors.ECODE_STATE)
else:
affected_instances = None
" passed, and the target node is the"
" master", errors.ECODE_INVAL)
- assert not (frozenset(affected_instances) -
+ assert not (set([inst.name for inst in affected_instances.values()]) -
self.owned_locks(locking.LEVEL_INSTANCE))
if node.offline:
if affected_instances:
msg = ("Cannot change secondary IP address: offline node has"
" instances (%s) configured to use it" %
- utils.CommaJoin(affected_instances.keys()))
+ utils.CommaJoin(
+ [inst.name for inst in affected_instances.values()]))
raise errors.OpPrereqError(msg, errors.ECODE_STATE)
else:
# On online nodes, check that no instances are running, and that
"""
node = self.cfg.GetNodeInfo(self.op.node_uuid)
- old_role = self.old_role
- new_role = self.new_role
-
result = []
if self.op.ndparams:
setattr(node, attr, val)
result.append((attr, str(val)))
- if new_role != old_role:
+ if self.new_role != self.old_role:
# Tell the node to demote itself, if no longer MC and not offline
- if old_role == self._ROLE_CANDIDATE and new_role != self._ROLE_OFFLINE:
+ if self.old_role == self._ROLE_CANDIDATE and \
+ self.new_role != self._ROLE_OFFLINE:
msg = self.rpc.call_node_demote_from_mc(node.name).fail_msg
if msg:
self.LogWarning("Node failed to demote itself: %s", msg)
- new_flags = self._R2F[new_role]
+ new_flags = self._R2F[self.new_role]
for of, nf, desc in zip(self.old_flags, new_flags, self._FLAGS):
if of != nf:
result.append((desc, str(nf)))
# this will trigger job queue propagation or cleanup if the mc
# flag changed
- if [old_role, new_role].count(self._ROLE_CANDIDATE) == 1:
+ if [self.old_role, self.new_role].count(self._ROLE_CANDIDATE) == 1:
self.context.ReaddNode(node)
return result
def CheckPrereq(self):
# Verify locks
- owned_instances = self.owned_locks(locking.LEVEL_INSTANCE)
+ owned_instance_names = self.owned_locks(locking.LEVEL_INSTANCE)
owned_nodes = self.owned_locks(locking.LEVEL_NODE)
owned_groups = self.owned_locks(locking.LEVEL_NODEGROUP)
self.instances = self._DetermineInstances()
self.instance_names = [i.name for i in self.instances]
- if set(self.instance_names) != owned_instances:
+ if set(self.instance_names) != owned_instance_names:
raise errors.OpExecError("Instances on node '%s' changed since locks"
" were acquired, current instances are '%s',"
" used to be '%s'; retry the operation" %
(self.op.node_name,
utils.CommaJoin(self.instance_names),
- utils.CommaJoin(owned_instances)))
+ utils.CommaJoin(owned_instance_names)))
if self.instance_names:
self.LogInfo("Evacuating instances from node '%s': %s",
def Exec(self, feedback_fn):
# Prepare jobs for migration instances
- allow_runtime_changes = self.op.allow_runtime_changes
jobs = [
- [opcodes.OpInstanceMigrate(instance_name=inst.name,
- mode=self.op.mode,
- live=self.op.live,
- iallocator=self.op.iallocator,
- target_node=self.op.target_node,
- allow_runtime_changes=allow_runtime_changes,
- ignore_ipolicy=self.op.ignore_ipolicy)]
+ [opcodes.OpInstanceMigrate(
+ instance_name=inst.name,
+ mode=self.op.mode,
+ live=self.op.live,
+ iallocator=self.op.iallocator,
+ target_node=self.op.target_node,
+ allow_runtime_changes=self.op.allow_runtime_changes,
+ ignore_ipolicy=self.op.ignore_ipolicy)]
for inst in _GetNodePrimaryInstances(self.cfg, self.op.node_uuid)]
# TODO: Run iallocator in this opcode and pass correct placement options to
# will have to be found.
assert (frozenset(self.owned_locks(locking.LEVEL_NODE)) ==
- frozenset([self.op.node_name]))
+ frozenset([self.op.node_uuid]))
return ResultWithJobs(jobs)
# filter out non-vm_capable nodes
toquery_node_uuids = [node.uuid for node in all_info.values()
if node.vm_capable and node.uuid in node_uuids]
-
- es_flags = rpc.GetExclusiveStorageForNodes(lu.cfg, toquery_node_uuids)
- # FIXME: This currently maps everything to lvm, this should be more
- # flexible
- vg_req = rpc.BuildVgInfoQuery(lu.cfg)
+ lvm_enabled = utils.storage.IsLvmEnabled(
+ lu.cfg.GetClusterInfo().enabled_disk_templates)
+ # FIXME: this per default asks for storage space information for all
+ # enabled disk templates. Fix this by making it possible to specify
+ # space report fields for specific disk templates.
+ raw_storage_units = utils.storage.GetStorageUnitsOfCluster(
+ lu.cfg, include_spindles=lvm_enabled)
+ storage_units = rpc.PrepareStorageUnitsForNodes(
+ lu.cfg, raw_storage_units, toquery_node_uuids)
default_hypervisor = lu.cfg.GetHypervisorType()
hvparams = lu.cfg.GetClusterInfo().hvparams[default_hypervisor]
hvspecs = [(default_hypervisor, hvparams)]
- node_data = lu.rpc.call_node_info(toquery_node_uuids, vg_req,
- hvspecs, es_flags)
- live_data = dict((uuid, rpc.MakeLegacyNodeInfo(nresult.payload))
- for (uuid, nresult) in node_data.items()
- if not nresult.fail_msg and nresult.payload)
+ node_data = lu.rpc.call_node_info(toquery_node_uuids, storage_units,
+ hvspecs)
+ live_data = dict(
+ (uuid, rpc.MakeLegacyNodeInfo(nresult.payload,
+ require_spindles=lvm_enabled))
+ for (uuid, nresult) in node_data.items()
+ if not nresult.fail_msg and nresult.payload)
else:
live_data = None
node_to_secondary = dict([(uuid, set()) for uuid in node_uuids])
inst_data = lu.cfg.GetAllInstancesInfo()
+ inst_uuid_to_inst_name = {}
for inst in inst_data.values():
+ inst_uuid_to_inst_name[inst.uuid] = inst.name
if inst.primary_node in node_to_primary:
- node_to_primary[inst.primary_node].add(inst.name)
+ node_to_primary[inst.primary_node].add(inst.uuid)
for secnode in inst.secondary_nodes:
if secnode in node_to_secondary:
- node_to_secondary[secnode].add(inst.name)
+ node_to_secondary[secnode].add(inst.uuid)
else:
node_to_primary = None
node_to_secondary = None
+ inst_uuid_to_inst_name = None
if query.NQ_OOB in self.requested_data:
oob_support = dict((uuid, bool(SupportsOob(lu.cfg, node)))
return query.NodeQueryData([all_info[uuid] for uuid in node_uuids],
live_data, lu.cfg.GetMasterNode(),
- node_to_primary, node_to_secondary, groups,
- oob_support, lu.cfg.GetClusterInfo())
+ node_to_primary, node_to_secondary,
+ inst_uuid_to_inst_name, groups, oob_support,
+ lu.cfg.GetClusterInfo())
class LUNodeQuery(NoHooksLU):
volumes = self.rpc.call_node_volumes(node_uuids)
ilist = self.cfg.GetAllInstancesInfo()
- vol2inst = MapInstanceDisksToNodes(ilist.values())
+ vol2inst = MapInstanceLvsToNodes(ilist.values())
output = []
for node_uuid in node_uuids:
elif field == "size":
val = int(float(vol["size"]))
elif field == "instance":
- val = vol2inst.get((node_uuid, vol["vg"] + "/" + vol["name"]), "-")
+ inst = vol2inst.get((node_uuid, vol["vg"] + "/" + vol["name"]),
+ None)
+ if inst is not None:
+ val = inst.name
+ else:
+ val = "-"
else:
raise errors.ParameterError(field)
node_output.append(str(val))
raise errors.OpPrereqError("Node is the master node, failover to another"
" node is required", errors.ECODE_INVAL)
- for instance_name, instance in self.cfg.GetAllInstancesInfo().items():
+ for _, instance in self.cfg.GetAllInstancesInfo().items():
if node.uuid in instance.all_nodes:
raise errors.OpPrereqError("Instance %s is still running on the node,"
- " please remove first" % instance_name,
+ " please remove first" % instance.name,
errors.ECODE_INVAL)
self.op.node_name = node.name
self.node = node
"""Removes the node from the cluster.
"""
- node = self.node
logging.info("Stopping the node daemon and removing configs from node %s",
- node.name)
+ self.node.name)
modify_ssh_setup = self.cfg.GetClusterInfo().modify_ssh_setup
"Not owning BGL"
# Promote nodes to master candidate as needed
- AdjustCandidatePool(self, exceptions=[node.uuid])
- self.context.RemoveNode(node)
+ AdjustCandidatePool(self, exceptions=[self.node.uuid])
+ self.context.RemoveNode(self.node)
# Run post hooks on the node before it's removed
- RunPostHook(self, node.name)
+ RunPostHook(self, self.node.name)
# we have to call this by name rather than by UUID, as the node is no longer
# in the config
- result = self.rpc.call_node_leave_cluster(node.name, modify_ssh_setup)
+ result = self.rpc.call_node_leave_cluster(self.node.name, modify_ssh_setup)
msg = result.fail_msg
if msg:
self.LogWarning("Errors encountered on the remote node while leaving"
master_node_uuid = self.cfg.GetMasterNode()
result = self.rpc.call_etc_hosts_modify(master_node_uuid,
constants.ETC_HOSTS_REMOVE,
- node.name, None)
+ self.node.name, None)
result.Raise("Can't update hosts file with new host data")
RedistributeAncillaryFiles(self)