Revision 8a96c5a6 qa/qa_config.py
b/qa/qa_config.py | ||
---|---|---|
40 | 40 |
_exclusive_storage = None |
41 | 41 |
|
42 | 42 |
|
43 |
cfg = {} |
|
43 |
#: QA configuration (L{_QaConfig}) |
|
44 |
_config = None |
|
44 | 45 |
|
45 | 46 |
|
46 |
def Load(path): |
|
47 |
"""Loads the passed configuration file. |
|
47 |
class _QaConfig(object): |
|
48 |
def __init__(self, data): |
|
49 |
"""Initializes instances of this class. |
|
48 | 50 |
|
49 |
""" |
|
50 |
global cfg # pylint: disable=W0603 |
|
51 |
""" |
|
52 |
self._data = data |
|
53 |
|
|
54 |
@classmethod |
|
55 |
def Load(cls, filename): |
|
56 |
"""Loads a configuration file and produces a configuration object. |
|
57 |
|
|
58 |
@type filename: string |
|
59 |
@param filename: Path to configuration file |
|
60 |
@rtype: L{_QaConfig} |
|
61 |
|
|
62 |
""" |
|
63 |
data = serializer.LoadJson(utils.ReadFile(filename)) |
|
64 |
|
|
65 |
result = cls(data) |
|
66 |
result.Validate() |
|
67 |
|
|
68 |
return result |
|
69 |
|
|
70 |
def Validate(self): |
|
71 |
"""Validates loaded configuration data. |
|
72 |
|
|
73 |
""" |
|
74 |
if not self.get("nodes"): |
|
75 |
raise qa_error.Error("Need at least one node") |
|
76 |
|
|
77 |
if not self.get("instances"): |
|
78 |
raise qa_error.Error("Need at least one instance") |
|
79 |
|
|
80 |
if (self.get("disk") is None or |
|
81 |
self.get("disk-growth") is None or |
|
82 |
len(self.get("disk")) != len(self.get("disk-growth"))): |
|
83 |
raise qa_error.Error("Config options 'disk' and 'disk-growth' must exist" |
|
84 |
" and have the same number of items") |
|
85 |
|
|
86 |
check = self.GetInstanceCheckScript() |
|
87 |
if check: |
|
88 |
try: |
|
89 |
os.stat(check) |
|
90 |
except EnvironmentError, err: |
|
91 |
raise qa_error.Error("Can't find instance check script '%s': %s" % |
|
92 |
(check, err)) |
|
93 |
|
|
94 |
enabled_hv = frozenset(self.GetEnabledHypervisors()) |
|
95 |
if not enabled_hv: |
|
96 |
raise qa_error.Error("No hypervisor is enabled") |
|
97 |
|
|
98 |
difference = enabled_hv - constants.HYPER_TYPES |
|
99 |
if difference: |
|
100 |
raise qa_error.Error("Unknown hypervisor(s) enabled: %s" % |
|
101 |
utils.CommaJoin(difference)) |
|
102 |
|
|
103 |
def __getitem__(self, name): |
|
104 |
"""Returns configuration value. |
|
105 |
|
|
106 |
@type name: string |
|
107 |
@param name: Name of configuration entry |
|
108 |
|
|
109 |
""" |
|
110 |
return self._data[name] |
|
111 |
|
|
112 |
def get(self, name, default=None): |
|
113 |
"""Returns configuration value. |
|
114 |
|
|
115 |
@type name: string |
|
116 |
@param name: Name of configuration entry |
|
117 |
@param default: Default value |
|
118 |
|
|
119 |
""" |
|
120 |
return self._data.get(name, default) |
|
51 | 121 |
|
52 |
cfg = serializer.LoadJson(utils.ReadFile(path)) |
|
122 |
def GetMasterNode(self): |
|
123 |
"""Returns the default master node for the cluster. |
|
53 | 124 |
|
54 |
Validate() |
|
125 |
""" |
|
126 |
return self["nodes"][0] |
|
127 |
|
|
128 |
def GetInstanceCheckScript(self): |
|
129 |
"""Returns path to instance check script or C{None}. |
|
130 |
|
|
131 |
""" |
|
132 |
return self._data.get(_INSTANCE_CHECK_KEY, None) |
|
55 | 133 |
|
134 |
def GetEnabledHypervisors(self): |
|
135 |
"""Returns list of enabled hypervisors. |
|
56 | 136 |
|
57 |
def Validate(): |
|
58 |
if len(cfg["nodes"]) < 1: |
|
59 |
raise qa_error.Error("Need at least one node") |
|
60 |
if len(cfg["instances"]) < 1: |
|
61 |
raise qa_error.Error("Need at least one instance") |
|
62 |
if len(cfg["disk"]) != len(cfg["disk-growth"]): |
|
63 |
raise qa_error.Error("Config options 'disk' and 'disk-growth' must have" |
|
64 |
" the same number of items") |
|
137 |
@rtype: list |
|
65 | 138 |
|
66 |
check = GetInstanceCheckScript() |
|
67 |
if check: |
|
139 |
""" |
|
68 | 140 |
try: |
69 |
os.stat(check) |
|
70 |
except EnvironmentError, err: |
|
71 |
raise qa_error.Error("Can't find instance check script '%s': %s" % |
|
72 |
(check, err)) |
|
141 |
value = self._data[_ENABLED_HV_KEY] |
|
142 |
except KeyError: |
|
143 |
return [constants.DEFAULT_ENABLED_HYPERVISOR] |
|
144 |
else: |
|
145 |
if value is None: |
|
146 |
return [] |
|
147 |
elif isinstance(value, basestring): |
|
148 |
# The configuration key ("enabled-hypervisors") implies there can be |
|
149 |
# multiple values. Multiple hypervisors are comma-separated on the |
|
150 |
# command line option to "gnt-cluster init", so we need to handle them |
|
151 |
# equally here. |
|
152 |
return value.split(",") |
|
153 |
else: |
|
154 |
return value |
|
155 |
|
|
156 |
def GetDefaultHypervisor(self): |
|
157 |
"""Returns the default hypervisor to be used. |
|
158 |
|
|
159 |
""" |
|
160 |
return self.GetEnabledHypervisors()[0] |
|
161 |
|
|
162 |
|
|
163 |
def Load(path): |
|
164 |
"""Loads the passed configuration file. |
|
165 |
|
|
166 |
""" |
|
167 |
global _config # pylint: disable=W0603 |
|
73 | 168 |
|
74 |
enabled_hv = frozenset(GetEnabledHypervisors()) |
|
75 |
if not enabled_hv: |
|
76 |
raise qa_error.Error("No hypervisor is enabled") |
|
169 |
_config = _QaConfig.Load(path) |
|
77 | 170 |
|
78 |
difference = enabled_hv - constants.HYPER_TYPES |
|
79 |
if difference: |
|
80 |
raise qa_error.Error("Unknown hypervisor(s) enabled: %s" % |
|
81 |
utils.CommaJoin(difference)) |
|
171 |
|
|
172 |
def GetConfig(): |
|
173 |
"""Returns the configuration object. |
|
174 |
|
|
175 |
""" |
|
176 |
if _config is None: |
|
177 |
raise RuntimeError("Configuration not yet loaded") |
|
178 |
|
|
179 |
return _config |
|
82 | 180 |
|
83 | 181 |
|
84 | 182 |
def get(name, default=None): |
85 |
return cfg.get(name, default) |
|
183 |
"""Wrapper for L{_QaConfig.get}. |
|
184 |
|
|
185 |
""" |
|
186 |
return GetConfig().get(name, default=default) |
|
86 | 187 |
|
87 | 188 |
|
88 | 189 |
class Either: |
... | ... | |
148 | 249 |
|
149 | 250 |
""" |
150 | 251 |
if _cfg is None: |
151 |
_cfg = cfg |
|
252 |
cfg = GetConfig() |
|
253 |
else: |
|
254 |
cfg = _cfg |
|
152 | 255 |
|
153 | 256 |
# Get settings for all tests |
154 |
cfg_tests = _cfg.get("tests", {})
|
|
257 |
cfg_tests = cfg.get("tests", {}) |
|
155 | 258 |
|
156 | 259 |
# Get default setting |
157 | 260 |
default = cfg_tests.get("default", True) |
... | ... | |
160 | 263 |
tests, compat.all) |
161 | 264 |
|
162 | 265 |
|
163 |
def GetInstanceCheckScript(): |
|
164 |
"""Returns path to instance check script or C{None}.
|
|
266 |
def GetInstanceCheckScript(*args):
|
|
267 |
"""Wrapper for L{_QaConfig.GetInstanceCheckScript}.
|
|
165 | 268 |
|
166 | 269 |
""" |
167 |
return cfg.get(_INSTANCE_CHECK_KEY, None)
|
|
270 |
return GetConfig().GetInstanceCheckScript(*args)
|
|
168 | 271 |
|
169 | 272 |
|
170 |
def GetEnabledHypervisors(): |
|
171 |
"""Returns list of enabled hypervisors. |
|
172 |
|
|
173 |
@rtype: list |
|
273 |
def GetEnabledHypervisors(*args): |
|
274 |
"""Wrapper for L{_QaConfig.GetEnabledHypervisors}. |
|
174 | 275 |
|
175 | 276 |
""" |
176 |
try: |
|
177 |
value = cfg[_ENABLED_HV_KEY] |
|
178 |
except KeyError: |
|
179 |
return [constants.DEFAULT_ENABLED_HYPERVISOR] |
|
180 |
else: |
|
181 |
if isinstance(value, basestring): |
|
182 |
# The configuration key ("enabled-hypervisors") implies there can be |
|
183 |
# multiple values. Multiple hypervisors are comma-separated on the |
|
184 |
# command line option to "gnt-cluster init", so we need to handle them |
|
185 |
# equally here. |
|
186 |
return value.split(",") |
|
187 |
else: |
|
188 |
return value |
|
277 |
return GetConfig().GetEnabledHypervisors(*args) |
|
189 | 278 |
|
190 | 279 |
|
191 |
def GetDefaultHypervisor(): |
|
192 |
"""Returns the default hypervisor to be used.
|
|
280 |
def GetDefaultHypervisor(*args):
|
|
281 |
"""Wrapper for L{_QaConfig.GetDefaultHypervisor}.
|
|
193 | 282 |
|
194 | 283 |
""" |
195 |
return GetEnabledHypervisors()[0]
|
|
284 |
return GetConfig().GetDefaultHypervisor(*args)
|
|
196 | 285 |
|
197 | 286 |
|
198 | 287 |
def GetInstanceNicMac(inst, default=None): |
... | ... | |
203 | 292 |
|
204 | 293 |
|
205 | 294 |
def GetMasterNode(): |
206 |
return cfg["nodes"][0] |
|
295 |
"""Wrapper for L{_QaConfig.GetMasterNode}. |
|
296 |
|
|
297 |
""" |
|
298 |
return GetConfig().GetMasterNode() |
|
207 | 299 |
|
208 | 300 |
|
209 | 301 |
def AcquireInstance(): |
... | ... | |
212 | 304 |
""" |
213 | 305 |
# Filter out unwanted instances |
214 | 306 |
tmp_flt = lambda inst: not inst.get("_used", False) |
215 |
instances = filter(tmp_flt, cfg["instances"])
|
|
307 |
instances = filter(tmp_flt, GetConfig()["instances"])
|
|
216 | 308 |
del tmp_flt |
217 | 309 |
|
218 | 310 |
if len(instances) == 0: |
... | ... | |
263 | 355 |
|
264 | 356 |
|
265 | 357 |
def IsTemplateSupported(templ): |
266 |
"""Is the given templated supported by the current configuration?
|
|
358 |
"""Is the given disk template supported by the current configuration?
|
|
267 | 359 |
|
268 | 360 |
""" |
269 | 361 |
if GetExclusiveStorage(): |
... | ... | |
277 | 369 |
|
278 | 370 |
""" |
279 | 371 |
master = GetMasterNode() |
372 |
cfg = GetConfig() |
|
280 | 373 |
|
281 | 374 |
# Filter out unwanted nodes |
282 | 375 |
# TODO: Maybe combine filters |
Also available in: Unified diff