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

« back to all changes in this revision

Viewing changes to modules/rsctest.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.1 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
#
17
17
 
18
18
import os
19
 
from utils import *
20
 
from xmlutil import *
21
 
from msg import *
 
19
import sys
 
20
from msg import common_err, common_debug, common_warn, common_info
 
21
from utils import rmdir_r
 
22
from xmlutil import get_topmost_rsc, get_op_timeout, get_child_nvset_node, is_ms, is_cloned
 
23
 
22
24
 
23
25
#
24
26
# Resource testing suite
25
27
#
26
28
 
 
29
 
27
30
class RADriver(object):
28
31
    '''
29
32
    Execute operations on resources.
30
33
    '''
31
34
    pfx = {
32
 
        "instance_attributes" : "OCF_RESKEY_",
33
 
        "meta_attributes" : "OCF_RESKEY_CRM_meta_",
 
35
        "instance_attributes": "OCF_RESKEY_",
 
36
        "meta_attributes": "OCF_RESKEY_CRM_meta_",
34
37
    }
35
38
    undef = -200
36
39
    unused = -201
 
40
 
37
41
    def __init__(self, rsc_node, node_l):
38
42
        from tempfile import mkdtemp
39
43
        self.rscdef_node = rsc_node
48
52
            self.ra_provider = None
49
53
            self.id = None
50
54
        self.node_l = node_l
51
 
        self.outdir = mkdtemp(prefix = "crmsh_out.")
52
 
        self.errdir = mkdtemp(prefix = "crmsh_err.")
 
55
        self.outdir = mkdtemp(prefix="crmsh_out.")
 
56
        self.errdir = mkdtemp(prefix="crmsh_err.")
53
57
        self.ec_l = {}
54
58
        self.ec_ok = self.unused
55
59
        self.ec_stopped = self.unused
57
61
        self.last_op = None
58
62
        self.last_rec = {}
59
63
        self.timeout = 20000
 
64
 
60
65
    def __del__(self):
61
66
        rmdir_r(self.outdir)
62
67
        rmdir_r(self.errdir)
 
68
 
63
69
    def id_str(self):
64
70
        return self.last_op and "%s:%s" % (self.id, self.last_op) or self.id
 
71
 
65
72
    def err(self, s):
66
73
        common_err("%s: %s" % (self.id_str(), s))
 
74
 
67
75
    def warn(self, s):
68
76
        common_warn("%s: %s" % (self.id_str(), s))
 
77
 
69
78
    def info(self, s):
70
79
        common_info("%s: %s" % (self.id_str(), s))
 
80
 
71
81
    def debug(self, s):
72
82
        common_debug("%s: %s" % (self.id_str(), s))
 
83
 
73
84
    def is_ms(self):
74
85
        return is_ms(self.rscdef_node)
 
86
 
75
87
    def nvset2env(self, set_n):
76
88
        if not set_n:
77
89
            return
81
93
            self.err("unknown attributes set: %s" % set_n.tag)
82
94
            return
83
95
        for nvpair in set_n.iterchildren():
84
 
            if not is_element(nvpair) or nvpair.tag != "nvpair":
 
96
            if nvpair.tag != "nvpair":
85
97
                continue
86
98
            n = nvpair.get("name")
87
99
            v = nvpair.get("value")
88
100
            self.rscenv["%s%s" % (pfx, n)] = v
 
101
 
89
102
    def set_rscenv(self, op):
90
103
        '''
91
104
        Setup the environment. Class specific.
101
114
            # by resource agents
102
115
            cn = get_topmost_rsc(n)
103
116
            self.nvset2env(get_child_nvset_node(cn))
 
117
 
104
118
    def op_status(self, host):
105
119
        'Status of the last op.'
106
 
        try: return self.ec_l[host]
107
 
        except: return self.undef
 
120
        try:
 
121
            return self.ec_l[host]
 
122
        except:
 
123
            return self.undef
 
124
 
108
125
    def explain_op_status(self, host):
109
126
        stat = self.op_status(host)
110
127
        if stat == -9:
113
130
            return "unknown reason (the RA couldn't run?)"
114
131
        else:
115
132
            return "exit code %d" % stat
 
133
 
116
134
    def is_ok(self, host):
117
135
        'Was last op successful?'
118
136
        return self.op_status(host) == self.ec_ok
 
137
 
119
138
    def is_master(self, host):
120
139
        'Only if last op was probe/monitor.'
121
140
        return self.op_status(host) == self.ec_master
 
141
 
122
142
    def is_stopped(self, host):
123
143
        'Only if last op was probe/monitor.'
124
144
        return self.op_status(host) == self.ec_stopped
 
145
 
125
146
    def show_log(self, host):
126
147
        '''
127
148
        Execute an operation.
128
149
        '''
129
150
        from crm_pssh import show_output
130
 
        sys.stderr.write("host %s (%s)\n" % \
131
 
            (host, self.explain_op_status(host)))
 
151
        sys.stderr.write("host %s (%s)\n" %
 
152
                         (host, self.explain_op_status(host)))
132
153
        show_output(self.errdir, (host,), "stderr")
133
154
        show_output(self.outdir, (host,), "stdout")
 
155
 
134
156
    def run_on_all(self, op):
135
157
        '''
136
158
        In case of cloned resources, it doesn't make sense to run
139
161
        For instance, some clones require quorum.
140
162
        '''
141
163
        return is_cloned(self.rscdef_node) and op in ("start", "stop")
 
164
 
142
165
    def exec_cmd(self, op):
143
166
        '''defined in subclasses'''
144
167
        pass
 
168
 
145
169
    def runop(self, op, node_l=None):
146
170
        '''
