Revision 21e77d7f lib/cmdlib.py
b/lib/cmdlib.py | ||
---|---|---|
66 | 66 |
|
67 | 67 |
import ganeti.masterd.instance # pylint: disable=W0611 |
68 | 68 |
|
69 |
|
|
70 | 69 |
# States of instance |
71 | 70 |
INSTANCE_DOWN = [constants.ADMINST_DOWN] |
72 | 71 |
INSTANCE_ONLINE = [constants.ADMINST_DOWN, constants.ADMINST_UP] |
... | ... | |
6765 | 6764 |
|
6766 | 6765 |
|
6767 | 6766 |
def _AssembleInstanceDisks(lu, instance, disks=None, ignore_secondaries=False, |
6768 |
ignore_size=False): |
|
6767 |
ignore_size=False, check=True):
|
|
6769 | 6768 |
"""Prepare the block devices for an instance. |
6770 | 6769 |
|
6771 | 6770 |
This sets up the block devices on all nodes. |
... | ... | |
6791 | 6790 |
device_info = [] |
6792 | 6791 |
disks_ok = True |
6793 | 6792 |
iname = instance.name |
6794 |
disks = _ExpandCheckDisks(instance, disks) |
|
6793 |
if check: |
|
6794 |
disks = _ExpandCheckDisks(instance, disks) |
|
6795 | 6795 |
|
6796 | 6796 |
# With the two passes mechanism we try to reduce the window of |
6797 | 6797 |
# opportunity for the race condition of switching DRBD to primary |
... | ... | |
9282 | 9282 |
return results |
9283 | 9283 |
|
9284 | 9284 |
|
9285 |
def _GetDeviceUniqueIdx(lu, dev_type): |
|
9286 |
"""Get unique idx for a device |
|
9287 |
|
|
9288 |
""" |
|
9289 |
|
|
9290 |
if lu.op.OP_ID == "OP_INSTANCE_CREATE": |
|
9291 |
base = lu |
|
9292 |
elif lu.op.OP_ID == "OP_INSTANCE_SET_PARAMS": |
|
9293 |
base = lu.instance |
|
9294 |
|
|
9295 |
idx = base.dev_idxs[dev_type] |
|
9296 |
base.dev_idxs[dev_type] += 1 |
|
9297 |
|
|
9298 |
if lu.op.OP_ID == "OP_INSTANCE_SET_PARAMS": |
|
9299 |
lu.cfg.UpdateDeviceUniqueIdx(lu.instance, dev_type) |
|
9300 |
|
|
9301 |
return idx |
|
9302 |
|
|
9303 |
|
|
9304 |
def _DeviceHotplugable(dev): |
|
9305 |
|
|
9306 |
return dev.idx is not None |
|
9307 |
|
|
9308 |
|
|
9285 | 9309 |
def _GenerateDRBD8Branch(lu, primary, secondary, size, vgnames, names, |
9286 | 9310 |
iv_name, p_minor, s_minor): |
9287 | 9311 |
"""Generate a drbd8 device complete with its children. |
... | ... | |
9298 | 9322 |
size=constants.DRBD_META_SIZE, |
9299 | 9323 |
logical_id=(vgnames[1], names[1]), |
9300 | 9324 |
params={}) |
9325 |
|
|
9301 | 9326 |
drbd_dev = objects.Disk(dev_type=constants.LD_DRBD8, size=size, |
9302 | 9327 |
logical_id=(primary, secondary, port, |
9303 | 9328 |
p_minor, s_minor, |
9304 | 9329 |
shared_secret), |
9305 | 9330 |
children=[dev_data, dev_meta], |
9306 | 9331 |
iv_name=iv_name, params={}) |
9332 |
drbd_dev.idx = _GetDeviceUniqueIdx(lu, 'disks') |
|
9333 |
|
|
9307 | 9334 |
return drbd_dev |
9308 | 9335 |
|
9309 | 9336 |
|
... | ... | |
9425 | 9452 |
size = disk[constants.IDISK_SIZE] |
9426 | 9453 |
feedback_fn("* disk %s, size %s" % |
9427 | 9454 |
(disk_index, utils.FormatUnit(size, "h"))) |
9428 |
disks.append(objects.Disk(dev_type=dev_type, size=size, |
|
9429 |
logical_id=logical_id_fn(idx, disk_index, disk), |
|
9430 |
iv_name="disk/%d" % disk_index, |
|
9431 |
mode=disk[constants.IDISK_MODE], |
|
9432 |
params=params)) |
|
9455 |
disk_obj = objects.Disk(dev_type=dev_type, size=size, |
|
9456 |
logical_id=logical_id_fn(idx, disk_index, disk), |
|
9457 |
iv_name="disk/%d" % disk_index, |
|
9458 |
mode=disk[constants.IDISK_MODE], |
|
9459 |
params=params) |
|
9460 |
disk_obj.idx = _GetDeviceUniqueIdx(lu, 'disks') |
|
9461 |
|
|
9462 |
disks.append(disk_obj) |
|
9433 | 9463 |
|
9434 | 9464 |
return disks |
9435 | 9465 |
|
... | ... | |
9785 | 9815 |
node_whitelist=node_whitelist) |
9786 | 9816 |
|
9787 | 9817 |
|
9788 |
def _ComputeNics(op, cluster, default_ip, cfg, ec_id): |
|
9818 |
def _ComputeNics(lu, op, cluster, default_ip, cfg, ec_id):
|
|
9789 | 9819 |
"""Computes the nics. |
9790 | 9820 |
|
9821 |
@param lu: The LU |
|
9791 | 9822 |
@param op: The instance opcode |
9792 | 9823 |
@param cluster: Cluster configuration object |
9793 | 9824 |
@param default_ip: The default ip to assign |
... | ... | |
9867 | 9898 |
|
9868 | 9899 |
check_params = cluster.SimpleFillNIC(nicparams) |
9869 | 9900 |
objects.NIC.CheckParameterSyntax(check_params) |
9870 |
nics.append(objects.NIC(mac=mac, ip=nic_ip, |
|
9871 |
network=net, nicparams=nicparams)) |
|
9901 |
nic_obj = objects.NIC(mac=mac, ip=nic_ip, network=net, |
|
9902 |
nicparams=check_params) |
|
9903 |
nic_obj.idx = _GetDeviceUniqueIdx(lu, 'nics') |
|
9904 |
|
|
9905 |
nics.append(nic_obj) |
|
9872 | 9906 |
|
9873 | 9907 |
return nics |
9874 | 9908 |
|
... | ... | |
10518 | 10552 |
if self.op.identify_defaults: |
10519 | 10553 |
self._RevertToDefaults(cluster) |
10520 | 10554 |
|
10555 |
self.dev_idxs = { "disks": 0, "nics": 0 } |
|
10556 |
|
|
10521 | 10557 |
# NIC buildup |
10522 |
self.nics = _ComputeNics(self.op, cluster, self.check_ip, self.cfg, |
|
10558 |
self.nics = _ComputeNics(self, self.op, cluster, self.check_ip, self.cfg,
|
|
10523 | 10559 |
self.proc.GetECId()) |
10524 | 10560 |
|
10525 | 10561 |
# disk checks/pre-build |
... | ... | |
10855 | 10891 |
hvparams=self.op.hvparams, |
10856 | 10892 |
hypervisor=self.op.hypervisor, |
10857 | 10893 |
osparams=self.op.osparams, |
10894 |
dev_idxs=self.dev_idxs, |
|
10858 | 10895 |
) |
10859 | 10896 |
|
10860 | 10897 |
if self.op.tags: |
... | ... | |
11144 | 11181 |
node_whitelist = None |
11145 | 11182 |
|
11146 | 11183 |
insts = [_CreateInstanceAllocRequest(op, _ComputeDisks(op, default_vg), |
11147 |
_ComputeNics(op, cluster, None, |
|
11184 |
_ComputeNics(self, op, cluster, None,
|
|
11148 | 11185 |
self.cfg, ec_id), |
11149 | 11186 |
_ComputeFullBeParams(op, cluster), |
11150 | 11187 |
node_whitelist) |
... | ... | |
13016 | 13053 |
if remove_fn is not None: |
13017 | 13054 |
remove_fn(absidx, item, private) |
13018 | 13055 |
|
13056 |
#TODO: include a hotplugged msg in changes |
|
13019 | 13057 |
changes = [("%s/%s" % (kind, absidx), "remove")] |
13020 | 13058 |
|
13021 | 13059 |
assert container[absidx] == item |
13022 | 13060 |
del container[absidx] |
13023 | 13061 |
elif op == constants.DDM_MODIFY: |
13024 | 13062 |
if modify_fn is not None: |
13063 |
#TODO: include a hotplugged msg in changes |
|
13025 | 13064 |
changes = modify_fn(absidx, item, params, private) |
13065 |
|
|
13026 | 13066 |
else: |
13027 | 13067 |
raise errors.ProgrammerError("Unhandled operation '%s'" % op) |
13028 | 13068 |
|
... | ... | |
13747 | 13787 |
" (%d), cannot add more" % constants.MAX_NICS, |
13748 | 13788 |
errors.ECODE_STATE) |
13749 | 13789 |
|
13790 |
|
|
13750 | 13791 |
# Verify disk changes (operating on a copy) |
13751 | 13792 |
disks = instance.disks[:] |
13752 |
ApplyContainerMods("disk", disks, None, self.diskmod, None, None, None) |
|
13793 |
ApplyContainerMods("disk", disks, None, self.diskmod, |
|
13794 |
None, None, None) |
|
13753 | 13795 |
if len(disks) > constants.MAX_DISKS: |
13754 | 13796 |
raise errors.OpPrereqError("Instance has too many disks (%d), cannot add" |
13755 | 13797 |
" more" % constants.MAX_DISKS, |
... | ... | |
13770 | 13812 |
# Operate on copies as this is still in prereq |
13771 | 13813 |
nics = [nic.Copy() for nic in instance.nics] |
13772 | 13814 |
ApplyContainerMods("NIC", nics, self._nic_chgdesc, self.nicmod, |
13773 |
self._CreateNewNic, self._ApplyNicMods, None) |
|
13815 |
self._CreateNewNic, self._ApplyNicMods, |
|
13816 |
self._RemoveNic) |
|
13774 | 13817 |
self._new_nics = nics |
13775 | 13818 |
ispec[constants.ISPEC_NIC_COUNT] = len(self._new_nics) |
13776 | 13819 |
else: |
... | ... | |
13805 | 13848 |
utils.CommaJoin(set(res_max + res_min)))) |
13806 | 13849 |
raise errors.OpPrereqError(msg, errors.ECODE_INVAL) |
13807 | 13850 |
|
13851 |
|
|
13808 | 13852 |
def _ConvertPlainToDrbd(self, feedback_fn): |
13809 | 13853 |
"""Converts an instance from plain to drbd. |
13810 | 13854 |
|
... | ... | |
13956 | 14000 |
self.LogWarning("Failed to create volume %s (%s) on node '%s': %s", |
13957 | 14001 |
disk.iv_name, disk, node, err) |
13958 | 14002 |
|
14003 |
if self.op.hotplug: |
|
14004 |
self.LogInfo("Trying to hotplug device.") |
|
14005 |
_, device_info = _AssembleInstanceDisks(self, self.instance, |
|
14006 |
[disk], check=False) |
|
14007 |
_, _, dev_path = device_info[0] |
|
14008 |
result = self.rpc.call_hot_add_disk(self.instance.primary_node, |
|
14009 |
self.instance, disk, dev_path, idx) |
|
14010 |
result.Raise("Could not hotplug device.") |
|
14011 |
self.LogInfo("Hotplug done.") |
|
14012 |
|
|
13959 | 14013 |
return (disk, [ |
13960 | 14014 |
("disk/%d" % idx, "add:size=%s,mode=%s" % (disk.size, disk.mode)), |
13961 | 14015 |
]) |
... | ... | |
13975 | 14029 |
"""Removes a disk. |
13976 | 14030 |
|
13977 | 14031 |
""" |
14032 |
#TODO: log warning in case hotplug is not possible |
|
14033 |
if self.op.hotplug and _DeviceHotplugable(root): |
|
14034 |
self.LogInfo("Trying to hotplug device.") |
|
14035 |
result = self.rpc.call_hot_del_disk(self.instance.primary_node, |
|
14036 |
self.instance, root, idx) |
|
14037 |
result.Raise("Could not hotplug device.") |
|
14038 |
self.LogInfo("Hotplug done.") |
|
14039 |
_ShutdownInstanceDisks(self, self.instance, [root]) |
|
14040 |
|
|
13978 | 14041 |
(anno_disk,) = _AnnotateDiskParams(self.instance, [root], self.cfg) |
13979 | 14042 |
for node, disk in anno_disk.ComputeNodeTree(self.instance.primary_node): |
13980 | 14043 |
self.cfg.SetDiskID(disk, node) |
... | ... | |
13987 | 14050 |
if root.dev_type in constants.LDS_DRBD: |
13988 | 14051 |
self.cfg.AddTcpUdpPort(root.logical_id[2]) |
13989 | 14052 |
|
13990 |
@staticmethod |
|
13991 |
def _CreateNewNic(idx, params, private): |
|
14053 |
def _CreateNewNic(self, idx, params, private): |
|
13992 | 14054 |
"""Creates data structure for a new network interface. |
13993 | 14055 |
|
13994 | 14056 |
""" |
13995 | 14057 |
mac = params[constants.INIC_MAC] |
13996 | 14058 |
ip = params.get(constants.INIC_IP, None) |
13997 | 14059 |
net = params.get(constants.INIC_NETWORK, None) |
13998 |
#TODO: not private.filled?? can a nic have no nicparams??
|
|
14060 |
#TODO: not private.filled?? can a nic be saved without nicparams??
|
|
13999 | 14061 |
nicparams = private.filled |
14000 | 14062 |
|
14001 |
return (objects.NIC(mac=mac, ip=ip, network=net, nicparams=nicparams), [ |
|
14063 |
nic = objects.NIC(mac=mac, ip=ip, network=net, nicparams=nicparams) |
|
14064 |
|
|
14065 |
nic.idx = _GetDeviceUniqueIdx(self, 'nics') |
|
14066 |
#TODO: log warning in case hotplug is not possible |
|
14067 |
if self.op.hotplug: |
|
14068 |
result = self.rpc.call_hot_add_nic(self.instance.primary_node, |
|
14069 |
self.instance, nic, idx) |
|
14070 |
result.Raise("Could not hotplug device") |
|
14071 |
self.Log("Hotplug done.") |
|
14072 |
|
|
14073 |
desc = [ |
|
14002 | 14074 |
("nic.%d" % idx, |
14003 | 14075 |
"add:mac=%s,ip=%s,mode=%s,link=%s,network=%s" % |
14004 | 14076 |
(mac, ip, private.filled[constants.NIC_MODE], |
14005 |
private.filled[constants.NIC_LINK], |
|
14006 |
net)),
|
|
14007 |
])
|
|
14077 |
private.filled[constants.NIC_LINK], net)),
|
|
14078 |
]
|
|
14079 |
return (nic, desc)
|
|
14008 | 14080 |
|
14009 |
@staticmethod |
|
14010 |
def _ApplyNicMods(idx, nic, params, private): |
|
14081 |
def _ApplyNicMods(self, idx, nic, params, private): |
|
14011 | 14082 |
"""Modifies a network interface. |
14012 | 14083 |
|
14013 | 14084 |
""" |
... | ... | |
14024 | 14095 |
for (key, val) in nic.nicparams.items(): |
14025 | 14096 |
changes.append(("nic.%s/%d" % (key, idx), val)) |
14026 | 14097 |
|
14098 |
#TODO: log warning in case hotplug is not possible |
|
14099 |
if self.op.hotplug and _DeviceHotplugable(nic): |
|
14100 |
self.LogInfo("Trying to hotplug device.") |
|
14101 |
result = self.rpc.call_hot_del_nic(self.instance.primary_node, |
|
14102 |
self.instance, nic, idx) |
|
14103 |
result.Raise("Could not hotplug device.") |
|
14104 |
result = self.rpc.call_hot_add_nic(self.instance.primary_node, |
|
14105 |
self.instance, nic, idx) |
|
14106 |
result.Raise("Could not hotplug device.") |
|
14107 |
self.Log("Hotplug done.") |
|
14108 |
|
|
14027 | 14109 |
return changes |
14028 | 14110 |
|
14111 |
def _RemoveNic(self, idx, nic, _): |
|
14112 |
#TODO: log warning in case hotplug is not possible |
|
14113 |
if self.op.hotplug and _DeviceHotplugable(nic): |
|
14114 |
self.LogInfo("Trying to hotplug device.") |
|
14115 |
result = self.rpc.call_hot_del_nic(self.instance.primary_node, |
|
14116 |
self.instance, nic, idx) |
|
14117 |
result.Raise("Could not hotplug device.") |
|
14118 |
self.Log("Hotplug done.") |
|
14119 |
|
|
14120 |
|
|
14029 | 14121 |
def Exec(self, feedback_fn): |
14030 | 14122 |
"""Modifies an instance. |
14031 | 14123 |
|
Also available in: Unified diff