40 |
40 |
_config = None
|
41 |
41 |
|
42 |
42 |
|
|
43 |
class _QaInstance(object):
|
|
44 |
__slots__ = [
|
|
45 |
"name",
|
|
46 |
"nicmac",
|
|
47 |
"used",
|
|
48 |
"disk_template",
|
|
49 |
]
|
|
50 |
|
|
51 |
def __init__(self, name, nicmac):
|
|
52 |
"""Initializes instances of this class.
|
|
53 |
|
|
54 |
"""
|
|
55 |
self.name = name
|
|
56 |
self.nicmac = nicmac
|
|
57 |
self.used = None
|
|
58 |
self.disk_template = None
|
|
59 |
|
|
60 |
@classmethod
|
|
61 |
def FromDict(cls, data):
|
|
62 |
"""Creates instance object from JSON dictionary.
|
|
63 |
|
|
64 |
"""
|
|
65 |
nicmac = []
|
|
66 |
|
|
67 |
macaddr = data.get("nic.mac/0")
|
|
68 |
if macaddr:
|
|
69 |
nicmac.append(macaddr)
|
|
70 |
|
|
71 |
return cls(name=data["name"], nicmac=nicmac)
|
|
72 |
|
|
73 |
def __getitem__(self, key):
|
|
74 |
"""Legacy dict-like interface.
|
|
75 |
|
|
76 |
"""
|
|
77 |
if key == "name":
|
|
78 |
return self.name
|
|
79 |
else:
|
|
80 |
raise KeyError(key)
|
|
81 |
|
|
82 |
def get(self, key, default):
|
|
83 |
"""Legacy dict-like interface.
|
|
84 |
|
|
85 |
"""
|
|
86 |
try:
|
|
87 |
return self[key]
|
|
88 |
except KeyError:
|
|
89 |
return default
|
|
90 |
|
|
91 |
def GetNicMacAddr(self, idx, default):
|
|
92 |
"""Returns MAC address for NIC.
|
|
93 |
|
|
94 |
@type idx: int
|
|
95 |
@param idx: NIC index
|
|
96 |
@param default: Default value
|
|
97 |
|
|
98 |
"""
|
|
99 |
if len(self.nicmac) > idx:
|
|
100 |
return self.nicmac[idx]
|
|
101 |
else:
|
|
102 |
return default
|
|
103 |
|
|
104 |
|
|
105 |
_RESOURCE_CONVERTER = {
|
|
106 |
"instances": _QaInstance.FromDict,
|
|
107 |
}
|
|
108 |
|
|
109 |
|
|
110 |
def _ConvertResources((key, value)):
|
|
111 |
"""Converts cluster resources in configuration to Python objects.
|
|
112 |
|
|
113 |
"""
|
|
114 |
fn = _RESOURCE_CONVERTER.get(key, None)
|
|
115 |
if fn:
|
|
116 |
return (key, map(fn, value))
|
|
117 |
else:
|
|
118 |
return (key, value)
|
|
119 |
|
|
120 |
|
43 |
121 |
class _QaConfig(object):
|
44 |
122 |
def __init__(self, data):
|
45 |
123 |
"""Initializes instances of this class.
|
... | ... | |
61 |
139 |
"""
|
62 |
140 |
data = serializer.LoadJson(utils.ReadFile(filename))
|
63 |
141 |
|
64 |
|
result = cls(data)
|
|
142 |
result = cls(dict(map(_ConvertResources,
|
|
143 |
data.items()))) # pylint: disable=E1103
|
65 |
144 |
result.Validate()
|
66 |
145 |
|
67 |
146 |
return result
|
... | ... | |
308 |
387 |
"""Returns MAC address for instance's network interface.
|
309 |
388 |
|
310 |
389 |
"""
|
311 |
|
return inst.get("nic.mac/0", default)
|
|
390 |
return inst.GetNicMacAddr(0, default)
|
312 |
391 |
|
313 |
392 |
|
314 |
393 |
def GetMasterNode():
|
... | ... | |
318 |
397 |
return GetConfig().GetMasterNode()
|
319 |
398 |
|
320 |
399 |
|
321 |
|
def AcquireInstance():
|
|
400 |
def AcquireInstance(_cfg=None):
|
322 |
401 |
"""Returns an instance which isn't in use.
|
323 |
402 |
|
324 |
403 |
"""
|
|
404 |
if _cfg is None:
|
|
405 |
cfg = GetConfig()
|
|
406 |
else:
|
|
407 |
cfg = _cfg
|
|
408 |
|
325 |
409 |
# Filter out unwanted instances
|
326 |
|
tmp_flt = lambda inst: not inst.get("_used", False)
|
327 |
|
instances = filter(tmp_flt, GetConfig()["instances"])
|
328 |
|
del tmp_flt
|
|
410 |
instances = filter(lambda inst: not inst.used, cfg["instances"])
|
329 |
411 |
|
330 |
|
if len(instances) == 0:
|
|
412 |
if not instances:
|
331 |
413 |
raise qa_error.OutOfInstancesError("No instances left")
|
332 |
414 |
|
333 |
415 |
inst = instances[0]
|
334 |
|
inst["_used"] = True
|
335 |
|
inst["_template"] = None
|
|
416 |
|
|
417 |
assert not inst.used
|
|
418 |
assert inst.disk_template is None
|
|
419 |
|
|
420 |
inst.used = True
|
|
421 |
|
336 |
422 |
return inst
|
337 |
423 |
|
338 |
424 |
|
339 |
425 |
def ReleaseInstance(inst):
|
340 |
|
inst["_used"] = False
|
|
426 |
inst.used = False
|
|
427 |
inst.disk_template = None
|
341 |
428 |
|
342 |
429 |
|
343 |
430 |
def GetInstanceTemplate(inst):
|
344 |
431 |
"""Return the disk template of an instance.
|
345 |
432 |
|
346 |
433 |
"""
|
347 |
|
templ = inst["_template"]
|
|
434 |
templ = inst.disk_template
|
348 |
435 |
assert templ is not None
|
349 |
436 |
return templ
|
350 |
437 |
|
... | ... | |
353 |
440 |
"""Set the disk template for an instance.
|
354 |
441 |
|
355 |
442 |
"""
|
356 |
|
inst["_template"] = template
|
|
443 |
inst.disk_template = template
|
357 |
444 |
|
358 |
445 |
|
359 |
446 |
def SetExclusiveStorage(value):
|