Revision fb60bc6a
b/lib/masterd/iallocator.py | ||
---|---|---|
153 | 153 |
("nics", ht.TListOf(ht.TDict)), |
154 | 154 |
("vcpus", ht.TInt), |
155 | 155 |
("hypervisor", ht.TString), |
156 |
("node_whitelist", ht.TMaybeListOf(ht.TNonEmptyString)), |
|
156 | 157 |
] |
157 | 158 |
REQ_RESULT = ht.TList |
158 | 159 |
|
... | ... | |
421 | 422 |
|
422 | 423 |
if isinstance(self.req, IAReqInstanceAlloc): |
423 | 424 |
hypervisor_name = self.req.hypervisor |
425 |
node_whitelist = self.req.node_whitelist |
|
424 | 426 |
elif isinstance(self.req, IAReqRelocate): |
425 | 427 |
hypervisor_name = cfg.GetInstanceInfo(self.req.name).hypervisor |
428 |
node_whitelist = None |
|
426 | 429 |
else: |
427 | 430 |
hypervisor_name = cluster_info.primary_hypervisor |
431 |
node_whitelist = None |
|
428 | 432 |
|
429 | 433 |
node_data = self.rpc.call_node_info(node_list, [cfg.GetVGName()], |
430 | 434 |
[hypervisor_name]) |
... | ... | |
434 | 438 |
|
435 | 439 |
data["nodegroups"] = self._ComputeNodeGroupData(cfg) |
436 | 440 |
|
437 |
config_ndata = self._ComputeBasicNodeData(cfg, ninfo) |
|
441 |
config_ndata = self._ComputeBasicNodeData(cfg, ninfo, node_whitelist)
|
|
438 | 442 |
data["nodes"] = self._ComputeDynamicNodeData(ninfo, node_data, node_iinfo, |
439 | 443 |
i_list, config_ndata) |
440 | 444 |
assert len(data["nodes"]) == len(ninfo), \ |
... | ... | |
461 | 465 |
return ng |
462 | 466 |
|
463 | 467 |
@staticmethod |
464 |
def _ComputeBasicNodeData(cfg, node_cfg): |
|
468 |
def _ComputeBasicNodeData(cfg, node_cfg, node_whitelist):
|
|
465 | 469 |
"""Compute global node data. |
466 | 470 |
|
467 | 471 |
@rtype: dict |
... | ... | |
473 | 477 |
"tags": list(ninfo.GetTags()), |
474 | 478 |
"primary_ip": ninfo.primary_ip, |
475 | 479 |
"secondary_ip": ninfo.secondary_ip, |
476 |
"offline": ninfo.offline, |
|
480 |
"offline": (ninfo.offline or |
|
481 |
not (node_whitelist is None or |
|
482 |
ninfo.name in node_whitelist)), |
|
477 | 483 |
"drained": ninfo.drained, |
478 | 484 |
"master_candidate": ninfo.master_candidate, |
479 | 485 |
"group": ninfo.group, |
b/test/ganeti.masterd.iallocator_unittest.py | ||
---|---|---|
26 | 26 |
from ganeti import compat |
27 | 27 |
from ganeti import constants |
28 | 28 |
from ganeti import errors |
29 |
from ganeti import objects |
|
29 | 30 |
from ganeti import ht |
30 | 31 |
from ganeti.masterd import iallocator |
31 | 32 |
|
... | ... | |
88 | 89 |
stub.ValidateResult(_StubIAllocator(False), "foo") |
89 | 90 |
|
90 | 91 |
|
92 |
class _FakeConfigWithNdParams: |
|
93 |
def GetNdParams(self, _): |
|
94 |
return None |
|
95 |
|
|
96 |
|
|
97 |
class TestComputeBasicNodeData(unittest.TestCase): |
|
98 |
def setUp(self): |
|
99 |
self.fn = compat.partial(iallocator.IAllocator._ComputeBasicNodeData, |
|
100 |
_FakeConfigWithNdParams()) |
|
101 |
|
|
102 |
def testEmpty(self): |
|
103 |
self.assertEqual(self.fn({}, None), {}) |
|
104 |
|
|
105 |
def testSimple(self): |
|
106 |
node1 = objects.Node(name="node1", |
|
107 |
primary_ip="192.0.2.1", |
|
108 |
secondary_ip="192.0.2.2", |
|
109 |
offline=False, |
|
110 |
drained=False, |
|
111 |
master_candidate=True, |
|
112 |
master_capable=True, |
|
113 |
group="11112222", |
|
114 |
vm_capable=False) |
|
115 |
|
|
116 |
node2 = objects.Node(name="node2", |
|
117 |
primary_ip="192.0.2.3", |
|
118 |
secondary_ip="192.0.2.4", |
|
119 |
offline=True, |
|
120 |
drained=False, |
|
121 |
master_candidate=False, |
|
122 |
master_capable=False, |
|
123 |
group="11112222", |
|
124 |
vm_capable=True) |
|
125 |
|
|
126 |
assert node1 != node2 |
|
127 |
|
|
128 |
ninfo = { |
|
129 |
"#unused-1#": node1, |
|
130 |
"#unused-2#": node2, |
|
131 |
} |
|
132 |
|
|
133 |
self.assertEqual(self.fn(ninfo, None), { |
|
134 |
"node1": { |
|
135 |
"tags": [], |
|
136 |
"primary_ip": "192.0.2.1", |
|
137 |
"secondary_ip": "192.0.2.2", |
|
138 |
"offline": False, |
|
139 |
"drained": False, |
|
140 |
"master_candidate": True, |
|
141 |
"group": "11112222", |
|
142 |
"master_capable": True, |
|
143 |
"vm_capable": False, |
|
144 |
"ndparams": None, |
|
145 |
}, |
|
146 |
"node2": { |
|
147 |
"tags": [], |
|
148 |
"primary_ip": "192.0.2.3", |
|
149 |
"secondary_ip": "192.0.2.4", |
|
150 |
"offline": True, |
|
151 |
"drained": False, |
|
152 |
"master_candidate": False, |
|
153 |
"group": "11112222", |
|
154 |
"master_capable": False, |
|
155 |
"vm_capable": True, |
|
156 |
"ndparams": None, |
|
157 |
}, |
|
158 |
}) |
|
159 |
|
|
160 |
def testOfflineNode(self): |
|
161 |
for whitelist in [None, [], set(), ["node1"], ["node2"]]: |
|
162 |
result = self.fn({ |
|
163 |
"node1": objects.Node(name="node1", offline=True) |
|
164 |
}, whitelist) |
|
165 |
self.assertEqual(len(result), 1) |
|
166 |
self.assertTrue(result["node1"]["offline"]) |
|
167 |
|
|
168 |
def testWhitelist(self): |
|
169 |
for whitelist in [None, [], set(), ["node1"], ["node2"]]: |
|
170 |
result = self.fn({ |
|
171 |
"node1": objects.Node(name="node1", offline=False) |
|
172 |
}, whitelist) |
|
173 |
self.assertEqual(len(result), 1) |
|
174 |
|
|
175 |
if whitelist is None or "node1" in whitelist: |
|
176 |
self.assertFalse(result["node1"]["offline"]) |
|
177 |
else: |
|
178 |
self.assertTrue(result["node1"]["offline"]) |
|
179 |
|
|
180 |
|
|
91 | 181 |
if __name__ == "__main__": |
92 | 182 |
testutils.GanetiTestProgram() |
Also available in: Unified diff