Revision 735e1318 lib/cmdlib.py
b/lib/cmdlib.py | ||
---|---|---|
6901 | 6901 |
HTYPE = constants.HTYPE_INSTANCE |
6902 | 6902 |
REQ_BGL = False |
6903 | 6903 |
|
6904 |
_MODIFYABLE = frozenset([ |
|
6905 |
constants.IDISK_SIZE, |
|
6906 |
constants.IDISK_MODE, |
|
6907 |
]) |
|
6908 |
|
|
6909 |
# New or changed disk parameters may have different semantics |
|
6910 |
assert constants.IDISK_PARAMS == (_MODIFYABLE | frozenset([ |
|
6911 |
constants.IDISK_ADOPT, |
|
6912 |
|
|
6913 |
# TODO: Implement support changing VG while recreating |
|
6914 |
constants.IDISK_VG, |
|
6915 |
constants.IDISK_METAVG, |
|
6916 |
])) |
|
6917 |
|
|
6904 | 6918 |
def CheckArguments(self): |
6905 |
# normalise the disk list |
|
6906 |
self.op.disks = sorted(frozenset(self.op.disks)) |
|
6919 |
if self.op.disks and ht.TPositiveInt(self.op.disks[0]): |
|
6920 |
# Normalize and convert deprecated list of disk indices |
|
6921 |
self.op.disks = [(idx, {}) for idx in sorted(frozenset(self.op.disks))] |
|
6922 |
|
|
6923 |
duplicates = utils.FindDuplicates(map(compat.fst, self.op.disks)) |
|
6924 |
if duplicates: |
|
6925 |
raise errors.OpPrereqError("Some disks have been specified more than" |
|
6926 |
" once: %s" % utils.CommaJoin(duplicates), |
|
6927 |
errors.ECODE_INVAL) |
|
6928 |
|
|
6929 |
for (idx, params) in self.op.disks: |
|
6930 |
utils.ForceDictType(params, constants.IDISK_PARAMS_TYPES) |
|
6931 |
unsupported = frozenset(params.keys()) - self._MODIFYABLE |
|
6932 |
if unsupported: |
|
6933 |
raise errors.OpPrereqError("Parameters for disk %s try to change" |
|
6934 |
" unmodifyable parameter(s): %s" % |
|
6935 |
(idx, utils.CommaJoin(unsupported)), |
|
6936 |
errors.ECODE_INVAL) |
|
6907 | 6937 |
|
6908 | 6938 |
def ExpandNames(self): |
6909 | 6939 |
self._ExpandAndLockInstance() |
... | ... | |
6969 | 6999 |
if instance.disk_template == constants.DT_DISKLESS: |
6970 | 7000 |
raise errors.OpPrereqError("Instance '%s' has no disks" % |
6971 | 7001 |
self.op.instance_name, errors.ECODE_INVAL) |
7002 |
|
|
6972 | 7003 |
# if we replace nodes *and* the old primary is offline, we don't |
6973 | 7004 |
# check |
6974 | 7005 |
assert instance.primary_node in self.owned_locks(locking.LEVEL_NODE) |
... | ... | |
6978 | 7009 |
_CheckInstanceState(self, instance, INSTANCE_NOT_RUNNING, |
6979 | 7010 |
msg="cannot recreate disks") |
6980 | 7011 |
|
6981 |
if not self.op.disks:
|
|
6982 |
self.op.disks = range(len(instance.disks))
|
|
7012 |
if self.op.disks: |
|
7013 |
self.disks = dict(self.op.disks)
|
|
6983 | 7014 |
else: |
6984 |
for idx in self.op.disks: |
|
6985 |
if idx >= len(instance.disks): |
|
6986 |
raise errors.OpPrereqError("Invalid disk index '%s'" % idx, |
|
6987 |
errors.ECODE_INVAL) |
|
6988 |
if self.op.disks != range(len(instance.disks)) and self.op.nodes: |
|
7015 |
self.disks = dict((idx, {}) for idx in range(len(instance.disks))) |
|
7016 |
|
|
7017 |
maxidx = max(self.disks.keys()) |
|
7018 |
if maxidx >= len(instance.disks): |
|
7019 |
raise errors.OpPrereqError("Invalid disk index '%s'" % maxidx, |
|
7020 |
errors.ECODE_INVAL) |
|
7021 |
|
|
7022 |
if (self.op.nodes and |
|
7023 |
sorted(self.disks.keys()) != range(len(instance.disks))): |
|
6989 | 7024 |
raise errors.OpPrereqError("Can't recreate disks partially and" |
6990 | 7025 |
" change the nodes at the same time", |
6991 | 7026 |
errors.ECODE_INVAL) |
7027 |
|
|
6992 | 7028 |
self.instance = instance |
6993 | 7029 |
|
6994 | 7030 |
def Exec(self, feedback_fn): |
... | ... | |
7001 | 7037 |
self.owned_locks(locking.LEVEL_NODE_RES)) |
7002 | 7038 |
|
7003 | 7039 |
to_skip = [] |
7004 |
mods = [] # keeps track of needed logical_id changes
|
|
7040 |
mods = [] # keeps track of needed changes |
|
7005 | 7041 |
|
7006 | 7042 |
for idx, disk in enumerate(instance.disks): |
7007 |
if idx not in self.op.disks: # disk idx has not been passed in |
|
7043 |
try: |
|
7044 |
changes = self.disks[idx] |
|
7045 |
except KeyError: |
|
7046 |
# Disk should not be recreated |
|
7008 | 7047 |
to_skip.append(idx) |
7009 | 7048 |
continue |
7049 |
|
|
7010 | 7050 |
# update secondaries for disks, if needed |
7011 |
if self.op.nodes: |
|
7012 |
if disk.dev_type == constants.LD_DRBD8: |
|
7013 |
# need to update the nodes and minors |
|
7014 |
assert len(self.op.nodes) == 2 |
|
7015 |
assert len(disk.logical_id) == 6 # otherwise disk internals |
|
7016 |
# have changed |
|
7017 |
(_, _, old_port, _, _, old_secret) = disk.logical_id |
|
7018 |
new_minors = self.cfg.AllocateDRBDMinor(self.op.nodes, instance.name) |
|
7019 |
new_id = (self.op.nodes[0], self.op.nodes[1], old_port, |
|
7020 |
new_minors[0], new_minors[1], old_secret) |
|
7021 |
assert len(disk.logical_id) == len(new_id) |
|
7022 |
mods.append((idx, new_id)) |
|
7051 |
if self.op.nodes and disk.dev_type == constants.LD_DRBD8: |
|
7052 |
# need to update the nodes and minors |
|
7053 |
assert len(self.op.nodes) == 2 |
|
7054 |
assert len(disk.logical_id) == 6 # otherwise disk internals |
|
7055 |
# have changed |
|
7056 |
(_, _, old_port, _, _, old_secret) = disk.logical_id |
|
7057 |
new_minors = self.cfg.AllocateDRBDMinor(self.op.nodes, instance.name) |
|
7058 |
new_id = (self.op.nodes[0], self.op.nodes[1], old_port, |
|
7059 |
new_minors[0], new_minors[1], old_secret) |
|
7060 |
assert len(disk.logical_id) == len(new_id) |
|
7061 |
else: |
|
7062 |
new_id = None |
|
7063 |
|
|
7064 |
mods.append((idx, new_id, changes)) |
|
7023 | 7065 |
|
7024 | 7066 |
# now that we have passed all asserts above, we can apply the mods |
7025 | 7067 |
# in a single run (to avoid partial changes) |
7026 |
for idx, new_id in mods: |
|
7027 |
instance.disks[idx].logical_id = new_id |
|
7068 |
for idx, new_id, changes in mods: |
|
7069 |
disk = instance.disks[idx] |
|
7070 |
if new_id is not None: |
|
7071 |
assert disk.dev_type == constants.LD_DRBD8 |
|
7072 |
disk.logical_id = new_id |
|
7073 |
if changes: |
|
7074 |
disk.Update(size=changes.get(constants.IDISK_SIZE, None), |
|
7075 |
mode=changes.get(constants.IDISK_MODE, None)) |
|
7028 | 7076 |
|
7029 | 7077 |
# change primary node, if needed |
7030 | 7078 |
if self.op.nodes: |
Also available in: Unified diff