Statistics
| Branch: | Tag: | Revision:

root / tools / burnin @ a4af651e

History | View | Annotate | Download (15 kB)

1 a8083063 Iustin Pop
#!/usr/bin/python
2 a8083063 Iustin Pop
#
3 a8083063 Iustin Pop
4 01b69ec5 Michael Hanselmann
# Copyright (C) 2006, 2007 Google Inc.
5 01b69ec5 Michael Hanselmann
#
6 01b69ec5 Michael Hanselmann
# This program is free software; you can redistribute it and/or modify
7 01b69ec5 Michael Hanselmann
# it under the terms of the GNU General Public License as published by
8 01b69ec5 Michael Hanselmann
# the Free Software Foundation; either version 2 of the License, or
9 01b69ec5 Michael Hanselmann
# (at your option) any later version.
10 01b69ec5 Michael Hanselmann
#
11 01b69ec5 Michael Hanselmann
# This program is distributed in the hope that it will be useful, but
12 01b69ec5 Michael Hanselmann
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 01b69ec5 Michael Hanselmann
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 01b69ec5 Michael Hanselmann
# General Public License for more details.
15 01b69ec5 Michael Hanselmann
#
16 01b69ec5 Michael Hanselmann
# You should have received a copy of the GNU General Public License
17 01b69ec5 Michael Hanselmann
# along with this program; if not, write to the Free Software
18 01b69ec5 Michael Hanselmann
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 01b69ec5 Michael Hanselmann
# 02110-1301, USA.
20 01b69ec5 Michael Hanselmann
21 01b69ec5 Michael Hanselmann
22 01b69ec5 Michael Hanselmann
"""Burnin program
23 01b69ec5 Michael Hanselmann
24 01b69ec5 Michael Hanselmann
"""
25 175f44c2 Iustin Pop
26 bd5e77f9 Guido Trotter
import os
27 a8083063 Iustin Pop
import sys
28 a8083063 Iustin Pop
import optparse
29 175f44c2 Iustin Pop
from itertools import izip, islice, cycle
30 21546b1c Iustin Pop
from cStringIO import StringIO
31 a8083063 Iustin Pop
32 a8083063 Iustin Pop
from ganeti import opcodes
33 a8083063 Iustin Pop
from ganeti import mcpu
34 a8083063 Iustin Pop
from ganeti import constants
35 a8083063 Iustin Pop
from ganeti import cli
36 a8083063 Iustin Pop
from ganeti import logger
37 9f13fc7a Iustin Pop
from ganeti import errors
38 9f13fc7a Iustin Pop
from ganeti import utils
39 a8083063 Iustin Pop
40 01b69ec5 Michael Hanselmann
41 9f13fc7a Iustin Pop
USAGE = ("\tburnin -o OS_NAME [options...] instance_name ...")
42 a8083063 Iustin Pop
43 01b69ec5 Michael Hanselmann
44 a8083063 Iustin Pop
def Usage():
45 a8083063 Iustin Pop
  """Shows program usage information and exits the program."""
46 a8083063 Iustin Pop
47 a8083063 Iustin Pop
  print >> sys.stderr, "Usage:"
48 a8083063 Iustin Pop
  print >> sys.stderr, USAGE
49 a8083063 Iustin Pop
  sys.exit(2)
50 a8083063 Iustin Pop
51 01b69ec5 Michael Hanselmann
52 21546b1c Iustin Pop
def Log(msg):
53 3ecf6786 Iustin Pop
  """Simple function that prints out its argument.
54 3ecf6786 Iustin Pop
55 3ecf6786 Iustin Pop
  """
56 3ecf6786 Iustin Pop
  print msg
57 84cc52ab Michael Hanselmann
  sys.stdout.flush()
58 a8083063 Iustin Pop
59 01b69ec5 Michael Hanselmann
60 175f44c2 Iustin Pop
class Burner(object):
61 175f44c2 Iustin Pop
  """Burner class."""
