~ubuntu-branches/ubuntu/vivid/crmsh/vivid

« back to all changes in this revision

Viewing changes to modules/cibstatus.py

  • Committer: Package Import Robot
  • Author(s): Martin Loschwitz
  • Date: 2013-08-05 05:21:29 UTC
  • mfrom: (1.1.2)
  • Revision ID: package-import@ubuntu.com-20130805052129-aooqqanxrctmy93m
Tags: 1.2.5+hg1034-1
New upstream checkout

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
# Copyright (C) 2008-2011 Dejan Muhamedagic <dmuhamedagic@suse.de>
2
 
 
2
#
3
3
# This program is free software; you can redistribute it and/or
4
4
# modify it under the terms of the GNU General Public
5
5
# License as published by the Free Software Foundation; either
6
6
# version 2 of the License, or (at your option) any later version.
7
 
 
7
#
8
8
# This software is distributed in the hope that it will be useful,
9
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11
11
# General Public License for more details.
12
 
 
12
#
13
13
# You should have received a copy of the GNU General Public
14
14
# License along with this library; if not, write to the Free Software
15
15
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19
19
from lxml import etree
20
20
from singletonmixin import Singleton
21
21
from vars import Vars
22
 
from xmlutil import *
23
 
from msg import *
 
22
from tempfile import mkstemp
 
23
from utils import ext_cmd, show_dot_graph, page_string
 
24
from msg import common_err, common_info, common_warn, user_prefs
 
25
import xmlutil
 
26
 
24
27
 
25
28
def get_tag_by_id(node, tag, id):
26
29
    "Find a doc node which matches tag and id."
28
31
        if n.get("id") == id:
29
32
            return n
30
33
    return None
 
34
 
 
35
 
31
36
def get_status_node_id(n):
32
 
    try: n = n.getparent()
33
 
    except: return None
 
37
    try:
 
38
        n = n.getparent()
 
39
    except:
 
40
        return None
34
41
    if n.tag != "node_state":
35
42
        return get_status_node_id(n)
36
43
    return n.get("id")
 
44
 
 
45
 
37
46
def get_status_node(status_node, node):
38
47
    for n in status_node.iterchildren("node_state"):
39
48
        if n.get("id") == node:
40
49
            return n
41
50
    return None
 
51
 
 
52
 
42
53
def get_status_ops(status_node, rsc, op, interval, node=''):
43
54
    '''
44
55
    Find a doc node which matches the operation. interval set to
60
71
                    l.append(o)
61
72
    return l
62
73
 
 
74
 
63
75
def split_op(op):
64
76
    if op == "probe":
65
77
        return "monitor", "0"
69
81
        return "monitor", op[8:]
70
82
    return op, "0"
71
83
 
 
84
 
72
85
def cib_path(source):
73
 
    return source[0:7] == "shadow:" and shadowfile(source[7:]) or source
 
86
    return source[0:7] == "shadow:" and xmlutil.shadowfile(source[7:]) or source
 
87
 
74
88
 
75
89
class CibStatus(Singleton):
76
90
    '''
90
104
        "standby": "-b",
91
105
        "activate": "-e",
92
106
    }
 
107
 
93
108
    def __init__(self):
94
109
        self.origin = ""
95
 
        self.backing_file = "" # file to keep the live cib
 
110
        self.backing_file = ""  # file to keep the live cib
96
111
        self.status_node = None
97
112
        self.cib = None
98
113
        self.reset_state()
 
114
 
99
115
    def _cib_path(self, source):
100
116
        if source[0:7] == "shadow:":
101
 
            return shadowfile(source[7:])
 
117
            return xmlutil.shadowfile(source[7:])
102
118
        else:
103
119
            return source
 
120
 
104
121
    def _load_cib(self, source):
105
122
        if source == "live":
106
123
            if not self.backing_file:
107
 
                self.backing_file = cibdump2tmp()
 
124
                self.backing_file = xmlutil.cibdump2tmp()
108
125
                if not self.backing_file:
109
126
                    return None
110
127
                vars.tmpfiles.append(self.backing_file)
111
128
            else:
112
 
                cibdump2file(self.backing_file)
 
129
                xmlutil.cibdump2file(self.backing_file)
113
130
            f = self.backing_file
114
131
        else:
115
132
            f = cib_path(source)
116
 
        return read_cib(file2cib_elem, f)
 
133
        return xmlutil.read_cib(xmlutil.file2cib_elem, f)
 
134
 
117
135
    def _load(self, source):
118
136
        cib = self._load_cib(source)
119
137
        if cib is None:
125
143
        self.status_node = status
126
144
        self.reset_state()
127
145
        return True
 
146
 
128
147
    def reset_state(self):
129
148
        self.modified = False
130
149
        self.quorum = ''
131
150
        self.node_changes = {}
132
151
        self.op_changes = {}
133
152
        self.ticket_changes = {}
 
153
 
134
154
    def initialize(self):
135
155
        if not vars.cib_in_use:
136
156
            src = "live"
138
158
            src = "shadow:%s" % vars.cib_in_use
139
159
        if self._load(src):
140
160
            self.origin = src
 
161
 
141
162
    def source_file(self):
