Revision 776b6291 lib/masterd/iallocator.py
b/lib/masterd/iallocator.py | ||
---|---|---|
78 | 78 |
__metaclass__ = _AutoReqParam |
79 | 79 |
|
80 | 80 |
MODE = NotImplemented |
81 |
REQ_PARAMS = [ |
|
82 |
("required_nodes", ht.TPositiveInt) |
|
83 |
] |
|
81 |
REQ_PARAMS = [] |
|
84 | 82 |
REQ_RESULT = NotImplemented |
85 | 83 |
|
86 | 84 |
def __init__(self, **kwargs): |
... | ... | |
92 | 90 |
REQ_PARAMS attribute for this class. |
93 | 91 |
|
94 | 92 |
""" |
95 |
self.required_nodes = 0 |
|
96 | 93 |
objectutils.ValidatedSlots.__init__(self, **kwargs) |
97 | 94 |
|
98 | 95 |
self.Validate() |
... | ... | |
128 | 125 |
|
129 | 126 |
@param ia: The IAllocator instance |
130 | 127 |
@param result: The IAllocator run result |
131 |
@returns: If it validates
|
|
128 |
@raises ResultValidationError: If validation fails
|
|
132 | 129 |
|
133 | 130 |
""" |
134 | 131 |
if not (ia.success and self.REQ_RESULT(result)): |
135 |
raise errors.OpExecError("Iallocator returned invalid result,"
|
|
136 |
" expected %s, got %s" % |
|
137 |
(self.REQ_RESULT, result)) |
|
132 |
raise errors.ResultValidationError("iallocator returned invalid result,"
|
|
133 |
" expected %s, got %s" %
|
|
134 |
(self.REQ_RESULT, result))
|
|
138 | 135 |
|
139 | 136 |
|
140 | 137 |
class IAReqInstanceAlloc(IARequestBase): |
... | ... | |
157 | 154 |
] |
158 | 155 |
REQ_RESULT = ht.TList |
159 | 156 |
|
157 |
def RequiredNodes(self): |
|
158 |
"""Calculates the required nodes based on the disk_template. |
|
159 |
|
|
160 |
""" |
|
161 |
if self.disk_template in constants.DTS_INT_MIRROR: |
|
162 |
return 2 |
|
163 |
else: |
|
164 |
return 1 |
|
165 |
|
|
160 | 166 |
def GetRequest(self, cfg): |
161 | 167 |
"""Requests a new instance. |
162 | 168 |
|
... | ... | |
166 | 172 |
""" |
167 | 173 |
disk_space = gmi.ComputeDiskSize(self.disk_template, self.disks) |
168 | 174 |
|
169 |
if self.disk_template in constants.DTS_INT_MIRROR: |
|
170 |
self.required_nodes = 2 |
|
171 |
else: |
|
172 |
self.required_nodes = 1 |
|
173 |
|
|
174 | 175 |
return { |
175 | 176 |
"name": self.name, |
176 | 177 |
"disk_template": self.disk_template, |
... | ... | |
182 | 183 |
"disks": self.disks, |
183 | 184 |
"disk_space_total": disk_space, |
184 | 185 |
"nics": self.nics, |
185 |
"required_nodes": self.required_nodes,
|
|
186 |
"required_nodes": self.RequiredNodes(),
|
|
186 | 187 |
"hypervisor": self.hypervisor, |
187 | 188 |
} |
188 | 189 |
|
190 |
def ValidateResult(self, ia, result): |
|
191 |
"""Validates an single instance allocation request. |
|
192 |
|
|
193 |
""" |
|
194 |
IARequestBase.ValidateResult(self, ia, result) |
|
195 |
|
|
196 |
if len(result) != self.RequiredNodes(): |
|
197 |
raise errors.ResultValidationError("iallocator returned invalid number" |
|
198 |
" of nodes (%s), required %s" % |
|
199 |
(len(result), self.RequiredNodes())) |
|
200 |
|
|
189 | 201 |
|
190 | 202 |
class IAReqMultiInstanceAlloc(IARequestBase): |
191 | 203 |
"""An multi instance allocation request. |
... | ... | |
244 | 256 |
raise errors.OpPrereqError("Instance has not exactly one secondary node", |
245 | 257 |
errors.ECODE_STATE) |
246 | 258 |
|
247 |
self.required_nodes = 1 |
|
248 | 259 |
disk_sizes = [{constants.IDISK_SIZE: disk.size} for disk in instance.disks] |
249 | 260 |
disk_space = gmi.ComputeDiskSize(instance.disk_template, disk_sizes) |
250 | 261 |
|
251 | 262 |
return { |
252 | 263 |
"name": self.name, |
253 | 264 |
"disk_space_total": disk_space, |
254 |
"required_nodes": self.required_nodes,
|
|
265 |
"required_nodes": 1,
|
|
255 | 266 |
"relocate_from": self.relocate_from, |
256 | 267 |
} |
257 | 268 |
|
... | ... | |
259 | 270 |
"""Validates the result of an relocation request. |
260 | 271 |
|
261 | 272 |
""" |
273 |
IARequestBase.ValidateResult(self, ia, result) |
|
274 |
|
|
262 | 275 |
node2group = dict((name, ndata["group"]) |
263 | 276 |
for (name, ndata) in ia.in_data["nodes"].items()) |
264 | 277 |
|
... | ... | |
270 | 283 |
result_groups = fn(result + [instance.primary_node]) |
271 | 284 |
|
272 | 285 |
if ia.success and not set(result_groups).issubset(request_groups): |
273 |
raise errors.OpExecError("Groups of nodes returned by iallocator (%s)" |
|
274 |
" differ from original groups (%s)" % |
|
275 |
(utils.CommaJoin(result_groups), |
|
276 |
utils.CommaJoin(request_groups))) |
|
286 |
raise errors.ResultValidationError("Groups of nodes returned by" |
|
287 |
"iallocator (%s) differ from original" |
|
288 |
" groups (%s)" % |
|
289 |
(utils.CommaJoin(result_groups), |
|
290 |
utils.CommaJoin(request_groups))) |
|
277 | 291 |
|
278 | 292 |
@staticmethod |
279 | 293 |
def _NodesToGroups(node2group, groups, nodes): |
... | ... | |
591 | 605 |
result = call_fn(self.cfg.GetMasterNode(), name, self.in_text) |
592 | 606 |
result.Raise("Failure while running the iallocator script") |
593 | 607 |
|
594 |
self.required_nodes = self.req.required_nodes |
|
595 | 608 |
self.out_text = result.payload |
596 | 609 |
if validate: |
597 | 610 |
self._ValidateResult() |
Also available in: Unified diff