Statistics
| Branch: | Tag: | Revision:

root / tools / burnin @ ee7d831d

History | View | Annotate | Download (6.1 kB)

1 a8083063 Iustin Pop
#!/usr/bin/python
2 a8083063 Iustin Pop
#
3 a8083063 Iustin Pop
4 a8083063 Iustin Pop
import sys
5 a8083063 Iustin Pop
import optparse
6 a8083063 Iustin Pop
7 a8083063 Iustin Pop
from ganeti import opcodes
8 a8083063 Iustin Pop
from ganeti import mcpu
9 a8083063 Iustin Pop
from ganeti import objects
10 a8083063 Iustin Pop
from ganeti import constants
11 a8083063 Iustin Pop
from ganeti import cli
12 a8083063 Iustin Pop
from ganeti import logger
13 9f13fc7a Iustin Pop
from ganeti import errors
14 9f13fc7a Iustin Pop
from ganeti import utils
15 a8083063 Iustin Pop
16 9f13fc7a Iustin Pop
USAGE = ("\tburnin -o OS_NAME [options...] instance_name ...")
17 a8083063 Iustin Pop
18 a8083063 Iustin Pop
def Usage():
19 a8083063 Iustin Pop
  """Shows program usage information and exits the program."""
20 a8083063 Iustin Pop
21 a8083063 Iustin Pop
  print >> sys.stderr, "Usage:"
22 a8083063 Iustin Pop
  print >> sys.stderr, USAGE
23 a8083063 Iustin Pop
  sys.exit(2)
24 a8083063 Iustin Pop
25 a8083063 Iustin Pop
26 a8083063 Iustin Pop
def Feedback(msg):
27 a8083063 Iustin Pop
    print msg
28 a8083063 Iustin Pop
29 a8083063 Iustin Pop
30 a8083063 Iustin Pop
def ParseOptions():
31 a8083063 Iustin Pop
  """Parses the command line options.
32 a8083063 Iustin Pop
33 a8083063 Iustin Pop
  In case of command line errors, it will show the usage and exit the
34 a8083063 Iustin Pop
  program.
35 a8083063 Iustin Pop
36 a8083063 Iustin Pop
  Returns:
37 a8083063 Iustin Pop
    (options, args), as returned by OptionParser.parse_args
38 a8083063 Iustin Pop
  """
39 a8083063 Iustin Pop
40 a8083063 Iustin Pop
  parser = optparse.OptionParser(usage="\n%s" % USAGE,
41 a8083063 Iustin Pop
                                 version="%%prog (ganeti) %s" %
42 a8083063 Iustin Pop
                                 constants.RELEASE_VERSION,
43 a8083063 Iustin Pop
                                 option_class=cli.CliOption)
44 a8083063 Iustin Pop
45 a8083063 Iustin Pop
  parser.add_option("-o", "--os", dest="os", default=None,
46 a8083063 Iustin Pop
                    help="OS to use during burnin",
47 a8083063 Iustin Pop
                    metavar="<OS>")
48 a8083063 Iustin Pop
  parser.add_option("--os-size", dest="os_size", help="Disk size",
49 a8083063 Iustin Pop
                    default=4 * 1024, type="unit", metavar="<size>")
50 a8083063 Iustin Pop
  parser.add_option("--swap-size", dest="swap_size", help="Swap size",
51 a8083063 Iustin Pop
                    default=4 * 1024, type="unit", metavar="<size>")
52 a8083063 Iustin Pop
  parser.add_option("-v", "--verbose",
53 a8083063 Iustin Pop
                    action="store_true", dest="verbose", default=False,
54 a8083063 Iustin Pop
                    help="print command execution messages to stdout")
55 9f13fc7a Iustin Pop
  parser.add_option("--do-replace1", dest="do_replace1",
56 9f13fc7a Iustin Pop
                    help="Do disk replacement with the same secondary",
57 9f13fc7a Iustin Pop
                    action="store_false", default=True)
58 9f13fc7a Iustin Pop
  parser.add_option("--do-replace2", dest="do_replace2",
59 9f13fc7a Iustin Pop
                    help="Do disk replacement with a different secondary",
60 9f13fc7a Iustin Pop
                    action="store_false", default=True)
61 9f13fc7a Iustin Pop
  parser.add_option("--do-failover", dest="do_failover",
62 9f13fc7a Iustin Pop
                    help="Do instance failovers", action="store_false",
63 9f13fc7a Iustin Pop
                    default=True)
64 a8083063 Iustin Pop
65 a8083063 Iustin Pop
  options, args = parser.parse_args()
