all_changes = [opts.master_candidate, opts.drained, opts.offline,
opts.master_capable, opts.vm_capable, opts.secondary_ip,
opts.ndparams]
- if all_changes.count(None) == len(all_changes):
+ if (all_changes.count(None) == len(all_changes) and
+ not (opts.hv_state or opts.disk_state)):
ToStderr("Please give at least one of the parameters.")
return 1
+ if opts.disk_state:
+ disk_state = utils.FlatToDict(opts.disk_state)
+ else:
+ disk_state = {}
+
+ hv_state = dict(opts.hv_state)
+
op = opcodes.OpNodeSetParams(node_name=args[0],
master_candidate=opts.master_candidate,
offline=opts.offline,
force=opts.force,
ndparams=opts.ndparams,
auto_promote=opts.auto_promote,
- powered=opts.node_powered)
+ powered=opts.node_powered,
+ hv_state=hv_state,
+ disk_state=disk_state)
# even if here we process the result, we allow submit only
result = SubmitOrSend(op, opts)
[FORCE_OPT, SUBMIT_OPT, MC_OPT, DRAINED_OPT, OFFLINE_OPT,
CAPAB_MASTER_OPT, CAPAB_VM_OPT, SECONDARY_IP_OPT,
AUTO_PROMOTE_OPT, DRY_RUN_OPT, PRIORITY_OPT, NODE_PARAMS_OPT,
- NODE_POWERED_OPT],
+ NODE_POWERED_OPT, HV_STATE_OPT, DISK_STATE_OPT],
"<node_name>", "Alters the parameters of a node"),
"powercycle": (
PowercycleNode, ARGS_ONE_NODE,
self.op.node_name = _ExpandNodeName(self.cfg, self.op.node_name)
all_mods = [self.op.offline, self.op.master_candidate, self.op.drained,
self.op.master_capable, self.op.vm_capable,
- self.op.secondary_ip, self.op.ndparams]
+ self.op.secondary_ip, self.op.ndparams, self.op.hv_state,
+ self.op.disk_state]
if all_mods.count(None) == len(all_mods):
raise errors.OpPrereqError("Please pass at least one modification",
errors.ECODE_INVAL)
utils.ForceDictType(new_ndparams, constants.NDS_PARAMETER_TYPES)
self.new_ndparams = new_ndparams
+ if self.op.hv_state:
+ self.new_hv_state = _MergeAndVerifyHvState(self.op.hv_state,
+ self.node.hv_state_static)
+
+ if self.op.disk_state:
+ self.new_disk_state = \
+ _MergeAndVerifyDiskState(self.op.disk_state,
+ self.node.disk_state_static)
+
def Exec(self, feedback_fn):
"""Modifies a node.
if self.op.powered is not None:
node.powered = self.op.powered
+ if self.op.hv_state:
+ node.hv_state_static = self.new_hv_state
+
+ if self.op.disk_state:
+ node.disk_state_static = self.new_disk_state
+
for attr in ["master_capable", "vm_capable"]:
val = getattr(self.op, attr)
if val is not None:
}
DSS_PARAMETERS = frozenset(DSS_PARAMETER_TYPES.keys())
+DS_VALID_TYPES = frozenset([LD_LV])
# Backend parameter names
BE_MEMORY = "memory" # deprecated and replaced by max and min mem
ht.TNone),
"Disk templates' parameter defaults")
+# Parameters for node resource model
+_PHvState = ("hv_state", None, ht.TMaybeDict, "Set hypervisor states")
+_PDiskState = ("disk_state", None, ht.TMaybeDict, "Set disk states")
+
#: OP_ID conversion regular expression
_OPID_RE = re.compile("([a-z])([A-Z])")
OP_PARAMS = [
_PNodeName,
_PForce,
+ _PHvState,
+ _PDiskState,
("master_candidate", None, ht.TMaybeBool,
"Whether the node should become a master candidate"),
("offline", None, ht.TMaybeBool,
document.
+Hypervisor State Parameters
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Using ``--hypervisor-state`` you can set hypervisor specific states as
+pointed out in ``Ganeti Resource Model <design-resource-model.rst>``.
+
+The format is: ``hypervisor:option=value``.
+
+Currently we support the following hypervisor state values:
+
+mem_total
+ Total node memory, as discovered by this hypervisor
+mem_node
+ Memory used by, or reserved for, the node itself; note that some
+ hypervisors can report this in an authoritative way, other not
+mem_hv
+ Memory used either by the hypervisor itself or lost due to instance
+ allocation rounding; usually this cannot be precisely computed, but
+ only roughly estimated
+cpu_total
+ Total node cpu (core) count; usually this can be discovered
+ automatically
+cpu_node
+ Number of cores reserved for the node itself; this can either be
+ discovered or set manually. Only used for estimating how many VCPUs
+ are left for instances
+
+
+Disk State Parameters
+~~~~~~~~~~~~~~~~~~~~~
+
+Using ``--disk-state`` you can set disk specific states as pointed out
+in ``Ganeti Resource Model <design-resource-model.rst>``.
+
+The format is: ``storage_type/identifier:option=value``. Where we
+currently just support ``lvm`` as storage type. The identifier in this
+case is the LVM volume group. By default this is ``xenvg``.
+
+Currently we support the following hypervisor state values:
+
+disk_total
+ Total disk size (usually discovered automatically)
+disk_reserved
+ Reserved disk size; this is a lower limit on the free space, if such a
+ limit is desired
+disk_overhead
+ Disk that is expected to be used by other volumes (set via
+ ``reserved_lvs``); usually should be zero
+
+
Cluster configuration
~~~~~~~~~~~~~~~~~~~~~
| [{-s|--secondary-ip} *secondary_ip*]
| [--node-parameters *ndparams*]
| [--node-powered=``yes|no``]
+| [--hypervisor-state *hvstate*]
+| [--disk-state *diskstate*]
| {*node*}
This command changes the role of the node. Each options takes