root / testing / ganeti.qa.py @ 2a710df1
History | View | Annotate | Download (19.6 kB)
1 | a8083063 | Iustin Pop | #!/usr/bin/python
|
---|---|---|---|
2 | a8083063 | Iustin Pop | #
|
3 | a8083063 | Iustin Pop | |
4 | a8083063 | Iustin Pop | # Copyright (C) 2006, 2007 Google Inc.
|
5 | a8083063 | Iustin Pop | #
|
6 | a8083063 | Iustin Pop | # This program is free software; you can redistribute it and/or modify
|
7 | a8083063 | Iustin Pop | # it under the terms of the GNU General Public License as published by
|
8 | a8083063 | Iustin Pop | # the Free Software Foundation; either version 2 of the License, or
|
9 | a8083063 | Iustin Pop | # (at your option) any later version.
|
10 | a8083063 | Iustin Pop | #
|
11 | a8083063 | Iustin Pop | # This program is distributed in the hope that it will be useful, but
|
12 | a8083063 | Iustin Pop | # WITHOUT ANY WARRANTY; without even the implied warranty of
|
13 | a8083063 | Iustin Pop | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
14 | a8083063 | Iustin Pop | # General Public License for more details.
|
15 | a8083063 | Iustin Pop | #
|
16 | a8083063 | Iustin Pop | # You should have received a copy of the GNU General Public License
|
17 | a8083063 | Iustin Pop | # along with this program; if not, write to the Free Software
|
18 | a8083063 | Iustin Pop | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
19 | a8083063 | Iustin Pop | # 02110-1301, USA.
|
20 | a8083063 | Iustin Pop | |
21 | a8083063 | Iustin Pop | |
22 | 94508060 | Michael Hanselmann | """Script for doing Q&A on Ganeti
|
23 | 94508060 | Michael Hanselmann |
|
24 | 94508060 | Michael Hanselmann | You can create the required known_hosts file using ssh-keyscan. It's mandatory
|
25 | 94508060 | Michael Hanselmann | to use the full name of a node (FQDN). For security reasons, verify the keys
|
26 | 94508060 | Michael Hanselmann | before using them.
|
27 | 94508060 | Michael Hanselmann | Example: ssh-keyscan -t rsa node{1,2,3,4}.example.com > known_hosts
|
28 | 94508060 | Michael Hanselmann | """
|
29 | a8083063 | Iustin Pop | |
30 | a8083063 | Iustin Pop | import os |
31 | a8083063 | Iustin Pop | import re |
32 | a8083063 | Iustin Pop | import sys |
33 | a8083063 | Iustin Pop | import yaml |
34 | a8083063 | Iustin Pop | import time |
35 | 180bdd1f | Michael Hanselmann | import tempfile |
36 | a8083063 | Iustin Pop | from datetime import datetime |
37 | a8083063 | Iustin Pop | from optparse import OptionParser |
38 | a8083063 | Iustin Pop | |
39 | a8083063 | Iustin Pop | # I want more flexibility for testing over SSH, therefore I'm not using
|
40 | a8083063 | Iustin Pop | # Ganeti's ssh module.
|
41 | a8083063 | Iustin Pop | import subprocess |
42 | a8083063 | Iustin Pop | |
43 | a8083063 | Iustin Pop | from ganeti import utils |
44 | a8083063 | Iustin Pop | from ganeti import constants |
45 | a8083063 | Iustin Pop | |
46 | a8083063 | Iustin Pop | # {{{ Global variables
|
47 | a8083063 | Iustin Pop | cfg = None
|
48 | a8083063 | Iustin Pop | options = None
|
49 | a8083063 | Iustin Pop | # }}}
|
50 | a8083063 | Iustin Pop | |
51 | a8083063 | Iustin Pop | # {{{ Errors
|
52 | a8083063 | Iustin Pop | class Error(Exception): |
53 | a8083063 | Iustin Pop | """An error occurred during Q&A testing.
|
54 | a8083063 | Iustin Pop |
|
55 | a8083063 | Iustin Pop | """
|
56 | a8083063 | Iustin Pop | pass
|
57 | a8083063 | Iustin Pop | |
58 | a8083063 | Iustin Pop | |
59 | a8083063 | Iustin Pop | class OutOfNodesError(Error): |
60 | a8083063 | Iustin Pop | """Out of nodes.
|
61 | a8083063 | Iustin Pop |
|
62 | a8083063 | Iustin Pop | """
|
63 | a8083063 | Iustin Pop | pass
|
64 | a8083063 | Iustin Pop | |
65 | a8083063 | Iustin Pop | |
66 | a8083063 | Iustin Pop | class OutOfInstancesError(Error): |
67 | a8083063 | Iustin Pop | """Out of instances.
|
68 | a8083063 | Iustin Pop |
|
69 | a8083063 | Iustin Pop | """
|
70 | a8083063 | Iustin Pop | pass
|
71 | a8083063 | Iustin Pop | # }}}
|
72 | a8083063 | Iustin Pop | |
73 | a8083063 | Iustin Pop | # {{{ Utilities
|
74 | a8083063 | Iustin Pop | def TestEnabled(test): |
75 | a8083063 | Iustin Pop | """Returns True if the given test is enabled."""
|
76 | a8083063 | Iustin Pop | return cfg.get('tests', {}).get(test, False) |
77 | a8083063 | Iustin Pop | |
78 | a8083063 | Iustin Pop | |
79 | a8083063 | Iustin Pop | def RunTest(callable, *args): |
80 | a8083063 | Iustin Pop | """Runs a test after printing a header.
|
81 | a8083063 | Iustin Pop |
|
82 | a8083063 | Iustin Pop | """
|
83 | a8083063 | Iustin Pop | if callable.__doc__: |
84 | a8083063 | Iustin Pop | desc = callable.__doc__.splitlines()[0].strip() |
85 | a8083063 | Iustin Pop | else:
|
86 | a8083063 | Iustin Pop | desc = '%r' % callable |
87 | a8083063 | Iustin Pop | |
88 | a8083063 | Iustin Pop | now = str(datetime.now())
|
89 | a8083063 | Iustin Pop | |
90 | a8083063 | Iustin Pop | print
|
91 | a8083063 | Iustin Pop | print '---', now, ('-' * (55 - len(now))) |
92 | a8083063 | Iustin Pop | print desc
|
93 | a8083063 | Iustin Pop | print '-' * 60 |
94 | a8083063 | Iustin Pop | |
95 | a8083063 | Iustin Pop | return callable(*args) |
96 | a8083063 | Iustin Pop | |
97 | a8083063 | Iustin Pop | |
98 | a8083063 | Iustin Pop | def AssertEqual(first, second, msg=None): |
99 | a8083063 | Iustin Pop | """Raises an error when values aren't equal.
|
100 | a8083063 | Iustin Pop |
|
101 | a8083063 | Iustin Pop | """
|
102 | a8083063 | Iustin Pop | if not first == second: |
103 | 3ecf6786 | Iustin Pop | raise Error(msg or '%r == %r' % (first, second)) |
104 | a8083063 | Iustin Pop | |
105 | a8083063 | Iustin Pop | |
106 | a8083063 | Iustin Pop | def GetSSHCommand(node, cmd, strict=True): |
107 | a8083063 | Iustin Pop | """Builds SSH command to be executed.
|
108 | a8083063 | Iustin Pop |
|
109 | a8083063 | Iustin Pop | """
|
110 | a8083063 | Iustin Pop | args = [ 'ssh', '-oEscapeChar=none', '-oBatchMode=yes', '-l', 'root' ] |
111 | a8083063 | Iustin Pop | |
112 | a8083063 | Iustin Pop | if strict:
|
113 | a8083063 | Iustin Pop | tmp = 'yes'
|
114 | a8083063 | Iustin Pop | else:
|
115 | a8083063 | Iustin Pop | tmp = 'no'
|
116 | a8083063 | Iustin Pop | args.append('-oStrictHostKeyChecking=%s' % tmp)
|
117 | 807d926c | Michael Hanselmann | args.append('-oClearAllForwardings=yes')
|
118 | 807d926c | Michael Hanselmann | args.append('-oForwardAgent=yes')
|
119 | a8083063 | Iustin Pop | args.append(node) |
120 | a8083063 | Iustin Pop | |
121 | a8083063 | Iustin Pop | if options.dry_run:
|
122 | a8083063 | Iustin Pop | prefix = 'exit 0; '
|
123 | a8083063 | Iustin Pop | else:
|
124 | a8083063 | Iustin Pop | prefix = ''
|
125 | a8083063 | Iustin Pop | |
126 | a8083063 | Iustin Pop | args.append(prefix + cmd) |
127 | a8083063 | Iustin Pop | |
128 | 180bdd1f | Michael Hanselmann | print 'SSH:', utils.ShellQuoteArgs(args) |
129 | a8083063 | Iustin Pop | |
130 | a8083063 | Iustin Pop | return args
|
131 | a8083063 | Iustin Pop | |
132 | a8083063 | Iustin Pop | |
133 | a8083063 | Iustin Pop | def StartSSH(node, cmd, strict=True): |
134 | a8083063 | Iustin Pop | """Starts SSH.
|
135 | a8083063 | Iustin Pop |
|
136 | a8083063 | Iustin Pop | """
|
137 | a8083063 | Iustin Pop | args = GetSSHCommand(node, cmd, strict=strict) |
138 | a8083063 | Iustin Pop | return subprocess.Popen(args, shell=False) |
139 | a8083063 | Iustin Pop | |
140 | a8083063 | Iustin Pop | |
141 | a8083063 | Iustin Pop | def UploadFile(node, file): |
142 | a8083063 | Iustin Pop | """Uploads a file to a node and returns the filename.
|
143 | a8083063 | Iustin Pop |
|
144 | 180bdd1f | Michael Hanselmann | Caller needs to remove the returned file on the node when it's not needed
|
145 | 180bdd1f | Michael Hanselmann | anymore.
|
146 | a8083063 | Iustin Pop | """
|
147 | 180bdd1f | Michael Hanselmann | # Make sure nobody else has access to it while preserving local permissions
|
148 | 180bdd1f | Michael Hanselmann | mode = os.stat(file).st_mode & 0700 |
149 | a8083063 | Iustin Pop | |
150 | 180bdd1f | Michael Hanselmann | cmd = ('tmp=$(tempfile --mode %o --prefix gnt) && '
|
151 | a8083063 | Iustin Pop | '[[ -f "${tmp}" ]] && '
|
152 | a8083063 | Iustin Pop | 'cat > "${tmp}" && '
|
153 | a8083063 | Iustin Pop | 'echo "${tmp}"') % mode
|
154 | a8083063 | Iustin Pop | |
155 | a8083063 | Iustin Pop | f = open(file, 'r') |
156 | a8083063 | Iustin Pop | try:
|
157 | a8083063 | Iustin Pop | p = subprocess.Popen(GetSSHCommand(node, cmd), shell=False, stdin=f,
|
158 | a8083063 | Iustin Pop | stdout=subprocess.PIPE) |
159 | a8083063 | Iustin Pop | AssertEqual(p.wait(), 0)
|
160 | a8083063 | Iustin Pop | |
161 | 180bdd1f | Michael Hanselmann | # Return temporary filename
|
162 | 180bdd1f | Michael Hanselmann | return p.stdout.read().strip()
|
163 | a8083063 | Iustin Pop | finally:
|
164 | a8083063 | Iustin Pop | f.close() |
165 | a8083063 | Iustin Pop | # }}}
|
166 | a8083063 | Iustin Pop | |
167 | a8083063 | Iustin Pop | # {{{ Config helpers
|
168 | a8083063 | Iustin Pop | def GetMasterNode(): |
169 | a8083063 | Iustin Pop | return cfg['nodes'][0] |
170 | a8083063 | Iustin Pop | |
171 | a8083063 | Iustin Pop | |
172 | a8083063 | Iustin Pop | def AcquireInstance(): |
173 | a8083063 | Iustin Pop | """Returns an instance which isn't in use.
|
174 | a8083063 | Iustin Pop |
|
175 | a8083063 | Iustin Pop | """
|
176 | a8083063 | Iustin Pop | # Filter out unwanted instances
|
177 | a8083063 | Iustin Pop | tmp_flt = lambda inst: not inst.get('_used', False) |
178 | a8083063 | Iustin Pop | instances = filter(tmp_flt, cfg['instances']) |
179 | a8083063 | Iustin Pop | del tmp_flt
|
180 | a8083063 | Iustin Pop | |
181 | a8083063 | Iustin Pop | if len(instances) == 0: |
182 | 3ecf6786 | Iustin Pop | raise OutOfInstancesError("No instances left") |
183 | a8083063 | Iustin Pop | |
184 | a8083063 | Iustin Pop | inst = instances[0]
|
185 | a8083063 | Iustin Pop | inst['_used'] = True |
186 | a8083063 | Iustin Pop | return inst
|
187 | a8083063 | Iustin Pop | |
188 | a8083063 | Iustin Pop | |
189 | a8083063 | Iustin Pop | def ReleaseInstance(inst): |
190 | a8083063 | Iustin Pop | inst['_used'] = False |
191 | a8083063 | Iustin Pop | |
192 | a8083063 | Iustin Pop | |
193 | a8083063 | Iustin Pop | def AcquireNode(exclude=None): |
194 | a8083063 | Iustin Pop | """Returns the least used node.
|
195 | a8083063 | Iustin Pop |
|
196 | a8083063 | Iustin Pop | """
|
197 | a8083063 | Iustin Pop | master = GetMasterNode() |
198 | a8083063 | Iustin Pop | |
199 | a8083063 | Iustin Pop | # Filter out unwanted nodes
|
200 | a8083063 | Iustin Pop | # TODO: Maybe combine filters
|
201 | a8083063 | Iustin Pop | if exclude is None: |
202 | a8083063 | Iustin Pop | nodes = cfg['nodes'][:]
|
203 | a8083063 | Iustin Pop | else:
|
204 | a8083063 | Iustin Pop | nodes = filter(lambda node: node != exclude, cfg['nodes']) |
205 | a8083063 | Iustin Pop | |
206 | a8083063 | Iustin Pop | tmp_flt = lambda node: node.get('_added', False) or node == master |
207 | a8083063 | Iustin Pop | nodes = filter(tmp_flt, nodes)
|
208 | a8083063 | Iustin Pop | del tmp_flt
|
209 | a8083063 | Iustin Pop | |
210 | a8083063 | Iustin Pop | if len(nodes) == 0: |
211 | 3ecf6786 | Iustin Pop | raise OutOfNodesError("No nodes left") |
212 | a8083063 | Iustin Pop | |
213 | a8083063 | Iustin Pop | # Get node with least number of uses
|
214 | a8083063 | Iustin Pop | def compare(a, b): |
215 | a8083063 | Iustin Pop | result = cmp(a.get('_count', 0), b.get('_count', 0)) |
216 | a8083063 | Iustin Pop | if result == 0: |
217 | a8083063 | Iustin Pop | result = cmp(a['primary'], b['primary']) |
218 | a8083063 | Iustin Pop | return result
|
219 | a8083063 | Iustin Pop | |
220 | a8083063 | Iustin Pop | nodes.sort(cmp=compare) |
221 | a8083063 | Iustin Pop | |
222 | a8083063 | Iustin Pop | node = nodes[0]
|
223 | a8083063 | Iustin Pop | node['_count'] = node.get('_count', 0) + 1 |
224 | a8083063 | Iustin Pop | return node
|
225 | a8083063 | Iustin Pop | |
226 | a8083063 | Iustin Pop | |
227 | a8083063 | Iustin Pop | def ReleaseNode(node): |
228 | a8083063 | Iustin Pop | node['_count'] = node.get('_count', 0) - 1 |
229 | a8083063 | Iustin Pop | # }}}
|
230 | a8083063 | Iustin Pop | |
231 | a8083063 | Iustin Pop | # {{{ Environment tests
|
232 | a8083063 | Iustin Pop | def TestConfig(): |
233 | a8083063 | Iustin Pop | """Test configuration for sanity.
|
234 | a8083063 | Iustin Pop |
|
235 | a8083063 | Iustin Pop | """
|
236 | a8083063 | Iustin Pop | if len(cfg['nodes']) < 1: |
237 | 3ecf6786 | Iustin Pop | raise Error("Need at least one node") |
238 | a8083063 | Iustin Pop | if len(cfg['instances']) < 1: |
239 | 3ecf6786 | Iustin Pop | raise Error("Need at least one instance") |
240 | a8083063 | Iustin Pop | # TODO: Add more checks
|
241 | a8083063 | Iustin Pop | |
242 | a8083063 | Iustin Pop | |
243 | a8083063 | Iustin Pop | def TestSshConnection(): |
244 | a8083063 | Iustin Pop | """Test SSH connection.
|
245 | a8083063 | Iustin Pop |
|
246 | a8083063 | Iustin Pop | """
|
247 | a8083063 | Iustin Pop | for node in cfg['nodes']: |
248 | a8083063 | Iustin Pop | AssertEqual(StartSSH(node['primary'], 'exit').wait(), 0) |
249 | a8083063 | Iustin Pop | |
250 | a8083063 | Iustin Pop | |
251 | a8083063 | Iustin Pop | def TestGanetiCommands(): |
252 | a8083063 | Iustin Pop | """Test availibility of Ganeti commands.
|
253 | a8083063 | Iustin Pop |
|
254 | a8083063 | Iustin Pop | """
|
255 | a8083063 | Iustin Pop | cmds = ( ['gnt-cluster', '--version'], |
256 | a8083063 | Iustin Pop | ['gnt-os', '--version'], |
257 | a8083063 | Iustin Pop | ['gnt-node', '--version'], |
258 | a8083063 | Iustin Pop | ['gnt-instance', '--version'], |
259 | a8083063 | Iustin Pop | ['gnt-backup', '--version'], |
260 | a8083063 | Iustin Pop | ['ganeti-noded', '--version'], |
261 | a8083063 | Iustin Pop | ['ganeti-watcher', '--version'] ) |
262 | a8083063 | Iustin Pop | |
263 | e9e35aaa | Michael Hanselmann | cmd = ' && '.join([utils.ShellQuoteArgs(i) for i in cmds]) |
264 | a8083063 | Iustin Pop | |
265 | a8083063 | Iustin Pop | for node in cfg['nodes']: |
266 | a8083063 | Iustin Pop | AssertEqual(StartSSH(node['primary'], cmd).wait(), 0) |
267 | a8083063 | Iustin Pop | |
268 | a8083063 | Iustin Pop | |
269 | a8083063 | Iustin Pop | def TestIcmpPing(): |
270 | a8083063 | Iustin Pop | """ICMP ping each node.
|
271 | a8083063 | Iustin Pop |
|
272 | a8083063 | Iustin Pop | """
|
273 | a8083063 | Iustin Pop | for node in cfg['nodes']: |
274 | a8083063 | Iustin Pop | check = [] |
275 | a8083063 | Iustin Pop | for i in cfg['nodes']: |
276 | a8083063 | Iustin Pop | check.append(i['primary'])
|
277 | a8083063 | Iustin Pop | if i.has_key('secondary'): |
278 | a8083063 | Iustin Pop | check.append(i['secondary'])
|
279 | a8083063 | Iustin Pop | |
280 | a8083063 | Iustin Pop | ping = lambda ip: utils.ShellQuoteArgs(['ping', '-w', '3', '-c', '1', ip]) |
281 | e9e35aaa | Michael Hanselmann | cmd = ' && '.join([ping(i) for i in check]) |
282 | a8083063 | Iustin Pop | |
283 | a8083063 | Iustin Pop | AssertEqual(StartSSH(node['primary'], cmd).wait(), 0) |
284 | a8083063 | Iustin Pop | # }}}
|
285 | a8083063 | Iustin Pop | |
286 | a8083063 | Iustin Pop | # {{{ Cluster tests
|
287 | a8083063 | Iustin Pop | def TestClusterInit(): |
288 | a8083063 | Iustin Pop | """gnt-cluster init"""
|
289 | a8083063 | Iustin Pop | master = GetMasterNode() |
290 | a8083063 | Iustin Pop | |
291 | a8083063 | Iustin Pop | cmd = ['gnt-cluster', 'init'] |
292 | a8083063 | Iustin Pop | if master.get('secondary', None): |
293 | a8083063 | Iustin Pop | cmd.append('--secondary-ip=%s' % master['secondary']) |
294 | 6f11f250 | Michael Hanselmann | if cfg.get('bridge', None): |
295 | 6f11f250 | Michael Hanselmann | cmd.append('--bridge=%s' % cfg['bridge']) |
296 | e9e35aaa | Michael Hanselmann | cmd.append('--master-netdev=%s' % cfg['bridge']) |
297 | a8083063 | Iustin Pop | cmd.append(cfg['name'])
|
298 | a8083063 | Iustin Pop | |
299 | a8083063 | Iustin Pop | AssertEqual(StartSSH(master['primary'],
|
300 | a8083063 | Iustin Pop | utils.ShellQuoteArgs(cmd)).wait(), 0)
|
301 | a8083063 | Iustin Pop | |
302 | a8083063 | Iustin Pop | |
303 | a8083063 | Iustin Pop | def TestClusterVerify(): |
304 | a8083063 | Iustin Pop | """gnt-cluster verify"""
|
305 | a8083063 | Iustin Pop | cmd = ['gnt-cluster', 'verify'] |
306 | a8083063 | Iustin Pop | AssertEqual(StartSSH(GetMasterNode()['primary'],
|
307 | a8083063 | Iustin Pop | utils.ShellQuoteArgs(cmd)).wait(), 0)
|
308 | a8083063 | Iustin Pop | |
309 | a8083063 | Iustin Pop | |
310 | a8083063 | Iustin Pop | def TestClusterInfo(): |
311 | a8083063 | Iustin Pop | """gnt-cluster info"""
|
312 | a8083063 | Iustin Pop | cmd = ['gnt-cluster', 'info'] |
313 | a8083063 | Iustin Pop | AssertEqual(StartSSH(GetMasterNode()['primary'],
|
314 | a8083063 | Iustin Pop | utils.ShellQuoteArgs(cmd)).wait(), 0)
|
315 | a8083063 | Iustin Pop | |
316 | a8083063 | Iustin Pop | |
317 | a8083063 | Iustin Pop | def TestClusterBurnin(): |
318 | a8083063 | Iustin Pop | """Burnin"""
|
319 | a8083063 | Iustin Pop | master = GetMasterNode() |
320 | a8083063 | Iustin Pop | |
321 | a8083063 | Iustin Pop | # Get as many instances as we need
|
322 | a8083063 | Iustin Pop | instances = [] |
323 | a8083063 | Iustin Pop | try:
|
324 | a8083063 | Iustin Pop | for _ in xrange(0, cfg.get('options', {}).get('burnin-instances', 1)): |
325 | a8083063 | Iustin Pop | instances.append(AcquireInstance()) |
326 | a8083063 | Iustin Pop | except OutOfInstancesError:
|
327 | a8083063 | Iustin Pop | print "Not enough instances, continuing anyway." |
328 | a8083063 | Iustin Pop | |
329 | a8083063 | Iustin Pop | if len(instances) < 1: |
330 | 3ecf6786 | Iustin Pop | raise Error("Burnin needs at least one instance") |
331 | a8083063 | Iustin Pop | |
332 | a8083063 | Iustin Pop | # Run burnin
|
333 | a8083063 | Iustin Pop | try:
|
334 | a8083063 | Iustin Pop | script = UploadFile(master['primary'], '../tools/burnin') |
335 | a8083063 | Iustin Pop | try:
|
336 | a8083063 | Iustin Pop | cmd = [script, '--os=%s' % cfg['os']] |
337 | e9e35aaa | Michael Hanselmann | cmd += [inst['name'] for inst in instances] |
338 | a8083063 | Iustin Pop | AssertEqual(StartSSH(master['primary'],
|
339 | a8083063 | Iustin Pop | utils.ShellQuoteArgs(cmd)).wait(), 0)
|
340 | a8083063 | Iustin Pop | finally:
|
341 | a8083063 | Iustin Pop | cmd = ['rm', '-f', script] |
342 | a8083063 | Iustin Pop | AssertEqual(StartSSH(master['primary'],
|
343 | a8083063 | Iustin Pop | utils.ShellQuoteArgs(cmd)).wait(), 0)
|
344 | a8083063 | Iustin Pop | finally:
|
345 | a8083063 | Iustin Pop | for inst in instances: |
346 | a8083063 | Iustin Pop | ReleaseInstance(inst) |
347 | a8083063 | Iustin Pop | |
348 | a8083063 | Iustin Pop | |
349 | a8083063 | Iustin Pop | def TestClusterMasterFailover(): |
350 | a8083063 | Iustin Pop | """gnt-cluster masterfailover"""
|
351 | a8083063 | Iustin Pop | master = GetMasterNode() |
352 | a8083063 | Iustin Pop | |
353 | a8083063 | Iustin Pop | failovermaster = AcquireNode(exclude=master) |
354 | a8083063 | Iustin Pop | try:
|
355 | a8083063 | Iustin Pop | cmd = ['gnt-cluster', 'masterfailover'] |
356 | a8083063 | Iustin Pop | AssertEqual(StartSSH(failovermaster['primary'],
|
357 | a8083063 | Iustin Pop | utils.ShellQuoteArgs(cmd)).wait(), 0)
|
358 | a8083063 | Iustin Pop | |
359 | a8083063 | Iustin Pop | cmd = ['gnt-cluster', 'masterfailover'] |
360 | a8083063 | Iustin Pop | AssertEqual(StartSSH(master['primary'],
|
361 | a8083063 | Iustin Pop | utils.ShellQuoteArgs(cmd)).wait(), 0)
|
362 | a8083063 | Iustin Pop | finally:
|
363 | a8083063 | Iustin Pop | ReleaseNode(failovermaster) |
364 | a8083063 | Iustin Pop | |
365 | a8083063 | Iustin Pop | |
366 | 180bdd1f | Michael Hanselmann | def TestClusterCopyfile(): |
367 | 180bdd1f | Michael Hanselmann | """gnt-cluster copyfile"""
|
368 | 180bdd1f | Michael Hanselmann | master = GetMasterNode() |
369 | 180bdd1f | Michael Hanselmann | |
370 | 180bdd1f | Michael Hanselmann | # Create temporary file
|
371 | 180bdd1f | Michael Hanselmann | f = tempfile.NamedTemporaryFile() |
372 | 180bdd1f | Michael Hanselmann | f.write("I'm a testfile.\n")
|
373 | 180bdd1f | Michael Hanselmann | f.flush() |
374 | 180bdd1f | Michael Hanselmann | f.seek(0)
|
375 | 180bdd1f | Michael Hanselmann | |
376 | 180bdd1f | Michael Hanselmann | # Upload file to master node
|
377 | 180bdd1f | Michael Hanselmann | testname = UploadFile(master['primary'], f.name)
|
378 | 180bdd1f | Michael Hanselmann | try:
|
379 | 180bdd1f | Michael Hanselmann | # Copy file to all nodes
|
380 | 180bdd1f | Michael Hanselmann | cmd = ['gnt-cluster', 'copyfile', testname] |
381 | 180bdd1f | Michael Hanselmann | AssertEqual(StartSSH(master['primary'],
|
382 | 180bdd1f | Michael Hanselmann | utils.ShellQuoteArgs(cmd)).wait(), 0)
|
383 | 180bdd1f | Michael Hanselmann | finally:
|
384 | 180bdd1f | Michael Hanselmann | # Remove file from all nodes
|
385 | 180bdd1f | Michael Hanselmann | for node in cfg['nodes']: |
386 | 180bdd1f | Michael Hanselmann | cmd = ['rm', '-f', testname] |
387 | 180bdd1f | Michael Hanselmann | AssertEqual(StartSSH(node['primary'],
|
388 | 180bdd1f | Michael Hanselmann | utils.ShellQuoteArgs(cmd)).wait(), 0)
|
389 | 180bdd1f | Michael Hanselmann | |
390 | 180bdd1f | Michael Hanselmann | |
391 | a8083063 | Iustin Pop | def TestClusterDestroy(): |
392 | a8083063 | Iustin Pop | """gnt-cluster destroy"""
|
393 | a8083063 | Iustin Pop | cmd = ['gnt-cluster', 'destroy', '--yes-do-it'] |
394 | a8083063 | Iustin Pop | AssertEqual(StartSSH(GetMasterNode()['primary'],
|
395 | a8083063 | Iustin Pop | utils.ShellQuoteArgs(cmd)).wait(), 0)
|
396 | a8083063 | Iustin Pop | # }}}
|
397 | a8083063 | Iustin Pop | |
398 | a8083063 | Iustin Pop | # {{{ Node tests
|
399 | a8083063 | Iustin Pop | def _NodeAdd(node): |
400 | a8083063 | Iustin Pop | if node.get('_added', False): |
401 | 3ecf6786 | Iustin Pop | raise Error("Node %s already in cluster" % node['primary']) |
402 | a8083063 | Iustin Pop | |
403 | a8083063 | Iustin Pop | cmd = ['gnt-node', 'add'] |
404 | a8083063 | Iustin Pop | if node.get('secondary', None): |
405 | a8083063 | Iustin Pop | cmd.append('--secondary-ip=%s' % node['secondary']) |
406 | a8083063 | Iustin Pop | cmd.append(node['primary'])
|
407 | a8083063 | Iustin Pop | AssertEqual(StartSSH(GetMasterNode()['primary'],
|
408 | a8083063 | Iustin Pop | utils.ShellQuoteArgs(cmd)).wait(), 0)
|
409 | a8083063 | Iustin Pop | |
410 | a8083063 | Iustin Pop | node['_added'] = True |
411 | a8083063 | Iustin Pop | |
412 | a8083063 | Iustin Pop | |
413 | a8083063 | Iustin Pop | def TestNodeAddAll(): |
414 | a8083063 | Iustin Pop | """Adding all nodes to cluster."""
|
415 | a8083063 | Iustin Pop | master = GetMasterNode() |
416 | a8083063 | Iustin Pop | for node in cfg['nodes']: |
417 | a8083063 | Iustin Pop | if node != master:
|
418 | a8083063 | Iustin Pop | _NodeAdd(node) |
419 | a8083063 | Iustin Pop | |
420 | a8083063 | Iustin Pop | |
421 | a8083063 | Iustin Pop | def _NodeRemove(node): |
422 | a8083063 | Iustin Pop | cmd = ['gnt-node', 'remove', node['primary']] |
423 | a8083063 | Iustin Pop | AssertEqual(StartSSH(GetMasterNode()['primary'],
|
424 | a8083063 | Iustin Pop | utils.ShellQuoteArgs(cmd)).wait(), 0)
|
425 | a8083063 | Iustin Pop | node['_added'] = False |
426 | a8083063 | Iustin Pop | |
427 | a8083063 | Iustin Pop | |
428 | a8083063 | Iustin Pop | def TestNodeRemoveAll(): |
429 | a8083063 | Iustin Pop | """Removing all nodes from cluster."""
|
430 | a8083063 | Iustin Pop | master = GetMasterNode() |
431 | a8083063 | Iustin Pop | for node in cfg['nodes']: |
432 | a8083063 | Iustin Pop | if node != master:
|
433 | a8083063 | Iustin Pop | _NodeRemove(node) |
434 | e9e35aaa | Michael Hanselmann | |
435 | e9e35aaa | Michael Hanselmann | |
436 | e9e35aaa | Michael Hanselmann | def TestNodeInfo(): |
437 | e9e35aaa | Michael Hanselmann | """gnt-node info"""
|
438 | e9e35aaa | Michael Hanselmann | cmd = ['gnt-node', 'info'] |
439 | e9e35aaa | Michael Hanselmann | AssertEqual(StartSSH(GetMasterNode()['primary'],
|
440 | e9e35aaa | Michael Hanselmann | utils.ShellQuoteArgs(cmd)).wait(), 0)
|
441 | a8083063 | Iustin Pop | # }}}
|
442 | a8083063 | Iustin Pop | |
443 | a8083063 | Iustin Pop | # {{{ Instance tests
|
444 | a8083063 | Iustin Pop | def _DiskTest(node, instance, args): |
445 | a8083063 | Iustin Pop | cmd = ['gnt-instance', 'add', |
446 | a8083063 | Iustin Pop | '--os-type=%s' % cfg['os'], |
447 | a8083063 | Iustin Pop | '--os-size=%s' % cfg['os-size'], |
448 | a8083063 | Iustin Pop | '--swap-size=%s' % cfg['swap-size'], |
449 | a8083063 | Iustin Pop | '--memory=%s' % cfg['mem'], |
450 | a8083063 | Iustin Pop | '--node=%s' % node['primary']] |
451 | a8083063 | Iustin Pop | if args:
|
452 | a8083063 | Iustin Pop | cmd += args |
453 | a8083063 | Iustin Pop | cmd.append(instance['name'])
|
454 | a8083063 | Iustin Pop | |
455 | a8083063 | Iustin Pop | AssertEqual(StartSSH(GetMasterNode()['primary'],
|
456 | a8083063 | Iustin Pop | utils.ShellQuoteArgs(cmd)).wait(), 0)
|
457 | a8083063 | Iustin Pop | return instance
|
458 | a8083063 | Iustin Pop | |
459 | a8083063 | Iustin Pop | |
460 | a8083063 | Iustin Pop | def TestInstanceAddWithPlainDisk(node): |
461 | a8083063 | Iustin Pop | """gnt-instance add -t plain"""
|
462 | a8083063 | Iustin Pop | return _DiskTest(node, AcquireInstance(), ['--disk-template=plain']) |
463 | a8083063 | Iustin Pop | |
464 | a8083063 | Iustin Pop | |
465 | a8083063 | Iustin Pop | def TestInstanceAddWithLocalMirrorDisk(node): |
466 | a8083063 | Iustin Pop | """gnt-instance add -t local_raid1"""
|
467 | a8083063 | Iustin Pop | return _DiskTest(node, AcquireInstance(), ['--disk-template=local_raid1']) |
468 | a8083063 | Iustin Pop | |
469 | a8083063 | Iustin Pop | |
470 | a8083063 | Iustin Pop | def TestInstanceAddWithRemoteRaidDisk(node, node2): |
471 | a8083063 | Iustin Pop | """gnt-instance add -t remote_raid1"""
|
472 | a8083063 | Iustin Pop | return _DiskTest(node, AcquireInstance(),
|
473 | a8083063 | Iustin Pop | ['--disk-template=remote_raid1',
|
474 | a8083063 | Iustin Pop | '--secondary-node=%s' % node2['primary']]) |
475 | a8083063 | Iustin Pop | |
476 | a8083063 | Iustin Pop | |
477 | a8083063 | Iustin Pop | def TestInstanceRemove(instance): |
478 | a8083063 | Iustin Pop | """gnt-instance remove"""
|
479 | a8083063 | Iustin Pop | cmd = ['gnt-instance', 'remove', '-f', instance['name']] |
480 | a8083063 | Iustin Pop | AssertEqual(StartSSH(GetMasterNode()['primary'],
|
481 | a8083063 | Iustin Pop | utils.ShellQuoteArgs(cmd)).wait(), 0)
|
482 | a8083063 | Iustin Pop | |
483 | a8083063 | Iustin Pop | ReleaseInstance(instance) |
484 | a8083063 | Iustin Pop | |
485 | a8083063 | Iustin Pop | |
486 | a8083063 | Iustin Pop | def TestInstanceStartup(instance): |
487 | a8083063 | Iustin Pop | """gnt-instance startup"""
|
488 | a8083063 | Iustin Pop | cmd = ['gnt-instance', 'startup', instance['name']] |
489 | a8083063 | Iustin Pop | AssertEqual(StartSSH(GetMasterNode()['primary'],
|
490 | a8083063 | Iustin Pop | utils.ShellQuoteArgs(cmd)).wait(), 0)
|
491 | a8083063 | Iustin Pop | |
492 | a8083063 | Iustin Pop | |
493 | a8083063 | Iustin Pop | def TestInstanceShutdown(instance): |
494 | a8083063 | Iustin Pop | """gnt-instance shutdown"""
|
495 | a8083063 | Iustin Pop | cmd = ['gnt-instance', 'shutdown', instance['name']] |
496 | a8083063 | Iustin Pop | AssertEqual(StartSSH(GetMasterNode()['primary'],
|
497 | a8083063 | Iustin Pop | utils.ShellQuoteArgs(cmd)).wait(), 0)
|
498 | a8083063 | Iustin Pop | |
499 | a8083063 | Iustin Pop | |
500 | a8083063 | Iustin Pop | def TestInstanceFailover(instance): |
501 | a8083063 | Iustin Pop | """gnt-instance failover"""
|
502 | a8083063 | Iustin Pop | cmd = ['gnt-instance', 'failover', '--force', instance['name']] |
503 | a8083063 | Iustin Pop | AssertEqual(StartSSH(GetMasterNode()['primary'],
|
504 | a8083063 | Iustin Pop | utils.ShellQuoteArgs(cmd)).wait(), 0)
|
505 | e9e35aaa | Michael Hanselmann | |
506 | e9e35aaa | Michael Hanselmann | |
507 | e9e35aaa | Michael Hanselmann | def TestInstanceInfo(instance): |
508 | e9e35aaa | Michael Hanselmann | """gnt-instance info"""
|
509 | e9e35aaa | Michael Hanselmann | cmd = ['gnt-instance', 'info', instance['name']] |
510 | e9e35aaa | Michael Hanselmann | AssertEqual(StartSSH(GetMasterNode()['primary'],
|
511 | e9e35aaa | Michael Hanselmann | utils.ShellQuoteArgs(cmd)).wait(), 0)
|
512 | a8083063 | Iustin Pop | # }}}
|
513 | a8083063 | Iustin Pop | |
514 | a8083063 | Iustin Pop | # {{{ Daemon tests
|
515 | a8083063 | Iustin Pop | def _ResolveInstanceName(instance): |
516 | a8083063 | Iustin Pop | """Gets the full Xen name of an instance.
|
517 | a8083063 | Iustin Pop |
|
518 | a8083063 | Iustin Pop | """
|
519 | a8083063 | Iustin Pop | master = GetMasterNode() |
520 | a8083063 | Iustin Pop | |
521 | a8083063 | Iustin Pop | info_cmd = utils.ShellQuoteArgs(['gnt-instance', 'info', instance['name']]) |
522 | a8083063 | Iustin Pop | sed_cmd = utils.ShellQuoteArgs(['sed', '-n', '-e', 's/^Instance name: *//p']) |
523 | a8083063 | Iustin Pop | |
524 | a8083063 | Iustin Pop | cmd = '%s | %s' % (info_cmd, sed_cmd)
|
525 | a8083063 | Iustin Pop | p = subprocess.Popen(GetSSHCommand(master['primary'], cmd), shell=False, |
526 | a8083063 | Iustin Pop | stdout=subprocess.PIPE) |
527 | a8083063 | Iustin Pop | AssertEqual(p.wait(), 0)
|
528 | a8083063 | Iustin Pop | |
529 | a8083063 | Iustin Pop | return p.stdout.read().strip()
|
530 | a8083063 | Iustin Pop | |
531 | a8083063 | Iustin Pop | |
532 | a8083063 | Iustin Pop | def _InstanceRunning(node, name): |
533 | a8083063 | Iustin Pop | """Checks whether an instance is running.
|
534 | a8083063 | Iustin Pop |
|
535 | a8083063 | Iustin Pop | Args:
|
536 | a8083063 | Iustin Pop | node: Node the instance runs on
|
537 | a8083063 | Iustin Pop | name: Full name of Xen instance
|
538 | a8083063 | Iustin Pop | """
|
539 | a8083063 | Iustin Pop | cmd = utils.ShellQuoteArgs(['xm', 'list', name]) + ' >/dev/null' |
540 | a8083063 | Iustin Pop | ret = StartSSH(node['primary'], cmd).wait()
|
541 | a8083063 | Iustin Pop | return ret == 0 |
542 | a8083063 | Iustin Pop | |
543 | a8083063 | Iustin Pop | |
544 | a8083063 | Iustin Pop | def _XmShutdownInstance(node, name): |
545 | a8083063 | Iustin Pop | """Shuts down instance using "xm" and waits for completion.
|
546 | a8083063 | Iustin Pop |
|
547 | a8083063 | Iustin Pop | Args:
|
548 | a8083063 | Iustin Pop | node: Node the instance runs on
|
549 | a8083063 | Iustin Pop | name: Full name of Xen instance
|
550 | a8083063 | Iustin Pop | """
|
551 | a8083063 | Iustin Pop | cmd = ['xm', 'shutdown', name] |
552 | a8083063 | Iustin Pop | AssertEqual(StartSSH(GetMasterNode()['primary'],
|
553 | a8083063 | Iustin Pop | utils.ShellQuoteArgs(cmd)).wait(), 0)
|
554 | a8083063 | Iustin Pop | |
555 | a8083063 | Iustin Pop | # Wait up to a minute
|
556 | a8083063 | Iustin Pop | end = time.time() + 60
|
557 | a8083063 | Iustin Pop | while time.time() <= end:
|
558 | a8083063 | Iustin Pop | if not _InstanceRunning(node, name): |
559 | a8083063 | Iustin Pop | break
|
560 | a8083063 | Iustin Pop | time.sleep(5)
|
561 | a8083063 | Iustin Pop | else:
|
562 | 3ecf6786 | Iustin Pop | raise Error("xm shutdown failed") |
563 | a8083063 | Iustin Pop | |
564 | a8083063 | Iustin Pop | |
565 | a8083063 | Iustin Pop | def _ResetWatcherDaemon(node): |
566 | a8083063 | Iustin Pop | """Removes the watcher daemon's state file.
|
567 | a8083063 | Iustin Pop |
|
568 | a8083063 | Iustin Pop | Args:
|
569 | a8083063 | Iustin Pop | node: Node to be reset
|
570 | a8083063 | Iustin Pop | """
|
571 | a8083063 | Iustin Pop | cmd = ['rm', '-f', constants.WATCHER_STATEFILE] |
572 | a8083063 | Iustin Pop | AssertEqual(StartSSH(node['primary'],
|
573 | a8083063 | Iustin Pop | utils.ShellQuoteArgs(cmd)).wait(), 0)
|
574 | a8083063 | Iustin Pop | |
575 | a8083063 | Iustin Pop | |
576 | a8083063 | Iustin Pop | def TestInstanceAutomaticRestart(node, instance): |
577 | a8083063 | Iustin Pop | """Test automatic restart of instance by ganeti-watcher.
|
578 | a8083063 | Iustin Pop |
|
579 | a8083063 | Iustin Pop | Note: takes up to 6 minutes to complete.
|
580 | a8083063 | Iustin Pop | """
|
581 | a8083063 | Iustin Pop | master = GetMasterNode() |
582 | a8083063 | Iustin Pop | inst_name = _ResolveInstanceName(instance) |
583 | a8083063 | Iustin Pop | |
584 | a8083063 | Iustin Pop | _ResetWatcherDaemon(node) |
585 | a8083063 | Iustin Pop | _XmShutdownInstance(node, inst_name) |
586 | a8083063 | Iustin Pop | |
587 | a8083063 | Iustin Pop | # Give it a bit more than five minutes to start again
|
588 | a8083063 | Iustin Pop | restart_at = time.time() + 330
|
589 | a8083063 | Iustin Pop | |
590 | a8083063 | Iustin Pop | # Wait until it's running again
|
591 | a8083063 | Iustin Pop | while time.time() <= restart_at:
|
592 | a8083063 | Iustin Pop | if _InstanceRunning(node, inst_name):
|
593 | a8083063 | Iustin Pop | break
|
594 | a8083063 | Iustin Pop | time.sleep(15)
|
595 | a8083063 | Iustin Pop | else:
|
596 | 3ecf6786 | Iustin Pop | raise Error("Daemon didn't restart instance in time") |
597 | a8083063 | Iustin Pop | |
598 | a8083063 | Iustin Pop | cmd = ['gnt-instance', 'info', inst_name] |
599 | a8083063 | Iustin Pop | AssertEqual(StartSSH(master['primary'],
|
600 | a8083063 | Iustin Pop | utils.ShellQuoteArgs(cmd)).wait(), 0)
|
601 | a8083063 | Iustin Pop | |
602 | a8083063 | Iustin Pop | |
603 | a8083063 | Iustin Pop | def TestInstanceConsecutiveFailures(node, instance): |
604 | a8083063 | Iustin Pop | """Test five consecutive instance failures.
|
605 | a8083063 | Iustin Pop |
|
606 | a8083063 | Iustin Pop | Note: takes at least 35 minutes to complete.
|
607 | a8083063 | Iustin Pop | """
|
608 | a8083063 | Iustin Pop | master = GetMasterNode() |
609 | a8083063 | Iustin Pop | inst_name = _ResolveInstanceName(instance) |
610 | a8083063 | Iustin Pop | |
611 | a8083063 | Iustin Pop | _ResetWatcherDaemon(node) |
612 | a8083063 | Iustin Pop | _XmShutdownInstance(node, inst_name) |
613 | a8083063 | Iustin Pop | |
614 | a8083063 | Iustin Pop | # Do shutdowns for 30 minutes
|
615 | a8083063 | Iustin Pop | finished_at = time.time() + (35 * 60) |
616 | a8083063 | Iustin Pop | |
617 | a8083063 | Iustin Pop | while time.time() <= finished_at:
|
618 | a8083063 | Iustin Pop | if _InstanceRunning(node, inst_name):
|
619 | a8083063 | Iustin Pop | _XmShutdownInstance(node, inst_name) |
620 | a8083063 | Iustin Pop | time.sleep(30)
|
621 | a8083063 | Iustin Pop | |
622 | a8083063 | Iustin Pop | # Check for some time whether the instance doesn't start again
|
623 | a8083063 | Iustin Pop | check_until = time.time() + 330
|
624 | a8083063 | Iustin Pop | while time.time() <= check_until:
|
625 | a8083063 | Iustin Pop | if _InstanceRunning(node, inst_name):
|
626 | 3ecf6786 | Iustin Pop | raise Error("Instance started when it shouldn't") |
627 | a8083063 | Iustin Pop | time.sleep(30)
|
628 | a8083063 | Iustin Pop | |
629 | a8083063 | Iustin Pop | cmd = ['gnt-instance', 'info', inst_name] |
630 | a8083063 | Iustin Pop | AssertEqual(StartSSH(master['primary'],
|
631 | a8083063 | Iustin Pop | utils.ShellQuoteArgs(cmd)).wait(), 0)
|
632 | a8083063 | Iustin Pop | # }}}
|
633 | a8083063 | Iustin Pop | |
634 | 94508060 | Michael Hanselmann | # {{{ Other tests
|
635 | 94508060 | Michael Hanselmann | def TestUploadKnownHostsFile(localpath): |
636 | 94508060 | Michael Hanselmann | """Uploading known_hosts file.
|
637 | 94508060 | Michael Hanselmann |
|
638 | 94508060 | Michael Hanselmann | """
|
639 | 94508060 | Michael Hanselmann | master = GetMasterNode() |
640 | 94508060 | Michael Hanselmann | |
641 | 94508060 | Michael Hanselmann | tmpfile = UploadFile(master['primary'], localpath)
|
642 | 94508060 | Michael Hanselmann | try:
|
643 | 94508060 | Michael Hanselmann | cmd = ['mv', tmpfile, constants.SSH_KNOWN_HOSTS_FILE]
|
644 | 94508060 | Michael Hanselmann | AssertEqual(StartSSH(master['primary'],
|
645 | 94508060 | Michael Hanselmann | utils.ShellQuoteArgs(cmd)).wait(), 0)
|
646 | 94508060 | Michael Hanselmann | except:
|
647 | 94508060 | Michael Hanselmann | cmd = ['rm', '-f', tmpfile] |
648 | 94508060 | Michael Hanselmann | AssertEqual(StartSSH(master['primary'],
|
649 | 94508060 | Michael Hanselmann | utils.ShellQuoteArgs(cmd)).wait(), 0)
|
650 | 94508060 | Michael Hanselmann | raise
|
651 | 94508060 | Michael Hanselmann | |
652 | 94508060 | Michael Hanselmann | # }}}
|
653 | 94508060 | Michael Hanselmann | |
654 | a8083063 | Iustin Pop | # {{{ Main program
|
655 | a8083063 | Iustin Pop | if __name__ == '__main__': |
656 | a8083063 | Iustin Pop | # {{{ Option parsing
|
657 | 94508060 | Michael Hanselmann | parser = OptionParser(usage="%prog [options] <config-file> "
|
658 | 94508060 | Michael Hanselmann | "<known-hosts-file>")
|
659 | a8083063 | Iustin Pop | parser.add_option('--dry-run', dest='dry_run', |
660 | a8083063 | Iustin Pop | action="store_true",
|
661 | a8083063 | Iustin Pop | help="Show what would be done")
|
662 | a8083063 | Iustin Pop | parser.add_option('--yes-do-it', dest='yes_do_it', |
663 | a8083063 | Iustin Pop | action="store_true",
|
664 | a8083063 | Iustin Pop | help="Really execute the tests")
|
665 | a8083063 | Iustin Pop | (options, args) = parser.parse_args() |
666 | a8083063 | Iustin Pop | # }}}
|
667 | a8083063 | Iustin Pop | |
668 | 94508060 | Michael Hanselmann | if len(args) == 2: |
669 | 94508060 | Michael Hanselmann | (config_file, known_hosts_file) = args |
670 | a8083063 | Iustin Pop | else:
|
671 | 94508060 | Michael Hanselmann | parser.error("Not enough arguments.")
|
672 | a8083063 | Iustin Pop | |
673 | a8083063 | Iustin Pop | if not options.yes_do_it: |
674 | a8083063 | Iustin Pop | print ("Executing this script irreversibly destroys any Ganeti\n" |
675 | a8083063 | Iustin Pop | "configuration on all nodes involved. If you really want\n"
|
676 | a8083063 | Iustin Pop | "to start testing, supply the --yes-do-it option.")
|
677 | a8083063 | Iustin Pop | sys.exit(1)
|
678 | a8083063 | Iustin Pop | |
679 | a8083063 | Iustin Pop | f = open(config_file, 'r') |
680 | a8083063 | Iustin Pop | try:
|
681 | a8083063 | Iustin Pop | cfg = yaml.load(f.read()) |
682 | a8083063 | Iustin Pop | finally:
|
683 | a8083063 | Iustin Pop | f.close() |
684 | a8083063 | Iustin Pop | |
685 | a8083063 | Iustin Pop | RunTest(TestConfig) |
686 | a8083063 | Iustin Pop | |
687 | 94508060 | Michael Hanselmann | RunTest(TestUploadKnownHostsFile, known_hosts_file) |
688 | 94508060 | Michael Hanselmann | |
689 | a8083063 | Iustin Pop | if TestEnabled('env'): |
690 | a8083063 | Iustin Pop | RunTest(TestSshConnection) |
691 | a8083063 | Iustin Pop | RunTest(TestIcmpPing) |
692 | a8083063 | Iustin Pop | RunTest(TestGanetiCommands) |
693 | a8083063 | Iustin Pop | |
694 | a8083063 | Iustin Pop | RunTest(TestClusterInit) |
695 | a8083063 | Iustin Pop | |
696 | 180bdd1f | Michael Hanselmann | RunTest(TestNodeAddAll) |
697 | 180bdd1f | Michael Hanselmann | |
698 | a8083063 | Iustin Pop | if TestEnabled('cluster-verify'): |
699 | a8083063 | Iustin Pop | RunTest(TestClusterVerify) |
700 | e9e35aaa | Michael Hanselmann | |
701 | e9e35aaa | Michael Hanselmann | if TestEnabled('cluster-info'): |
702 | a8083063 | Iustin Pop | RunTest(TestClusterInfo) |
703 | a8083063 | Iustin Pop | |
704 | 180bdd1f | Michael Hanselmann | if TestEnabled('cluster-copyfile'): |
705 | 180bdd1f | Michael Hanselmann | RunTest(TestClusterCopyfile) |
706 | a8083063 | Iustin Pop | |
707 | e9e35aaa | Michael Hanselmann | if TestEnabled('node-info'): |
708 | e9e35aaa | Michael Hanselmann | RunTest(TestNodeInfo) |
709 | e9e35aaa | Michael Hanselmann | |
710 | a8083063 | Iustin Pop | if TestEnabled('cluster-burnin'): |
711 | a8083063 | Iustin Pop | RunTest(TestClusterBurnin) |
712 | a8083063 | Iustin Pop | |
713 | a8083063 | Iustin Pop | if TestEnabled('cluster-master-failover'): |
714 | a8083063 | Iustin Pop | RunTest(TestClusterMasterFailover) |
715 | a8083063 | Iustin Pop | |
716 | a8083063 | Iustin Pop | node = AcquireNode() |
717 | a8083063 | Iustin Pop | try:
|
718 | a8083063 | Iustin Pop | if TestEnabled('instance-add-plain-disk'): |
719 | a8083063 | Iustin Pop | instance = RunTest(TestInstanceAddWithPlainDisk, node) |
720 | a8083063 | Iustin Pop | RunTest(TestInstanceShutdown, instance) |
721 | a8083063 | Iustin Pop | RunTest(TestInstanceStartup, instance) |
722 | a8083063 | Iustin Pop | |
723 | e9e35aaa | Michael Hanselmann | if TestEnabled('instance-info'): |
724 | e9e35aaa | Michael Hanselmann | RunTest(TestInstanceInfo, instance) |
725 | e9e35aaa | Michael Hanselmann | |
726 | a8083063 | Iustin Pop | if TestEnabled('instance-automatic-restart'): |
727 | a8083063 | Iustin Pop | RunTest(TestInstanceAutomaticRestart, node, instance) |
728 | a8083063 | Iustin Pop | |
729 | a8083063 | Iustin Pop | if TestEnabled('instance-consecutive-failures'): |
730 | a8083063 | Iustin Pop | RunTest(TestInstanceConsecutiveFailures, node, instance) |
731 | a8083063 | Iustin Pop | |
732 | a8083063 | Iustin Pop | RunTest(TestInstanceRemove, instance) |
733 | a8083063 | Iustin Pop | del instance
|
734 | a8083063 | Iustin Pop | |
735 | a8083063 | Iustin Pop | if TestEnabled('instance-add-local-mirror-disk'): |
736 | a8083063 | Iustin Pop | instance = RunTest(TestInstanceAddWithLocalMirrorDisk, node) |
737 | a8083063 | Iustin Pop | RunTest(TestInstanceShutdown, instance) |
738 | a8083063 | Iustin Pop | RunTest(TestInstanceStartup, instance) |
739 | e9e35aaa | Michael Hanselmann | |
740 | e9e35aaa | Michael Hanselmann | if TestEnabled('instance-info'): |
741 | e9e35aaa | Michael Hanselmann | RunTest(TestInstanceInfo, instance) |
742 | e9e35aaa | Michael Hanselmann | |
743 | a8083063 | Iustin Pop | RunTest(TestInstanceRemove, instance) |
744 | a8083063 | Iustin Pop | del instance
|
745 | a8083063 | Iustin Pop | |
746 | a8083063 | Iustin Pop | if TestEnabled('instance-add-remote-raid-disk'): |
747 | a8083063 | Iustin Pop | node2 = AcquireNode(exclude=node) |
748 | a8083063 | Iustin Pop | try:
|
749 | a8083063 | Iustin Pop | instance = RunTest(TestInstanceAddWithRemoteRaidDisk, node, node2) |
750 | a8083063 | Iustin Pop | RunTest(TestInstanceShutdown, instance) |
751 | a8083063 | Iustin Pop | RunTest(TestInstanceStartup, instance) |
752 | a8083063 | Iustin Pop | |
753 | e9e35aaa | Michael Hanselmann | if TestEnabled('instance-info'): |
754 | e9e35aaa | Michael Hanselmann | RunTest(TestInstanceInfo, instance) |
755 | e9e35aaa | Michael Hanselmann | |
756 | a8083063 | Iustin Pop | if TestEnabled('instance-failover'): |
757 | a8083063 | Iustin Pop | RunTest(TestInstanceFailover, instance) |
758 | a8083063 | Iustin Pop | |
759 | a8083063 | Iustin Pop | RunTest(TestInstanceRemove, instance) |
760 | a8083063 | Iustin Pop | del instance
|
761 | a8083063 | Iustin Pop | finally:
|
762 | a8083063 | Iustin Pop | ReleaseNode(node2) |
763 | a8083063 | Iustin Pop | |
764 | a8083063 | Iustin Pop | finally:
|
765 | a8083063 | Iustin Pop | ReleaseNode(node) |
766 | a8083063 | Iustin Pop | |
767 | a8083063 | Iustin Pop | RunTest(TestNodeRemoveAll) |
768 | a8083063 | Iustin Pop | |
769 | a8083063 | Iustin Pop | if TestEnabled('cluster-destroy'): |
770 | a8083063 | Iustin Pop | RunTest(TestClusterDestroy) |
771 | a8083063 | Iustin Pop | # }}}
|
772 | a8083063 | Iustin Pop | |
773 | a8083063 | Iustin Pop | # vim: foldmethod=marker : |