62 175f44c2 Iustin Pop
63 175f44c2 Iustin Pop
  def __init__(self):
64 175f44c2 Iustin Pop
    """Constructor."""
65 21546b1c Iustin Pop
    logger.SetupLogging(debug=False, program="ganeti/burnin")
66 21546b1c Iustin Pop
    self._feed_buf = StringIO()
67 21546b1c Iustin Pop
    self.proc = mcpu.Processor(feedback=self.Feedback)
68 175f44c2 Iustin Pop
    self.nodes = []
69 175f44c2 Iustin Pop
    self.instances = []
70 175f44c2 Iustin Pop
    self.to_rem = []
71 175f44c2 Iustin Pop
    self.opts = None
72 175f44c2 Iustin Pop
    self.ParseOptions()
73 175f44c2 Iustin Pop
    self.GetState()
74 175f44c2 Iustin Pop
75 21546b1c Iustin Pop
  def ClearFeedbackBuf(self):
76 21546b1c Iustin Pop
    """Clear the feedback buffer."""
77 21546b1c Iustin Pop
    self._feed_buf.truncate(0)
78 21546b1c Iustin Pop
79 21546b1c Iustin Pop
  def GetFeedbackBuf(self):
80 21546b1c Iustin Pop
    """Return the contents of the buffer."""
81 21546b1c Iustin Pop
    return self._feed_buf.getvalue()
82 21546b1c Iustin Pop
83 21546b1c Iustin Pop
  def Feedback(self, msg):
84 21546b1c Iustin Pop
    """Acumulate feedback in our buffer."""
85 21546b1c Iustin Pop
    self._feed_buf.write(msg)
86 21546b1c Iustin Pop
    self._feed_buf.write("\n")
87 d7b47a77 Iustin Pop
    if self.opts.verbose:
88 d7b47a77 Iustin Pop
      Log(msg)
89 21546b1c Iustin Pop
90 21546b1c Iustin Pop
  def ExecOp(self, op):
91 21546b1c Iustin Pop
    """Execute an opcode and manage the exec buffer."""
92 21546b1c Iustin Pop
    self.ClearFeedbackBuf()
93 685ee993 Iustin Pop
    return cli.SubmitOpCode(op)
94 21546b1c Iustin Pop
95 175f44c2 Iustin Pop
  def ParseOptions(self):
96 175f44c2 Iustin Pop
    """Parses the command line options.
97 175f44c2 Iustin Pop
98 175f44c2 Iustin Pop
    In case of command line errors, it will show the usage and exit the
99 175f44c2 Iustin Pop
    program.
100 175f44c2 Iustin Pop
101 175f44c2 Iustin Pop
    """
102 175f44c2 Iustin Pop
103 175f44c2 Iustin Pop
    parser = optparse.OptionParser(usage="\n%s" % USAGE,
104 175f44c2 Iustin Pop
                                   version="%%prog (ganeti) %s" %
105 175f44c2 Iustin Pop
                                   constants.RELEASE_VERSION,
106 175f44c2 Iustin Pop
                                   option_class=cli.CliOption)
107 175f44c2 Iustin Pop
108 175f44c2 Iustin Pop
    parser.add_option("-o", "--os", dest="os", default=None,
109 175f44c2 Iustin Pop
                      help="OS to use during burnin",
110 175f44c2 Iustin Pop
                      metavar="<OS>")
111 175f44c2 Iustin Pop
    parser.add_option("--os-size", dest="os_size", help="Disk size",
112 175f44c2 Iustin Pop
                      default=4 * 1024, type="unit", metavar="<size>")
113 175f44c2 Iustin Pop
    parser.add_option("--swap-size", dest="swap_size", help="Swap size",
114 175f44c2 Iustin Pop
                      default=4 * 1024, type="unit", metavar="<size>")
115 5e767b34 Iustin Pop
    parser.add_option("--mem-size", dest="mem_size", help="Memory size",
116 5e767b34 Iustin Pop
                      default=128, type="unit", metavar="<size>")
