47 |
47 |
|
48 |
48 |
_config_lock = locking.SharedLock()
|
49 |
49 |
|
|
50 |
# job id used for resource management at config upgrade time
|
|
51 |
_UPGRADE_CONFIG_JID="jid-cfg-upgrade"
|
|
52 |
|
50 |
53 |
|
51 |
54 |
def _ValidateConfig(data):
|
52 |
55 |
"""Verifies that a configuration objects looks valid.
|
... | ... | |
132 |
135 |
self._cfg_file = constants.CLUSTER_CONF_FILE
|
133 |
136 |
else:
|
134 |
137 |
self._cfg_file = cfg_file
|
135 |
|
self._temporary_ids = set()
|
|
138 |
self._temporary_ids = TemporaryReservationManager()
|
136 |
139 |
self._temporary_drbds = {}
|
137 |
140 |
self._temporary_macs = set()
|
138 |
141 |
# Note: in order to prevent errors when resolving our name in
|
... | ... | |
225 |
228 |
"""
|
226 |
229 |
existing = set()
|
227 |
230 |
if include_temporary:
|
228 |
|
existing.update(self._temporary_ids)
|
|
231 |
existing.update(self._temporary_ids.GetReserved())
|
229 |
232 |
existing.update(self._AllLVs())
|
230 |
233 |
existing.update(self._config_data.instances.keys())
|
231 |
234 |
existing.update(self._config_data.nodes.keys())
|
232 |
235 |
existing.update([i.uuid for i in self._AllUUIDObjects() if i.uuid])
|
233 |
236 |
return existing
|
234 |
237 |
|
235 |
|
def _GenerateUniqueID(self):
|
|
238 |
def _GenerateUniqueID(self, ec_id):
|
236 |
239 |
"""Generate an unique UUID.
|
237 |
240 |
|
238 |
241 |
This checks the current node, instances and disk names for
|
... | ... | |
242 |
245 |
@return: the unique id
|
243 |
246 |
|
244 |
247 |
"""
|
245 |
|
existing = self._AllIDs(include_temporary=True)
|
246 |
|
retries = 64
|
247 |
|
while retries > 0:
|
248 |
|
unique_id = utils.NewUUID()
|
249 |
|
if unique_id not in existing and unique_id is not None:
|
250 |
|
break
|
251 |
|
else:
|
252 |
|
raise errors.ConfigurationError("Not able generate an unique ID"
|
253 |
|
" (last tried ID: %s" % unique_id)
|
254 |
|
self._temporary_ids.add(unique_id)
|
255 |
|
return unique_id
|
|
248 |
existing = self._AllIDs(include_temporary=False)
|
|
249 |
return self._temporary_ids.Generate(existing, utils.NewUUID, ec_id)
|
256 |
250 |
|
257 |
251 |
@locking.ssynchronized(_config_lock, shared=1)
|
258 |
|
def GenerateUniqueID(self):
|
|
252 |
def GenerateUniqueID(self, ec_id):
|
259 |
253 |
"""Generate an unique ID.
|
260 |
254 |
|
261 |
255 |
This is just a wrapper over the unlocked version.
|
262 |
256 |
|
263 |
|
"""
|
264 |
|
return self._GenerateUniqueID()
|
265 |
|
|
266 |
|
def _CleanupTemporaryIDs(self):
|
267 |
|
"""Cleanups the _temporary_ids structure.
|
|
257 |
@type ec_id: string
|
|
258 |
@param ec_id: unique id for the job to reserve the id to
|
268 |
259 |
|
269 |
260 |
"""
|
270 |
|
existing = self._AllIDs(include_temporary=False)
|
271 |
|
self._temporary_ids = self._temporary_ids - existing
|
|
261 |
return self._GenerateUniqueID(ec_id)
|
272 |
262 |
|
273 |
263 |
def _AllMACs(self):
|
274 |
264 |
"""Return all MACs present in the config.
|
... | ... | |
821 |
811 |
|
822 |
812 |
"""
|
823 |
813 |
if not item.uuid:
|
824 |
|
item.uuid = self._GenerateUniqueID()
|
|
814 |
item.uuid = self._GenerateUniqueID(ec_id)
|
825 |
815 |
elif item.uuid in self._AllIDs(temporary=True):
|
826 |
816 |
raise errors.ConfigurationError("Cannot add '%s': UUID already in use" %
|
827 |
817 |
(item.name, item.uuid))
|
... | ... | |
1205 |
1195 |
modified = False
|
1206 |
1196 |
for item in self._AllUUIDObjects():
|
1207 |
1197 |
if item.uuid is None:
|
1208 |
|
item.uuid = self._GenerateUniqueID()
|
|
1198 |
item.uuid = self._GenerateUniqueID(_UPGRADE_CONFIG_JID)
|
1209 |
1199 |
modified = True
|
1210 |
1200 |
if modified:
|
1211 |
1201 |
self._WriteConfig()
|
|
1202 |
# This is ok even if it acquires the internal lock, as _UpgradeConfig is
|
|
1203 |
# only called at config init time, without the lock held
|
|
1204 |
self.DropECReservations(_UPGRADE_CONFIG_JID)
|
|
1205 |
|
1212 |
1206 |
|
1213 |
1207 |
def _DistributeConfig(self, feedback_fn):
|
1214 |
1208 |
"""Distribute the configuration to the other nodes.
|
... | ... | |
1260 |
1254 |
"""
|
1261 |
1255 |
assert feedback_fn is None or callable(feedback_fn)
|
1262 |
1256 |
|
1263 |
|
# First, cleanup the _temporary_ids set, if an ID is now in the
|
1264 |
|
# other objects it should be discarded to prevent unbounded growth
|
1265 |
|
# of that structure
|
1266 |
|
self._CleanupTemporaryIDs()
|
1267 |
|
|
1268 |
1257 |
# Warn on config errors, but don't abort the save - the
|
1269 |
1258 |
# configuration has already been modified, and we can't revert;
|
1270 |
1259 |
# the best we can do is to warn the user and save as is, leaving
|
... | ... | |
1441 |
1430 |
"""Drop per-execution-context reservations
|
1442 |
1431 |
|
1443 |
1432 |
"""
|
1444 |
|
pass
|
|
1433 |
self._temporary_ids.DropECReservations(ec_id)
|
1445 |
1434 |
|