Revision 31b836b8 lib/cmdlib/common.py
b/lib/cmdlib/common.py | ||
---|---|---|
37 | 37 |
from ganeti import utils |
38 | 38 |
|
39 | 39 |
|
40 |
# States of instance |
|
41 |
INSTANCE_DOWN = [constants.ADMINST_DOWN] |
|
42 |
INSTANCE_ONLINE = [constants.ADMINST_DOWN, constants.ADMINST_UP] |
|
43 |
INSTANCE_NOT_RUNNING = [constants.ADMINST_DOWN, constants.ADMINST_OFFLINE] |
|
44 |
|
|
45 |
#: Instance status in which an instance can be marked as offline/online |
|
46 |
CAN_CHANGE_INSTANCE_OFFLINE = (frozenset(INSTANCE_DOWN) | frozenset([ |
|
47 |
constants.ADMINST_OFFLINE, |
|
48 |
])) |
|
49 |
|
|
50 |
|
|
40 | 51 |
def _ExpandItemName(fn, name, kind): |
41 | 52 |
"""Expand an item name. |
42 | 53 |
|
... | ... | |
873 | 884 |
for inst in instances |
874 | 885 |
for (node, vols) in inst.MapLVsByNode().items() |
875 | 886 |
for vol in vols) |
887 |
|
|
888 |
|
|
889 |
def _CheckParamsNotGlobal(params, glob_pars, kind, bad_levels, good_levels): |
|
890 |
"""Make sure that none of the given paramters is global. |
|
891 |
|
|
892 |
If a global parameter is found, an L{errors.OpPrereqError} exception is |
|
893 |
raised. This is used to avoid setting global parameters for individual nodes. |
|
894 |
|
|
895 |
@type params: dictionary |
|
896 |
@param params: Parameters to check |
|
897 |
@type glob_pars: dictionary |
|
898 |
@param glob_pars: Forbidden parameters |
|
899 |
@type kind: string |
|
900 |
@param kind: Kind of parameters (e.g. "node") |
|
901 |
@type bad_levels: string |
|
902 |
@param bad_levels: Level(s) at which the parameters are forbidden (e.g. |
|
903 |
"instance") |
|
904 |
@type good_levels: strings |
|
905 |
@param good_levels: Level(s) at which the parameters are allowed (e.g. |
|
906 |
"cluster or group") |
|
907 |
|
|
908 |
""" |
|
909 |
used_globals = glob_pars.intersection(params) |
|
910 |
if used_globals: |
|
911 |
msg = ("The following %s parameters are global and cannot" |
|
912 |
" be customized at %s level, please modify them at" |
|
913 |
" %s level: %s" % |
|
914 |
(kind, bad_levels, good_levels, utils.CommaJoin(used_globals))) |
|
915 |
raise errors.OpPrereqError(msg, errors.ECODE_INVAL) |
|
916 |
|
|
917 |
|
|
918 |
def _IsExclusiveStorageEnabledNode(cfg, node): |
|
919 |
"""Whether exclusive_storage is in effect for the given node. |
|
920 |
|
|
921 |
@type cfg: L{config.ConfigWriter} |
|
922 |
@param cfg: The cluster configuration |
|
923 |
@type node: L{objects.Node} |
|
924 |
@param node: The node |
|
925 |
@rtype: bool |
|
926 |
@return: The effective value of exclusive_storage |
|
927 |
|
|
928 |
""" |
|
929 |
return cfg.GetNdParams(node)[constants.ND_EXCLUSIVE_STORAGE] |
|
930 |
|
|
931 |
|
|
932 |
def _CheckInstanceState(lu, instance, req_states, msg=None): |
|
933 |
"""Ensure that an instance is in one of the required states. |
|
934 |
|
|
935 |
@param lu: the LU on behalf of which we make the check |
|
936 |
@param instance: the instance to check |
|
937 |
@param msg: if passed, should be a message to replace the default one |
|
938 |
@raise errors.OpPrereqError: if the instance is not in the required state |
|
939 |
|
|
940 |
""" |
|
941 |
if msg is None: |
|
942 |
msg = ("can't use instance from outside %s states" % |
|
943 |
utils.CommaJoin(req_states)) |
|
944 |
if instance.admin_state not in req_states: |
|
945 |
raise errors.OpPrereqError("Instance '%s' is marked to be %s, %s" % |
|
946 |
(instance.name, instance.admin_state, msg), |
|
947 |
errors.ECODE_STATE) |
|
948 |
|
|
949 |
if constants.ADMINST_UP not in req_states: |
|
950 |
pnode = instance.primary_node |
|
951 |
if not lu.cfg.GetNodeInfo(pnode).offline: |
|
952 |
ins_l = lu.rpc.call_instance_list([pnode], [instance.hypervisor])[pnode] |
|
953 |
ins_l.Raise("Can't contact node %s for instance information" % pnode, |
|
954 |
prereq=True, ecode=errors.ECODE_ENVIRON) |
|
955 |
if instance.name in ins_l.payload: |
|
956 |
raise errors.OpPrereqError("Instance %s is running, %s" % |
|
957 |
(instance.name, msg), errors.ECODE_STATE) |
|
958 |
else: |
|
959 |
lu.LogWarning("Primary node offline, ignoring check that instance" |
|
960 |
" is down") |
|
961 |
|
|
962 |
|
|
963 |
def _CheckIAllocatorOrNode(lu, iallocator_slot, node_slot): |
|
964 |
"""Check the sanity of iallocator and node arguments and use the |
|
965 |
cluster-wide iallocator if appropriate. |
|
966 |
|
|
967 |
Check that at most one of (iallocator, node) is specified. If none is |
|
968 |
specified, or the iallocator is L{constants.DEFAULT_IALLOCATOR_SHORTCUT}, |
|
969 |
then the LU's opcode's iallocator slot is filled with the cluster-wide |
|
970 |
default iallocator. |
|
971 |
|
|
972 |
@type iallocator_slot: string |
|
973 |
@param iallocator_slot: the name of the opcode iallocator slot |
|
974 |
@type node_slot: string |
|
975 |
@param node_slot: the name of the opcode target node slot |
|
976 |
|
|
977 |
""" |
|
978 |
node = getattr(lu.op, node_slot, None) |
|
979 |
ialloc = getattr(lu.op, iallocator_slot, None) |
|
980 |
if node == []: |
|
981 |
node = None |
|
982 |
|
|
983 |
if node is not None and ialloc is not None: |
|
984 |
raise errors.OpPrereqError("Do not specify both, iallocator and node", |
|
985 |
errors.ECODE_INVAL) |
|
986 |
elif ((node is None and ialloc is None) or |
|
987 |
ialloc == constants.DEFAULT_IALLOCATOR_SHORTCUT): |
|
988 |
default_iallocator = lu.cfg.GetDefaultIAllocator() |
|
989 |
if default_iallocator: |
|
990 |
setattr(lu.op, iallocator_slot, default_iallocator) |
|
991 |
else: |
|
992 |
raise errors.OpPrereqError("No iallocator or node given and no" |
|
993 |
" cluster-wide default iallocator found;" |
|
994 |
" please specify either an iallocator or a" |
|
995 |
" node, or set a cluster-wide default" |
|
996 |
" iallocator", errors.ECODE_INVAL) |
|
997 |
|
|
998 |
|
|
999 |
def _FindFaultyInstanceDisks(cfg, rpc_runner, instance, node_name, prereq): |
|
1000 |
faulty = [] |
|
1001 |
|
|
1002 |
for dev in instance.disks: |
|
1003 |
cfg.SetDiskID(dev, node_name) |
|
1004 |
|
|
1005 |
result = rpc_runner.call_blockdev_getmirrorstatus(node_name, (instance.disks, |
|
1006 |
instance)) |
|
1007 |
result.Raise("Failed to get disk status from node %s" % node_name, |
|
1008 |
prereq=prereq, ecode=errors.ECODE_ENVIRON) |
|
1009 |
|
|
1010 |
for idx, bdev_status in enumerate(result.payload): |
|
1011 |
if bdev_status and bdev_status.ldisk_status == constants.LDS_FAULTY: |
|
1012 |
faulty.append(idx) |
|
1013 |
|
|
1014 |
return faulty |
Also available in: Unified diff