117 175f44c2 Iustin Pop
    parser.add_option("-v", "--verbose",
118 175f44c2 Iustin Pop
                      action="store_true", dest="verbose", default=False,
119 175f44c2 Iustin Pop
                      help="print command execution messages to stdout")
120 175f44c2 Iustin Pop
    parser.add_option("--no-replace1", dest="do_replace1",
121 175f44c2 Iustin Pop
                      help="Skip disk replacement with the same secondary",
122 175f44c2 Iustin Pop
                      action="store_false", default=True)
123 175f44c2 Iustin Pop
    parser.add_option("--no-replace2", dest="do_replace2",
124 175f44c2 Iustin Pop
                      help="Skip disk replacement with a different secondary",
125 175f44c2 Iustin Pop
                      action="store_false", default=True)
126 175f44c2 Iustin Pop
    parser.add_option("--no-failover", dest="do_failover",
127 175f44c2 Iustin Pop
                      help="Skip instance failovers", action="store_false",
128 175f44c2 Iustin Pop
                      default=True)
129 bd5e77f9 Guido Trotter
    parser.add_option("--no-importexport", dest="do_importexport",
130 bd5e77f9 Guido Trotter
                      help="Skip instance export/import", action="store_false",
131 bd5e77f9 Guido Trotter
                      default=True)
132 d4844f0f Guido Trotter
    parser.add_option("--no-startstop", dest="do_startstop",
133 d4844f0f Guido Trotter
                      help="Skip instance stop/start", action="store_false",
134 d4844f0f Guido Trotter
                      default=True)
135 054a8696 Manuel Franceschini
    parser.add_option("--rename", dest="rename", default=None,
136 054a8696 Manuel Franceschini
                      help="Give one unused instance name which is taken"
137 054a8696 Manuel Franceschini
                           " to start the renaming sequence",
138 054a8696 Manuel Franceschini
                      metavar="<instance_name>")
139 175f44c2 Iustin Pop
    parser.add_option("-t", "--disk-template", dest="disk_template",
140 2f505cb5 Manuel Franceschini
                      choices=("diskless", "file", "plain", "drbd"),
141 f9193417 Iustin Pop
                      default="drbd",
142 2f505cb5 Manuel Franceschini
                      help="Disk template (diskless, file, plain or drbd)"
143 2f505cb5 Manuel Franceschini
                            " [drbd]")
144 175f44c2 Iustin Pop
    parser.add_option("-n", "--nodes", dest="nodes", default="",
145 175f44c2 Iustin Pop
                      help="Comma separated list of nodes to perform"
146 175f44c2 Iustin Pop
                      " the burnin on (defaults to all nodes)")
147 b91bde14 Iustin Pop
    parser.add_option("--iallocator", dest="iallocator",
148 b91bde14 Iustin Pop
                      default=None, type="string",
149 b91bde14 Iustin Pop
                      help="Perform the allocation using an iallocator"
150 b91bde14 Iustin Pop
                      " instead of fixed node spread (node restrictions no"
151 b91bde14 Iustin Pop
                      " longer apply, therefore -n/--nodes must not be used")
152 175f44c2 Iustin Pop
153 175f44c2 Iustin Pop
    options, args = parser.parse_args()
154 175f44c2 Iustin Pop
    if len(args) < 1 or options.os is None:
155 175f44c2 Iustin Pop
      Usage()
156 175f44c2 Iustin Pop
157 f9193417 Iustin Pop
    supported_disk_templates = (constants.DT_DISKLESS,
158 2f505cb5 Manuel Franceschini
                                constants.DT_FILE,
159 f9193417 Iustin Pop
                                constants.DT_PLAIN,
160 12c3449a Michael Hanselmann
                                constants.DT_DRBD8)
161 12c3449a Michael Hanselmann
    if options.disk_template not in supported_disk_templates:
162 21546b1c Iustin Pop
      Log("Unknown disk template '%s'" % options.disk_template)
163 175f44c2 Iustin Pop
      sys.exit(1)
