100 |
100 |
attr_val = getattr(op, attr_name, None)
|
101 |
101 |
if attr_val is None:
|
102 |
102 |
raise errors.OpPrereqError("Required parameter '%s' missing" %
|
103 |
|
attr_name)
|
|
103 |
attr_name, errors.ECODE_INVAL)
|
104 |
104 |
|
105 |
105 |
self.CheckArguments()
|
106 |
106 |
|
... | ... | |
297 |
297 |
expanded_name = self.cfg.ExpandInstanceName(self.op.instance_name)
|
298 |
298 |
if expanded_name is None:
|
299 |
299 |
raise errors.OpPrereqError("Instance '%s' not known" %
|
300 |
|
self.op.instance_name)
|
|
300 |
self.op.instance_name, errors.ECODE_NOENT)
|
301 |
301 |
self.needed_locks[locking.LEVEL_INSTANCE] = expanded_name
|
302 |
302 |
self.op.instance_name = expanded_name
|
303 |
303 |
|
... | ... | |
417 |
417 |
|
418 |
418 |
"""
|
419 |
419 |
if not isinstance(nodes, list):
|
420 |
|
raise errors.OpPrereqError("Invalid argument type 'nodes'")
|
|
420 |
raise errors.OpPrereqError("Invalid argument type 'nodes'",
|
|
421 |
errors.ECODE_INVAL)
|
421 |
422 |
|
422 |
423 |
if not nodes:
|
423 |
424 |
raise errors.ProgrammerError("_GetWantedNodes should only be called with a"
|
... | ... | |
427 |
428 |
for name in nodes:
|
428 |
429 |
node = lu.cfg.ExpandNodeName(name)
|
429 |
430 |
if node is None:
|
430 |
|
raise errors.OpPrereqError("No such node name '%s'" % name)
|
|
431 |
raise errors.OpPrereqError("No such node name '%s'" % name,
|
|
432 |
errors.ECODE_NOENT)
|
431 |
433 |
wanted.append(node)
|
432 |
434 |
|
433 |
435 |
return utils.NiceSort(wanted)
|
... | ... | |
447 |
449 |
|
448 |
450 |
"""
|
449 |
451 |
if not isinstance(instances, list):
|
450 |
|
raise errors.OpPrereqError("Invalid argument type 'instances'")
|
|
452 |
raise errors.OpPrereqError("Invalid argument type 'instances'",
|
|
453 |
errors.ECODE_INVAL)
|
451 |
454 |
|
452 |
455 |
if instances:
|
453 |
456 |
wanted = []
|
... | ... | |
455 |
458 |
for name in instances:
|
456 |
459 |
instance = lu.cfg.ExpandInstanceName(name)
|
457 |
460 |
if instance is None:
|
458 |
|
raise errors.OpPrereqError("No such instance name '%s'" % name)
|
|
461 |
raise errors.OpPrereqError("No such instance name '%s'" % name,
|
|
462 |
errors.ECODE_NOENT)
|
459 |
463 |
wanted.append(instance)
|
460 |
464 |
|
461 |
465 |
else:
|
... | ... | |
479 |
483 |
delta = f.NonMatching(selected)
|
480 |
484 |
if delta:
|
481 |
485 |
raise errors.OpPrereqError("Unknown output fields selected: %s"
|
482 |
|
% ",".join(delta))
|
|
486 |
% ",".join(delta), errors.ECODE_INVAL)
|
483 |
487 |
|
484 |
488 |
|
485 |
489 |
def _CheckBooleanOpField(op, name):
|
... | ... | |
492 |
496 |
val = getattr(op, name, None)
|
493 |
497 |
if not (val is None or isinstance(val, bool)):
|
494 |
498 |
raise errors.OpPrereqError("Invalid boolean parameter '%s' (%s)" %
|
495 |
|
(name, str(val)))
|
|
499 |
(name, str(val)), errors.ECODE_INVAL)
|
496 |
500 |
setattr(op, name, val)
|
497 |
501 |
|
498 |
502 |
|
... | ... | |
505 |
509 |
|
506 |
510 |
"""
|
507 |
511 |
if lu.cfg.GetNodeInfo(node).offline:
|
508 |
|
raise errors.OpPrereqError("Can't use offline node %s" % node)
|
|
512 |
raise errors.OpPrereqError("Can't use offline node %s" % node,
|
|
513 |
errors.ECODE_INVAL)
|
509 |
514 |
|
510 |
515 |
|
511 |
516 |
def _CheckNodeNotDrained(lu, node):
|
... | ... | |
517 |
522 |
|
518 |
523 |
"""
|
519 |
524 |
if lu.cfg.GetNodeInfo(node).drained:
|
520 |
|
raise errors.OpPrereqError("Can't use drained node %s" % node)
|
|
525 |
raise errors.OpPrereqError("Can't use drained node %s" % node,
|
|
526 |
errors.ECODE_INVAL)
|
521 |
527 |
|
522 |
528 |
|
523 |
529 |
def _BuildInstanceHookEnv(name, primary_node, secondary_nodes, os_type, status,
|
... | ... | |
736 |
742 |
try:
|
737 |
743 |
variant = name.split("+", 1)[1]
|
738 |
744 |
except IndexError:
|
739 |
|
raise errors.OpPrereqError("OS name must include a variant")
|
|
745 |
raise errors.OpPrereqError("OS name must include a variant",
|
|
746 |
errors.ECODE_INVAL)
|
740 |
747 |
|
741 |
748 |
if variant not in os_obj.supported_variants:
|
742 |
|
raise errors.OpPrereqError("Unsupported OS variant")
|
|
749 |
raise errors.OpPrereqError("Unsupported OS variant", errors.ECODE_INVAL)
|
743 |
750 |
|
744 |
751 |
|
745 |
752 |
def _GetNodeInstancesInner(cfg, fn):
|
... | ... | |
856 |
863 |
nodelist = self.cfg.GetNodeList()
|
857 |
864 |
if len(nodelist) != 1 or nodelist[0] != master:
|
858 |
865 |
raise errors.OpPrereqError("There are still %d node(s) in"
|
859 |
|
" this cluster." % (len(nodelist) - 1))
|
|
866 |
" this cluster." % (len(nodelist) - 1),
|
|
867 |
errors.ECODE_INVAL)
|
860 |
868 |
instancelist = self.cfg.GetInstanceList()
|
861 |
869 |
if instancelist:
|
862 |
870 |
raise errors.OpPrereqError("There are still %d instance(s) in"
|
863 |
|
" this cluster." % len(instancelist))
|
|
871 |
" this cluster." % len(instancelist),
|
|
872 |
errors.ECODE_INVAL)
|
864 |
873 |
|
865 |
874 |
def Exec(self, feedback_fn):
|
866 |
875 |
"""Destroys the cluster.
|
... | ... | |
1217 |
1226 |
"""
|
1218 |
1227 |
self.skip_set = frozenset(self.op.skip_checks)
|
1219 |
1228 |
if not constants.VERIFY_OPTIONAL_CHECKS.issuperset(self.skip_set):
|
1220 |
|
raise errors.OpPrereqError("Invalid checks to be skipped specified")
|
|
1229 |
raise errors.OpPrereqError("Invalid checks to be skipped specified",
|
|
1230 |
errors.ECODE_INVAL)
|
1221 |
1231 |
|
1222 |
1232 |
def BuildHooksEnv(self):
|
1223 |
1233 |
"""Build hooks env.
|
... | ... | |
1626 |
1636 |
|
1627 |
1637 |
def ExpandNames(self):
|
1628 |
1638 |
if not isinstance(self.op.instances, list):
|
1629 |
|
raise errors.OpPrereqError("Invalid argument type 'instances'")
|
|
1639 |
raise errors.OpPrereqError("Invalid argument type 'instances'",
|
|
1640 |
errors.ECODE_INVAL)
|
1630 |
1641 |
|
1631 |
1642 |
if self.op.instances:
|
1632 |
1643 |
self.wanted_names = []
|
1633 |
1644 |
for name in self.op.instances:
|
1634 |
1645 |
full_name = self.cfg.ExpandInstanceName(name)
|
1635 |
1646 |
if full_name is None:
|
1636 |
|
raise errors.OpPrereqError("Instance '%s' not known" % name)
|
|
1647 |
raise errors.OpPrereqError("Instance '%s' not known" % name,
|
|
1648 |
errors.ECODE_NOENT)
|
1637 |
1649 |
self.wanted_names.append(full_name)
|
1638 |
1650 |
self.needed_locks = {
|
1639 |
1651 |
locking.LEVEL_NODE: [],
|
... | ... | |
1769 |
1781 |
old_ip = self.cfg.GetMasterIP()
|
1770 |
1782 |
if new_name == old_name and new_ip == old_ip:
|
1771 |
1783 |
raise errors.OpPrereqError("Neither the name nor the IP address of the"
|
1772 |
|
" cluster has changed")
|
|
1784 |
" cluster has changed",
|
|
1785 |
errors.ECODE_INVAL)
|
1773 |
1786 |
if new_ip != old_ip:
|
1774 |
1787 |
if utils.TcpPing(new_ip, constants.DEFAULT_NODED_PORT):
|
1775 |
1788 |
raise errors.OpPrereqError("The given cluster IP address (%s) is"
|
1776 |
1789 |
" reachable on the network. Aborting." %
|
1777 |
|
new_ip)
|
|
1790 |
new_ip, errors.ECODE_NOTUNIQUE)
|
1778 |
1791 |
|
1779 |
1792 |
self.op.name = new_name
|
1780 |
1793 |
|
... | ... | |
1856 |
1869 |
self.op.candidate_pool_size = int(self.op.candidate_pool_size)
|
1857 |
1870 |
except (ValueError, TypeError), err:
|
1858 |
1871 |
raise errors.OpPrereqError("Invalid candidate_pool_size value: %s" %
|
1859 |
|
str(err))
|
|
1872 |
str(err), errors.ECODE_INVAL)
|
1860 |
1873 |
if self.op.candidate_pool_size < 1:
|
1861 |
|
raise errors.OpPrereqError("At least one master candidate needed")
|
|
1874 |
raise errors.OpPrereqError("At least one master candidate needed",
|
|
1875 |
errors.ECODE_INVAL)
|
1862 |
1876 |
|
1863 |
1877 |
def ExpandNames(self):
|
1864 |
1878 |
# FIXME: in the future maybe other cluster params won't require checking on
|
... | ... | |
1892 |
1906 |
for disk in inst.disks:
|
1893 |
1907 |
if _RecursiveCheckIfLVMBased(disk):
|
1894 |
1908 |
raise errors.OpPrereqError("Cannot disable lvm storage while"
|
1895 |
|
" lvm-based instances exist")
|
|
1909 |
" lvm-based instances exist",
|
|
1910 |
errors.ECODE_INVAL)
|
1896 |
1911 |
|
1897 |
1912 |
node_list = self.acquired_locks[locking.LEVEL_NODE]
|
1898 |
1913 |
|
... | ... | |
1911 |
1926 |
constants.MIN_VG_SIZE)
|
1912 |
1927 |
if vgstatus:
|
1913 |
1928 |
raise errors.OpPrereqError("Error on node '%s': %s" %
|
1914 |
|
(node, vgstatus))
|
|
1929 |
(node, vgstatus), errors.ECODE_ENVIRON)
|
1915 |
1930 |
|
1916 |
1931 |
self.cluster = cluster = self.cfg.GetClusterInfo()
|
1917 |
1932 |
# validate params changes
|
... | ... | |
1930 |
1945 |
self.new_hvparams = objects.FillDict(cluster.hvparams, {})
|
1931 |
1946 |
if self.op.hvparams:
|
1932 |
1947 |
if not isinstance(self.op.hvparams, dict):
|
1933 |
|
raise errors.OpPrereqError("Invalid 'hvparams' parameter on input")
|
|
1948 |
raise errors.OpPrereqError("Invalid 'hvparams' parameter on input",
|
|
1949 |
errors.ECODE_INVAL)
|
1934 |
1950 |
for hv_name, hv_dict in self.op.hvparams.items():
|
1935 |
1951 |
if hv_name not in self.new_hvparams:
|
1936 |
1952 |
self.new_hvparams[hv_name] = hv_dict
|
... | ... | |
1941 |
1957 |
self.hv_list = self.op.enabled_hypervisors
|
1942 |
1958 |
if not self.hv_list:
|
1943 |
1959 |
raise errors.OpPrereqError("Enabled hypervisors list must contain at"
|
1944 |
|
" least one member")
|
|
1960 |
" least one member",
|
|
1961 |
errors.ECODE_INVAL)
|
1945 |
1962 |
invalid_hvs = set(self.hv_list) - constants.HYPER_TYPES
|
1946 |
1963 |
if invalid_hvs:
|
1947 |
1964 |
raise errors.OpPrereqError("Enabled hypervisors contains invalid"
|
1948 |
|
" entries: %s" % " ,".join(invalid_hvs))
|
|
1965 |
" entries: %s" % " ,".join(invalid_hvs),
|
|
1966 |
errors.ECODE_INVAL)
|
1949 |
1967 |
else:
|
1950 |
1968 |
self.hv_list = cluster.enabled_hypervisors
|
1951 |
1969 |
|
... | ... | |
2181 |
2199 |
|
2182 |
2200 |
def ExpandNames(self):
|
2183 |
2201 |
if self.op.names:
|
2184 |
|
raise errors.OpPrereqError("Selective OS query not supported")
|
|
2202 |
raise errors.OpPrereqError("Selective OS query not supported",
|
|
2203 |
errors.ECODE_INVAL)
|
2185 |
2204 |
|
2186 |
2205 |
_CheckOutputFields(static=self._FIELDS_STATIC,
|
2187 |
2206 |
dynamic=self._FIELDS_DYNAMIC,
|
... | ... | |
2320 |
2339 |
"""
|
2321 |
2340 |
node = self.cfg.GetNodeInfo(self.cfg.ExpandNodeName(self.op.node_name))
|
2322 |
2341 |
if node is None:
|
2323 |
|
raise errors.OpPrereqError, ("Node '%s' is unknown." % self.op.node_name)
|
|
2342 |
raise errors.OpPrereqError("Node '%s' is unknown." % self.op.node_name,
|
|
2343 |
errors.ECODE_NOENT)
|
2324 |
2344 |
|
2325 |
2345 |
instance_list = self.cfg.GetInstanceList()
|
2326 |
2346 |
|
2327 |
2347 |
masternode = self.cfg.GetMasterNode()
|
2328 |
2348 |
if node.name == masternode:
|
2329 |
2349 |
raise errors.OpPrereqError("Node is the master node,"
|
2330 |
|
" you need to failover first.")
|
|
2350 |
" you need to failover first.",
|
|
2351 |
errors.ECODE_INVAL)
|
2331 |
2352 |
|
2332 |
2353 |
for instance_name in instance_list:
|
2333 |
2354 |
instance = self.cfg.GetInstanceInfo(instance_name)
|
2334 |
2355 |
if node.name in instance.all_nodes:
|
2335 |
2356 |
raise errors.OpPrereqError("Instance %s is still running on the node,"
|
2336 |
|
" please remove first." % instance_name)
|
|
2357 |
" please remove first." % instance_name,
|
|
2358 |
errors.ECODE_INVAL)
|
2337 |
2359 |
self.op.node_name = node.name
|
2338 |
2360 |
self.node = node
|
2339 |
2361 |
|
... | ... | |
2624 |
2646 |
storage_type = self.op.storage_type
|
2625 |
2647 |
|
2626 |
2648 |
if storage_type not in constants.VALID_STORAGE_TYPES:
|
2627 |
|
raise errors.OpPrereqError("Unknown storage type: %s" % storage_type)
|
|
2649 |
raise errors.OpPrereqError("Unknown storage type: %s" % storage_type,
|
|
2650 |
errors.ECODE_INVAL)
|
2628 |
2651 |
|
2629 |
2652 |
_CheckOutputFields(static=self._FIELDS_STATIC,
|
2630 |
2653 |
dynamic=utils.FieldSet(*constants.VALID_STORAGE_FIELDS),
|
... | ... | |
2718 |
2741 |
def CheckArguments(self):
|
2719 |
2742 |
node_name = self.cfg.ExpandNodeName(self.op.node_name)
|
2720 |
2743 |
if node_name is None:
|
2721 |
|
raise errors.OpPrereqError("Invalid node name '%s'" % self.op.node_name)
|
|
2744 |
raise errors.OpPrereqError("Invalid node name '%s'" % self.op.node_name,
|
|
2745 |
errors.ECODE_NOENT)
|
2722 |
2746 |
|
2723 |
2747 |
self.op.node_name = node_name
|
2724 |
2748 |
|
2725 |
2749 |
storage_type = self.op.storage_type
|
2726 |
2750 |
if storage_type not in constants.VALID_STORAGE_TYPES:
|
2727 |
|
raise errors.OpPrereqError("Unknown storage type: %s" % storage_type)
|
|
2751 |
raise errors.OpPrereqError("Unknown storage type: %s" % storage_type,
|
|
2752 |
errors.ECODE_INVAL)
|
2728 |
2753 |
|
2729 |
2754 |
def ExpandNames(self):
|
2730 |
2755 |
self.needed_locks = {
|
... | ... | |
2741 |
2766 |
modifiable = constants.MODIFIABLE_STORAGE_FIELDS[storage_type]
|
2742 |
2767 |
except KeyError:
|
2743 |
2768 |
raise errors.OpPrereqError("Storage units of type '%s' can not be"
|
2744 |
|
" modified" % storage_type)
|
|
2769 |
" modified" % storage_type,
|
|
2770 |
errors.ECODE_INVAL)
|
2745 |
2771 |
|
2746 |
2772 |
diff = set(self.op.changes.keys()) - modifiable
|
2747 |
2773 |
if diff:
|
2748 |
2774 |
raise errors.OpPrereqError("The following fields can not be modified for"
|
2749 |
2775 |
" storage units of type '%s': %r" %
|
2750 |
|
(storage_type, list(diff)))
|
|
2776 |
(storage_type, list(diff)),
|
|
2777 |
errors.ECODE_INVAL)
|
2751 |
2778 |
|
2752 |
2779 |
def Exec(self, feedback_fn):
|
2753 |
2780 |
"""Computes the list of nodes and their attributes.
|
... | ... | |
2807 |
2834 |
if secondary_ip is None:
|
2808 |
2835 |
secondary_ip = primary_ip
|
2809 |
2836 |
if not utils.IsValidIP(secondary_ip):
|
2810 |
|
raise errors.OpPrereqError("Invalid secondary IP given")
|
|
2837 |
raise errors.OpPrereqError("Invalid secondary IP given",
|
|
2838 |
errors.ECODE_INVAL)
|
2811 |
2839 |
self.op.secondary_ip = secondary_ip
|
2812 |
2840 |
|
2813 |
2841 |
node_list = cfg.GetNodeList()
|
2814 |
2842 |
if not self.op.readd and node in node_list:
|
2815 |
2843 |
raise errors.OpPrereqError("Node %s is already in the configuration" %
|
2816 |
|
node)
|
|
2844 |
node, errors.ECODE_EXISTS)
|
2817 |
2845 |
elif self.op.readd and node not in node_list:
|
2818 |
|
raise errors.OpPrereqError("Node %s is not in the configuration" % node)
|
|
2846 |
raise errors.OpPrereqError("Node %s is not in the configuration" % node,
|
|
2847 |
errors.ECODE_NOENT)
|
2819 |
2848 |
|
2820 |
2849 |
for existing_node_name in node_list:
|
2821 |
2850 |
existing_node = cfg.GetNodeInfo(existing_node_name)
|
... | ... | |
2824 |
2853 |
if (existing_node.primary_ip != primary_ip or
|
2825 |
2854 |
existing_node.secondary_ip != secondary_ip):
|
2826 |
2855 |
raise errors.OpPrereqError("Readded node doesn't have the same IP"
|
2827 |
|
" address configuration as before")
|
|
2856 |
" address configuration as before",
|
|
2857 |
errors.ECODE_INVAL)
|
2828 |
2858 |
continue
|
2829 |
2859 |
|
2830 |
2860 |
if (existing_node.primary_ip == primary_ip or
|
... | ... | |
2832 |
2862 |
existing_node.primary_ip == secondary_ip or
|
2833 |
2863 |
existing_node.secondary_ip == secondary_ip):
|
2834 |
2864 |
raise errors.OpPrereqError("New node ip address(es) conflict with"
|
2835 |
|
" existing node %s" % existing_node.name)
|
|
2865 |
" existing node %s" % existing_node.name,
|
|
2866 |
errors.ECODE_NOTUNIQUE)
|
2836 |
2867 |
|
2837 |
2868 |
# check that the type of the node (single versus dual homed) is the
|
2838 |
2869 |
# same as for the master
|
... | ... | |
2842 |
2873 |
if master_singlehomed != newbie_singlehomed:
|
2843 |
2874 |
if master_singlehomed:
|
2844 |
2875 |
raise errors.OpPrereqError("The master has no private ip but the"
|
2845 |
|
" new node has one")
|
|
2876 |
" new node has one",
|
|
2877 |
errors.ECODE_INVAL)
|
2846 |
2878 |
else:
|
2847 |
2879 |
raise errors.OpPrereqError("The master has a private ip but the"
|
2848 |
|
" new node doesn't have one")
|
|
2880 |
" new node doesn't have one",
|
|
2881 |
errors.ECODE_INVAL)
|
2849 |
2882 |
|
2850 |
2883 |
# checks reachability
|
2851 |
2884 |
if not utils.TcpPing(primary_ip, constants.DEFAULT_NODED_PORT):
|
2852 |
|
raise errors.OpPrereqError("Node not reachable by ping")
|
|
2885 |
raise errors.OpPrereqError("Node not reachable by ping",
|
|
2886 |
errors.ECODE_ENVIRON)
|
2853 |
2887 |
|
2854 |
2888 |
if not newbie_singlehomed:
|
2855 |
2889 |
# check reachability from my secondary ip to newbie's secondary ip
|
2856 |
2890 |
if not utils.TcpPing(secondary_ip, constants.DEFAULT_NODED_PORT,
|
2857 |
2891 |
source=myself.secondary_ip):
|
2858 |
2892 |
raise errors.OpPrereqError("Node secondary ip not reachable by TCP"
|
2859 |
|
" based ping to noded port")
|
|
2893 |
" based ping to noded port",
|
|
2894 |
errors.ECODE_ENVIRON)
|
2860 |
2895 |
|
2861 |
2896 |
if self.op.readd:
|
2862 |
2897 |
exceptions = [node]
|
... | ... | |
2985 |
3020 |
def CheckArguments(self):
|
2986 |
3021 |
node_name = self.cfg.ExpandNodeName(self.op.node_name)
|
2987 |
3022 |
if node_name is None:
|
2988 |
|
raise errors.OpPrereqError("Invalid node name '%s'" % self.op.node_name)
|
|
3023 |
raise errors.OpPrereqError("Invalid node name '%s'" % self.op.node_name,
|
|
3024 |
errors.ECODE_INVAL)
|
2989 |
3025 |
self.op.node_name = node_name
|
2990 |
3026 |
_CheckBooleanOpField(self.op, 'master_candidate')
|
2991 |
3027 |
_CheckBooleanOpField(self.op, 'offline')
|
2992 |
3028 |
_CheckBooleanOpField(self.op, 'drained')
|
2993 |
3029 |
all_mods = [self.op.offline, self.op.master_candidate, self.op.drained]
|
2994 |
3030 |
if all_mods.count(None) == 3:
|
2995 |
|
raise errors.OpPrereqError("Please pass at least one modification")
|
|
3031 |
raise errors.OpPrereqError("Please pass at least one modification",
|
|
3032 |
errors.ECODE_INVAL)
|
2996 |
3033 |
if all_mods.count(True) > 1:
|
2997 |
3034 |
raise errors.OpPrereqError("Can't set the node into more than one"
|
2998 |
|
" state at the same time")
|
|
3035 |
" state at the same time",
|
|
3036 |
errors.ECODE_INVAL)
|
2999 |
3037 |
|
3000 |
3038 |
def ExpandNames(self):
|
3001 |
3039 |
self.needed_locks = {locking.LEVEL_NODE: self.op.node_name}
|
... | ... | |
3030 |
3068 |
# we can't change the master's node flags
|
3031 |
3069 |
if self.op.node_name == self.cfg.GetMasterNode():
|
3032 |
3070 |
raise errors.OpPrereqError("The master role can be changed"
|
3033 |
|
" only via masterfailover")
|
|
3071 |
" only via masterfailover",
|
|
3072 |
errors.ECODE_INVAL)
|
3034 |
3073 |
|
3035 |
3074 |
# Boolean value that tells us whether we're offlining or draining the node
|
3036 |
3075 |
offline_or_drain = self.op.offline == True or self.op.drained == True
|
... | ... | |
3050 |
3089 |
if self.op.force and offline_or_drain and mc_should == mc_max:
|
3051 |
3090 |
self.LogWarning(msg)
|
3052 |
3091 |
else:
|
3053 |
|
raise errors.OpPrereqError(msg)
|
|
3092 |
raise errors.OpPrereqError(msg, errors.ECODE_INVAL)
|
3054 |
3093 |
|
3055 |
3094 |
if (self.op.master_candidate == True and
|
3056 |
3095 |
((node.offline and not self.op.offline == False) or
|
3057 |
3096 |
(node.drained and not self.op.drained == False))):
|
3058 |
3097 |
raise errors.OpPrereqError("Node '%s' is offline or drained, can't set"
|
3059 |
|
" to master_candidate" % node.name)
|
|
3098 |
" to master_candidate" % node.name,
|
|
3099 |
errors.ECODE_INVAL)
|
3060 |
3100 |
|
3061 |
3101 |
# If we're being deofflined/drained, we'll MC ourself if needed
|
3062 |
3102 |
if (deoffline_or_drain and not offline_or_drain and not
|
... | ... | |
3133 |
3173 |
def CheckArguments(self):
|
3134 |
3174 |
node_name = self.cfg.ExpandNodeName(self.op.node_name)
|
3135 |
3175 |
if node_name is None:
|
3136 |
|
raise errors.OpPrereqError("Invalid node name '%s'" % self.op.node_name)
|
|
3176 |
raise errors.OpPrereqError("Invalid node name '%s'" % self.op.node_name,
|
|
3177 |
errors.ECODE_NOENT)
|
3137 |
3178 |
self.op.node_name = node_name
|
3138 |
3179 |
if node_name == self.cfg.GetMasterNode() and not self.op.force:
|
3139 |
3180 |
raise errors.OpPrereqError("The node is the master and the force"
|
3140 |
|
" parameter was not set")
|
|
3181 |
" parameter was not set",
|
|
3182 |
errors.ECODE_INVAL)
|
3141 |
3183 |
|
3142 |
3184 |
def ExpandNames(self):
|
3143 |
3185 |
"""Locking for PowercycleNode.
|
... | ... | |
3501 |
3543 |
free_mem = nodeinfo[node].payload.get('memory_free', None)
|
3502 |
3544 |
if not isinstance(free_mem, int):
|
3503 |
3545 |
raise errors.OpPrereqError("Can't compute free memory on node %s, result"
|
3504 |
|
" was '%s'" % (node, free_mem))
|
|
3546 |
" was '%s'" % (node, free_mem),
|
|
3547 |
errors.ECODE_ENVIRON)
|
3505 |
3548 |
if requested > free_mem:
|
3506 |
3549 |
raise errors.OpPrereqError("Not enough memory on node %s for %s:"
|
3507 |
3550 |
" needed %s MiB, available %s MiB" %
|
3508 |
|
(node, reason, requested, free_mem))
|
|
3551 |
(node, reason, requested, free_mem),
|
|
3552 |
errors.ECODE_NORES)
|
3509 |
3553 |
|
3510 |
3554 |
|
3511 |
3555 |
class LUStartupInstance(LogicalUnit):
|
... | ... | |
3548 |
3592 |
if self.beparams:
|
3549 |
3593 |
if not isinstance(self.beparams, dict):
|
3550 |
3594 |
raise errors.OpPrereqError("Invalid beparams passed: %s, expected"
|
3551 |
|
" dict" % (type(self.beparams), ))
|
|
3595 |
" dict" % (type(self.beparams), ),
|
|
3596 |
errors.ECODE_INVAL)
|
3552 |
3597 |
# fill the beparams dict
|
3553 |
3598 |
utils.ForceDictType(self.beparams, constants.BES_PARAMETER_TYPES)
|
3554 |
3599 |
self.op.beparams = self.beparams
|
... | ... | |
3558 |
3603 |
if self.hvparams:
|
3559 |
3604 |
if not isinstance(self.hvparams, dict):
|
3560 |
3605 |
raise errors.OpPrereqError("Invalid hvparams passed: %s, expected"
|
3561 |
|
" dict" % (type(self.hvparams), ))
|
|
3606 |
" dict" % (type(self.hvparams), ),
|
|
3607 |
errors.ECODE_INVAL)
|
3562 |
3608 |
|
3563 |
3609 |
# check hypervisor parameter syntax (locally)
|
3564 |
3610 |
cluster = self.cfg.GetClusterInfo()
|
... | ... | |
3790 |
3836 |
|
3791 |
3837 |
if instance.disk_template == constants.DT_DISKLESS:
|
3792 |
3838 |
raise errors.OpPrereqError("Instance '%s' has no disks" %
|
3793 |
|
self.op.instance_name)
|
|
3839 |
self.op.instance_name,
|
|
3840 |
errors.ECODE_INVAL)
|
3794 |
3841 |
if instance.admin_up:
|
3795 |
3842 |
raise errors.OpPrereqError("Instance '%s' is marked to be up" %
|
3796 |
|
self.op.instance_name)
|
|
3843 |
self.op.instance_name,
|
|
3844 |
errors.ECODE_STATE)
|
3797 |
3845 |
remote_info = self.rpc.call_instance_info(instance.primary_node,
|
3798 |
3846 |
instance.name,
|
3799 |
3847 |
instance.hypervisor)
|
... | ... | |
3802 |
3850 |
if remote_info.payload:
|
3803 |
3851 |
raise errors.OpPrereqError("Instance '%s' is running on the node %s" %
|
3804 |
3852 |
(self.op.instance_name,
|
3805 |
|
instance.primary_node))
|
|
3853 |
instance.primary_node),
|
|
3854 |
errors.ECODE_STATE)
|
3806 |
3855 |
|
3807 |
3856 |
self.op.os_type = getattr(self.op, "os_type", None)
|
3808 |
3857 |
self.op.force_variant = getattr(self.op, "force_variant", False)
|
... | ... | |
3812 |
3861 |
self.cfg.ExpandNodeName(instance.primary_node))
|
3813 |
3862 |
if pnode is None:
|
3814 |
3863 |
raise errors.OpPrereqError("Primary node '%s' is unknown" %
|
3815 |
|
self.op.pnode)
|
|
3864 |
self.op.pnode, errors.ECODE_NOENT)
|
3816 |
3865 |
result = self.rpc.call_os_get(pnode.name, self.op.os_type)
|
3817 |
3866 |
result.Raise("OS '%s' not in supported OS list for primary node %s" %
|
3818 |
3867 |
(self.op.os_type, pnode.name), prereq=True)
|
... | ... | |
3856 |
3905 |
|
3857 |
3906 |
"""
|
3858 |
3907 |
if not isinstance(self.op.disks, list):
|
3859 |
|
raise errors.OpPrereqError("Invalid disks parameter")
|
|
3908 |
raise errors.OpPrereqError("Invalid disks parameter", errors.ECODE_INVAL)
|
3860 |
3909 |
for item in self.op.disks:
|
3861 |
3910 |
if (not isinstance(item, int) or
|
3862 |
3911 |
item < 0):
|
3863 |
3912 |
raise errors.OpPrereqError("Invalid disk specification '%s'" %
|
3864 |
|
str(item))
|
|
3913 |
str(item), errors.ECODE_INVAL)
|
3865 |
3914 |
|
3866 |
3915 |
def ExpandNames(self):
|
3867 |
3916 |
self._ExpandAndLockInstance()
|
... | ... | |
3889 |
3938 |
|
3890 |
3939 |
if instance.disk_template == constants.DT_DISKLESS:
|
3891 |
3940 |
raise errors.OpPrereqError("Instance '%s' has no disks" %
|
3892 |
|
self.op.instance_name)
|
|
3941 |
self.op.instance_name, errors.ECODE_INVAL)
|
3893 |
3942 |
if instance.admin_up:
|
3894 |
3943 |
raise errors.OpPrereqError("Instance '%s' is marked to be up" %
|
3895 |
|
self.op.instance_name)
|
|
3944 |
self.op.instance_name, errors.ECODE_STATE)
|
3896 |
3945 |
remote_info = self.rpc.call_instance_info(instance.primary_node,
|
3897 |
3946 |
instance.name,
|
3898 |
3947 |
instance.hypervisor)
|
... | ... | |
3901 |
3950 |
if remote_info.payload:
|
3902 |
3951 |
raise errors.OpPrereqError("Instance '%s' is running on the node %s" %
|
3903 |
3952 |
(self.op.instance_name,
|
3904 |
|
instance.primary_node))
|
|
3953 |
instance.primary_node), errors.ECODE_STATE)
|
3905 |
3954 |
|
3906 |
3955 |
if not self.op.disks:
|
3907 |
3956 |
self.op.disks = range(len(instance.disks))
|
3908 |
3957 |
else:
|
3909 |
3958 |
for idx in self.op.disks:
|
3910 |
3959 |
if idx >= len(instance.disks):
|
3911 |
|
raise errors.OpPrereqError("Invalid disk index passed '%s'" % idx)
|
|
3960 |
raise errors.OpPrereqError("Invalid disk index passed '%s'" % idx,
|
|
3961 |
errors.ECODE_INVAL)
|
3912 |
3962 |
|
3913 |
3963 |
self.instance = instance
|
3914 |
3964 |
|
... | ... | |
3954 |
4004 |
self.cfg.ExpandInstanceName(self.op.instance_name))
|
3955 |
4005 |
if instance is None:
|
3956 |
4006 |
raise errors.OpPrereqError("Instance '%s' not known" %
|
3957 |
|
self.op.instance_name)
|
|
4007 |
self.op.instance_name, errors.ECODE_NOENT)
|
3958 |
4008 |
_CheckNodeOnline(self, instance.primary_node)
|
3959 |
4009 |
|
3960 |
4010 |
if instance.admin_up:
|
3961 |
4011 |
raise errors.OpPrereqError("Instance '%s' is marked to be up" %
|
3962 |
|
self.op.instance_name)
|
|
4012 |
self.op.instance_name, errors.ECODE_STATE)
|
3963 |
4013 |
remote_info = self.rpc.call_instance_info(instance.primary_node,
|
3964 |
4014 |
instance.name,
|
3965 |
4015 |
instance.hypervisor)
|
... | ... | |
3968 |
4018 |
if remote_info.payload:
|
3969 |
4019 |
raise errors.OpPrereqError("Instance '%s' is running on the node %s" %
|
3970 |
4020 |
(self.op.instance_name,
|
3971 |
|
instance.primary_node))
|
|
4021 |
instance.primary_node), errors.ECODE_STATE)
|
3972 |
4022 |
self.instance = instance
|
3973 |
4023 |
|
3974 |
4024 |
# new name verification
|
... | ... | |
3978 |
4028 |
instance_list = self.cfg.GetInstanceList()
|
3979 |
4029 |
if new_name in instance_list:
|
3980 |
4030 |
raise errors.OpPrereqError("Instance '%s' is already in the cluster" %
|
3981 |
|
new_name)
|
|
4031 |
new_name, errors.ECODE_EXISTS)
|
3982 |
4032 |
|
3983 |
4033 |
if not getattr(self.op, "ignore_ip", False):
|
3984 |
4034 |
if utils.TcpPing(name_info.ip, constants.DEFAULT_NODED_PORT):
|
3985 |
4035 |
raise errors.OpPrereqError("IP %s of instance %s already in use" %
|
3986 |
|
(name_info.ip, new_name))
|
|
4036 |
(name_info.ip, new_name),
|
|
4037 |
errors.ECODE_NOTUNIQUE)
|
3987 |
4038 |
|
3988 |
4039 |
|
3989 |
4040 |
def Exec(self, feedback_fn):
|
... | ... | |
4437 |
4488 |
bep = self.cfg.GetClusterInfo().FillBE(instance)
|
4438 |
4489 |
if instance.disk_template not in constants.DTS_NET_MIRROR:
|
4439 |
4490 |
raise errors.OpPrereqError("Instance's disk layout is not"
|
4440 |
|
" network mirrored, cannot failover.")
|
|
4491 |
" network mirrored, cannot failover.",
|
|
4492 |
errors.ECODE_STATE)
|
4441 |
4493 |
|
4442 |
4494 |
secondary_nodes = instance.secondary_nodes
|
4443 |
4495 |
if not secondary_nodes:
|
... | ... | |
4591 |
4643 |
target_node = self.cfg.ExpandNodeName(self.op.target_node)
|
4592 |
4644 |
if target_node is None:
|
4593 |
4645 |
raise errors.OpPrereqError("Node '%s' not known" %
|
4594 |
|
self.op.target_node)
|
|
4646 |
self.op.target_node, errors.ECODE_NOENT)
|
4595 |
4647 |
self.op.target_node = target_node
|
4596 |
4648 |
self.needed_locks[locking.LEVEL_NODE] = [target_node]
|
4597 |
4649 |
self.recalculate_locks[locking.LEVEL_NODE] = constants.LOCKS_APPEND
|
... | ... | |
4633 |
4685 |
|
4634 |
4686 |
if target_node == instance.primary_node:
|
4635 |
4687 |
raise errors.OpPrereqError("Instance %s is already on the node %s" %
|
4636 |
|
(instance.name, target_node))
|
|
4688 |
(instance.name, target_node),
|
|
4689 |
errors.ECODE_STATE)
|
4637 |
4690 |
|
4638 |
4691 |
bep = self.cfg.GetClusterInfo().FillBE(instance)
|
4639 |
4692 |
|
4640 |
4693 |
for idx, dsk in enumerate(instance.disks):
|
4641 |
4694 |
if dsk.dev_type not in (constants.LD_LV, constants.LD_FILE):
|
4642 |
4695 |
raise errors.OpPrereqError("Instance disk %d has a complex layout,"
|
4643 |
|
" cannot copy")
|
|
4696 |
" cannot copy", errors.ECODE_STATE)
|
4644 |
4697 |
|
4645 |
4698 |
_CheckNodeOnline(self, target_node)
|
4646 |
4699 |
_CheckNodeNotDrained(self, target_node)
|
... | ... | |
4766 |
4819 |
def ExpandNames(self):
|
4767 |
4820 |
self.op.node_name = self.cfg.ExpandNodeName(self.op.node_name)
|
4768 |
4821 |
if self.op.node_name is None:
|
4769 |
|
raise errors.OpPrereqError("Node '%s' not known" % self.op.node_name)
|
|
4822 |
raise errors.OpPrereqError("Node '%s' not known" % self.op.node_name,
|
|
4823 |
errors.ECODE_NOENT)
|
4770 |
4824 |
|
4771 |
4825 |
self.needed_locks = {
|
4772 |
4826 |
locking.LEVEL_NODE: [self.op.node_name],
|
... | ... | |
4830 |
4884 |
self.cfg.ExpandInstanceName(self.instance_name))
|
4831 |
4885 |
if instance is None:
|
4832 |
4886 |
raise errors.OpPrereqError("Instance '%s' not known" %
|
4833 |
|
self.instance_name)
|
|
4887 |
self.instance_name, errors.ECODE_NOENT)
|
4834 |
4888 |
|
4835 |
4889 |
if instance.disk_template != constants.DT_DRBD8:
|
4836 |
4890 |
raise errors.OpPrereqError("Instance's disk layout is not"
|
4837 |
|
" drbd8, cannot migrate.")
|
|
4891 |
" drbd8, cannot migrate.", errors.ECODE_STATE)
|
4838 |
4892 |
|
4839 |
4893 |
secondary_nodes = instance.secondary_nodes
|
4840 |
4894 |
if not secondary_nodes:
|
... | ... | |
5476 |
5530 |
"""
|
5477 |
5531 |
node_full = self.cfg.ExpandNodeName(node)
|
5478 |
5532 |
if node_full is None:
|
5479 |
|
raise errors.OpPrereqError("Unknown node %s" % node)
|
|
5533 |
raise errors.OpPrereqError("Unknown node %s" % node, errors.ECODE_NOENT)
|
5480 |
5534 |
return node_full
|
5481 |
5535 |
|
5482 |
5536 |
def ExpandNames(self):
|
... | ... | |
5498 |
5552 |
if self.op.mode not in (constants.INSTANCE_CREATE,
|
5499 |
5553 |
constants.INSTANCE_IMPORT):
|
5500 |
5554 |
raise errors.OpPrereqError("Invalid instance creation mode '%s'" %
|
5501 |
|
self.op.mode)
|
|
5555 |
self.op.mode, errors.ECODE_INVAL)
|
5502 |
5556 |
|
5503 |
5557 |
# disk template and mirror node verification
|
5504 |
5558 |
if self.op.disk_template not in constants.DISK_TEMPLATES:
|
5505 |
|
raise errors.OpPrereqError("Invalid disk template name")
|
|
5559 |
raise errors.OpPrereqError("Invalid disk template name",
|
|
5560 |
errors.ECODE_INVAL)
|
5506 |
5561 |
|
5507 |
5562 |
if self.op.hypervisor is None:
|
5508 |
5563 |
self.op.hypervisor = self.cfg.GetHypervisorType()
|
... | ... | |
5512 |
5567 |
if self.op.hypervisor not in enabled_hvs:
|
5513 |
5568 |
raise errors.OpPrereqError("Selected hypervisor (%s) not enabled in the"
|
5514 |
5569 |
" cluster (%s)" % (self.op.hypervisor,
|
5515 |
|
",".join(enabled_hvs)))
|
|
5570 |
",".join(enabled_hvs)),
|
|
5571 |
errors.ECODE_STATE)
|
5516 |
5572 |
|
5517 |
5573 |
# check hypervisor parameter syntax (locally)
|
5518 |
5574 |
utils.ForceDictType(self.op.hvparams, constants.HVS_PARAMETER_TYPES)
|
... | ... | |
5537 |
5593 |
# instance in the meantime, and creation will fail at lock-add time
|
5538 |
5594 |
if instance_name in self.cfg.GetInstanceList():
|
5539 |
5595 |
raise errors.OpPrereqError("Instance '%s' is already in the cluster" %
|
5540 |
|
instance_name)
|
|
5596 |
instance_name, errors.ECODE_EXISTS)
|
5541 |
5597 |
|
5542 |
5598 |
self.add_locks[locking.LEVEL_INSTANCE] = instance_name
|
5543 |
5599 |
|
... | ... | |
5564 |
5620 |
else:
|
5565 |
5621 |
if not utils.IsValidIP(ip):
|
5566 |
5622 |
raise errors.OpPrereqError("Given IP address '%s' doesn't look"
|
5567 |
|
" like a valid IP" % ip)
|
|
5623 |
" like a valid IP" % ip,
|
|
5624 |
errors.ECODE_INVAL)
|
5568 |
5625 |
nic_ip = ip
|
5569 |
5626 |
|
5570 |
5627 |
# TODO: check the ip for uniqueness !!
|
5571 |
5628 |
if nic_mode == constants.NIC_MODE_ROUTED and not nic_ip:
|
5572 |
|
raise errors.OpPrereqError("Routed nic mode requires an ip address")
|
|
5629 |
raise errors.OpPrereqError("Routed nic mode requires an ip address",
|
|
5630 |
errors.ECODE_INVAL)
|
5573 |
5631 |
|
5574 |
5632 |
# MAC address verification
|
5575 |
5633 |
mac = nic.get("mac", constants.VALUE_AUTO)
|
5576 |
5634 |
if mac not in (constants.VALUE_AUTO, constants.VALUE_GENERATE):
|
5577 |
5635 |
if not utils.IsValidMac(mac.lower()):
|
5578 |
5636 |
raise errors.OpPrereqError("Invalid MAC address specified: %s" %
|
5579 |
|
mac)
|
|
5637 |
mac, errors.ECODE_INVAL)
|
5580 |
5638 |
else:
|
5581 |
5639 |
# or validate/reserve the current one
|
5582 |
5640 |
if self.cfg.IsMacInUse(mac):
|
5583 |
5641 |
raise errors.OpPrereqError("MAC address %s already in use"
|
5584 |
|
" in cluster" % mac)
|
|
5642 |
" in cluster" % mac,
|
|
5643 |
errors.ECODE_NOTUNIQUE)
|
5585 |
5644 |
|
5586 |
5645 |
# bridge verification
|
5587 |
5646 |
bridge = nic.get("bridge", None)
|
5588 |
5647 |
link = nic.get("link", None)
|
5589 |
5648 |
if bridge and link:
|
5590 |
5649 |
raise errors.OpPrereqError("Cannot pass 'bridge' and 'link'"
|
5591 |
|
" at the same time")
|
|
5650 |
" at the same time", errors.ECODE_INVAL)
|
5592 |
5651 |
elif bridge and nic_mode == constants.NIC_MODE_ROUTED:
|
5593 |
|
raise errors.OpPrereqError("Cannot pass 'bridge' on a routed nic")
|
|
5652 |
raise errors.OpPrereqError("Cannot pass 'bridge' on a routed nic",
|
|
5653 |
errors.ECODE_INVAL)
|
5594 |
5654 |
elif bridge:
|
5595 |
5655 |
link = bridge
|
5596 |
5656 |
|
... | ... | |
5611 |
5671 |
mode = disk.get("mode", constants.DISK_RDWR)
|
5612 |
5672 |
if mode not in constants.DISK_ACCESS_SET:
|
5613 |
5673 |
raise errors.OpPrereqError("Invalid disk access mode '%s'" %
|
5614 |
|
mode)
|
|
5674 |
mode, errors.ECODE_INVAL)
|
5615 |
5675 |
size = disk.get("size", None)
|
5616 |
5676 |
if size is None:
|
5617 |
|
raise errors.OpPrereqError("Missing disk size")
|
|
5677 |
raise errors.OpPrereqError("Missing disk size", errors.ECODE_INVAL)
|
5618 |
5678 |
try:
|
5619 |
5679 |
size = int(size)
|
5620 |
5680 |
except ValueError:
|
5621 |
|
raise errors.OpPrereqError("Invalid disk size '%s'" % size)
|
|
5681 |
raise errors.OpPrereqError("Invalid disk size '%s'" % size,
|
|
5682 |
errors.ECODE_INVAL)
|
5622 |
5683 |
self.disks.append({"size": size, "mode": mode})
|
5623 |
5684 |
|
5624 |
5685 |
# used in CheckPrereq for ip ping check
|
... | ... | |
5628 |
5689 |
if (self.op.file_driver and
|
5629 |
5690 |
not self.op.file_driver in constants.FILE_DRIVER):
|
5630 |
5691 |
raise errors.OpPrereqError("Invalid file driver name '%s'" %
|
5631 |
|
self.op.file_driver)
|
|
5692 |
self.op.file_driver, errors.ECODE_INVAL)
|
5632 |
5693 |
|
5633 |
5694 |
if self.op.file_storage_dir and os.path.isabs(self.op.file_storage_dir):
|
5634 |
|
raise errors.OpPrereqError("File storage directory path not absolute")
|
|
5695 |
raise errors.OpPrereqError("File storage directory path not absolute",
|
|
5696 |
errors.ECODE_INVAL)
|
5635 |
5697 |
|
5636 |
5698 |
### Node/iallocator related checks
|
5637 |
5699 |
if [self.op.iallocator, self.op.pnode].count(None) != 1:
|
5638 |
5700 |
raise errors.OpPrereqError("One and only one of iallocator and primary"
|
5639 |
|
" node must be given")
|
|
5701 |
" node must be given",
|
|
5702 |
errors.ECODE_INVAL)
|
5640 |
5703 |
|
5641 |
5704 |
if self.op.iallocator:
|
5642 |
5705 |
self.needed_locks[locking.LEVEL_NODE] = locking.ALL_SET
|
... | ... | |
5661 |
5724 |
self.op.src_node = None
|
5662 |
5725 |
if os.path.isabs(src_path):
|
5663 |
5726 |
raise errors.OpPrereqError("Importing an instance from an absolute"
|
5664 |
|
" path requires a source node option.")
|
|
5727 |
" path requires a source node option.",
|
|
5728 |
errors.ECODE_INVAL)
|
5665 |
5729 |
else:
|
5666 |
5730 |
self.op.src_node = src_node = self._ExpandNode(src_node)
|
5667 |
5731 |
if self.needed_locks[locking.LEVEL_NODE] is not locking.ALL_SET:
|
... | ... | |
5677 |
5741 |
|
5678 |
5742 |
else: # INSTANCE_CREATE
|
5679 |
5743 |
if getattr(self.op, "os_type", None) is None:
|
5680 |
|
raise errors.OpPrereqError("No guest OS specified")
|
|
5744 |
raise errors.OpPrereqError("No guest OS specified",
|
|
5745 |
errors.ECODE_INVAL)
|
5681 |
5746 |
self.op.force_variant = getattr(self.op, "force_variant", False)
|
5682 |
5747 |
|
5683 |
5748 |
def _RunAllocator(self):
|
... | ... | |
5702 |
5767 |
|
5703 |
5768 |
if not ial.success:
|
5704 |
5769 |
raise errors.OpPrereqError("Can't compute nodes using"
|
5705 |
|
" iallocator '%s': %s" % (self.op.iallocator,
|
5706 |
|
ial.info))
|
|
5770 |
" iallocator '%s': %s" %
|
|
5771 |
(self.op.iallocator, ial.info),
|
|
5772 |
errors.ECODE_NORES)
|
5707 |
5773 |
if len(ial.nodes) != ial.required_nodes:
|
5708 |
5774 |
raise errors.OpPrereqError("iallocator '%s' returned invalid number"
|
5709 |
5775 |
" of nodes (%s), required %s" %
|
5710 |
5776 |
(self.op.iallocator, len(ial.nodes),
|
5711 |
|
ial.required_nodes))
|
|
5777 |
ial.required_nodes), errors.ECODE_FAULT)
|
5712 |
5778 |
self.op.pnode = ial.nodes[0]
|
5713 |
5779 |
self.LogInfo("Selected nodes for instance %s via iallocator %s: %s",
|
5714 |
5780 |
self.op.instance_name, self.op.iallocator,
|
... | ... | |
5758 |
5824 |
if (not self.cfg.GetVGName() and
|
5759 |
5825 |
self.op.disk_template not in constants.DTS_NOT_LVM):
|
5760 |
5826 |
raise errors.OpPrereqError("Cluster does not support lvm-based"
|
5761 |
|
" instances")
|
|
5827 |
" instances", errors.ECODE_STATE)
|
5762 |
5828 |
|
5763 |
5829 |
if self.op.mode == constants.INSTANCE_IMPORT:
|
5764 |
5830 |
src_node = self.op.src_node
|
... | ... | |
5779 |
5845 |
break
|
5780 |
5846 |
if not found:
|
5781 |
5847 |
raise errors.OpPrereqError("No export found for relative path %s" %
|
5782 |
|
src_path)
|
|
5848 |
src_path, errors.ECODE_INVAL)
|
5783 |
5849 |
|
5784 |
5850 |
_CheckNodeOnline(self, src_node)
|
5785 |
5851 |
result = self.rpc.call_export_info(src_node, src_path)
|
... | ... | |
5787 |
5853 |
|
5788 |
5854 |
export_info = objects.SerializableConfigParser.Loads(str(result.payload))
|
5789 |
5855 |
if not export_info.has_section(constants.INISECT_EXP):
|
5790 |
|
raise errors.ProgrammerError("Corrupted export config")
|
|
5856 |
raise errors.ProgrammerError("Corrupted export config",
|
|
5857 |
errors.ECODE_ENVIRON)
|
5791 |
5858 |
|
5792 |
5859 |
ei_version = export_info.get(constants.INISECT_EXP, 'version')
|
5793 |
5860 |
if (int(ei_version) != constants.EXPORT_VERSION):
|
5794 |
5861 |
raise errors.OpPrereqError("Wrong export version %s (wanted %d)" %
|
5795 |
|
(ei_version, constants.EXPORT_VERSION))
|
|
5862 |
(ei_version, constants.EXPORT_VERSION),
|
|
5863 |
errors.ECODE_ENVIRON)
|
5796 |
5864 |
|
5797 |
5865 |
# Check that the new instance doesn't have less disks than the export
|
5798 |
5866 |
instance_disks = len(self.disks)
|
... | ... | |
5800 |
5868 |
if instance_disks < export_disks:
|
5801 |
5869 |
raise errors.OpPrereqError("Not enough disks to import."
|
5802 |
5870 |
" (instance: %d, export: %d)" %
|
5803 |
|
(instance_disks, export_disks))
|
|
5871 |
(instance_disks, export_disks),
|
|
5872 |
errors.ECODE_INVAL)
|
5804 |
5873 |
|
5805 |
5874 |
self.op.os_type = export_info.get(constants.INISECT_EXP, 'os')
|
5806 |
5875 |
disk_images = []
|
... | ... | |
5829 |
5898 |
# ip ping checks (we use the same ip that was resolved in ExpandNames)
|
5830 |
5899 |
if self.op.start and not self.op.ip_check:
|
5831 |
5900 |
raise errors.OpPrereqError("Cannot ignore IP address conflicts when"
|
5832 |
|
" adding an instance in start mode")
|
|
5901 |
" adding an instance in start mode",
|
|
5902 |
errors.ECODE_INVAL)
|
5833 |
5903 |
|
5834 |
5904 |
if self.op.ip_check:
|
5835 |
5905 |
if utils.TcpPing(self.check_ip, constants.DEFAULT_NODED_PORT):
|
5836 |
5906 |
raise errors.OpPrereqError("IP %s of instance %s already in use" %
|
5837 |
|
(self.check_ip, self.op.instance_name))
|
|
5907 |
(self.check_ip, self.op.instance_name),
|
|
5908 |
errors.ECODE_NOTUNIQUE)
|
5838 |
5909 |
|
5839 |
5910 |
#### mac address generation
|
5840 |
5911 |
# By generating here the mac address both the allocator and the hooks get
|
... | ... | |
5861 |
5932 |
"Cannot retrieve locked node %s" % self.op.pnode
|
5862 |
5933 |
if pnode.offline:
|
5863 |
5934 |
raise errors.OpPrereqError("Cannot use offline primary node '%s'" %
|
5864 |
|
pnode.name)
|
|
5935 |
pnode.name, errors.ECODE_STATE)
|
5865 |
5936 |
if pnode.drained:
|
5866 |
5937 |
raise errors.OpPrereqError("Cannot use drained primary node '%s'" %
|
5867 |
|
pnode.name)
|
|
5938 |
pnode.name, errors.ECODE_STATE)
|
5868 |
5939 |
|
5869 |
5940 |
self.secondaries = []
|
5870 |
5941 |
|
... | ... | |
5872 |
5943 |
if self.op.disk_template in constants.DTS_NET_MIRROR:
|
5873 |
5944 |
if self.op.snode is None:
|
5874 |
5945 |
raise errors.OpPrereqError("The networked disk templates need"
|
5875 |
|
" a mirror node")
|
|
5946 |
" a mirror node", errors.ECODE_INVAL)
|
5876 |
5947 |
if self.op.snode == pnode.name:
|
5877 |
|
raise errors.OpPrereqError("The secondary node cannot be"
|
5878 |
|
" the primary node.")
|
|
5948 |
raise errors.OpPrereqError("The secondary node cannot be the"
|
|
5949 |
" primary node.", errors.ECODE_INVAL)
|
5879 |
5950 |
_CheckNodeOnline(self, self.op.snode)
|
5880 |
5951 |
_CheckNodeNotDrained(self, self.op.snode)
|
5881 |
5952 |
self.secondaries.append(self.op.snode)
|
... | ... | |
5896 |
5967 |
vg_free = info.get('vg_free', None)
|
5897 |
5968 |
if not isinstance(vg_free, int):
|
5898 |
5969 |
raise errors.OpPrereqError("Can't compute free disk space on"
|
5899 |
|
" node %s" % node)
|
|
5970 |
" node %s" % node, errors.ECODE_ENVIRON)
|
5900 |
5971 |
if req_size > vg_free:
|
5901 |
5972 |
raise errors.OpPrereqError("Not enough disk space on target node %s."
|
5902 |
5973 |
" %d MB available, %d MB required" %
|
5903 |
|
(node, vg_free, req_size))
|
|
5974 |
(node, vg_free, req_size),
|
|
5975 |
errors.ECODE_NORES)
|
5904 |
5976 |
|
5905 |
5977 |
_CheckHVParams(self, nodenames, self.op.hypervisor, self.op.hvparams)
|
5906 |
5978 |
|
... | ... | |
6135 |
6207 |
remote_node = self.cfg.ExpandNodeName(self.op.remote_node)
|
6136 |
6208 |
if remote_node is None:
|
6137 |
6209 |
raise errors.OpPrereqError("Node '%s' not known" %
|
6138 |
|
self.op.remote_node)
|
|
6210 |
self.op.remote_node, errors.ECODE_NOENT)
|
6139 |
6211 |
|
6140 |
6212 |
self.op.remote_node = remote_node
|
6141 |
6213 |
|
... | ... | |
6207 |
6279 |
def ExpandNames(self):
|
6208 |
6280 |
self.op.node_name = self.cfg.ExpandNodeName(self.op.node_name)
|
6209 |
6281 |
if self.op.node_name is None:
|
6210 |
|
raise errors.OpPrereqError("Node '%s' not known" % self.op.node_name)
|
|
6282 |
raise errors.OpPrereqError("Node '%s' not known" % self.op.node_name,
|
|
6283 |
errors.ECODE_NOENT)
|
6211 |
6284 |
|
6212 |
6285 |
self.needed_locks = {}
|
6213 |
6286 |
|
... | ... | |
6219 |
6292 |
remote_node = self.cfg.ExpandNodeName(self.op.remote_node)
|
6220 |
6293 |
if remote_node is None:
|
6221 |
6294 |
raise errors.OpPrereqError("Node '%s' not known" %
|
6222 |
|
self.op.remote_node)
|
|
6295 |
self.op.remote_node, errors.ECODE_NOENT)
|
6223 |
6296 |
|
6224 |
6297 |
self.op.remote_node = remote_node
|
6225 |
6298 |
|
... | ... | |
6231 |
6304 |
self.recalculate_locks[locking.LEVEL_NODE] = constants.LOCKS_APPEND
|
6232 |
6305 |
|
6233 |
6306 |
else:
|
6234 |
|
raise errors.OpPrereqError("Invalid parameters")
|
|
6307 |
raise errors.OpPrereqError("Invalid parameters", errors.ECODE_INVAL)
|
6235 |
6308 |
|
6236 |
6309 |
# Create tasklets for replacing disks for all secondary instances on this
|
6237 |
6310 |
# node
|
... | ... | |
6316 |
6389 |
if remote_node is None and iallocator is None:
|
6317 |
6390 |
raise errors.OpPrereqError("When changing the secondary either an"
|
6318 |
6391 |
" iallocator script must be used or the"
|
6319 |
|
" new node given")
|
|
6392 |
" new node given", errors.ECODE_INVAL)
|
6320 |
6393 |
|
6321 |
6394 |
if remote_node is not None and iallocator is not None:
|
6322 |
6395 |
raise errors.OpPrereqError("Give either the iallocator or the new"
|
6323 |
|
" secondary, not both")
|
|
6396 |
" secondary, not both", errors.ECODE_INVAL)
|
6324 |
6397 |
|
6325 |
6398 |
elif remote_node is not None or iallocator is not None:
|
6326 |
6399 |
# Not replacing the secondary
|
6327 |
6400 |
raise errors.OpPrereqError("The iallocator and new node options can"
|
6328 |
6401 |
" only be used when changing the"
|
6329 |
|
" secondary node")
|
|
6402 |
" secondary node", errors.ECODE_INVAL)
|
6330 |
6403 |
|
6331 |
6404 |
@staticmethod
|
6332 |
6405 |
def _RunAllocator(lu, iallocator_name, instance_name, relocate_from):
|
... | ... | |
6342 |
6415 |
|
6343 |
6416 |
if not ial.success:
|
6344 |
6417 |
raise errors.OpPrereqError("Can't compute nodes using iallocator '%s':"
|
6345 |
|
" %s" % (iallocator_name, ial.info))
|
|
6418 |
" %s" % (iallocator_name, ial.info),
|
|
6419 |
errors.ECODE_NORES)
|
6346 |
6420 |
|
6347 |
6421 |
if len(ial.nodes) != ial.required_nodes:
|
6348 |
6422 |
raise errors.OpPrereqError("iallocator '%s' returned invalid number"
|
6349 |
6423 |
" of nodes (%s), required %s" %
|
6350 |
|
(len(ial.nodes), ial.required_nodes))
|
|
6424 |
(len(ial.nodes), ial.required_nodes),
|
|
6425 |
errors.ECODE_FAULT)
|
6351 |
6426 |
|
6352 |
6427 |
remote_node_name = ial.nodes[0]
|
6353 |
6428 |
|
... | ... | |
6372 |
6447 |
|
6373 |
6448 |
if instance.disk_template != constants.DT_DRBD8:
|
6374 |
6449 |
raise errors.OpPrereqError("Can only run replace disks for DRBD8-based"
|
6375 |
|
" instances")
|
|
6450 |
" instances", errors.ECODE_INVAL)
|
6376 |
6451 |
|
6377 |
6452 |
if len(instance.secondary_nodes) != 1:
|
6378 |
6453 |
raise errors.OpPrereqError("The instance has a strange layout,"
|
6379 |
6454 |
" expected one secondary but found %d" %
|
6380 |
|
len(instance.secondary_nodes))
|
|
6455 |
len(instance.secondary_nodes),
|
|
6456 |
errors.ECODE_FAULT)
|
6381 |
6457 |
|
6382 |
6458 |
secondary_node = instance.secondary_nodes[0]
|
6383 |
6459 |
|
... | ... | |
6396 |
6472 |
|
6397 |
6473 |
if remote_node == self.instance.primary_node:
|
6398 |
6474 |
raise errors.OpPrereqError("The specified node is the primary node of"
|
6399 |
|
" the instance.")
|
|
6475 |
" the instance.", errors.ECODE_INVAL)
|
6400 |
6476 |
|
6401 |
6477 |
if remote_node == secondary_node:
|
6402 |
6478 |
raise errors.OpPrereqError("The specified node is already the"
|
6403 |
|
" secondary node of the instance.")
|
|
6479 |
" secondary node of the instance.",
|
|
6480 |
errors.ECODE_INVAL)
|
6404 |
6481 |
|
6405 |
6482 |
if self.disks and self.mode in (constants.REPLACE_DISK_AUTO,
|
6406 |
6483 |
constants.REPLACE_DISK_CHG):
|
6407 |
|
raise errors.OpPrereqError("Cannot specify disks to be replaced")
|
|
6484 |
raise errors.OpPrereqError("Cannot specify disks to be replaced",
|
|
6485 |
errors.ECODE_INVAL)
|
6408 |
6486 |
|
6409 |
6487 |
if self.mode == constants.REPLACE_DISK_AUTO:
|
6410 |
6488 |
faulty_primary = self._FindFaultyDisks(instance.primary_node)
|
... | ... | |
6413 |
6491 |
if faulty_primary and faulty_secondary:
|
6414 |
6492 |
raise errors.OpPrereqError("Instance %s has faulty disks on more than"
|
6415 |
6493 |
" one node and can not be repaired"
|
6416 |
|
" automatically" % self.instance_name)
|
|
6494 |
" automatically" % self.instance_name,
|
|
6495 |
errors.ECODE_STATE)
|
6417 |
6496 |
|
6418 |
6497 |
if faulty_primary:
|
6419 |
6498 |
self.disks = faulty_primary
|
... | ... | |
6502 |
6581 |
return fn(feedback_fn)
|
6503 |
6582 |
|
6504 |
6583 |
finally:
|
6505 |
|
# Deactivate the instance disks if we're replacing them on a down instance
|
|
6584 |
# Deactivate the instance disks if we're replacing them on a
|
|
6585 |
# down instance
|
6506 |
6586 |
if activate_disks:
|
6507 |
6587 |
_SafeShutdownInstanceDisks(self.lu, self.instance)
|
6508 |
6588 |
|
... | ... | |
6894 |
6974 |
def CheckArguments(self):
|
6895 |
6975 |
node_name = self.cfg.ExpandNodeName(self.op.node_name)
|
6896 |
6976 |
if node_name is None:
|
6897 |
|
raise errors.OpPrereqError("Invalid node name '%s'" % self.op.node_name)
|
|
6977 |
raise errors.OpPrereqError("Invalid node name '%s'" % self.op.node_name,
|
|
6978 |
errors.ECODE_NOENT)
|
6898 |
6979 |
|
6899 |
6980 |
self.op.node_name = node_name
|
6900 |
6981 |
|
... | ... | |
6907 |
6988 |
if _FindFaultyInstanceDisks(self.cfg, self.rpc, instance,
|
6908 |
6989 |
node_name, True):
|
6909 |
6990 |
raise errors.OpPrereqError("Instance '%s' has faulty disks on"
|
6910 |
|
" node '%s'" % (instance.name, node_name))
|
|
6991 |
" node '%s'" % (instance.name, node_name),
|
|
6992 |
errors.ECODE_STATE)
|
6911 |
6993 |
|
6912 |
6994 |
def CheckPrereq(self):
|
6913 |
6995 |
"""Check prerequisites.
|
... | ... | |
6918 |
7000 |
if (constants.SO_FIX_CONSISTENCY not in
|
6919 |
7001 |
constants.VALID_STORAGE_OPERATIONS.get(storage_type, [])):
|
6920 |
7002 |
raise errors.OpPrereqError("Storage units of type '%s' can not be"
|
6921 |
|
" repaired" % storage_type)
|
|
7003 |
" repaired" % storage_type,
|
|
7004 |
errors.ECODE_INVAL)
|
6922 |
7005 |
|
6923 |
7006 |
# Check whether any instance on this node has faulty disks
|
6924 |
7007 |
for inst in _GetNodeInstances(self.cfg, self.op.node_name):
|
... | ... | |
6993 |
7076 |
|
6994 |
7077 |
if instance.disk_template not in (constants.DT_PLAIN, constants.DT_DRBD8):
|
6995 |
7078 |
raise errors.OpPrereqError("Instance's disk layout does not support"
|
6996 |
|
" growing.")
|
|
7079 |
" growing.", errors.ECODE_INVAL)
|
6997 |
7080 |
|
6998 |
7081 |
self.disk = instance.FindDisk(self.op.disk)
|
6999 |
7082 |
|
... | ... | |
7005 |
7088 |
vg_free = info.payload.get('vg_free', None)
|
7006 |
7089 |
if not isinstance(vg_free, int):
|
7007 |
7090 |
raise errors.OpPrereqError("Can't compute free disk space on"
|
7008 |
|
" node %s" % node)
|
|
7091 |
" node %s" % node, errors.ECODE_ENVIRON)
|
7009 |
7092 |
if self.op.amount > vg_free:
|
7010 |
7093 |
raise errors.OpPrereqError("Not enough disk space on target node %s:"
|
7011 |
7094 |
" %d MiB available, %d MiB required" %
|
7012 |
|
(node, vg_free, self.op.amount))
|
|
7095 |
(node, vg_free, self.op.amount),
|
|
7096 |
errors.ECODE_NORES)
|
7013 |
7097 |
|
7014 |
7098 |
def Exec(self, feedback_fn):
|
7015 |
7099 |
"""Execute disk grow.
|
... | ... | |
7042 |
7126 |
self.share_locks = dict.fromkeys(locking.LEVELS, 1)
|
7043 |
7127 |
|
7044 |
7128 |
if not isinstance(self.op.instances, list):
|
7045 |
|
raise errors.OpPrereqError("Invalid argument type 'instances'")
|
|
7129 |
raise errors.OpPrereqError("Invalid argument type 'instances'",
|
|
7130 |
errors.ECODE_INVAL)
|
7046 |
7131 |
|
7047 |
7132 |
if self.op.instances:
|
7048 |
7133 |
self.wanted_names = []
|
7049 |
7134 |
for name in self.op.instances:
|
7050 |
7135 |
full_name = self.cfg.ExpandInstanceName(name)
|
7051 |
7136 |
if full_name is None:
|
7052 |
|
raise errors.OpPrereqError("Instance '%s' not known" % name)
|
|
7137 |
raise errors.OpPrereqError("Instance '%s' not known" % name,
|
|
7138 |
errors.ECODE_NOENT)
|
7053 |
7139 |
self.wanted_names.append(full_name)
|
7054 |
7140 |
self.needed_locks[locking.LEVEL_INSTANCE] = self.wanted_names
|
7055 |
7141 |
else:
|
... | ... | |
7209 |
7295 |
self.op.force = getattr(self.op, "force", False)
|
7210 |
7296 |
if not (self.op.nics or self.op.disks or
|
7211 |
7297 |
self.op.hvparams or self.op.beparams):
|
7212 |
|
raise errors.OpPrereqError("No changes submitted")
|
|
7298 |
raise errors.OpPrereqError("No changes submitted", errors.ECODE_INVAL)
|
7213 |
7299 |
|
7214 |
7300 |
# Disk validation
|
7215 |
7301 |
disk_addremove = 0
|
... | ... | |
7221 |
7307 |
disk_addremove += 1
|
7222 |
7308 |
else:
|
7223 |
7309 |
if not isinstance(disk_op, int):
|
7224 |
|
raise errors.OpPrereqError("Invalid disk index")
|
|
7310 |
raise errors.OpPrereqError("Invalid disk index", errors.ECODE_INVAL)
|
7225 |
7311 |
if not isinstance(disk_dict, dict):
|
7226 |
7312 |
msg = "Invalid disk value: expected dict, got '%s'" % disk_dict
|
7227 |
|
raise errors.OpPrereqError(msg)
|
|
7313 |
raise errors.OpPrereqError(msg, errors.ECODE_INVAL)
|
7228 |
7314 |
|
7229 |
7315 |
if disk_op == constants.DDM_ADD:
|
7230 |
7316 |
mode = disk_dict.setdefault('mode', constants.DISK_RDWR)
|
7231 |
7317 |
if mode not in constants.DISK_ACCESS_SET:
|
7232 |
|
raise errors.OpPrereqError("Invalid disk access mode '%s'" % mode)
|
|
7318 |
raise errors.OpPrereqError("Invalid disk access mode '%s'" % mode,
|
|
7319 |
errors.ECODE_INVAL)
|
7233 |
7320 |
size = disk_dict.get('size', None)
|
7234 |
7321 |
if size is None:
|
7235 |
|
raise errors.OpPrereqError("Required disk parameter size missing")
|
|
7322 |
raise errors.OpPrereqError("Required disk parameter size missing",
|
|
7323 |
errors.ECODE_INVAL)
|
7236 |
7324 |
try:
|
7237 |
7325 |
size = int(size)
|
7238 |
7326 |
except ValueError, err:
|
7239 |
7327 |
raise errors.OpPrereqError("Invalid disk size parameter: %s" %
|
7240 |
|
str(err))
|
|
7328 |
str(err), errors.ECODE_INVAL)
|
7241 |
7329 |
disk_dict['size'] = size
|
7242 |
7330 |
else:
|
7243 |
7331 |
# modification of disk
|
7244 |
7332 |
if 'size' in disk_dict:
|
7245 |
7333 |
raise errors.OpPrereqError("Disk size change not possible, use"
|
7246 |
|
" grow-disk")
|
|
7334 |
" grow-disk", errors.ECODE_INVAL)
|
7247 |
7335 |
|
7248 |
7336 |
if disk_addremove > 1:
|
7249 |
7337 |
raise errors.OpPrereqError("Only one disk add or remove operation"
|
7250 |
|
" supported at a time")
|
|
7338 |
" supported at a time", errors.ECODE_INVAL)
|
7251 |
7339 |
|
7252 |
7340 |
# NIC validation
|
7253 |
7341 |
nic_addremove = 0
|
... | ... | |
7259 |
7347 |
nic_addremove += 1
|
7260 |
7348 |
else:
|
7261 |
7349 |
if not isinstance(nic_op, int):
|
7262 |
|
raise errors.OpPrereqError("Invalid nic index")
|
|
7350 |
raise errors.OpPrereqError("Invalid nic index", errors.ECODE_INVAL)
|
7263 |
7351 |
if not isinstance(nic_dict, dict):
|
7264 |
7352 |
msg = "Invalid nic value: expected dict, got '%s'" % nic_dict
|
7265 |
|
raise errors.OpPrereqError(msg)
|
|
7353 |
raise errors.OpPrereqError(msg, errors.ECODE_INVAL)
|
7266 |
7354 |
|
7267 |
7355 |
# nic_dict should be a dict
|
7268 |
7356 |
nic_ip = nic_dict.get('ip', None)
|
... | ... | |
7271 |
7359 |
nic_dict['ip'] = None
|
7272 |
7360 |
else:
|
7273 |
7361 |
if not utils.IsValidIP(nic_ip):
|
7274 |
|
raise errors.OpPrereqError("Invalid IP address '%s'" % nic_ip)
|
|
7362 |
raise errors.OpPrereqError("Invalid IP address '%s'" % nic_ip,
|
|
7363 |
errors.ECODE_INVAL)
|
7275 |
7364 |
|
7276 |
7365 |
nic_bridge = nic_dict.get('bridge', None)
|
7277 |
7366 |
nic_link = nic_dict.get('link', None)
|
7278 |
7367 |
if nic_bridge and nic_link:
|
7279 |
7368 |
raise errors.OpPrereqError("Cannot pass 'bridge' and 'link'"
|
7280 |
|
" at the same time")
|
|
7369 |
" at the same time", errors.ECODE_INVAL)
|
7281 |
7370 |
elif nic_bridge and nic_bridge.lower() == constants.VALUE_NONE:
|
7282 |
7371 |
nic_dict['bridge'] = None
|
7283 |
7372 |
elif nic_link and nic_link.lower() == constants.VALUE_NONE:
|
... | ... | |
7292 |
7381 |
nic_mac = nic_dict['mac']
|
7293 |
7382 |
if nic_mac not in (constants.VALUE_AUTO, constants.VALUE_GENERATE):
|
7294 |
7383 |
if not utils.IsValidMac(nic_mac):
|
7295 |
|
raise errors.OpPrereqError("Invalid MAC address %s" % nic_mac)
|
|
7384 |
raise errors.OpPrereqError("Invalid MAC address %s" % nic_mac,
|
|
7385 |
errors.ECODE_INVAL)
|
7296 |
7386 |
if nic_op != constants.DDM_ADD and nic_mac == constants.VALUE_AUTO:
|
7297 |
7387 |
raise errors.OpPrereqError("'auto' is not a valid MAC address when"
|
7298 |
|
" modifying an existing nic")
|
|
7388 |
" modifying an existing nic",
|
|
7389 |
errors.ECODE_INVAL)
|
7299 |
7390 |
|
7300 |
7391 |
if nic_addremove > 1:
|
7301 |
7392 |
raise errors.OpPrereqError("Only one NIC add or remove operation"
|
7302 |
|
" supported at a time")
|
|
7393 |
" supported at a time", errors.ECODE_INVAL)
|
7303 |
7394 |
|
7304 |
7395 |
def ExpandNames(self):
|
7305 |
7396 |
self._ExpandAndLockInstance()
|
... | ... | |
7472 |
7563 |
if miss_mem > 0:
|
7473 |
7564 |
raise errors.OpPrereqError("This change will prevent the instance"
|
7474 |
7565 |
" from starting, due to %d MB of memory"
|
7475 |
|
" missing on its primary node" % miss_mem)
|
|
7566 |
" missing on its primary node" % miss_mem,
|
|
7567 |
errors.ECODE_NORES)
|
7476 |
7568 |
|
7477 |
7569 |
if be_new[constants.BE_AUTO_BALANCE]:
|
7478 |
7570 |
for node, nres in nodeinfo.items():
|
... | ... | |
7495 |
7587 |
for nic_op, nic_dict in self.op.nics:
|
7496 |
7588 |
if nic_op == constants.DDM_REMOVE:
|
7497 |
7589 |
if not instance.nics:
|
7498 |
|
raise errors.OpPrereqError("Instance has no NICs, cannot remove")
|
|
7590 |
raise errors.OpPrereqError("Instance has no NICs, cannot remove",
|
|
7591 |
errors.ECODE_INVAL)
|
7499 |
7592 |
continue
|
7500 |
7593 |
if nic_op != constants.DDM_ADD:
|
7501 |
7594 |
# an existing nic
|
7502 |
7595 |
if nic_op < 0 or nic_op >= len(instance.nics):
|
7503 |
7596 |
raise errors.OpPrereqError("Invalid NIC index %s, valid values"
|
7504 |
7597 |
" are 0 to %d" %
|
7505 |
|
(nic_op, len(instance.nics)))
|
|
7598 |
(nic_op, len(instance.nics)),
|
|
7599 |
errors.ECODE_INVAL)
|
7506 |
7600 |
old_nic_params = instance.nics[nic_op].nicparams
|
7507 |
7601 |
old_nic_ip = instance.nics[nic_op].ip
|
7508 |
7602 |
else:
|
... | ... | |
7533 |
7627 |
if self.force:
|
7534 |
7628 |
self.warn.append(msg)
|
7535 |
7629 |
else:
|
7536 |
|
raise errors.OpPrereqError(msg)
|
|
7630 |
raise errors.OpPrereqError(msg, errors.ECODE_ENVIRON)
|
7537 |
7631 |
if new_nic_mode == constants.NIC_MODE_ROUTED:
|
7538 |
7632 |
if 'ip' in nic_dict:
|
7539 |
7633 |
nic_ip = nic_dict['ip']
|
... | ... | |
7541 |
7635 |
nic_ip = old_nic_ip
|
7542 |
7636 |
if nic_ip is None:
|
7543 |
7637 |
raise errors.OpPrereqError('Cannot set the nic ip to None'
|
7544 |
|
' on a routed nic')
|
|
7638 |
' on a routed nic', errors.ECODE_INVAL)
|
7545 |
7639 |
if 'mac' in nic_dict:
|
7546 |
7640 |
nic_mac = nic_dict['mac']
|
7547 |
7641 |
if nic_mac is None:
|
7548 |
|
raise errors.OpPrereqError('Cannot set the nic mac to None')
|
|
7642 |
raise errors.OpPrereqError('Cannot set the nic mac to None',
|
|
7643 |
errors.ECODE_INVAL)
|
7549 |
7644 |
elif nic_mac in (constants.VALUE_AUTO, constants.VALUE_GENERATE):
|
7550 |
7645 |
# otherwise generate the mac
|
7551 |
7646 |
nic_dict['mac'] = self.cfg.GenerateMAC()
|
... | ... | |
7553 |
7648 |
# or validate/reserve the current one
|
7554 |
7649 |
if self.cfg.IsMacInUse(nic_mac):
|
7555 |
7650 |
raise errors.OpPrereqError("MAC address %s already in use"
|
7556 |
|
" in cluster" % nic_mac)
|
|
7651 |
" in cluster" % nic_mac,
|
|
7652 |
errors.ECODE_NOTUNIQUE)
|
7557 |
7653 |
|
7558 |
7654 |
# DISK processing
|
7559 |
7655 |
if self.op.disks and instance.disk_template == constants.DT_DISKLESS:
|
7560 |
7656 |
raise errors.OpPrereqError("Disk operations not supported for"
|
7561 |
|
" diskless instances")
|
|
7657 |
" diskless instances",
|
|
7658 |
errors.ECODE_INVAL)
|
7562 |
7659 |
for disk_op, disk_dict in self.op.disks:
|
7563 |
7660 |
if disk_op == constants.DDM_REMOVE:
|
7564 |
7661 |
if len(instance.disks) == 1:
|
7565 |
7662 |
raise errors.OpPrereqError("Cannot remove the last disk of"
|
7566 |
|
" an instance")
|
|
7663 |
" an instance",
|
|
7664 |
errors.ECODE_INVAL)
|
7567 |
7665 |
ins_l = self.rpc.call_instance_list([pnode], [instance.hypervisor])
|
7568 |
7666 |
ins_l = ins_l[pnode]
|
7569 |
7667 |
msg = ins_l.fail_msg
|
7570 |
7668 |
if msg:
|
7571 |
7669 |
raise errors.OpPrereqError("Can't contact node %s: %s" %
|
7572 |
|
(pnode, msg))
|
|
7670 |
(pnode, msg), errors.ECODE_ENVIRON)
|
7573 |
7671 |
if instance.name in ins_l.payload:
|
7574 |
7672 |
raise errors.OpPrereqError("Instance is running, can't remove"
|
7575 |
|
" disks.")
|
|
7673 |
" disks.", errors.ECODE_STATE)
|
7576 |
7674 |
|
7577 |
7675 |
if (disk_op == constants.DDM_ADD and
|
7578 |
7676 |
len(instance.nics) >= constants.MAX_DISKS):
|
7579 |
7677 |
raise errors.OpPrereqError("Instance has too many disks (%d), cannot"
|
7580 |
|
" add more" % constants.MAX_DISKS)
|
|
7678 |
" add more" % constants.MAX_DISKS,
|
|
7679 |
errors.ECODE_STATE)
|
7581 |
7680 |
if disk_op not in (constants.DDM_ADD, constants.DDM_REMOVE):
|
7582 |
7681 |
# an existing disk
|
7583 |
7682 |
if disk_op < 0 or disk_op >= len(instance.disks):
|
7584 |
7683 |
raise errors.OpPrereqError("Invalid disk index %s, valid values"
|
7585 |
7684 |
" are 0 to %d" %
|
7586 |
|
(disk_op, len(instance.disks)))
|
|
7685 |
(disk_op, len(instance.disks)),
|
|
7686 |
errors.ECODE_INVAL)
|
7587 |
7687 |
|
7588 |
7688 |
return
|
7589 |
7689 |
|
... | ... | |
7804 |
7904 |
|
7805 |
7905 |
if self.dst_node is None:
|
7806 |
7906 |
# This is wrong node name, not a non-locked node
|
7807 |
|
raise errors.OpPrereqError("Wrong node name %s" % self.op.target_node)
|
|
7907 |
raise errors.OpPrereqError("Wrong node name %s" % self.op.target_node,
|
|
7908 |
errors.ECODE_NOENT)
|
7808 |
7909 |
_CheckNodeOnline(self, self.dst_node.name)
|
7809 |
7910 |
_CheckNodeNotDrained(self, self.dst_node.name)
|
7810 |
7911 |
|
... | ... | |
7812 |
7913 |
for disk in self.instance.disks:
|
7813 |
7914 |
if disk.dev_type == constants.LD_FILE:
|
7814 |
7915 |
raise errors.OpPrereqError("Export not supported for instances with"
|
7815 |
|
" file-based disks")
|
|
7916 |
" file-based disks", errors.ECODE_INVAL)
|
7816 |
7917 |
|
7817 |
7918 |
def Exec(self, feedback_fn):
|
7818 |
7919 |
"""Export an instance to an image in the cluster.
|
... | ... | |
8003 |
8104 |
name = self.cfg.ExpandNodeName(self.op.name)
|
8004 |
8105 |
if name is None:
|
8005 |
8106 |
raise errors.OpPrereqError("Invalid node name (%s)" %
|
8006 |
|
(self.op.name,))
|
|
8107 |
(self.op.name,), errors.ECODE_NOENT)
|
8007 |
8108 |
self.op.name = name
|
8008 |
8109 |
self.needed_locks[locking.LEVEL_NODE] = name
|
8009 |
8110 |
elif self.op.kind == constants.TAG_INSTANCE:
|
8010 |
8111 |
name = self.cfg.ExpandInstanceName(self.op.name)
|
8011 |
8112 |
if name is None:
|
8012 |
8113 |
raise errors.OpPrereqError("Invalid instance name (%s)" %
|
8013 |
|
(self.op.name,))
|
|
8114 |
(self.op.name,), errors.ECODE_NOENT)
|
8014 |
8115 |
self.op.name = name
|
8015 |
8116 |
self.needed_locks[locking.LEVEL_INSTANCE] = name
|
8016 |
8117 |
|
... | ... | |
8026 |
8127 |
self.target = self.cfg.GetInstanceInfo(self.op.name)
|
8027 |
8128 |
else:
|
8028 |
8129 |
raise errors.OpPrereqError("Wrong tag type requested (%s)" %
|
8029 |
|
str(self.op.kind))
|
|
8130 |
str(self.op.kind), errors.ECODE_INVAL)
|
8030 |
8131 |
|
8031 |
8132 |
|
8032 |
8133 |
class LUGetTags(TagsLU):
|
... | ... | |
8063 |
8164 |
self.re = re.compile(self.op.pattern)
|
8064 |
8165 |
except re.error, err:
|
8065 |
8166 |
raise errors.OpPrereqError("Invalid search pattern '%s': %s" %
|
8066 |
|
(self.op.pattern, err))
|
|
8167 |
(self.op.pattern, err), errors.ECODE_INVAL)
|
8067 |
8168 |
|
8068 |
8169 |
def Exec(self, feedback_fn):
|
8069 |
8170 |
"""Returns the tag list.
|
... | ... | |
8135 |
8236 |
diff_names = ["'%s'" % tag for tag in diff_tags]
|
8136 |
8237 |
diff_names.sort()
|
8137 |
8238 |
raise errors.OpPrereqError("Tag(s) %s not found" %
|
8138 |
|
(",".join(diff_names)))
|
|
8239 |
(",".join(diff_names)), errors.ECODE_NOENT)
|
8139 |
8240 |
|
8140 |
8241 |
def Exec(self, feedback_fn):
|
8141 |
8242 |
"""Remove the tag from the object.
|
... | ... | |
8419 |
8520 |
" IAllocator" % self.name)
|
8420 |
8521 |
|
8421 |
8522 |
if instance.disk_template not in constants.DTS_NET_MIRROR:
|
8422 |
|
raise errors.OpPrereqError("Can't relocate non-mirrored instances")
|
|
8523 |
raise errors.OpPrereqError("Can't relocate non-mirrored instances",
|
|
8524 |
errors.ECODE_INVAL)
|
8423 |
8525 |
|
8424 |
8526 |
if len(instance.secondary_nodes) != 1:
|
8425 |
|
raise errors.OpPrereqError("Instance has not exactly one secondary node")
|
|
8527 |
raise errors.OpPrereqError("Instance has not exactly one secondary node",
|
|
8528 |
errors.ECODE_STATE)
|
8426 |
8529 |
|
8427 |
8530 |
self.required_nodes = 1
|
8428 |
8531 |
disk_sizes = [{'size': disk.size} for disk in instance.disks]
|
... | ... | |
8510 |
8613 |
"os", "tags", "nics", "vcpus"]:
|
8511 |
8614 |
if not hasattr(self.op, attr):
|
8512 |
8615 |
raise errors.OpPrereqError("Missing attribute '%s' on opcode input" %
|
8513 |
|
attr)
|
|
8616 |
attr, errors.ECODE_INVAL)
|
8514 |
8617 |
iname = self.cfg.ExpandInstanceName(self.op.name)
|
8515 |
8618 |
if iname is not None:
|
8516 |
8619 |
raise errors.OpPrereqError("Instance '%s' already in the cluster" %
|
8517 |
|
iname)
|
|
8620 |
iname, errors.ECODE_EXISTS)
|
8518 |
8621 |
if not isinstance(self.op.nics, list):
|
8519 |
|
raise errors.OpPrereqError("Invalid parameter 'nics'")
|
|
8622 |
raise errors.OpPrereqError("Invalid parameter 'nics'",
|
|
8623 |
errors.ECODE_INVAL)
|
8520 |
8624 |
for row in self.op.nics:
|
8521 |
8625 |
if (not isinstance(row, dict) or
|
8522 |
8626 |
"mac" not in row or
|
8523 |
8627 |
"ip" not in row or
|
8524 |
8628 |
"bridge" not in row):
|
8525 |
|
raise errors.OpPrereqError("Invalid contents of the"
|
8526 |
|
" 'nics' parameter")
|
|
8629 |
raise errors.OpPrereqError("Invalid contents of the 'nics'"
|
|
8630 |
" parameter", errors.ECODE_INVAL)
|
8527 |
8631 |
if not isinstance(self.op.disks, list):
|
8528 |
|
raise errors.OpPrereqError("Invalid parameter 'disks'")
|
|
8632 |
raise errors.OpPrereqError("Invalid parameter 'disks'",
|
|
8633 |
errors.ECODE_INVAL)
|
8529 |
8634 |
for row in self.op.disks:
|
8530 |
8635 |
if (not isinstance(row, dict) or
|
8531 |
8636 |
"size" not in row or
|
8532 |
8637 |
not isinstance(row["size"], int) or
|
8533 |
8638 |
"mode" not in row or
|
8534 |
8639 |
row["mode"] not in ['r', 'w']):
|
8535 |
|
raise errors.OpPrereqError("Invalid contents of the"
|
8536 |
|
" 'disks' parameter")
|