66 9f13fc7a Iustin Pop
  if len(args) < 1 or options.os is None:
67 a8083063 Iustin Pop
    Usage()
68 a8083063 Iustin Pop
69 a8083063 Iustin Pop
  return options, args
70 a8083063 Iustin Pop
71 a8083063 Iustin Pop
72 a8083063 Iustin Pop
def BurninCluster(opts, args):
73 a8083063 Iustin Pop
  """Test a cluster intensively.
74 a8083063 Iustin Pop
75 a8083063 Iustin Pop
  This will create instances and then start/stop/failover them.
76 a8083063 Iustin Pop
  It is safe for existing instances but could impact performance.
77 a8083063 Iustin Pop
78 a8083063 Iustin Pop
  """
79 a8083063 Iustin Pop
80 a8083063 Iustin Pop
  logger.SetupLogging(debug=True, program="ganeti/burnin")
81 a8083063 Iustin Pop
  proc = mcpu.Processor()
82 a8083063 Iustin Pop
  result = proc.ExecOpCode(opcodes.OpQueryNodes(output_fields=["name"]),
83 a8083063 Iustin Pop
                             Feedback)
84 a8083063 Iustin Pop
  nodelist = [data[0] for data in result]
85 a8083063 Iustin Pop
86 a8083063 Iustin Pop
  Feedback("- Testing global parameters")
87 a8083063 Iustin Pop
88 a8083063 Iustin Pop
  result = proc.ExecOpCode(opcodes.OpDiagnoseOS(), Feedback)
89 a8083063 Iustin Pop
90 a8083063 Iustin Pop
  if not result:
91 a8083063 Iustin Pop
    Feedback("Can't get the OS list")
92 a8083063 Iustin Pop
    return 1
93 a8083063 Iustin Pop
94 a8083063 Iustin Pop
  # filter non-valid OS-es
95 a8083063 Iustin Pop
  oses = {}
96 a8083063 Iustin Pop
  for node_name in result:
97 a8083063 Iustin Pop
    oses[node_name] = [obj for obj in result[node_name]
98 a8083063 Iustin Pop
                       if isinstance(obj, objects.OS)]
99 a8083063 Iustin Pop
100 a8083063 Iustin Pop
  fnode = oses.keys()[0]
101 a8083063 Iustin Pop
  os_set = set([os_inst.name for os_inst in oses[fnode]])
102 a8083063 Iustin Pop
  del oses[fnode]
103 a8083063 Iustin Pop
  for node in oses:
104 a8083063 Iustin Pop
    os_set &= set([os_inst.name for os_inst in oses[node]])
105 a8083063 Iustin Pop
106 a8083063 Iustin Pop
  if opts.os not in os_set:
107 9f13fc7a Iustin Pop
    Feedback("OS '%s' not found" % opts.os)
108 a8083063 Iustin Pop
    return 1
109 a8083063 Iustin Pop
110 a8083063 Iustin Pop
  to_remove = []
111 a8083063 Iustin Pop
  try:
112 a8083063 Iustin Pop
    idx = 0
113 a8083063 Iustin Pop
    for instance_name in args:
114 a8083063 Iustin Pop
      next_idx = idx + 1
115 a8083063 Iustin Pop
      if next_idx >= len(nodelist):
116 a8083063 Iustin Pop
        next_idx = 0
117 a8083063 Iustin Pop
      pnode = nodelist[idx]
118 a8083063 Iustin Pop
      snode = nodelist[next_idx]
119 a8083063 Iustin Pop
      if len(nodelist) > 1:
120 a8083063 Iustin Pop
        tplate = constants.DT_REMOTE_RAID1
121 a8083063 Iustin Pop
      else:
122 a8083063 Iustin Pop
        tplate = constants.DT_PLAIN
123 a8083063 Iustin Pop
124 a8083063 Iustin Pop
      op = opcodes.OpCreateInstance(instance_name=instance_name, mem_size=128,
125 a8083063 Iustin Pop
                                    disk_size=opts.os_size,
126 a8083063 Iustin Pop
                                    swap_size=opts.swap_size,
127 a8083063 Iustin Pop
                                    disk_template=tplate,
128 a8083063 Iustin Pop
                                    mode=constants.INSTANCE_CREATE,
129 a8083063 Iustin Pop
                                    os_type=opts.os, pnode=pnode,
130 a8083063 Iustin Pop
                                    snode=snode, vcpus=1,
131 a8083063 Iustin Pop
                                    start=True,
132 a8083063 Iustin Pop
                                    wait_for_sync=True)
133 a8083063 Iustin Pop
      Feedback("- Add instance %s on node %s" % (instance_name, pnode))