164 175f44c2 Iustin Pop
165 b91bde14 Iustin Pop
    if options.nodes and options.iallocator:
166 b91bde14 Iustin Pop
      Log("Give either the nodes option or the iallocator option, not both")
167 b91bde14 Iustin Pop
      sys.exit(1)
168 b91bde14 Iustin Pop
169 175f44c2 Iustin Pop
    self.opts = options
170 175f44c2 Iustin Pop
    self.instances = args
171 175f44c2 Iustin Pop
172 175f44c2 Iustin Pop
  def GetState(self):
173 175f44c2 Iustin Pop
    """Read the cluster state from the config."""
174 175f44c2 Iustin Pop
    if self.opts.nodes:
175 175f44c2 Iustin Pop
      names = self.opts.nodes.split(",")
176 175f44c2 Iustin Pop
    else:
177 175f44c2 Iustin Pop
      names = []
178 175f44c2 Iustin Pop
    try:
179 175f44c2 Iustin Pop
      op = opcodes.OpQueryNodes(output_fields=["name"], names=names)
180 21546b1c Iustin Pop
      result = self.ExecOp(op)
181 175f44c2 Iustin Pop
    except errors.GenericError, err:
182 175f44c2 Iustin Pop
      err_code, msg = cli.FormatError(err)
183 21546b1c Iustin Pop
      Log(msg)
184 175f44c2 Iustin Pop
      sys.exit(err_code)
185 175f44c2 Iustin Pop
    self.nodes = [data[0] for data in result]
186 175f44c2 Iustin Pop
187 1f9430d6 Iustin Pop
    result = self.ExecOp(opcodes.OpDiagnoseOS(output_fields=["name", "valid"],
188 1f9430d6 Iustin Pop
                                              names=[]))
189 175f44c2 Iustin Pop
190 175f44c2 Iustin Pop
    if not result:
191 21546b1c Iustin Pop
      Log("Can't get the OS list")
192 175f44c2 Iustin Pop
      sys.exit(1)
193 175f44c2 Iustin Pop
194 175f44c2 Iustin Pop
    # filter non-valid OS-es
195 1f9430d6 Iustin Pop
    os_set = [val[0] for val in result if val[1]]
196 175f44c2 Iustin Pop
197 175f44c2 Iustin Pop
    if self.opts.os not in os_set:
198 21546b1c Iustin Pop
      Log("OS '%s' not found" % self.opts.os)
199 175f44c2 Iustin Pop
      sys.exit(1)
200 175f44c2 Iustin Pop
201 175f44c2 Iustin Pop
  def CreateInstances(self):
202 175f44c2 Iustin Pop
    """Create the given instances.
203 175f44c2 Iustin Pop
204 175f44c2 Iustin Pop
    """
205 175f44c2 Iustin Pop
    self.to_rem = []
206 175f44c2 Iustin Pop
    mytor = izip(cycle(self.nodes),
207 175f44c2 Iustin Pop
                 islice(cycle(self.nodes), 1, None),
208 175f44c2 Iustin Pop
                 self.instances)
209 175f44c2 Iustin Pop
    for pnode, snode, instance in mytor:
210 b91bde14 Iustin Pop
      if self.opts.iallocator:
211 b91bde14 Iustin Pop
        pnode = snode = None
212 6d54548e Guido Trotter
        Log("- Add instance %s (iallocator: %s)" %
213 6d54548e Guido Trotter
              (instance, self.opts.iallocator))
214 6d54548e Guido Trotter
      elif self.opts.disk_template not in constants.DTS_NET_MIRROR:
215 6d54548e Guido Trotter
        snode = None
216 6d54548e Guido Trotter
        Log("- Add instance %s on node %s" % (instance, pnode))
217 6d54548e Guido Trotter
      else:
218 6d54548e Guido Trotter
        Log("- Add instance %s on nodes %s/%s" % (instance, pnode, snode))
