Revision 3636400f lib/cmdlib.py
b/lib/cmdlib.py | ||
---|---|---|
53 | 53 |
import ganeti.masterd.instance # pylint: disable-msg=W0611 |
54 | 54 |
|
55 | 55 |
|
56 |
# need to define these here before the actual LUs |
|
56 |
# Modifiable default values; need to define these here before the |
|
57 |
# actual LUs |
|
57 | 58 |
|
58 | 59 |
def _EmptyList(): |
59 | 60 |
"""Returns an empty list. |
... | ... | |
69 | 70 |
return {} |
70 | 71 |
|
71 | 72 |
|
73 |
# Some basic types |
|
74 |
def _TNotNone(val): |
|
75 |
"""Checks if the given value is not None. |
|
76 |
|
|
77 |
""" |
|
78 |
return val is not None |
|
79 |
|
|
80 |
|
|
81 |
def _TNone(val): |
|
82 |
"""Checks if the given value is None. |
|
83 |
|
|
84 |
""" |
|
85 |
return val is None |
|
86 |
|
|
87 |
|
|
88 |
def _TBool(val): |
|
89 |
"""Checks if the given value is a boolean. |
|
90 |
|
|
91 |
""" |
|
92 |
return isinstance(val, bool) |
|
93 |
|
|
94 |
|
|
95 |
def _TInt(val): |
|
96 |
"""Checks if the given value is an integer. |
|
97 |
|
|
98 |
""" |
|
99 |
return isinstance(val, int) |
|
100 |
|
|
101 |
|
|
102 |
def _TFloat(val): |
|
103 |
"""Checks if the given value is a float. |
|
104 |
|
|
105 |
""" |
|
106 |
return isinstance(val, float) |
|
107 |
|
|
108 |
|
|
109 |
def _TString(val): |
|
110 |
"""Checks if the given value is a string. |
|
111 |
|
|
112 |
""" |
|
113 |
return isinstance(val, basestring) |
|
114 |
|
|
115 |
|
|
116 |
def _TTrue(val): |
|
117 |
"""Checks if a given value evaluates to a boolean True value. |
|
118 |
|
|
119 |
""" |
|
120 |
return bool(val) |
|
121 |
|
|
122 |
|
|
123 |
def _TElemOf(target_list): |
|
124 |
"""Builds a function that checks if a given value is a member of a list. |
|
125 |
|
|
126 |
""" |
|
127 |
return lambda val: val in target_list |
|
128 |
|
|
129 |
|
|
130 |
# Container types |
|
131 |
def _TList(val): |
|
132 |
"""Checks if the given value is a list. |
|
133 |
|
|
134 |
""" |
|
135 |
return isinstance(val, list) |
|
136 |
|
|
137 |
|
|
138 |
def _TDict(val): |
|
139 |
"""Checks if the given value is a dictionary. |
|
140 |
|
|
141 |
""" |
|
142 |
return isinstance(val, dict) |
|
143 |
|
|
144 |
|
|
145 |
# Combinator types |
|
146 |
def _TAnd(*args): |
|
147 |
"""Combine multiple functions using an AND operation. |
|
148 |
|
|
149 |
""" |
|
150 |
def fn(val): |
|
151 |
return compat.all(t(val) for t in args) |
|
152 |
return fn |
|
153 |
|
|
154 |
|
|
155 |
def _TOr(*args): |
|
156 |
"""Combine multiple functions using an AND operation. |
|
157 |
|
|
158 |
""" |
|
159 |
def fn(val): |
|
160 |
return compat.any(t(val) for t in args) |
|
161 |
return fn |
|
162 |
|
|
163 |
|
|
164 |
# Type aliases |
|
165 |
|
|
166 |
# non-empty string |
|
167 |
_TNEString = _TAnd(_TString, _TTrue) |
|
168 |
|
|
169 |
|
|
170 |
# positive integer |
|
171 |
_TPInt = _TAnd(_TInt, lambda v: v >= 0) |
|
172 |
|
|
173 |
|
|
174 |
def _TListOf(my_type): |
|
175 |
"""Checks if a given value is a list with all elements of the same type. |
|
176 |
|
|
177 |
""" |
|
178 |
return _TAnd(_TList, |
|
179 |
lambda lst: compat.all(lst, my_type)) |
|
180 |
|
|
181 |
|
|
182 |
def _TDictOf(key_type, val_type): |
|
183 |
"""Checks a dict type for the type of its key/values. |
|
184 |
|
|
185 |
""" |
|
186 |
return _TAnd(_TDict, |
|
187 |
lambda my_dict: (compat.all(my_dict.keys(), key_type) and |
|
188 |
compat.all(my_dict.values(), val_type))) |
|
189 |
|
|
190 |
|
|
191 |
# End types |
|
72 | 192 |
class LogicalUnit(object): |
73 | 193 |
"""Logical Unit base class. |
74 | 194 |
|
... | ... | |
138 | 258 |
dval = aval |
139 | 259 |
setattr(self.op, aname, dval) |
140 | 260 |
|
141 |
for attr_name in self._OP_REQP: |
|
142 |
attr_val = getattr(op, attr_name, None) |
|
143 |
if attr_val is None: |
|
261 |
for attr_name, test in self._OP_REQP: |
|
262 |
if not hasattr(op, attr_name): |
|
144 | 263 |
raise errors.OpPrereqError("Required parameter '%s' missing" % |
145 | 264 |
attr_name, errors.ECODE_INVAL) |
265 |
attr_val = getattr(op, attr_name, None) |
|
266 |
if not callable(test): |
|
267 |
raise errors.ProgrammerError("Validation for parameter '%s' failed," |
|
268 |
" given type is not a proper type (%s)" % |
|
269 |
(attr_name, test)) |
|
270 |
if not test(attr_val): |
|
271 |
raise errors.OpPrereqError("Parameter '%s' has invalid type" % |
|
272 |
attr_name, errors.ECODE_INVAL) |
|
146 | 273 |
|
147 | 274 |
self.CheckArguments() |
148 | 275 |
|
... | ... | |
466 | 593 |
@raise errors.ProgrammerError: if the nodes parameter is wrong type |
467 | 594 |
|
468 | 595 |
""" |
469 |
if not isinstance(nodes, list): |
|
470 |
raise errors.OpPrereqError("Invalid argument type 'nodes'", |
|
471 |
errors.ECODE_INVAL) |
|
472 |
|
|
473 | 596 |
if not nodes: |
474 | 597 |
raise errors.ProgrammerError("_GetWantedNodes should only be called with a" |
475 | 598 |
" non-empty list of nodes whose name is to be expanded.") |
... | ... | |
491 | 614 |
@raise errors.OpPrereqError: if any of the passed instances is not found |
492 | 615 |
|
493 | 616 |
""" |
494 |
if not isinstance(instances, list): |
|
495 |
raise errors.OpPrereqError("Invalid argument type 'instances'", |
|
496 |
errors.ECODE_INVAL) |
|
497 |
|
|
498 | 617 |
if instances: |
499 | 618 |
wanted = [_ExpandInstanceName(lu.cfg, name) for name in instances] |
500 | 619 |
else: |
... | ... | |
659 | 778 |
errors.ECODE_INVAL) |
660 | 779 |
if storage_type == constants.ST_FILE: |
661 | 780 |
_RequireFileStorage() |
781 |
return True |
|
662 | 782 |
|
663 | 783 |
|
664 | 784 |
def _GetClusterDomainSecret(): |
... | ... | |
685 | 805 |
(instance.name, reason), errors.ECODE_STATE) |
686 | 806 |
|
687 | 807 |
|
688 |
def _CheckExportMode(mode): |
|
689 |
"""Ensures that a given export mode is valid. |
|
690 |
|
|
691 |
@param mode: the export mode to check |
|
692 |
@raise errors.OpPrereqError: when the export mode is not valid |
|
693 |
|
|
694 |
""" |
|
695 |
if mode not in constants.EXPORT_MODES: |
|
696 |
raise errors.OpPrereqError("Invalid export mode %r" % mode, |
|
697 |
errors.ECODE_INVAL) |
|
698 |
|
|
699 |
|
|
700 | 808 |
def _ExpandItemName(fn, name, kind): |
701 | 809 |
"""Expand an item name. |
702 | 810 |
|
... | ... | |
1126 | 1234 |
""" |
1127 | 1235 |
HPATH = "cluster-verify" |
1128 | 1236 |
HTYPE = constants.HTYPE_CLUSTER |
1129 |
_OP_REQP = ["skip_checks", "verbose", "error_codes", "debug_simulate_errors"] |
|
1237 |
_OP_REQP = [ |
|
1238 |
("skip_checks", _TListOf(_TElemOf(constants.VERIFY_OPTIONAL_CHECKS))), |
|
1239 |
("verbose", _TBool), |
|
1240 |
("error_codes", _TBool), |
|
1241 |
("debug_simulate_errors", _TBool), |
|
1242 |
] |
|
1130 | 1243 |
REQ_BGL = False |
1131 | 1244 |
|
1132 | 1245 |
TCLUSTER = "cluster" |
... | ... | |
1800 | 1913 |
_ErrorIf(True, self.ENODERPC, node, |
1801 | 1914 |
"node returned invalid LVM info, check LVM status") |
1802 | 1915 |
|
1803 |
def CheckArguments(self): |
|
1804 |
"""Check arguments. |
|
1805 |
|
|
1806 |
Transform the list of checks we're going to skip into a set and check that |
|
1807 |
all its members are valid. |
|
1808 |
|
|
1809 |
""" |
|
1810 |
self.skip_set = frozenset(self.op.skip_checks) |
|
1811 |
if not constants.VERIFY_OPTIONAL_CHECKS.issuperset(self.skip_set): |
|
1812 |
raise errors.OpPrereqError("Invalid checks to be skipped specified", |
|
1813 |
errors.ECODE_INVAL) |
|
1814 |
|
|
1815 | 1916 |
def BuildHooksEnv(self): |
1816 | 1917 |
"""Build hooks env. |
1817 | 1918 |
|
... | ... | |
2044 | 2145 |
feedback_fn("* Verifying orphan instances") |
2045 | 2146 |
self._VerifyOrphanInstances(instancelist, node_image) |
2046 | 2147 |
|
2047 |
if constants.VERIFY_NPLUSONE_MEM not in self.skip_set:
|
|
2148 |
if constants.VERIFY_NPLUSONE_MEM not in self.op.skip_checks:
|
|
2048 | 2149 |
feedback_fn("* Verifying N+1 Memory redundancy") |
2049 | 2150 |
self._VerifyNPlusOneMemory(node_image, instanceinfo) |
2050 | 2151 |
|
... | ... | |
2191 | 2292 |
"""Verifies the cluster disks sizes. |
2192 | 2293 |
|
2193 | 2294 |
""" |
2194 |
_OP_REQP = ["instances"]
|
|
2295 |
_OP_REQP = [("instances", _TListOf(_TNEString))]
|
|
2195 | 2296 |
REQ_BGL = False |
2196 | 2297 |
|
2197 |
def CheckArguments(self): |
|
2198 |
if not isinstance(self.op.instances, list): |
|
2199 |
raise errors.OpPrereqError("Invalid argument type 'instances'", |
|
2200 |
errors.ECODE_INVAL) |
|
2201 |
|
|
2202 | 2298 |
def ExpandNames(self): |
2203 | 2299 |
if self.op.instances: |
2204 | 2300 |
self.wanted_names = [] |
... | ... | |
2314 | 2410 |
""" |
2315 | 2411 |
HPATH = "cluster-rename" |
2316 | 2412 |
HTYPE = constants.HTYPE_CLUSTER |
2317 |
_OP_REQP = ["name"]
|
|
2413 |
_OP_REQP = [("name", _TNEString)]
|
|
2318 | 2414 |
|
2319 | 2415 |
def BuildHooksEnv(self): |
2320 | 2416 |
"""Build hooks env. |
... | ... | |
2414 | 2510 |
""" |
2415 | 2511 |
HPATH = "cluster-modify" |
2416 | 2512 |
HTYPE = constants.HTYPE_CLUSTER |
2417 |
_OP_REQP = [] |
|
2513 |
_OP_REQP = [ |
|
2514 |
("hvparams", _TOr(_TDictOf(_TNEString, _TDict), _TNone)), |
|
2515 |
("os_hvp", _TOr(_TDictOf(_TNEString, _TDict), _TNone)), |
|
2516 |
("osparams", _TOr(_TDictOf(_TNEString, _TDict), _TNone)), |
|
2517 |
("enabled_hypervisors", |
|
2518 |
_TOr(_TAnd(_TListOf(_TElemOf(constants.HYPER_TYPES)), _TTrue), _TNone)), |
|
2519 |
] |
|
2418 | 2520 |
_OP_DEFS = [ |
2419 | 2521 |
("candidate_pool_size", None), |
2420 | 2522 |
("uid_pool", None), |
2421 | 2523 |
("add_uids", None), |
2422 | 2524 |
("remove_uids", None), |
2525 |
("hvparams", None), |
|
2526 |
("ov_hvp", None), |
|
2423 | 2527 |
] |
2424 | 2528 |
REQ_BGL = False |
2425 | 2529 |
|
... | ... | |
2539 | 2643 |
# hypervisor list/parameters |
2540 | 2644 |
self.new_hvparams = new_hvp = objects.FillDict(cluster.hvparams, {}) |
2541 | 2645 |
if self.op.hvparams: |
2542 |
if not isinstance(self.op.hvparams, dict): |
|
2543 |
raise errors.OpPrereqError("Invalid 'hvparams' parameter on input", |
|
2544 |
errors.ECODE_INVAL) |
|
2545 | 2646 |
for hv_name, hv_dict in self.op.hvparams.items(): |
2546 | 2647 |
if hv_name not in self.new_hvparams: |
2547 | 2648 |
self.new_hvparams[hv_name] = hv_dict |
... | ... | |
2551 | 2652 |
# os hypervisor parameters |
2552 | 2653 |
self.new_os_hvp = objects.FillDict(cluster.os_hvp, {}) |
2553 | 2654 |
if self.op.os_hvp: |
2554 |
if not isinstance(self.op.os_hvp, dict): |
|
2555 |
raise errors.OpPrereqError("Invalid 'os_hvp' parameter on input", |
|
2556 |
errors.ECODE_INVAL) |
|
2557 | 2655 |
for os_name, hvs in self.op.os_hvp.items(): |
2558 |
if not isinstance(hvs, dict): |
|
2559 |
raise errors.OpPrereqError(("Invalid 'os_hvp' parameter on" |
|
2560 |
" input"), errors.ECODE_INVAL) |
|
2561 | 2656 |
if os_name not in self.new_os_hvp: |
2562 | 2657 |
self.new_os_hvp[os_name] = hvs |
2563 | 2658 |
else: |
... | ... | |
2570 | 2665 |
# os parameters |
2571 | 2666 |
self.new_osp = objects.FillDict(cluster.osparams, {}) |
2572 | 2667 |
if self.op.osparams: |
2573 |
if not isinstance(self.op.osparams, dict): |
|
2574 |
raise errors.OpPrereqError("Invalid 'osparams' parameter on input", |
|
2575 |
errors.ECODE_INVAL) |
|
2576 | 2668 |
for os_name, osp in self.op.osparams.items(): |
2577 |
if not isinstance(osp, dict): |
|
2578 |
raise errors.OpPrereqError(("Invalid 'osparams' parameter on" |
|
2579 |
" input"), errors.ECODE_INVAL) |
|
2580 | 2669 |
if os_name not in self.new_osp: |
2581 | 2670 |
self.new_osp[os_name] = {} |
2582 | 2671 |
|
... | ... | |
2594 | 2683 |
# changes to the hypervisor list |
2595 | 2684 |
if self.op.enabled_hypervisors is not None: |
2596 | 2685 |
self.hv_list = self.op.enabled_hypervisors |
2597 |
if not self.hv_list: |
|
2598 |
raise errors.OpPrereqError("Enabled hypervisors list must contain at" |
|
2599 |
" least one member", |
|
2600 |
errors.ECODE_INVAL) |
|
2601 |
invalid_hvs = set(self.hv_list) - constants.HYPER_TYPES |
|
2602 |
if invalid_hvs: |
|
2603 |
raise errors.OpPrereqError("Enabled hypervisors contains invalid" |
|
2604 |
" entries: %s" % |
|
2605 |
utils.CommaJoin(invalid_hvs), |
|
2606 |
errors.ECODE_INVAL) |
|
2607 | 2686 |
for hv in self.hv_list: |
2608 | 2687 |
# if the hypervisor doesn't already exist in the cluster |
2609 | 2688 |
# hvparams, we initialize it to empty, and then (in both |
... | ... | |
2871 | 2950 |
"""Logical unit for OS diagnose/query. |
2872 | 2951 |
|
2873 | 2952 |
""" |
2874 |
_OP_REQP = ["output_fields", "names"] |
|
2953 |
_OP_REQP = [ |
|
2954 |
("output_fields", _TListOf(_TNEString)), |
|
2955 |
("names", _TListOf(_TNEString)), |
|
2956 |
] |
|
2875 | 2957 |
REQ_BGL = False |
2876 | 2958 |
_FIELDS_STATIC = utils.FieldSet() |
2877 | 2959 |
_FIELDS_DYNAMIC = utils.FieldSet("name", "valid", "node_status", "variants", |
... | ... | |
2992 | 3074 |
""" |
2993 | 3075 |
HPATH = "node-remove" |
2994 | 3076 |
HTYPE = constants.HTYPE_NODE |
2995 |
_OP_REQP = ["node_name"]
|
|
3077 |
_OP_REQP = [("node_name", _TNEString)]
|
|
2996 | 3078 |
|
2997 | 3079 |
def BuildHooksEnv(self): |
2998 | 3080 |
"""Build hooks env. |
... | ... | |
3085 | 3167 |
|
3086 | 3168 |
""" |
3087 | 3169 |
# pylint: disable-msg=W0142 |
3088 |
_OP_REQP = ["output_fields", "names", "use_locking"] |
|
3170 |
_OP_REQP = [ |
|
3171 |
("output_fields", _TListOf(_TNEString)), |
|
3172 |
("names", _TListOf(_TNEString)), |
|
3173 |
("use_locking", _TBool), |
|
3174 |
] |
|
3089 | 3175 |
REQ_BGL = False |
3090 | 3176 |
|
3091 | 3177 |
_SIMPLE_FIELDS = ["name", "serial_no", "ctime", "mtime", "uuid", |
... | ... | |
3238 | 3324 |
"""Logical unit for getting volumes on node(s). |
3239 | 3325 |
|
3240 | 3326 |
""" |
3241 |
_OP_REQP = ["nodes", "output_fields"] |
|
3327 |
_OP_REQP = [ |
|
3328 |
("nodes", _TListOf(_TNEString)), |
|
3329 |
("output_fields", _TListOf(_TNEString)), |
|
3330 |
] |
|
3242 | 3331 |
REQ_BGL = False |
3243 | 3332 |
_FIELDS_DYNAMIC = utils.FieldSet("phys", "vg", "name", "size", "instance") |
3244 | 3333 |
_FIELDS_STATIC = utils.FieldSet("node") |
... | ... | |
3317 | 3406 |
"""Logical unit for getting information on storage units on node(s). |
3318 | 3407 |
|
3319 | 3408 |
""" |
3320 |
_OP_REQP = ["nodes", "storage_type", "output_fields"] |
|
3409 |
_FIELDS_STATIC = utils.FieldSet(constants.SF_NODE) |
|
3410 |
_OP_REQP = [ |
|
3411 |
("nodes", _TListOf(_TNEString)), |
|
3412 |
("storage_type", _CheckStorageType), |
|
3413 |
("output_fields", _TListOf(_TNEString)), |
|
3414 |
] |
|
3321 | 3415 |
_OP_DEFS = [("name", None)] |
3322 | 3416 |
REQ_BGL = False |
3323 |
_FIELDS_STATIC = utils.FieldSet(constants.SF_NODE) |
|
3324 | 3417 |
|
3325 | 3418 |
def CheckArguments(self): |
3326 |
_CheckStorageType(self.op.storage_type) |
|
3327 |
|
|
3328 | 3419 |
_CheckOutputFields(static=self._FIELDS_STATIC, |
3329 | 3420 |
dynamic=utils.FieldSet(*constants.VALID_STORAGE_FIELDS), |
3330 | 3421 |
selected=self.op.output_fields) |
... | ... | |
3404 | 3495 |
"""Logical unit for modifying a storage volume on a node. |
3405 | 3496 |
|
3406 | 3497 |
""" |
3407 |
_OP_REQP = ["node_name", "storage_type", "name", "changes"] |
|
3498 |
_OP_REQP = [ |
|
3499 |
("node_name", _TNEString), |
|
3500 |
("storage_type", _CheckStorageType), |
|
3501 |
("name", _TNEString), |
|
3502 |
("changes", _TDict), |
|
3503 |
] |
|
3408 | 3504 |
REQ_BGL = False |
3409 | 3505 |
|
3410 | 3506 |
def CheckArguments(self): |
3411 | 3507 |
self.op.node_name = _ExpandNodeName(self.cfg, self.op.node_name) |
3412 | 3508 |
|
3413 |
_CheckStorageType(self.op.storage_type) |
|
3414 |
|
|
3415 | 3509 |
storage_type = self.op.storage_type |
3416 | 3510 |
|
3417 | 3511 |
try: |
... | ... | |
3451 | 3545 |
""" |
3452 | 3546 |
HPATH = "node-add" |
3453 | 3547 |
HTYPE = constants.HTYPE_NODE |
3454 |
_OP_REQP = ["node_name"] |
|
3548 |
_OP_REQP = [ |
|
3549 |
("node_name", _TNEString), |
|
3550 |
] |
|
3455 | 3551 |
_OP_DEFS = [("secondary_ip", None)] |
3456 | 3552 |
|
3457 | 3553 |
def CheckArguments(self): |
... | ... | |
3682 | 3778 |
""" |
3683 | 3779 |
HPATH = "node-modify" |
3684 | 3780 |
HTYPE = constants.HTYPE_NODE |
3685 |
_OP_REQP = ["node_name"]
|
|
3781 |
_OP_REQP = [("node_name", _TNEString)]
|
|
3686 | 3782 |
REQ_BGL = False |
3687 | 3783 |
|
3688 | 3784 |
def CheckArguments(self): |
... | ... | |
3843 | 3939 |
"""Powercycles a node. |
3844 | 3940 |
|
3845 | 3941 |
""" |
3846 |
_OP_REQP = ["node_name", "force"] |
|
3942 |
_OP_REQP = [ |
|
3943 |
("node_name", _TNEString), |
|
3944 |
("force", _TBool), |
|
3945 |
] |
|
3847 | 3946 |
REQ_BGL = False |
3848 | 3947 |
|
3849 | 3948 |
def CheckArguments(self): |
... | ... | |
3970 | 4069 |
"""Bring up an instance's disks. |
3971 | 4070 |
|
3972 | 4071 |
""" |
3973 |
_OP_REQP = ["instance_name"]
|
|
4072 |
_OP_REQP = [("instance_name", _TNEString)]
|
|
3974 | 4073 |
_OP_DEFS = [("ignore_size", False)] |
3975 | 4074 |
REQ_BGL = False |
3976 | 4075 |
|
... | ... | |
4114 | 4213 |
"""Shutdown an instance's disks. |
4115 | 4214 |
|
4116 | 4215 |
""" |
4117 |
_OP_REQP = ["instance_name"]
|
|
4216 |
_OP_REQP = [("instance_name", _TNEString)]
|
|
4118 | 4217 |
REQ_BGL = False |
4119 | 4218 |
|
4120 | 4219 |
def ExpandNames(self): |
... | ... | |
4277 | 4376 |
""" |
4278 | 4377 |
HPATH = "instance-start" |
4279 | 4378 |
HTYPE = constants.HTYPE_INSTANCE |
4280 |
_OP_REQP = ["instance_name", "force"] |
|
4379 |
_OP_REQP = [ |
|
4380 |
("instance_name", _TNEString), |
|
4381 |
("force", _TBool), |
|
4382 |
("beparams", _TDict), |
|
4383 |
("hvparams", _TDict), |
|
4384 |
] |
|
4281 | 4385 |
_OP_DEFS = [ |
4282 | 4386 |
("beparams", _EmptyDict), |
4283 | 4387 |
("hvparams", _EmptyDict), |
... | ... | |
4287 | 4391 |
def CheckArguments(self): |
4288 | 4392 |
# extra beparams |
4289 | 4393 |
if self.op.beparams: |
4290 |
if not isinstance(self.op.beparams, dict): |
|
4291 |
raise errors.OpPrereqError("Invalid beparams passed: %s, expected" |
|
4292 |
" dict" % (type(self.op.beparams), ), |
|
4293 |
errors.ECODE_INVAL) |
|
4294 | 4394 |
# fill the beparams dict |
4295 | 4395 |
utils.ForceDictType(self.op.beparams, constants.BES_PARAMETER_TYPES) |
4296 | 4396 |
|
4297 |
if self.op.hvparams: |
|
4298 |
if not isinstance(self.op.hvparams, dict): |
|
4299 |
raise errors.OpPrereqError("Invalid hvparams passed: %s, expected" |
|
4300 |
" dict" % (type(self.op.hvparams), ), |
|
4301 |
errors.ECODE_INVAL) |
|
4302 |
|
|
4303 | 4397 |
def ExpandNames(self): |
4304 | 4398 |
self._ExpandAndLockInstance() |
4305 | 4399 |
|
... | ... | |
4380 | 4474 |
""" |
4381 | 4475 |
HPATH = "instance-reboot" |
4382 | 4476 |
HTYPE = constants.HTYPE_INSTANCE |
4383 |
_OP_REQP = ["instance_name", "ignore_secondaries", "reboot_type"] |
|
4477 |
_OP_REQP = [ |
|
4478 |
("instance_name", _TNEString), |
|
4479 |
("ignore_secondaries", _TBool), |
|
4480 |
("reboot_type", _TElemOf(constants.REBOOT_TYPES)), |
|
4481 |
] |
|
4384 | 4482 |
_OP_DEFS = [("shutdown_timeout", constants.DEFAULT_SHUTDOWN_TIMEOUT)] |
4385 | 4483 |
REQ_BGL = False |
4386 | 4484 |
|
4387 |
def CheckArguments(self): |
|
4388 |
if self.op.reboot_type not in constants.REBOOT_TYPES: |
|
4389 |
raise errors.OpPrereqError("Invalid reboot type '%s', not one of %s" % |
|
4390 |
(self.op.reboot_type, |
|
4391 |
utils.CommaJoin(constants.REBOOT_TYPES)), |
|
4392 |
errors.ECODE_INVAL) |
|
4393 |
|
|
4394 | 4485 |
def ExpandNames(self): |
4395 | 4486 |
self._ExpandAndLockInstance() |
4396 | 4487 |
|
... | ... | |
4464 | 4555 |
""" |
4465 | 4556 |
HPATH = "instance-stop" |
4466 | 4557 |
HTYPE = constants.HTYPE_INSTANCE |
4467 |
_OP_REQP = ["instance_name"]
|
|
4558 |
_OP_REQP = [("instance_name", _TNEString)]
|
|
4468 | 4559 |
_OP_DEFS = [("timeout", constants.DEFAULT_SHUTDOWN_TIMEOUT)] |
4469 | 4560 |
REQ_BGL = False |
4470 | 4561 |
|
... | ... | |
4515 | 4606 |
""" |
4516 | 4607 |
HPATH = "instance-reinstall" |
4517 | 4608 |
HTYPE = constants.HTYPE_INSTANCE |
4518 |
_OP_REQP = ["instance_name"]
|
|
4609 |
_OP_REQP = [("instance_name", _TNEString)]
|
|
4519 | 4610 |
_OP_DEFS = [ |
4520 | 4611 |
("os_type", None), |
4521 | 4612 |
("force_variant", False), |
... | ... | |
4588 | 4679 |
""" |
4589 | 4680 |
HPATH = "instance-recreate-disks" |
4590 | 4681 |
HTYPE = constants.HTYPE_INSTANCE |
4591 |
_OP_REQP = ["instance_name", "disks"] |
|
4682 |
_OP_REQP = [ |
|
4683 |
("instance_name", _TNEString), |
|
4684 |
("disks", _TListOf(_TPInt)), |
|
4685 |
] |
|
4592 | 4686 |
REQ_BGL = False |
4593 | 4687 |
|
4594 |
def CheckArguments(self): |
|
4595 |
"""Check the arguments. |
|
4596 |
|
|
4597 |
""" |
|
4598 |
if not isinstance(self.op.disks, list): |
|
4599 |
raise errors.OpPrereqError("Invalid disks parameter", errors.ECODE_INVAL) |
|
4600 |
for item in self.op.disks: |
|
4601 |
if (not isinstance(item, int) or |
|
4602 |
item < 0): |
|
4603 |
raise errors.OpPrereqError("Invalid disk specification '%s'" % |
|
4604 |
str(item), errors.ECODE_INVAL) |
|
4605 |
|
|
4606 | 4688 |
def ExpandNames(self): |
4607 | 4689 |
self._ExpandAndLockInstance() |
4608 | 4690 |
|
... | ... | |
4661 | 4743 |
""" |
4662 | 4744 |
HPATH = "instance-rename" |
4663 | 4745 |
HTYPE = constants.HTYPE_INSTANCE |
4664 |
_OP_REQP = ["instance_name", "new_name"] |
|
4746 |
_OP_REQP = [ |
|
4747 |
("instance_name", _TNEString), |
|
4748 |
("new_name", _TNEString), |
|
4749 |
] |
|
4665 | 4750 |
_OP_DEFS = [("ignore_ip", False)] |
4666 | 4751 |
|
4667 | 4752 |
def BuildHooksEnv(self): |
... | ... | |
4752 | 4837 |
""" |
4753 | 4838 |
HPATH = "instance-remove" |
4754 | 4839 |
HTYPE = constants.HTYPE_INSTANCE |
4755 |
_OP_REQP = ["instance_name", "ignore_failures"] |
|
4840 |
_OP_REQP = [ |
|
4841 |
("instance_name", _TNEString), |
|
4842 |
("ignore_failures", _TBool), |
|
4843 |
] |
|
4756 | 4844 |
_OP_DEFS = [("shutdown_timeout", constants.DEFAULT_SHUTDOWN_TIMEOUT)] |
4757 | 4845 |
REQ_BGL = False |
4758 | 4846 |
|
... | ... | |
4836 | 4924 |
|
4837 | 4925 |
""" |
4838 | 4926 |
# pylint: disable-msg=W0142 |
4839 |
_OP_REQP = ["output_fields", "names", "use_locking"] |
|
4927 |
_OP_REQP = [ |
|
4928 |
("output_fields", _TListOf(_TNEString)), |
|
4929 |
("names", _TListOf(_TNEString)), |
|
4930 |
("use_locking", _TBool), |
|
4931 |
] |
|
4840 | 4932 |
REQ_BGL = False |
4841 | 4933 |
_SIMPLE_FIELDS = ["name", "os", "network_port", "hypervisor", |
4842 | 4934 |
"serial_no", "ctime", "mtime", "uuid"] |
... | ... | |
5114 | 5206 |
""" |
5115 | 5207 |
HPATH = "instance-failover" |
5116 | 5208 |
HTYPE = constants.HTYPE_INSTANCE |
5117 |
_OP_REQP = ["instance_name", "ignore_consistency"] |
|
5209 |
_OP_REQP = [ |
|
5210 |
("instance_name", _TNEString), |
|
5211 |
("ignore_consistency", _TBool), |
|
5212 |
] |
|
5118 | 5213 |
_OP_DEFS = [("shutdown_timeout", constants.DEFAULT_SHUTDOWN_TIMEOUT)] |
5119 | 5214 |
REQ_BGL = False |
5120 | 5215 |
|
... | ... | |
5265 | 5360 |
""" |
5266 | 5361 |
HPATH = "instance-migrate" |
5267 | 5362 |
HTYPE = constants.HTYPE_INSTANCE |
5268 |
_OP_REQP = ["instance_name", "live", "cleanup"] |
|
5363 |
_OP_REQP = [ |
|
5364 |
("instance_name", _TNEString), |
|
5365 |
("live", _TBool), |
|
5366 |
("cleanup", _TBool), |
|
5367 |
] |
|
5269 | 5368 |
|
5270 | 5369 |
REQ_BGL = False |
5271 | 5370 |
|
... | ... | |
5313 | 5412 |
""" |
5314 | 5413 |
HPATH = "instance-move" |
5315 | 5414 |
HTYPE = constants.HTYPE_INSTANCE |
5316 |
_OP_REQP = ["instance_name", "target_node"] |
|
5415 |
_OP_REQP = [ |
|
5416 |
("instance_name", _TNEString), |
|
5417 |
("target_node", _TNEString), |
|
5418 |
] |
|
5317 | 5419 |
_OP_DEFS = [("shutdown_timeout", constants.DEFAULT_SHUTDOWN_TIMEOUT)] |
5318 | 5420 |
REQ_BGL = False |
5319 | 5421 |
|
... | ... | |
5489 | 5591 |
""" |
5490 | 5592 |
HPATH = "node-migrate" |
5491 | 5593 |
HTYPE = constants.HTYPE_NODE |
5492 |
_OP_REQP = ["node_name", "live"] |
|
5594 |
_OP_REQP = [ |
|
5595 |
("node_name", _TNEString), |
|
5596 |
("live", _TBool), |
|
5597 |
] |
|
5493 | 5598 |
REQ_BGL = False |
5494 | 5599 |
|
5495 | 5600 |
def ExpandNames(self): |
... | ... | |
6223 | 6328 |
""" |
6224 | 6329 |
HPATH = "instance-add" |
6225 | 6330 |
HTYPE = constants.HTYPE_INSTANCE |
6226 |
_OP_REQP = ["instance_name", "disks", |
|
6227 |
"mode", "start", |
|
6228 |
"wait_for_sync", "ip_check", "nics", |
|
6229 |
"hvparams", "beparams", "osparams"] |
|
6331 |
_OP_REQP = [ |
|
6332 |
("instance_name", _TNEString), |
|
6333 |
("mode", _TElemOf(constants.INSTANCE_CREATE_MODES)), |
|
6334 |
("start", _TBool), |
|
6335 |
("wait_for_sync", _TBool), |
|
6336 |
("ip_check", _TBool), |
|
6337 |
("disks", _TListOf(_TDict)), |
|
6338 |
("nics", _TListOf(_TDict)), |
|
6339 |
("hvparams", _TDict), |
|
6340 |
("beparams", _TDict), |
|
6341 |
("osparams", _TDict), |
|
6342 |
] |
|
6230 | 6343 |
_OP_DEFS = [ |
6231 | 6344 |
("name_check", True), |
6232 | 6345 |
("no_install", False), |
... | ... | |
6291 | 6404 |
|
6292 | 6405 |
self.adopt_disks = has_adopt |
6293 | 6406 |
|
6294 |
# verify creation mode |
|
6295 |
if self.op.mode not in constants.INSTANCE_CREATE_MODES: |
|
6296 |
raise errors.OpPrereqError("Invalid instance creation mode '%s'" % |
|
6297 |
self.op.mode, errors.ECODE_INVAL) |
|
6298 |
|
|
6299 | 6407 |
# instance name verification |
6300 | 6408 |
if self.op.name_check: |
6301 | 6409 |
self.hostname1 = utils.GetHostInfo(self.op.instance_name) |
... | ... | |
7128 | 7236 |
console. |
7129 | 7237 |
|
7130 | 7238 |
""" |
7131 |
_OP_REQP = ["instance_name"]
|
|
7239 |
_OP_REQP = [("instance_name", _TNEString)]
|
|
7132 | 7240 |
REQ_BGL = False |
7133 | 7241 |
|
7134 | 7242 |
def ExpandNames(self): |
... | ... | |
7179 | 7287 |
""" |
7180 | 7288 |
HPATH = "mirrors-replace" |
7181 | 7289 |
HTYPE = constants.HTYPE_INSTANCE |
7182 |
_OP_REQP = ["instance_name", "mode", "disks"] |
|
7290 |
_OP_REQP = [ |
|
7291 |
("instance_name", _TNEString), |
|
7292 |
("mode", _TElemOf(constants.REPLACE_MODES)), |
|
7293 |
("disks", _TListOf(_TPInt)), |
|
7294 |
] |
|
7183 | 7295 |
_OP_DEFS = [ |
7184 | 7296 |
("remote_node", None), |
7185 | 7297 |
("iallocator", None), |
... | ... | |
7920 | 8032 |
"""Repairs the volume group on a node. |
7921 | 8033 |
|
7922 | 8034 |
""" |
7923 |
_OP_REQP = ["node_name"]
|
|
8035 |
_OP_REQP = [("node_name", _TNEString)]
|
|
7924 | 8036 |
REQ_BGL = False |
7925 | 8037 |
|
7926 | 8038 |
def CheckArguments(self): |
... | ... | |
7985 | 8097 |
"""Computes the node evacuation strategy. |
7986 | 8098 |
|
7987 | 8099 |
""" |
7988 |
_OP_REQP = ["nodes"]
|
|
8100 |
_OP_REQP = [("nodes", _TListOf(_TNEString))]
|
|
7989 | 8101 |
_OP_DEFS = [ |
7990 | 8102 |
("remote_node", None), |
7991 | 8103 |
("iallocator", None), |
... | ... | |
8038 | 8150 |
""" |
8039 | 8151 |
HPATH = "disk-grow" |
8040 | 8152 |
HTYPE = constants.HTYPE_INSTANCE |
8041 |
_OP_REQP = ["instance_name", "disk", "amount", "wait_for_sync"] |
|
8153 |
_OP_REQP = [ |
|
8154 |
("instance_name", _TNEString), |
|
8155 |
("disk", _TInt), |
|
8156 |
("amount", _TInt), |
|
8157 |
("wait_for_sync", _TBool), |
|
8158 |
] |
|
8042 | 8159 |
REQ_BGL = False |
8043 | 8160 |
|
8044 | 8161 |
def ExpandNames(self): |
... | ... | |
8132 | 8249 |
"""Query runtime instance data. |
8133 | 8250 |
|
8134 | 8251 |
""" |
8135 |
_OP_REQP = ["instances", "static"] |
|
8252 |
_OP_REQP = [ |
|
8253 |
("instances", _TListOf(_TNEString)), |
|
8254 |
("static", _TBool), |
|
8255 |
] |
|
8136 | 8256 |
REQ_BGL = False |
8137 | 8257 |
|
8138 |
def CheckArguments(self): |
|
8139 |
if not isinstance(self.op.instances, list): |
|
8140 |
raise errors.OpPrereqError("Invalid argument type 'instances'", |
|
8141 |
errors.ECODE_INVAL) |
|
8142 |
|
|
8143 | 8258 |
def ExpandNames(self): |
8144 | 8259 |
self.needed_locks = {} |
8145 | 8260 |
self.share_locks = dict.fromkeys(locking.LEVELS, 1) |
... | ... | |
8294 | 8409 |
""" |
8295 | 8410 |
HPATH = "instance-modify" |
8296 | 8411 |
HTYPE = constants.HTYPE_INSTANCE |
8297 |
_OP_REQP = ["instance_name"]
|
|
8412 |
_OP_REQP = [("instance_name", _TNEString)]
|
|
8298 | 8413 |
_OP_DEFS = [ |
8299 | 8414 |
("nics", _EmptyList), |
8300 | 8415 |
("disks", _EmptyList), |
... | ... | |
8956 | 9071 |
"""Query the exports list |
8957 | 9072 |
|
8958 | 9073 |
""" |
8959 |
_OP_REQP = ['nodes']
|
|
9074 |
_OP_REQP = [("nodes", _TListOf(_TNEString))]
|
|
8960 | 9075 |
REQ_BGL = False |
8961 | 9076 |
|
8962 | 9077 |
def ExpandNames(self): |
... | ... | |
8993 | 9108 |
"""Prepares an instance for an export and returns useful information. |
8994 | 9109 |
|
8995 | 9110 |
""" |
8996 |
_OP_REQP = ["instance_name", "mode"] |
|
9111 |
_OP_REQP = [ |
|
9112 |
("instance_name", _TNEString), |
|
9113 |
("mode", _TElemOf(constants.EXPORT_MODES)), |
|
9114 |
] |
|
8997 | 9115 |
REQ_BGL = False |
8998 | 9116 |
|
8999 |
def CheckArguments(self): |
|
9000 |
"""Check the arguments. |
|
9001 |
|
|
9002 |
""" |
|
9003 |
_CheckExportMode(self.op.mode) |
|
9004 |
|
|
9005 | 9117 |
def ExpandNames(self): |
9006 | 9118 |
self._ExpandAndLockInstance() |
9007 | 9119 |
|
... | ... | |
9053 | 9165 |
""" |
9054 | 9166 |
HPATH = "instance-export" |
9055 | 9167 |
HTYPE = constants.HTYPE_INSTANCE |
9056 |
_OP_REQP = ["instance_name", "target_node", "shutdown"] |
|
9168 |
_OP_REQP = [ |
|
9169 |
("instance_name", _TNEString), |
|
9170 |
("target_node", _TNEString), |
|
9171 |
("shutdown", _TBool), |
|
9172 |
("mode", _TElemOf(constants.EXPORT_MODES)), |
|
9173 |
] |
|
9057 | 9174 |
_OP_DEFS = [ |
9058 | 9175 |
("shutdown_timeout", constants.DEFAULT_SHUTDOWN_TIMEOUT), |
9059 | 9176 |
("remove_instance", False), |
... | ... | |
9075 | 9192 |
raise errors.OpPrereqError("Can not remove instance without shutting it" |
9076 | 9193 |
" down before") |
9077 | 9194 |
|
9078 |
_CheckExportMode(self.op.mode) |
|
9079 |
|
|
9080 | 9195 |
if self.op.mode == constants.EXPORT_MODE_REMOTE: |
9081 | 9196 |
if not self.x509_key_name: |
9082 | 9197 |
raise errors.OpPrereqError("Missing X509 key name for encryption", |
... | ... | |
9339 | 9454 |
"""Remove exports related to the named instance. |
9340 | 9455 |
|
9341 | 9456 |
""" |
9342 |
_OP_REQP = ["instance_name"]
|
|
9457 |
_OP_REQP = [("instance_name", _TNEString)]
|
|
9343 | 9458 |
REQ_BGL = False |
9344 | 9459 |
|
9345 | 9460 |
def ExpandNames(self): |
... | ... | |
9418 | 9533 |
"""Returns the tags of a given object. |
9419 | 9534 |
|
9420 | 9535 |
""" |
9421 |
_OP_REQP = ["kind", "name"] |
|
9536 |
_OP_REQP = [ |
|
9537 |
("kind", _TElemOf(constants.VALID_TAG_TYPES)), |
|
9538 |
("name", _TNEString), |
|
9539 |
] |
|
9422 | 9540 |
REQ_BGL = False |
9423 | 9541 |
|
9424 | 9542 |
def Exec(self, feedback_fn): |
... | ... | |
9432 | 9550 |
"""Searches the tags for a given pattern. |
9433 | 9551 |
|
9434 | 9552 |
""" |
9435 |
_OP_REQP = ["pattern"]
|
|
9553 |
_OP_REQP = [("pattern", _TNEString)]
|
|
9436 | 9554 |
REQ_BGL = False |
9437 | 9555 |
|
9438 | 9556 |
def ExpandNames(self): |
... | ... | |
9472 | 9590 |
"""Sets a tag on a given object. |
9473 | 9591 |
|
9474 | 9592 |
""" |
9475 |
_OP_REQP = ["kind", "name", "tags"] |
|
9593 |
_OP_REQP = [ |
|
9594 |
("kind", _TElemOf(constants.VALID_TAG_TYPES)), |
|
9595 |
("name", _TNEString), |
|
9596 |
("tags", _TListOf(objects.TaggableObject.ValidateTag)), |
|
9597 |
] |
|
9476 | 9598 |
REQ_BGL = False |
9477 | 9599 |
|
9478 | 9600 |
def CheckPrereq(self): |
... | ... | |
9501 | 9623 |
"""Delete a list of tags from a given object. |
9502 | 9624 |
|
9503 | 9625 |
""" |
9504 |
_OP_REQP = ["kind", "name", "tags"] |
|
9626 |
_OP_REQP = [ |
|
9627 |
("kind", _TElemOf(constants.VALID_TAG_TYPES)), |
|
9628 |
("name", _TNEString), |
|
9629 |
("tags", _TListOf(objects.TaggableObject.ValidateTag)), |
|
9630 |
] |
|
9505 | 9631 |
REQ_BGL = False |
9506 | 9632 |
|
9507 | 9633 |
def CheckPrereq(self): |
... | ... | |
9538 | 9664 |
time. |
9539 | 9665 |
|
9540 | 9666 |
""" |
9541 |
_OP_REQP = ["duration", "on_master", "on_nodes"] |
|
9667 |
_OP_REQP = [ |
|
9668 |
("duration", _TFloat), |
|
9669 |
("on_master", _TBool), |
|
9670 |
("on_nodes", _TListOf(_TNEString)), |
|
9671 |
] |
|
9542 | 9672 |
REQ_BGL = False |
9543 | 9673 |
|
9544 | 9674 |
def CheckArguments(self): |
... | ... | |
9918 | 10048 |
This LU runs the allocator tests |
9919 | 10049 |
|
9920 | 10050 |
""" |
9921 |
_OP_REQP = ["direction", "mode", "name"] |
|
10051 |
_OP_REQP = [ |
|
10052 |
("direction", _TElemOf(constants.VALID_IALLOCATOR_DIRECTIONS)), |
|
10053 |
("mode", _TElemOf(constants.VALID_IALLOCATOR_MODES)), |
|
10054 |
("name", _TNEString), |
|
10055 |
("nics", _TOr(_TNone, _TListOf( |
|
10056 |
_TDictOf(_TElemOf(["mac", "ip", "bridge"]), _TNEString)))), |
|
10057 |
("disks", _TOr(_TNone, _TList)), |
|
10058 |
] |
|
9922 | 10059 |
_OP_DEFS = [ |
9923 | 10060 |
("hypervisor", None), |
9924 | 10061 |
("allocator", None), |
10062 |
("nics", None), |
|
10063 |
("disks", None), |
|
9925 | 10064 |
] |
9926 | 10065 |
|
9927 | 10066 |
def CheckPrereq(self): |
... | ... | |
9931 | 10070 |
|
9932 | 10071 |
""" |
9933 | 10072 |
if self.op.mode == constants.IALLOCATOR_MODE_ALLOC: |
9934 |
for attr in ["name", "mem_size", "disks", "disk_template",
|
|
10073 |
for attr in ["mem_size", "disks", "disk_template", |
|
9935 | 10074 |
"os", "tags", "nics", "vcpus"]: |
9936 | 10075 |
if not hasattr(self.op, attr): |
9937 | 10076 |
raise errors.OpPrereqError("Missing attribute '%s' on opcode input" % |
... | ... | |
9943 | 10082 |
if not isinstance(self.op.nics, list): |
9944 | 10083 |
raise errors.OpPrereqError("Invalid parameter 'nics'", |
9945 | 10084 |
errors.ECODE_INVAL) |
9946 |
for row in self.op.nics: |
|
9947 |
if (not isinstance(row, dict) or |
|
9948 |
"mac" not in row or |
|
9949 |
"ip" not in row or |
|
9950 |
"bridge" not in row): |
|
9951 |
raise errors.OpPrereqError("Invalid contents of the 'nics'" |
|
9952 |
" parameter", errors.ECODE_INVAL) |
|
9953 | 10085 |
if not isinstance(self.op.disks, list): |
9954 | 10086 |
raise errors.OpPrereqError("Invalid parameter 'disks'", |
9955 | 10087 |
errors.ECODE_INVAL) |
... | ... | |
9964 | 10096 |
if self.op.hypervisor is None: |
9965 | 10097 |
self.op.hypervisor = self.cfg.GetHypervisorType() |
9966 | 10098 |
elif self.op.mode == constants.IALLOCATOR_MODE_RELOC: |
9967 |
if not hasattr(self.op, "name"): |
|
9968 |
raise errors.OpPrereqError("Missing attribute 'name' on opcode input", |
|
9969 |
errors.ECODE_INVAL) |
|
9970 | 10099 |
fname = _ExpandInstanceName(self.cfg, self.op.name) |
9971 | 10100 |
self.op.name = fname |
9972 | 10101 |
self.relocate_from = self.cfg.GetInstanceInfo(fname).secondary_nodes |
Also available in: Unified diff