Revision 538475ca lib/cmdlib.py
b/lib/cmdlib.py | ||
---|---|---|
3126 | 3126 |
""" |
3127 | 3127 |
HPATH = "instance-add" |
3128 | 3128 |
HTYPE = constants.HTYPE_INSTANCE |
3129 |
_OP_REQP = ["instance_name", "mem_size", "disk_size", "pnode",
|
|
3129 |
_OP_REQP = ["instance_name", "mem_size", "disk_size", |
|
3130 | 3130 |
"disk_template", "swap_size", "mode", "start", "vcpus", |
3131 | 3131 |
"wait_for_sync", "ip_check", "mac"] |
3132 | 3132 |
|
3133 |
def _RunAllocator(self): |
|
3134 |
"""Run the allocator based on input opcode. |
|
3135 |
|
|
3136 |
""" |
|
3137 |
al_data = _IAllocatorGetClusterData(self.cfg, self.sstore) |
|
3138 |
disks = [{"size": self.op.disk_size, "mode": "w"}, |
|
3139 |
{"size": self.op.swap_size, "mode": "w"}] |
|
3140 |
nics = [{"mac": self.op.mac, "ip": getattr(self.op, "ip", None), |
|
3141 |
"bridge": self.op.bridge}] |
|
3142 |
op = opcodes.OpTestAllocator(name=self.op.instance_name, |
|
3143 |
disk_template=self.op.disk_template, |
|
3144 |
tags=[], |
|
3145 |
os=self.op.os_type, |
|
3146 |
vcpus=self.op.vcpus, |
|
3147 |
mem_size=self.op.mem_size, |
|
3148 |
disks=disks, |
|
3149 |
nics=nics) |
|
3150 |
|
|
3151 |
_IAllocatorAddNewInstance(al_data, op) |
|
3152 |
|
|
3153 |
if _JSON_INDENT is None: |
|
3154 |
text = simplejson.dumps(al_data) |
|
3155 |
else: |
|
3156 |
text = simplejson.dumps(al_data, indent=_JSON_INDENT) |
|
3157 |
|
|
3158 |
result = _IAllocatorRun(self.op.iallocator, text) |
|
3159 |
|
|
3160 |
result = _IAllocatorValidateResult(result) |
|
3161 |
|
|
3162 |
if not result["success"]: |
|
3163 |
raise errors.OpPrereqError("Can't compute nodes using" |
|
3164 |
" iallocator '%s': %s" % (self.op.iallocator, |
|
3165 |
result["info"])) |
|
3166 |
req_nodes = 1 |
|
3167 |
if self.op.disk_template in constants.DTS_NET_MIRROR: |
|
3168 |
req_nodes += 1 |
|
3169 |
|
|
3170 |
if len(result["nodes"]) != req_nodes: |
|
3171 |
raise errors.OpPrereqError("iallocator '%s' returned invalid number" |
|
3172 |
" of nodes (%s), required %s" % |
|
3173 |
(len(result["nodes"]), req_nodes)) |
|
3174 |
self.op.pnode = result["nodes"][0] |
|
3175 |
logger.ToStdout("Selected nodes for the instance: %s" % |
|
3176 |
(", ".join(result["nodes"]),)) |
|
3177 |
logger.Info("Selected nodes for instance %s via iallocator %s: %s" % |
|
3178 |
(self.op.instance_name, self.op.iallocator, result["nodes"])) |
|
3179 |
if req_nodes == 2: |
|
3180 |
self.op.snode = result["nodes"][1] |
|
3181 |
|
|
3133 | 3182 |
def BuildHooksEnv(self): |
3134 | 3183 |
"""Build hooks env. |
3135 | 3184 |
|
... | ... | |
3166 | 3215 |
"""Check prerequisites. |
3167 | 3216 |
|
3168 | 3217 |
""" |
3169 |
for attr in ["kernel_path", "initrd_path", "hvm_boot_order"]: |
|
3218 |
# set optional parameters to none if they don't exist |
|
3219 |
for attr in ["kernel_path", "initrd_path", "hvm_boot_order", "pnode", |
|
3220 |
"iallocator"]: |
|
3170 | 3221 |
if not hasattr(self.op, attr): |
3171 | 3222 |
setattr(self.op, attr, None) |
3172 | 3223 |
|
... | ... | |
3284 | 3335 |
if self.op.file_storage_dir and os.path.isabs(self.op.file_storage_dir): |
3285 | 3336 |
raise errors.OpPrereqError("File storage directory not a relative" |
3286 | 3337 |
" path") |
3338 |
#### allocator run |
|
3339 |
|
|
3340 |
if [self.op.iallocator, self.op.pnode].count(None) != 1: |
|
3341 |
raise errors.OpPrereqError("One and only one of iallocator and primary" |
|
3342 |
" node must be given") |
|
3343 |
|
|
3344 |
if self.op.iallocator is not None: |
|
3345 |
self._RunAllocator() |
|
3287 | 3346 |
|
3288 | 3347 |
#### node related checks |
3289 | 3348 |
|
... | ... | |
4784 | 4843 |
alloc_script = utils.FindFile(name, constants.IALLOCATOR_SEARCH_PATH, |
4785 | 4844 |
os.path.isfile) |
4786 | 4845 |
if alloc_script is None: |
4787 |
raise errors.OpExecError("Can't find allocator")
|
|
4846 |
raise errors.OpExecError("Can't find allocator '%s'" % name)
|
|
4788 | 4847 |
|
4789 | 4848 |
fd, fin_name = tempfile.mkstemp(prefix="ganeti-iallocator.") |
4790 | 4849 |
try: |
... | ... | |
4800 | 4859 |
return result.stdout |
4801 | 4860 |
|
4802 | 4861 |
|
4862 |
def _IAllocatorValidateResult(data): |
|
4863 |
"""Process the allocator results. |
|
4864 |
|
|
4865 |
""" |
|
4866 |
try: |
|
4867 |
rdict = simplejson.loads(data) |
|
4868 |
except Exception, err: |
|
4869 |
raise errors.OpExecError("Can't parse iallocator results: %s" % str(err)) |
|
4870 |
|
|
4871 |
if not isinstance(rdict, dict): |
|
4872 |
raise errors.OpExecError("Can't parse iallocator results: not a dict") |
|
4873 |
|
|
4874 |
for key in "success", "info", "nodes": |
|
4875 |
if key not in rdict: |
|
4876 |
raise errors.OpExecError("Can't parse iallocator results:" |
|
4877 |
" missing key '%s'" % key) |
|
4878 |
|
|
4879 |
if not isinstance(rdict["nodes"], list): |
|
4880 |
raise errors.OpExecError("Can't parse iallocator results: 'nodes' key" |
|
4881 |
" is not a list") |
|
4882 |
return rdict |
|
4883 |
|
|
4884 |
|
|
4803 | 4885 |
class LUTestAllocator(NoHooksLU): |
4804 | 4886 |
"""Run allocator tests. |
4805 | 4887 |
|
Also available in: Unified diff