219 6d54548e Guido Trotter
220 175f44c2 Iustin Pop
      op = opcodes.OpCreateInstance(instance_name=instance,
221 5e767b34 Iustin Pop
                                    mem_size=self.opts.mem_size,
222 175f44c2 Iustin Pop
                                    disk_size=self.opts.os_size,
223 175f44c2 Iustin Pop
                                    swap_size=self.opts.swap_size,
224 175f44c2 Iustin Pop
                                    disk_template=self.opts.disk_template,
225 a8083063 Iustin Pop
                                    mode=constants.INSTANCE_CREATE,
226 175f44c2 Iustin Pop
                                    os_type=self.opts.os,
227 175f44c2 Iustin Pop
                                    pnode=pnode,
228 175f44c2 Iustin Pop
                                    snode=snode,
229 175f44c2 Iustin Pop
                                    vcpus=1,
230 a8083063 Iustin Pop
                                    start=True,
231 e9f745aa Iustin Pop
                                    ip_check=True,
232 4501af56 Iustin Pop
                                    wait_for_sync=True,
233 4501af56 Iustin Pop
                                    mac="auto",
234 4501af56 Iustin Pop
                                    kernel_path=None,
235 25c5878d Alexander Schreiber
                                    initrd_path=None,
236 2f505cb5 Manuel Franceschini
                                    hvm_boot_order=None,
237 2f505cb5 Manuel Franceschini
                                    file_driver="loop",
238 b91bde14 Iustin Pop
                                    file_storage_dir=None,
239 b91bde14 Iustin Pop
                                    iallocator=self.opts.iallocator)
240 21546b1c Iustin Pop
      self.ExecOp(op)
241 175f44c2 Iustin Pop
      self.to_rem.append(instance)
242 175f44c2 Iustin Pop
243 175f44c2 Iustin Pop
  def ReplaceDisks1D8(self):
244 175f44c2 Iustin Pop
    """Replace disks on primary and secondary for drbd8."""
245 175f44c2 Iustin Pop
    for instance in self.instances:
246 175f44c2 Iustin Pop
      for mode in constants.REPLACE_DISK_SEC, constants.REPLACE_DISK_PRI:
247 175f44c2 Iustin Pop
        op = opcodes.OpReplaceDisks(instance_name=instance,
248 175f44c2 Iustin Pop
                                    mode=mode,
249 175f44c2 Iustin Pop
                                    disks=["sda", "sdb"])
250 21546b1c Iustin Pop
        Log("- Replace disks (%s) for instance %s" % (mode, instance))
251 21546b1c Iustin Pop
        self.ExecOp(op)
252 175f44c2 Iustin Pop
253 175f44c2 Iustin Pop
  def ReplaceDisks2(self):
254 175f44c2 Iustin Pop
    """Replace secondary node."""
255 f9193417 Iustin Pop
    mode = constants.REPLACE_DISK_SEC
256 175f44c2 Iustin Pop
257 175f44c2 Iustin Pop
    mytor = izip(islice(cycle(self.nodes), 2, None),
258 175f44c2 Iustin Pop
                 self.instances)
259 175f44c2 Iustin Pop
    for tnode, instance in mytor:
260 b6e82a65 Iustin Pop
      if self.opts.iallocator:
261 b6e82a65 Iustin Pop
        tnode = None
262 175f44c2 Iustin Pop
      op = opcodes.OpReplaceDisks(instance_name=instance,
263 175f44c2 Iustin Pop
                                  mode=mode,
264 175f44c2 Iustin Pop
                                  remote_node=tnode,
265 b6e82a65 Iustin Pop
                                  iallocator=self.opts.iallocator,
266 175f44c2 Iustin Pop
                                  disks=["sda", "sdb"])
267 21546b1c Iustin Pop
      Log("- Replace secondary (%s) for instance %s" % (mode, instance))
268 21546b1c Iustin Pop
      self.ExecOp(op)
269 175f44c2 Iustin Pop
270 175f44c2 Iustin Pop
  def Failover(self):
271 175f44c2 Iustin Pop
    """Failover the instances."""