142
163
        if self.origin == "live":
143
164
            return self.backing_file
144
165
        else:
145
166
            return cib_path(self.origin)
 
167
 
146
168
    def status_node_list(self):
147
169
        st = self.get_status()
148
170
        if st is None:
149
171
            return
150
172
        return [x.get("id") for x in st.xpath(".//node_state")]
 
173
 
151
174
    def status_rsc_list(self):
152
175
        st = self.get_status()
153
176
        if st is None:
158
181
        for e in rsc_list:
159
182
            d[e] = 0
160
183
        return d.keys()
 
184
 
161
185
    def load(self, source):
162
186
        '''
163
187
        Load the status section from the given source. The source
171
195
            return False
172
196
        self.origin = source
173
197
        return True
 
198
 
174
199
    def save(self, dest=None):
175
200
        '''
176
201
        Save the modified status section to a file/shadow. If the
197
222
            dest_path = cib_path(self.origin)
198
223
        if cib != self.cib:
199
224
            status = cib.find("status")
200
 
            rmnode(status)
 
225
            xmlutil.rmnode(status)
201
226
            cib.append(self.status_node)
202
227
        xml = etree.tostring(cib)
203
 
        try: f = open(dest_path, "w")
 
228
        try:
 
229
            f = open(dest_path, "w")
204
230
        except IOError, msg:
205
231
            common_err(msg)
206
232
            return False
207
233
        f.write(xml)
208
234
        f.close()
209
235
        return True
 
236
 
210
237
    def _crm_simulate(self, cmd, nograph, scores, utilization, verbosity):
211
238
        if not self.origin:
212
239
            self.initialize()
225
252
        if dotfile:
226
253
            show_dot_graph(dotfile)
227
254
        return rc == 0
 
255
 
228
256
    # actions is ignored
229
257
    def run(self, nograph, scores, utilization, actions, verbosity):
230
 
        return self._crm_simulate(self.cmd_run, \
231
 
            nograph, scores, utilization, verbosity)
 
258
        return self._crm_simulate(self.cmd_run,
 
259
                                  nograph, scores, utilization, verbosity)
 
260
 
232
261
    # actions is ignored
233
262
    def simulate(self, nograph, scores, utilization, actions, verbosity):
234
 
        return self._crm_simulate(self.cmd_simulate, \
235
 
            nograph, scores, utilization, verbosity)
 
263
        return self._crm_simulate(self.cmd_simulate,
 
264
                                  nograph, scores, utilization, verbosity)
 
265
 
236
266
    def get_status(self):
237
267
        '''
238
268
        Return the status section node.
239
269
        '''
240
270
        if not self.origin:
241
271
            self.initialize()
242
 
        if (self.status_node is None or \
 
272
        if (self.status_node is None or
243
273
            (self.origin == "live" and not self.modified)) \
244
274
                and not self._load(self.origin):
245
275
            return None
246
276
        return self.status_node
 
277
 
247
278
    def list_changes(self):
248
279
        '''
249
280
        Dump a set of changes done.
259
290
        if self.quorum:
260
291
            print "quorum:", self.quorum
261
292
        return True
 
293
 
262
294
    def show(self):
263
295
        '''
264
296
        Page the "pretty" XML of the status section.
267
299
            return False
268
300
        page_string(etree.tostring(self.status_node, pretty_print=True))
269
301
        return True
 
302
 
270
303
    def inject(self, opts):
271
 
        return ext_cmd("%s %s" % \
272
 
            (self.cmd_inject % (self.source_file(), self.source_file()), opts))
 
304
        return ext_cmd("%s %s" %
 
305
                       (self.cmd_inject % (self.source_file(), self.source_file()), opts))
 
306
 
273
307
    def set_quorum(self, v):
274
308
        if not self.origin:
275
309
            self.initialize()
280
314
        self.quorum = v and "true" or "false"
281
315
        self.modified = True
282
316
        return True
 
317
 
283
318
    def edit_node(self, node, state):
284
319
        '''
285
320
        Modify crmd, expected, and join attributes of node_state
301
336
        self.node_changes[node] = state
302
337
        self.modified = True
303
338
        return True
 
339
 
304
340
    def edit_ticket(self, ticket, subcmd):
305
341
        '''
306
342
        Modify ticket status.
317
353
        self.ticket_changes[ticket] = subcmd
318
354
        self.modified = True
319
355
        return True
 
356
 
320
357
    def edit_op(self, op, rsc, rc_code, op_status, node=''):
321
358
        '''
322
359
        Set rc-code and op-status in the lrm_rsc_op status
348
385
            if l_int == "-1":
349
386
                l_int = op_node.get("interval")
350
387
        op_op = op_status == "0" and "-i" or "-F"
351
 
        rc = self.inject("%s %s_%s_%s@%s=%s" % \
352
 
            (op_op, rsc, l_op, l_int, node, rc_code))
 
388
        rc = self.inject("%s %s_%s_%s@%s=%s" %
 
389
                         (op_op, rsc, l_op, l_int, node, rc_code))
353
390
        if rc != 0:
354
391
            return False
355
392
        self.op_changes[node+":"+rsc+":"+op] = "rc="+rc_code