147
171
        Execute an operation.
156
180
        common_debug("running %s on %s" % (real_op, node_l))
157
181
        for attr in self.rscenv.keys():
158
182
            # shell doesn't allow "-" in var names
159
 
            envvar = attr.replace("-","_")
160
 
            if "'" in  self.rscenv[attr]:
 
183
            envvar = attr.replace("-", "_")
 
184
            if "'" in self.rscenv[attr]:
161
185
                cmd = '%s="%s" %s' % (envvar, self.rscenv[attr], cmd)
162
186
            else:
163
187
                cmd = "%s='%s' %s" % (envvar, self.rscenv[attr], cmd)
164
188
        statuses = do_pssh_cmd(cmd, node_l, self.outdir, self.errdir, self.timeout)
165
189
        for i in range(len(node_l)):
166
 
            try: self.ec_l[node_l[i]] = statuses[i]
167
 
            except: self.ec_l[node_l[i]] = self.undef
 
190
            try:
 
191
                self.ec_l[node_l[i]] = statuses[i]
 
192
            except:
 
193
                self.ec_l[node_l[i]] = self.undef
168
194
        return
169
195
 
 
196
 
170
197
class RAOCF(RADriver):
171
198
    '''
172
199
    Execute operations on OCF resources.
182
209
    OCF_NOT_RUNNING = 7
183
210
    OCF_RUNNING_MASTER = 8
184
211
    OCF_FAILED_MASTER = 9
 
212
 
185
213
    def __init__(self, *args):
186
214
        RADriver.__init__(self, *args)
187
215
        self.ec_ok = self.OCF_SUCCESS
188
216
        self.ec_stopped = self.OCF_NOT_RUNNING
189
217
        self.ec_master = self.OCF_RUNNING_MASTER
 
218
 
190
219
    def set_rscenv(self, op):
191
220
        RADriver.set_rscenv(self, op)
192
221
        self.nvset2env(get_child_nvset_node(self.rscdef_node, "instance_attributes"))
193
222
        self.rscenv["OCF_RESOURCE_INSTANCE"] = self.id
194
223
        self.rscenv["OCF_ROOT"] = os.environ["OCF_ROOT"]
 
224
 
195
225
    def exec_cmd(self, op):
196
226
        cmd = "%s/resource.d/%s/%s %s" % \
197
227
            (os.environ["OCF_ROOT"], self.ra_provider, self.ra_type, op)
198
228
        return cmd
199
229
 
 
230
 
200
231
class RALSB(RADriver):
201
232
    '''
202
233
    Execute operations on LSB resources (init scripts).
203
234
    '''
 
235
 
204
236
    # OCF exit codes
205
237
    LSB_OK = 0
206
238
    LSB_ERR_GENERIC = 1
214
246
    LSB_STATUS_DEAD_LOCK = 2
215
247
    LSB_STATUS_NOT_RUNNING = 3
216
248
    LSB_STATUS_UNKNOWN = 4
 
249
 
217
250
    def __init__(self, *args):
218
251
        RADriver.__init__(self, *args)
219
252
        self.ec_ok = self.LSB_OK
220
253
        self.ec_stopped = self.LSB_STATUS_NOT_RUNNING
221
254
        self.ec_master = self.unused
 
255
 
222
256
    def set_rscenv(self, op):
223
257
        RADriver.set_rscenv(self, op)
 
258
 
224
259
    def exec_cmd(self, op):
225
260
        if self.ra_type.startswith("/"):
226
261
            prog = self.ra_type
229
264
        cmd = "%s %s" % (prog, op == "monitor" and "status" or op)
230
265
        return cmd
231
266
 
 
267
 
232
268
ra_driver = {
233
 
    "ocf" : RAOCF,
234
 
    "lsb" : RALSB,
 
269
    "ocf": RAOCF,
 
270
    "lsb": RALSB,
235
271
}
 
272
 
 
273
 
236
274
def check_test_support(rsc_l):
237
275
    rc = True
238
276
    for r in rsc_l:
242
280
            common_warn("class attribute not found in %s" % id)
243
281
            rc = False
244
282
        elif ra_class not in ra_driver:
245
 
            common_warn("testing of class %s resources not supported" % \
246
 
                ra_class)
 
283
            common_warn("testing of class %s resources not supported" %
 
284
                        ra_class)
247
285
            rc = False
248
286
    return rc
 
287
 
 
288
 
249
289
def are_all_stopped(rsc_l, node_l):
250
290
    rc = True
251
291
    sys.stderr.write("Probing resources ")
267
307
    sys.stderr.write("\n")
268
308
    return rc
269
309
 
 
310
 
270
311
def stop_all(started, node):
271
312
    'Stop all resources in started, in reverse order.'
272
313
    while started:
278
319
            drv.err("resource failed to stop on %s, clean it up!" % node)
279
320
            drv.show_log(node)
280
321
 
 
322
 
281
323
def test_resources_1(rsc_l, node):
282
324
    started = []
283
325
    sys.stderr.write("testing on %s:" % node)
300
342
    stop_all(started, node)
301
343
    return True
302
344
 
 
345
 
303
346
def test_resources(rsc_l, node_l, all_nodes_l):
304
347
    try:
305
348
        import crm_pssh
306
 
    except ImportError, msg:
 
349
    except ImportError:
307
350
        common_err("pssh not installed, rsctest can not be executed")
308
351
        return False
309
352
    if not check_test_support(rsc_l):