272 175f44c2 Iustin Pop
273 175f44c2 Iustin Pop
    for instance in self.instances:
274 175f44c2 Iustin Pop
      op = opcodes.OpFailoverInstance(instance_name=instance,
275 175f44c2 Iustin Pop
                                      ignore_consistency=False)
276 175f44c2 Iustin Pop
277 21546b1c Iustin Pop
      Log("- Failover instance %s" % (instance))
278 21546b1c Iustin Pop
      self.ExecOp(op)
279 175f44c2 Iustin Pop
280 bd5e77f9 Guido Trotter
  def ImportExport(self):
281 bd5e77f9 Guido Trotter
    """Export the instance, delete it, and import it back.
282 bd5e77f9 Guido Trotter
283 bd5e77f9 Guido Trotter
    """
284 bd5e77f9 Guido Trotter
285 bd5e77f9 Guido Trotter
    mytor = izip(cycle(self.nodes),
286 bd5e77f9 Guido Trotter
                 islice(cycle(self.nodes), 1, None),
287 bd5e77f9 Guido Trotter
                 islice(cycle(self.nodes), 2, None),
288 bd5e77f9 Guido Trotter
                 self.instances)
289 bd5e77f9 Guido Trotter
290 bd5e77f9 Guido Trotter
    for pnode, snode, enode, instance in mytor:
291 bd5e77f9 Guido Trotter
      exp_op = opcodes.OpExportInstance(instance_name=instance,
292 bd5e77f9 Guido Trotter
                                           target_node=enode,
293 bd5e77f9 Guido Trotter
                                           shutdown=True)
294 bd5e77f9 Guido Trotter
      rem_op = opcodes.OpRemoveInstance(instance_name=instance)
295 bd5e77f9 Guido Trotter
      nam_op = opcodes.OpQueryInstances(output_fields=["name"],
296 bd5e77f9 Guido Trotter
                                           names=[instance])
297 bd5e77f9 Guido Trotter
      full_name = self.ExecOp(nam_op)[0][0]
298 bd5e77f9 Guido Trotter
      imp_dir = os.path.join(constants.EXPORT_DIR, full_name)
299 bd5e77f9 Guido Trotter
      imp_op = opcodes.OpCreateInstance(instance_name=instance,
300 bd5e77f9 Guido Trotter
                                        mem_size=128,
301 bd5e77f9 Guido Trotter
                                        disk_size=self.opts.os_size,
302 bd5e77f9 Guido Trotter
                                        swap_size=self.opts.swap_size,
303 bd5e77f9 Guido Trotter
                                        disk_template=self.opts.disk_template,
304 bd5e77f9 Guido Trotter
                                        mode=constants.INSTANCE_IMPORT,
305 bd5e77f9 Guido Trotter
                                        src_node=enode,
306 bd5e77f9 Guido Trotter
                                        src_path=imp_dir,
307 bd5e77f9 Guido Trotter
                                        pnode=pnode,
308 bd5e77f9 Guido Trotter
                                        snode=snode,
309 bd5e77f9 Guido Trotter
                                        vcpus=1,
310 bd5e77f9 Guido Trotter
                                        start=True,
311 bd5e77f9 Guido Trotter
                                        ip_check=True,
312 bd5e77f9 Guido Trotter
                                        wait_for_sync=True,
313 96bb2f71 Manuel Franceschini
                                        mac="auto",
314 96bb2f71 Manuel Franceschini
                                        file_storage_dir=None,
315 96bb2f71 Manuel Franceschini
                                        file_driver=None)
316 4a7ff493 Guido Trotter
      erem_op = opcodes.OpRemoveExport(instance_name=instance)
317 bd5e77f9 Guido Trotter
318 bd5e77f9 Guido Trotter
      Log("- Export instance %s to node %s" % (instance, enode))
319 bd5e77f9 Guido Trotter
      self.ExecOp(exp_op)
320 bd5e77f9 Guido Trotter
      Log("- Remove instance %s" % (instance))
