1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
|
# Copyright (C) 2014 Kristoffer Gronlund <kgronlund@suse.com>
# See COPYING for license information.
from . import command
from . import completers as compl
from . import config
from .cibconfig import cib_factory
from . import utils
from . import xmlutil
_compl_actions = compl.choice(['start', 'stop', 'monitor', 'meta-data', 'validate-all',
'promote', 'demote', 'notify', 'reload', 'migrate_from',
'migrate_to', 'recover'])
class Maintenance(command.UI):
'''
Commands that should only be run while in
maintenance mode.
'''
name = "maintenance"
rsc_maintenance = "crm_resource -r '%s' --meta -p maintenance -v '%s'"
def __init__(self):
command.UI.__init__(self)
def requires(self):
return cib_factory.initialize()
def _onoff(self, resource, onoff):
if resource is not None:
return utils.ext_cmd(self.rsc_maintenance % (resource, onoff)) == 0
else:
cib_factory.create_object('property', 'maintenance-mode=%s' % (onoff))
return cib_factory.commit()
@command.skill_level('administrator')
@command.completers_repeating(compl.call(cib_factory.rsc_id_list))
def do_on(self, context, resource=None):
'''
Enable maintenance mode (for the optional resource or for everything)
'''
return self._onoff(resource, 'true')
@command.skill_level('administrator')
@command.completers_repeating(compl.call(cib_factory.rsc_id_list))
def do_off(self, context, resource=None):
'''
Disable maintenance mode (for the optional resource or for everything)
'''
return self._onoff(resource, 'false')
def _in_maintenance_mode(self, obj):
if cib_factory.get_property("maintenance-mode") == "true":
return True
v = obj.meta_attributes("maintenance")
return v and all(x == 'true' for x in v)
def _runs_on_this_node(self, resource):
nodes = utils.running_on(resource)
return set(nodes) == set([utils.this_node()])
@command.skill_level('administrator')
@command.completers(compl.call(cib_factory.rsc_id_list), _compl_actions, compl.choice(["ssh"]))
def do_action(self, context, resource, action, ssh=None):
'''
Issue action out-of-band to the given resource, making
sure that the resource is in maintenance mode first
'''
obj = cib_factory.find_object(resource)
if not obj:
context.fatal_error("Resource not found: %s" % (resource))
if not xmlutil.is_resource(obj.node):
context.fatal_error("Not a resource: %s" % (resource))
if not config.core.force and not self._in_maintenance_mode(obj):
context.fatal_error("Not in maintenance mode.")
if ssh is None:
if action not in ('start', 'monitor'):
if not self._runs_on_this_node(resource):
context.fatal_error("Resource %s must be running on this node (%s)" %
(resource, utils.this_node()))
from . import rsctest
return rsctest.call_resource(obj.node, action, [utils.this_node()], local_only=True)
elif ssh == "ssh":
from . import rsctest
if action in ('start', 'promote', 'demote', 'recover', 'meta-data'):
return rsctest.call_resource(obj.node, action,
[utils.this_node()], local_only=True)
else:
all_nodes = cib_factory.node_id_list()
return rsctest.call_resource(obj.node, action, all_nodes, local_only=False)
else:
context.fatal_error("Unknown argument: %s" % (ssh))
|