134 a8083063 Iustin Pop
      result = proc.ExecOpCode(op, Feedback)
135 a8083063 Iustin Pop
      to_remove.append(instance_name)
136 a8083063 Iustin Pop
      idx = next_idx
137 a8083063 Iustin Pop
138 a8083063 Iustin Pop
139 9f13fc7a Iustin Pop
    if opts.do_replace1:
140 9f13fc7a Iustin Pop
      if len(nodelist) > 1:
141 9f13fc7a Iustin Pop
        # failover
142 9f13fc7a Iustin Pop
        for instance_name in args:
143 9f13fc7a Iustin Pop
          op = opcodes.OpReplaceDisks(instance_name=instance_name,
144 9f13fc7a Iustin Pop
                                      remote_node=None)
145 9f13fc7a Iustin Pop
146 9f13fc7a Iustin Pop
          Feedback("- Replace disks for instance %s" % (instance_name))
147 9f13fc7a Iustin Pop
          result = proc.ExecOpCode(op, Feedback)
148 9f13fc7a Iustin Pop
      else:
149 9f13fc7a Iustin Pop
        Feedback("- Can't run replace1, not enough nodes")
150 a8083063 Iustin Pop
151 9f13fc7a Iustin Pop
    if opts.do_failover:
152 9f13fc7a Iustin Pop
      if len(nodelist) > 1:
153 9f13fc7a Iustin Pop
        # failover
154 9f13fc7a Iustin Pop
        for instance_name in args:
155 9f13fc7a Iustin Pop
          op = opcodes.OpFailoverInstance(instance_name=instance_name,
156 9f13fc7a Iustin Pop
                                          ignore_consistency=True)
157 9f13fc7a Iustin Pop
158 9f13fc7a Iustin Pop
          Feedback("- Failover instance %s" % (instance_name))
159 9f13fc7a Iustin Pop
          result = proc.ExecOpCode(op, Feedback)
160 9f13fc7a Iustin Pop
      else:
161 9f13fc7a Iustin Pop
        Feedback("- Can't run failovers, not enough nodes")
162 a8083063 Iustin Pop
163 a8083063 Iustin Pop
    # stop / start
164 a8083063 Iustin Pop
    for instance_name in args:
165 a8083063 Iustin Pop
      op = opcodes.OpShutdownInstance(instance_name=instance_name)
166 a8083063 Iustin Pop
      Feedback("- Shutdown instance %s" % instance_name)
167 a8083063 Iustin Pop
      result = proc.ExecOpCode(op, Feedback)
168 a8083063 Iustin Pop
      op = opcodes.OpStartupInstance(instance_name=instance_name, force=False)
169 a8083063 Iustin Pop
      Feedback("- Start instance %s" % instance_name)
170 a8083063 Iustin Pop
      result = proc.ExecOpCode(op, Feedback)
171 a8083063 Iustin Pop
172 a8083063 Iustin Pop
  finally:
173 a8083063 Iustin Pop
    # remove
174 a8083063 Iustin Pop
    for instance_name in to_remove:
175 a8083063 Iustin Pop
      op = opcodes.OpRemoveInstance(instance_name=instance_name)
176 a8083063 Iustin Pop
      Feedback("- Remove instance %s" % instance_name)
177 a8083063 Iustin Pop
      result = proc.ExecOpCode(op, Feedback)
178 a8083063 Iustin Pop
179 a8083063 Iustin Pop
  return 0
180 a8083063 Iustin Pop
181 a8083063 Iustin Pop
def main():
182 a8083063 Iustin Pop
    """Main function"""
183 a8083063 Iustin Pop
184 a8083063 Iustin Pop
    opts, args = ParseOptions()
185 9f13fc7a Iustin Pop
    try:
186 9f13fc7a Iustin Pop
      utils.Lock('cmd', max_retries=15, debug=True)
187 9f13fc7a Iustin Pop
    except errors.LockError, err:
188 9f13fc7a Iustin Pop
      logger.ToStderr(str(err))
189 9f13fc7a Iustin Pop
      return 1
190 9f13fc7a Iustin Pop
    try:
191 9f13fc7a Iustin Pop
      retval = BurninCluster(opts, args)
192 9f13fc7a Iustin Pop
    finally:
193 9f13fc7a Iustin Pop
      utils.Unlock('cmd')
194 9f13fc7a Iustin Pop
      utils.LockCleanup()
195 9f13fc7a Iustin Pop
    return retval
196 a8083063 Iustin Pop
197 a8083063 Iustin Pop
if __name__ == "__main__":
198 a8083063 Iustin Pop
    main()