321 bd5e77f9 Guido Trotter
      self.ExecOp(rem_op)
322 bd5e77f9 Guido Trotter
      self.to_rem.remove(instance)
323 bd5e77f9 Guido Trotter
      Log("- Import instance %s from node %s to node %s" %
324 bd5e77f9 Guido Trotter
          (instance, enode, pnode))
325 bd5e77f9 Guido Trotter
      self.ExecOp(imp_op)
326 4a7ff493 Guido Trotter
      Log("- Remove export of instance %s" % (instance))
327 4a7ff493 Guido Trotter
      self.ExecOp(erem_op)
328 4a7ff493 Guido Trotter
329 bd5e77f9 Guido Trotter
      self.to_rem.append(instance)
330 bd5e77f9 Guido Trotter
331 054a8696 Manuel Franceschini
  def StopInstance(self, instance):
332 054a8696 Manuel Franceschini
    """Stop given instance."""
333 054a8696 Manuel Franceschini
    op = opcodes.OpShutdownInstance(instance_name=instance)
334 054a8696 Manuel Franceschini
    Log("- Shutdown instance %s" % instance)
335 054a8696 Manuel Franceschini
    self.ExecOp(op)
336 054a8696 Manuel Franceschini
337 054a8696 Manuel Franceschini
  def StartInstance(self, instance):
338 054a8696 Manuel Franceschini
    """Start given instance."""
339 054a8696 Manuel Franceschini
    op = opcodes.OpStartupInstance(instance_name=instance, force=False)
340 054a8696 Manuel Franceschini
    Log("- Start instance %s" % instance)
341 054a8696 Manuel Franceschini
    self.ExecOp(op)
342 054a8696 Manuel Franceschini
343 054a8696 Manuel Franceschini
  def RenameInstance(self, instance, instance_new):
344 054a8696 Manuel Franceschini
    """Rename instance."""
345 054a8696 Manuel Franceschini
    op = opcodes.OpRenameInstance(instance_name=instance,
346 054a8696 Manuel Franceschini
                                  new_name=instance_new)
347 054a8696 Manuel Franceschini
    Log("- Rename instance %s to %s" % (instance, instance_new))
348 054a8696 Manuel Franceschini
    self.ExecOp(op)
349 054a8696 Manuel Franceschini
350 175f44c2 Iustin Pop
  def StopStart(self):
351 175f44c2 Iustin Pop
    """Stop/start the instances."""
352 175f44c2 Iustin Pop
    for instance in self.instances:
353 054a8696 Manuel Franceschini
      self.StopInstance(instance)
354 054a8696 Manuel Franceschini
      self.StartInstance(instance)
355 175f44c2 Iustin Pop
356 175f44c2 Iustin Pop
  def Remove(self):
357 175f44c2 Iustin Pop
    """Remove the instances."""
358 175f44c2 Iustin Pop
    for instance in self.to_rem:
359 175f44c2 Iustin Pop
      op = opcodes.OpRemoveInstance(instance_name=instance)
360 21546b1c Iustin Pop
      Log("- Remove instance %s" % instance)
361 21546b1c Iustin Pop
      self.ExecOp(op)
362 175f44c2 Iustin Pop
363 054a8696 Manuel Franceschini
364 054a8696 Manuel Franceschini
  def Rename(self):
365 054a8696 Manuel Franceschini
    """Rename the instances."""
366 054a8696 Manuel Franceschini
    rename = self.opts.rename
367 054a8696 Manuel Franceschini
    for instance in self.instances:
368 054a8696 Manuel Franceschini
      self.StopInstance(instance)
369 054a8696 Manuel Franceschini
      self.RenameInstance(instance, rename)
370 054a8696 Manuel Franceschini
      self.StartInstance(rename)
371 054a8696 Manuel Franceschini
      self.StopInstance(rename)
372 054a8696 Manuel Franceschini
      self.RenameInstance(rename, instance)
373 054a8696 Manuel Franceschini
      self.StartInstance(instance)
