3937 |
3937 |
return ret
|
3938 |
3938 |
|
3939 |
3939 |
|
|
3940 |
class LUGrowDisk(LogicalUnit):
|
|
3941 |
"""Grow a disk of an instance.
|
|
3942 |
|
|
3943 |
"""
|
|
3944 |
HPATH = "disk-grow"
|
|
3945 |
HTYPE = constants.HTYPE_INSTANCE
|
|
3946 |
_OP_REQP = ["instance_name", "disk", "amount"]
|
|
3947 |
|
|
3948 |
def BuildHooksEnv(self):
|
|
3949 |
"""Build hooks env.
|
|
3950 |
|
|
3951 |
This runs on the master, the primary and all the secondaries.
|
|
3952 |
|
|
3953 |
"""
|
|
3954 |
env = {
|
|
3955 |
"DISK": self.op.disk,
|
|
3956 |
"AMOUNT": self.op.amount,
|
|
3957 |
}
|
|
3958 |
env.update(_BuildInstanceHookEnvByObject(self.instance))
|
|
3959 |
nl = [
|
|
3960 |
self.sstore.GetMasterNode(),
|
|
3961 |
self.instance.primary_node,
|
|
3962 |
]
|
|
3963 |
return env, nl, nl
|
|
3964 |
|
|
3965 |
def CheckPrereq(self):
|
|
3966 |
"""Check prerequisites.
|
|
3967 |
|
|
3968 |
This checks that the instance is in the cluster.
|
|
3969 |
|
|
3970 |
"""
|
|
3971 |
instance = self.cfg.GetInstanceInfo(
|
|
3972 |
self.cfg.ExpandInstanceName(self.op.instance_name))
|
|
3973 |
if instance is None:
|
|
3974 |
raise errors.OpPrereqError("Instance '%s' not known" %
|
|
3975 |
self.op.instance_name)
|
|
3976 |
self.instance = instance
|
|
3977 |
self.op.instance_name = instance.name
|
|
3978 |
|
|
3979 |
if instance.disk_template not in (constants.DT_PLAIN, constants.DT_DRBD8):
|
|
3980 |
raise errors.OpPrereqError("Instance's disk layout does not support"
|
|
3981 |
" growing.")
|
|
3982 |
|
|
3983 |
if instance.FindDisk(self.op.disk) is None:
|
|
3984 |
raise errors.OpPrereqError("Disk '%s' not found for instance '%s'" %
|
|
3985 |
(name, instance.name))
|
|
3986 |
|
|
3987 |
nodenames = [instance.primary_node] + list(instance.secondary_nodes)
|
|
3988 |
nodeinfo = rpc.call_node_info(nodenames, self.cfg.GetVGName())
|
|
3989 |
for node in nodenames:
|
|
3990 |
info = nodeinfo.get(node, None)
|
|
3991 |
if not info:
|
|
3992 |
raise errors.OpPrereqError("Cannot get current information"
|
|
3993 |
" from node '%s'" % node)
|
|
3994 |
vg_free = info.get('vg_free', None)
|
|
3995 |
if not isinstance(vg_free, int):
|
|
3996 |
raise errors.OpPrereqError("Can't compute free disk space on"
|
|
3997 |
" node %s" % node)
|
|
3998 |
if self.op.amount > info['vg_free']:
|
|
3999 |
raise errors.OpPrereqError("Not enough disk space on target node %s:"
|
|
4000 |
" %d MiB available, %d MiB required" %
|
|
4001 |
(node, info['vg_free'], self.op.amount))
|
|
4002 |
|
|
4003 |
def Exec(self, feedback_fn):
|
|
4004 |
"""Execute disk grow.
|
|
4005 |
|
|
4006 |
"""
|
|
4007 |
instance = self.instance
|
|
4008 |
disk = instance.FindDisk(self.op.disk)
|
|
4009 |
for node in (instance.secondary_nodes + (instance.primary_node,)):
|
|
4010 |
self.cfg.SetDiskID(disk, node)
|
|
4011 |
result = rpc.call_blockdev_grow(node, disk, self.op.amount)
|
|
4012 |
if not result or not isinstance(result, tuple) or len(result) != 2:
|
|
4013 |
raise errors.OpExecError("grow request failed to node %s" % node)
|
|
4014 |
elif not result[0]:
|
|
4015 |
raise errors.OpExecError("grow request failed to node %s: %s" %
|
|
4016 |
(node, result[1]))
|
|
4017 |
disk.RecordGrow(self.op.amount)
|
|
4018 |
self.cfg.Update(instance)
|
|
4019 |
return
|
|
4020 |
|
|
4021 |
|
3940 |
4022 |
class LUQueryInstanceData(NoHooksLU):
|
3941 |
4023 |
"""Query runtime instance data.
|
3942 |
4024 |
|