374 054a8696 Manuel Franceschini
375 175f44c2 Iustin Pop
  def BurninCluster(self):
376 175f44c2 Iustin Pop
    """Test a cluster intensively.
377 175f44c2 Iustin Pop
378 175f44c2 Iustin Pop
    This will create instances and then start/stop/failover them.
379 175f44c2 Iustin Pop
    It is safe for existing instances but could impact performance.
380 175f44c2 Iustin Pop
381 175f44c2 Iustin Pop
    """
382 175f44c2 Iustin Pop
383 175f44c2 Iustin Pop
    opts = self.opts
384 175f44c2 Iustin Pop
385 21546b1c Iustin Pop
    Log("- Testing global parameters")
386 175f44c2 Iustin Pop
387 bd249e2f Iustin Pop
    if (len(self.nodes) == 1 and
388 2f505cb5 Manuel Franceschini
        opts.disk_template not in (constants.DT_DISKLESS, constants.DT_PLAIN,
389 2f505cb5 Manuel Franceschini
                                   constants.DT_FILE)):
390 21546b1c Iustin Pop
      Log("When one node is available/selected the disk template must"
391 2f505cb5 Manuel Franceschini
          " be 'diskless', 'file' or 'plain'")
392 175f44c2 Iustin Pop
      sys.exit(1)
393 175f44c2 Iustin Pop
394 21546b1c Iustin Pop
    has_err = True
395 175f44c2 Iustin Pop
    try:
396 175f44c2 Iustin Pop
      self.CreateInstances()
397 175f44c2 Iustin Pop
      if opts.do_replace1 and opts.disk_template in constants.DTS_NET_MIRROR:
398 f9193417 Iustin Pop
        self.ReplaceDisks1D8()
399 175f44c2 Iustin Pop
      if (opts.do_replace2 and len(self.nodes) > 2 and
400 175f44c2 Iustin Pop
          opts.disk_template in constants.DTS_NET_MIRROR) :
401 175f44c2 Iustin Pop
        self.ReplaceDisks2()
402 175f44c2 Iustin Pop
403 175f44c2 Iustin Pop
      if opts.do_failover and opts.disk_template in constants.DTS_NET_MIRROR:
404 175f44c2 Iustin Pop
        self.Failover()
405 175f44c2 Iustin Pop
406 bd5e77f9 Guido Trotter
      if opts.do_importexport:
407 bd5e77f9 Guido Trotter
        self.ImportExport()
408 bd5e77f9 Guido Trotter
409 d4844f0f Guido Trotter
      if opts.do_startstop:
410 d4844f0f Guido Trotter
        self.StopStart()
411 d4844f0f Guido Trotter
412 054a8696 Manuel Franceschini
      if opts.rename:
413 054a8696 Manuel Franceschini
        self.Rename()
414 054a8696 Manuel Franceschini
415 21546b1c Iustin Pop
      has_err = False
416 175f44c2 Iustin Pop
    finally:
417 21546b1c Iustin Pop
      if has_err:
418 21546b1c Iustin Pop
        Log("Error detected: opcode buffer follows:\n\n")
419 21546b1c Iustin Pop
        Log(self.GetFeedbackBuf())
420 21546b1c Iustin Pop
        Log("\n\n")
421 175f44c2 Iustin Pop
      self.Remove()
422 175f44c2 Iustin Pop
423 175f44c2 Iustin Pop
    return 0
424 a8083063 Iustin Pop
425 01b69ec5 Michael Hanselmann
426 a8083063 Iustin Pop
def main():
427 3ecf6786 Iustin Pop
  """Main function"""
428 3ecf6786 Iustin Pop
429 175f44c2 Iustin Pop
  burner = Burner()
430 a4af651e Iustin Pop
  return burner.BurninCluster()
431 a8083063 Iustin Pop
432 01b69ec5 Michael Hanselmann
433 a8083063 Iustin Pop
if __name__ == "__main__":
434 3ecf6786 Iustin Pop
  main()