Statistics
| Branch: | Tag: | Revision:

root / lib / client / gnt_debug.py @ dd47a0f0

History | View | Annotate | Download (19.5 kB)

1 c2855a12 Michael Hanselmann
#
2 fd3ee040 Iustin Pop
#
3 fd3ee040 Iustin Pop
4 b469eb4d Iustin Pop
# Copyright (C) 2006, 2007, 2010, 2011 Google Inc.
5 fd3ee040 Iustin Pop
#
6 fd3ee040 Iustin Pop
# This program is free software; you can redistribute it and/or modify
7 fd3ee040 Iustin Pop
# it under the terms of the GNU General Public License as published by
8 fd3ee040 Iustin Pop
# the Free Software Foundation; either version 2 of the License, or
9 fd3ee040 Iustin Pop
# (at your option) any later version.
10 fd3ee040 Iustin Pop
#
11 fd3ee040 Iustin Pop
# This program is distributed in the hope that it will be useful, but
12 fd3ee040 Iustin Pop
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 fd3ee040 Iustin Pop
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 fd3ee040 Iustin Pop
# General Public License for more details.
15 fd3ee040 Iustin Pop
#
16 fd3ee040 Iustin Pop
# You should have received a copy of the GNU General Public License
17 fd3ee040 Iustin Pop
# along with this program; if not, write to the Free Software
18 fd3ee040 Iustin Pop
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 fd3ee040 Iustin Pop
# 02110-1301, USA.
20 fd3ee040 Iustin Pop
21 7260cfbe Iustin Pop
"""Debugging commands"""
22 fd3ee040 Iustin Pop
23 7260cfbe Iustin Pop
# pylint: disable-msg=W0401,W0614,C0103
24 2f79bd34 Iustin Pop
# W0401: Wildcard import ganeti.cli
25 2f79bd34 Iustin Pop
# W0614: Unused import %s from wildcard import (since we need cli)
26 7260cfbe Iustin Pop
# C0103: Invalid name gnt-backup
27 2f79bd34 Iustin Pop
28 f1c66d13 Iustin Pop
import simplejson
29 f1c66d13 Iustin Pop
import time
30 e58f87a9 Michael Hanselmann
import socket
31 e58f87a9 Michael Hanselmann
import logging
32 f1c66d13 Iustin Pop
33 fd3ee040 Iustin Pop
from ganeti.cli import *
34 9d5ba39a Iustin Pop
from ganeti import cli
35 e58f87a9 Michael Hanselmann
from ganeti import constants
36 fd3ee040 Iustin Pop
from ganeti import opcodes
37 fd3ee040 Iustin Pop
from ganeti import utils
38 fd3ee040 Iustin Pop
from ganeti import errors
39 92ae7daf Michael Hanselmann
from ganeti import compat
40 fd3ee040 Iustin Pop
41 fd3ee040 Iustin Pop
42 19b9ba9a Michael Hanselmann
#: Default fields for L{ListLocks}
43 19b9ba9a Michael Hanselmann
_LIST_LOCKS_DEF_FIELDS = [
44 19b9ba9a Michael Hanselmann
  "name",
45 19b9ba9a Michael Hanselmann
  "mode",
46 19b9ba9a Michael Hanselmann
  "owner",
47 c31825f7 Michael Hanselmann
  "pending",
48 19b9ba9a Michael Hanselmann
  ]
49 19b9ba9a Michael Hanselmann
50 19b9ba9a Michael Hanselmann
51 fd3ee040 Iustin Pop
def Delay(opts, args):
52 fd3ee040 Iustin Pop
  """Sleeps for a while
53 fd3ee040 Iustin Pop

54 6099bfcf Iustin Pop
  @param opts: the command line options selected by the user
55 6099bfcf Iustin Pop
  @type args: list
56 6099bfcf Iustin Pop
  @param args: should contain only one element, the duration
57 6099bfcf Iustin Pop
      the sleep
58 6099bfcf Iustin Pop
  @rtype: int
59 6099bfcf Iustin Pop
  @return: the desired exit code
60 6099bfcf Iustin Pop

61 fd3ee040 Iustin Pop
  """
62 fd3ee040 Iustin Pop
  delay = float(args[0])
63 fd3ee040 Iustin Pop
  op = opcodes.OpTestDelay(duration=delay,
64 fd3ee040 Iustin Pop
                           on_master=opts.on_master,
65 85a87e21 Guido Trotter
                           on_nodes=opts.on_nodes,
66 85a87e21 Guido Trotter
                           repeat=opts.repeat)
67 400ca2f7 Iustin Pop
  SubmitOpCode(op, opts=opts)
68 fd3ee040 Iustin Pop
69 fd3ee040 Iustin Pop
  return 0
70 fd3ee040 Iustin Pop
71 fd3ee040 Iustin Pop
72 f1c66d13 Iustin Pop
def GenericOpCodes(opts, args):
73 6099bfcf Iustin Pop
  """Send any opcode to the master.
74 6099bfcf Iustin Pop

75 6099bfcf Iustin Pop
  @param opts: the command line options selected by the user
76 6099bfcf Iustin Pop
  @type args: list
77 6099bfcf Iustin Pop
  @param args: should contain only one element, the path of
78 6099bfcf Iustin Pop
      the file with the opcode definition
79 6099bfcf Iustin Pop
  @rtype: int
80 6099bfcf Iustin Pop
  @return: the desired exit code
81 f1c66d13 Iustin Pop

82 f1c66d13 Iustin Pop
  """
83 9d5ba39a Iustin Pop
  cl = cli.GetClient()
84 cb573a31 Iustin Pop
  jex = cli.JobExecutor(cl=cl, verbose=opts.verbose, opts=opts)
85 9d95c3af Iustin Pop
86 9d95c3af Iustin Pop
  job_cnt = 0
87 9d95c3af Iustin Pop
  op_cnt = 0
88 9d95c3af Iustin Pop
  if opts.timing_stats:
89 9d95c3af Iustin Pop
    ToStdout("Loading...")
90 9d95c3af Iustin Pop
  for job_idx in range(opts.rep_job):
91 9d95c3af Iustin Pop
    for fname in args:
92 7260cfbe Iustin Pop
      # pylint: disable-msg=W0142
93 4d5fe81b Michael Hanselmann
      op_data = simplejson.loads(utils.ReadFile(fname))
94 9d95c3af Iustin Pop
      op_list = [opcodes.OpCode.LoadOpCode(val) for val in op_data]
95 9d95c3af Iustin Pop
      op_list = op_list * opts.rep_op
96 9d95c3af Iustin Pop
      jex.QueueJob("file %s/%d" % (fname, job_idx), *op_list)
97 9d95c3af Iustin Pop
      op_cnt += len(op_list)
98 9d95c3af Iustin Pop
      job_cnt += 1
99 9d95c3af Iustin Pop
100 9d95c3af Iustin Pop
  if opts.timing_stats:
101 9d95c3af Iustin Pop
    t1 = time.time()
102 9d95c3af Iustin Pop
    ToStdout("Submitting...")
103 4d5fe81b Michael Hanselmann
104 66ecc479 Guido Trotter
  jex.SubmitPending(each=opts.each)
105 9d95c3af Iustin Pop
106 9d95c3af Iustin Pop
  if opts.timing_stats:
107 9d95c3af Iustin Pop
    t2 = time.time()
108 9d95c3af Iustin Pop
    ToStdout("Executing...")
109 b59252fe Iustin Pop
110 b59252fe Iustin Pop
  jex.GetResults()
111 9d95c3af Iustin Pop
  if opts.timing_stats:
112 9d95c3af Iustin Pop
    t3 = time.time()
113 9d95c3af Iustin Pop
    ToStdout("C:op     %4d" % op_cnt)
114 9d95c3af Iustin Pop
    ToStdout("C:job    %4d" % job_cnt)
115 9d95c3af Iustin Pop
    ToStdout("T:submit %4.4f" % (t2-t1))
116 9d95c3af Iustin Pop
    ToStdout("T:exec   %4.4f" % (t3-t2))
117 9d95c3af Iustin Pop
    ToStdout("T:total  %4.4f" % (t3-t1))
118 f1c66d13 Iustin Pop
  return 0
119 f1c66d13 Iustin Pop
120 f1c66d13 Iustin Pop
121 d61df03e Iustin Pop
def TestAllocator(opts, args):
122 6099bfcf Iustin Pop
  """Runs the test allocator opcode.
123 d61df03e Iustin Pop

124 6099bfcf Iustin Pop
  @param opts: the command line options selected by the user
125 6099bfcf Iustin Pop
  @type args: list
126 6099bfcf Iustin Pop
  @param args: should contain only one element, the iallocator name
127 6099bfcf Iustin Pop
  @rtype: int
128 6099bfcf Iustin Pop
  @return: the desired exit code
129 6099bfcf Iustin Pop

130 6099bfcf Iustin Pop
  """
131 d61df03e Iustin Pop
  try:
132 fdbe29ee Michael Hanselmann
    disks = [{
133 fdbe29ee Michael Hanselmann
      constants.IDISK_SIZE: utils.ParseUnit(val),
134 fdbe29ee Michael Hanselmann
      constants.IDISK_MODE: constants.DISK_RDWR,
135 fdbe29ee Michael Hanselmann
      } for val in opts.disks.split(",")]
136 d61df03e Iustin Pop
  except errors.UnitParseError, err:
137 3a24c527 Iustin Pop
    ToStderr("Invalid disks parameter '%s': %s", opts.disks, err)
138 d61df03e Iustin Pop
    return 1
139 d61df03e Iustin Pop
140 d61df03e Iustin Pop
  nics = [val.split("/") for val in opts.nics.split(",")]
141 d61df03e Iustin Pop
  for row in nics:
142 d61df03e Iustin Pop
    while len(row) < 3:
143 d61df03e Iustin Pop
      row.append(None)
144 d61df03e Iustin Pop
    for i in range(3):
145 d61df03e Iustin Pop
      if row[i] == '':
146 d61df03e Iustin Pop
        row[i] = None
147 fdbe29ee Michael Hanselmann
  nic_dict = [{
148 fdbe29ee Michael Hanselmann
    constants.INIC_MAC: v[0],
149 fdbe29ee Michael Hanselmann
    constants.INIC_IP: v[1],
150 fdbe29ee Michael Hanselmann
    # The iallocator interface defines a "bridge" item
151 fdbe29ee Michael Hanselmann
    "bridge": v[2],
152 fdbe29ee Michael Hanselmann
    } for v in nics]
153 d61df03e Iustin Pop
154 d61df03e Iustin Pop
  if opts.tags is None:
155 d61df03e Iustin Pop
    opts.tags = []
156 d61df03e Iustin Pop
  else:
157 d61df03e Iustin Pop
    opts.tags = opts.tags.split(",")
158 36bbf5b0 Iustin Pop
  if opts.target_groups is None:
159 36bbf5b0 Iustin Pop
    target_groups = []
160 36bbf5b0 Iustin Pop
  else:
161 36bbf5b0 Iustin Pop
    target_groups = opts.target_groups
162 d61df03e Iustin Pop
163 d61df03e Iustin Pop
  op = opcodes.OpTestAllocator(mode=opts.mode,
164 d61df03e Iustin Pop
                               name=args[0],
165 823a72bc Iustin Pop
                               evac_nodes=args,
166 42c161cf Michael Hanselmann
                               instances=args,
167 dd47a0f0 Iustin Pop
                               memory=opts.memory,
168 d61df03e Iustin Pop
                               disks=disks,
169 d61df03e Iustin Pop
                               disk_template=opts.disk_template,
170 d61df03e Iustin Pop
                               nics=nic_dict,
171 705dd60e Iustin Pop
                               os=opts.os,
172 d61df03e Iustin Pop
                               vcpus=opts.vcpus,
173 d61df03e Iustin Pop
                               tags=opts.tags,
174 d61df03e Iustin Pop
                               direction=opts.direction,
175 705dd60e Iustin Pop
                               allocator=opts.iallocator,
176 42c161cf Michael Hanselmann
                               reloc_mode=opts.reloc_mode,
177 36bbf5b0 Iustin Pop
                               target_groups=target_groups)
178 400ca2f7 Iustin Pop
  result = SubmitOpCode(op, opts=opts)
179 3a24c527 Iustin Pop
  ToStdout("%s" % result)
180 d61df03e Iustin Pop
  return 0
181 d61df03e Iustin Pop
182 d61df03e Iustin Pop
183 92ae7daf Michael Hanselmann
def _TestJobSubmission(opts):
184 92ae7daf Michael Hanselmann
  """Tests submitting jobs.
185 92ae7daf Michael Hanselmann

186 92ae7daf Michael Hanselmann
  """
187 92ae7daf Michael Hanselmann
  ToStdout("Testing job submission")
188 92ae7daf Michael Hanselmann
189 92ae7daf Michael Hanselmann
  testdata = [
190 92ae7daf Michael Hanselmann
    (0, 0, constants.OP_PRIO_LOWEST),
191 92ae7daf Michael Hanselmann
    (0, 0, constants.OP_PRIO_HIGHEST),
192 92ae7daf Michael Hanselmann
    ]
193 92ae7daf Michael Hanselmann
194 92ae7daf Michael Hanselmann
  for priority in (constants.OP_PRIO_SUBMIT_VALID |
195 92ae7daf Michael Hanselmann
                   frozenset([constants.OP_PRIO_LOWEST,
196 92ae7daf Michael Hanselmann
                              constants.OP_PRIO_HIGHEST])):
197 92ae7daf Michael Hanselmann
    for offset in [-1, +1]:
198 92ae7daf Michael Hanselmann
      testdata.extend([
199 92ae7daf Michael Hanselmann
        (0, 0, priority + offset),
200 92ae7daf Michael Hanselmann
        (3, 0, priority + offset),
201 92ae7daf Michael Hanselmann
        (0, 3, priority + offset),
202 92ae7daf Michael Hanselmann
        (4, 2, priority + offset),
203 92ae7daf Michael Hanselmann
        ])
204 92ae7daf Michael Hanselmann
205 92ae7daf Michael Hanselmann
  cl = cli.GetClient()
206 92ae7daf Michael Hanselmann
207 92ae7daf Michael Hanselmann
  for before, after, failpriority in testdata:
208 92ae7daf Michael Hanselmann
    ops = []
209 92ae7daf Michael Hanselmann
    ops.extend([opcodes.OpTestDelay(duration=0) for _ in range(before)])
210 92ae7daf Michael Hanselmann
    ops.append(opcodes.OpTestDelay(duration=0, priority=failpriority))
211 92ae7daf Michael Hanselmann
    ops.extend([opcodes.OpTestDelay(duration=0) for _ in range(after)])
212 92ae7daf Michael Hanselmann
213 92ae7daf Michael Hanselmann
    try:
214 92ae7daf Michael Hanselmann
      cl.SubmitJob(ops)
215 92ae7daf Michael Hanselmann
    except errors.GenericError, err:
216 92ae7daf Michael Hanselmann
      if opts.debug:
217 92ae7daf Michael Hanselmann
        ToStdout("Ignoring error: %s", err)
218 92ae7daf Michael Hanselmann
    else:
219 92ae7daf Michael Hanselmann
      raise errors.OpExecError("Submitting opcode with priority %s did not"
220 92ae7daf Michael Hanselmann
                               " fail when it should (allowed are %s)" %
221 92ae7daf Michael Hanselmann
                               (failpriority, constants.OP_PRIO_SUBMIT_VALID))
222 92ae7daf Michael Hanselmann
223 92ae7daf Michael Hanselmann
    jobs = [
224 92ae7daf Michael Hanselmann
      [opcodes.OpTestDelay(duration=0),
225 92ae7daf Michael Hanselmann
       opcodes.OpTestDelay(duration=0, dry_run=False),
226 92ae7daf Michael Hanselmann
       opcodes.OpTestDelay(duration=0, dry_run=True)],
227 92ae7daf Michael Hanselmann
      ops,
228 92ae7daf Michael Hanselmann
      ]
229 92ae7daf Michael Hanselmann
    result = cl.SubmitManyJobs(jobs)
230 92ae7daf Michael Hanselmann
    if not (len(result) == 2 and
231 92ae7daf Michael Hanselmann
            compat.all(len(i) == 2 for i in result) and
232 92ae7daf Michael Hanselmann
            compat.all(isinstance(i[1], basestring) for i in result) and
233 92ae7daf Michael Hanselmann
            result[0][0] and not result[1][0]):
234 92ae7daf Michael Hanselmann
      raise errors.OpExecError("Submitting multiple jobs did not work as"
235 92ae7daf Michael Hanselmann
                               " expected, result %s" % result)
236 92ae7daf Michael Hanselmann
    assert len(result) == 2
237 92ae7daf Michael Hanselmann
238 92ae7daf Michael Hanselmann
  ToStdout("Job submission tests were successful")
239 92ae7daf Michael Hanselmann
240 92ae7daf Michael Hanselmann
241 e58f87a9 Michael Hanselmann
class _JobQueueTestReporter(cli.StdioJobPollReportCb):
242 e58f87a9 Michael Hanselmann
  def __init__(self):
243 e58f87a9 Michael Hanselmann
    """Initializes this class.
244 e58f87a9 Michael Hanselmann

245 e58f87a9 Michael Hanselmann
    """
246 e58f87a9 Michael Hanselmann
    cli.StdioJobPollReportCb.__init__(self)
247 f99010b2 Michael Hanselmann
    self._expected_msgcount = 0
248 f99010b2 Michael Hanselmann
    self._all_testmsgs = []
249 f99010b2 Michael Hanselmann
    self._testmsgs = None
250 e58f87a9 Michael Hanselmann
    self._job_id = None
251 e58f87a9 Michael Hanselmann
252 e58f87a9 Michael Hanselmann
  def GetTestMessages(self):
253 e58f87a9 Michael Hanselmann
    """Returns all test log messages received so far.
254 e58f87a9 Michael Hanselmann

255 e58f87a9 Michael Hanselmann
    """
256 f99010b2 Michael Hanselmann
    return self._all_testmsgs
257 e58f87a9 Michael Hanselmann
258 e58f87a9 Michael Hanselmann
  def GetJobId(self):
259 e58f87a9 Michael Hanselmann
    """Returns the job ID.
260 e58f87a9 Michael Hanselmann

261 e58f87a9 Michael Hanselmann
    """
262 e58f87a9 Michael Hanselmann
    return self._job_id
263 e58f87a9 Michael Hanselmann
264 e58f87a9 Michael Hanselmann
  def ReportLogMessage(self, job_id, serial, timestamp, log_type, log_msg):
265 e58f87a9 Michael Hanselmann
    """Handles a log message.
266 e58f87a9 Michael Hanselmann

267 e58f87a9 Michael Hanselmann
    """
268 e58f87a9 Michael Hanselmann
    if self._job_id is None:
269 e58f87a9 Michael Hanselmann
      self._job_id = job_id
270 e58f87a9 Michael Hanselmann
    elif self._job_id != job_id:
271 e58f87a9 Michael Hanselmann
      raise errors.ProgrammerError("The same reporter instance was used for"
272 e58f87a9 Michael Hanselmann
                                   " more than one job")
273 e58f87a9 Michael Hanselmann
274 e58f87a9 Michael Hanselmann
    if log_type == constants.ELOG_JQUEUE_TEST:
275 e58f87a9 Michael Hanselmann
      (sockname, test, arg) = log_msg
276 e58f87a9 Michael Hanselmann
      return self._ProcessTestMessage(job_id, sockname, test, arg)
277 e58f87a9 Michael Hanselmann
278 e58f87a9 Michael Hanselmann
    elif (log_type == constants.ELOG_MESSAGE and
279 e58f87a9 Michael Hanselmann
          log_msg.startswith(constants.JQT_MSGPREFIX)):
280 f99010b2 Michael Hanselmann
      if self._testmsgs is None:
281 f99010b2 Michael Hanselmann
        raise errors.OpExecError("Received test message without a preceding"
282 f99010b2 Michael Hanselmann
                                 " start message")
283 f99010b2 Michael Hanselmann
      testmsg = log_msg[len(constants.JQT_MSGPREFIX):]
284 f99010b2 Michael Hanselmann
      self._testmsgs.append(testmsg)
285 f99010b2 Michael Hanselmann
      self._all_testmsgs.append(testmsg)
286 e58f87a9 Michael Hanselmann
      return
287 e58f87a9 Michael Hanselmann
288 e58f87a9 Michael Hanselmann
    return cli.StdioJobPollReportCb.ReportLogMessage(self, job_id, serial,
289 e58f87a9 Michael Hanselmann
                                                     timestamp, log_type,
290 e58f87a9 Michael Hanselmann
                                                     log_msg)
291 e58f87a9 Michael Hanselmann
292 e58f87a9 Michael Hanselmann
  def _ProcessTestMessage(self, job_id, sockname, test, arg):
293 e58f87a9 Michael Hanselmann
    """Handles a job queue test message.
294 e58f87a9 Michael Hanselmann

295 e58f87a9 Michael Hanselmann
    """
296 e58f87a9 Michael Hanselmann
    if test not in constants.JQT_ALL:
297 e58f87a9 Michael Hanselmann
      raise errors.OpExecError("Received invalid test message %s" % test)
298 e58f87a9 Michael Hanselmann
299 e58f87a9 Michael Hanselmann
    sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
300 e58f87a9 Michael Hanselmann
    try:
301 e58f87a9 Michael Hanselmann
      sock.settimeout(30.0)
302 e58f87a9 Michael Hanselmann
303 e58f87a9 Michael Hanselmann
      logging.debug("Connecting to %s", sockname)
304 e58f87a9 Michael Hanselmann
      sock.connect(sockname)
305 e58f87a9 Michael Hanselmann
306 e58f87a9 Michael Hanselmann
      logging.debug("Checking status")
307 e58f87a9 Michael Hanselmann
      jobdetails = cli.GetClient().QueryJobs([job_id], ["status"])[0]
308 e58f87a9 Michael Hanselmann
      if not jobdetails:
309 e58f87a9 Michael Hanselmann
        raise errors.OpExecError("Can't find job %s" % job_id)
310 e58f87a9 Michael Hanselmann
311 e58f87a9 Michael Hanselmann
      status = jobdetails[0]
312 e58f87a9 Michael Hanselmann
313 e58f87a9 Michael Hanselmann
      logging.debug("Status of job %s is %s", job_id, status)
314 e58f87a9 Michael Hanselmann
315 e58f87a9 Michael Hanselmann
      if test == constants.JQT_EXPANDNAMES:
316 e58f87a9 Michael Hanselmann
        if status != constants.JOB_STATUS_WAITLOCK:
317 e58f87a9 Michael Hanselmann
          raise errors.OpExecError("Job status while expanding names is '%s',"
318 e58f87a9 Michael Hanselmann
                                   " not '%s' as expected" %
319 e58f87a9 Michael Hanselmann
                                   (status, constants.JOB_STATUS_WAITLOCK))
320 e58f87a9 Michael Hanselmann
      elif test in (constants.JQT_EXEC, constants.JQT_LOGMSG):
321 e58f87a9 Michael Hanselmann
        if status != constants.JOB_STATUS_RUNNING:
322 e58f87a9 Michael Hanselmann
          raise errors.OpExecError("Job status while executing opcode is '%s',"
323 e58f87a9 Michael Hanselmann
                                   " not '%s' as expected" %
324 e58f87a9 Michael Hanselmann
                                   (status, constants.JOB_STATUS_RUNNING))
325 e58f87a9 Michael Hanselmann
326 f99010b2 Michael Hanselmann
      if test == constants.JQT_STARTMSG:
327 f99010b2 Michael Hanselmann
        logging.debug("Expecting %s test messages", arg)
328 f99010b2 Michael Hanselmann
        self._testmsgs = []
329 f99010b2 Michael Hanselmann
      elif test == constants.JQT_LOGMSG:
330 e58f87a9 Michael Hanselmann
        if len(self._testmsgs) != arg:
331 e58f87a9 Michael Hanselmann
          raise errors.OpExecError("Received %s test messages when %s are"
332 e58f87a9 Michael Hanselmann
                                   " expected" % (len(self._testmsgs), arg))
333 e58f87a9 Michael Hanselmann
    finally:
334 e58f87a9 Michael Hanselmann
      logging.debug("Closing socket")
335 e58f87a9 Michael Hanselmann
      sock.close()
336 e58f87a9 Michael Hanselmann
337 e58f87a9 Michael Hanselmann
338 e58f87a9 Michael Hanselmann
def TestJobqueue(opts, _):
339 e58f87a9 Michael Hanselmann
  """Runs a few tests on the job queue.
340 e58f87a9 Michael Hanselmann

341 e58f87a9 Michael Hanselmann
  """
342 92ae7daf Michael Hanselmann
  _TestJobSubmission(opts)
343 92ae7daf Michael Hanselmann
344 f99010b2 Michael Hanselmann
  (TM_SUCCESS,
345 f99010b2 Michael Hanselmann
   TM_MULTISUCCESS,
346 f99010b2 Michael Hanselmann
   TM_FAIL,
347 f99010b2 Michael Hanselmann
   TM_PARTFAIL) = range(4)
348 f99010b2 Michael Hanselmann
  TM_ALL = frozenset([TM_SUCCESS, TM_MULTISUCCESS, TM_FAIL, TM_PARTFAIL])
349 f99010b2 Michael Hanselmann
350 f99010b2 Michael Hanselmann
  for mode in TM_ALL:
351 f99010b2 Michael Hanselmann
    test_messages = [
352 f99010b2 Michael Hanselmann
      "Testing mode %s" % mode,
353 f99010b2 Michael Hanselmann
      "Hello World",
354 f99010b2 Michael Hanselmann
      "A",
355 f99010b2 Michael Hanselmann
      "",
356 f99010b2 Michael Hanselmann
      "B"
357 f99010b2 Michael Hanselmann
      "Foo|bar|baz",
358 f99010b2 Michael Hanselmann
      utils.TimestampForFilename(),
359 f99010b2 Michael Hanselmann
      ]
360 f99010b2 Michael Hanselmann
361 f99010b2 Michael Hanselmann
    fail = mode in (TM_FAIL, TM_PARTFAIL)
362 f99010b2 Michael Hanselmann
363 f99010b2 Michael Hanselmann
    if mode == TM_PARTFAIL:
364 f99010b2 Michael Hanselmann
      ToStdout("Testing partial job failure")
365 f99010b2 Michael Hanselmann
      ops = [
366 b469eb4d Iustin Pop
        opcodes.OpTestJqueue(notify_waitlock=True, notify_exec=True,
367 b469eb4d Iustin Pop
                             log_messages=test_messages, fail=False),
368 b469eb4d Iustin Pop
        opcodes.OpTestJqueue(notify_waitlock=True, notify_exec=True,
369 b469eb4d Iustin Pop
                             log_messages=test_messages, fail=False),
370 b469eb4d Iustin Pop
        opcodes.OpTestJqueue(notify_waitlock=True, notify_exec=True,
371 b469eb4d Iustin Pop
                             log_messages=test_messages, fail=True),
372 b469eb4d Iustin Pop
        opcodes.OpTestJqueue(notify_waitlock=True, notify_exec=True,
373 b469eb4d Iustin Pop
                             log_messages=test_messages, fail=False),
374 f99010b2 Michael Hanselmann
        ]
375 f99010b2 Michael Hanselmann
      expect_messages = 3 * [test_messages]
376 f99010b2 Michael Hanselmann
      expect_opstatus = [
377 f99010b2 Michael Hanselmann
        constants.OP_STATUS_SUCCESS,
378 f99010b2 Michael Hanselmann
        constants.OP_STATUS_SUCCESS,
379 f99010b2 Michael Hanselmann
        constants.OP_STATUS_ERROR,
380 f99010b2 Michael Hanselmann
        constants.OP_STATUS_ERROR,
381 f99010b2 Michael Hanselmann
        ]
382 f99010b2 Michael Hanselmann
      expect_resultlen = 2
383 f99010b2 Michael Hanselmann
    elif mode == TM_MULTISUCCESS:
384 f99010b2 Michael Hanselmann
      ToStdout("Testing multiple successful opcodes")
385 f99010b2 Michael Hanselmann
      ops = [
386 b469eb4d Iustin Pop
        opcodes.OpTestJqueue(notify_waitlock=True, notify_exec=True,
387 b469eb4d Iustin Pop
                             log_messages=test_messages, fail=False),
388 b469eb4d Iustin Pop
        opcodes.OpTestJqueue(notify_waitlock=True, notify_exec=True,
389 b469eb4d Iustin Pop
                             log_messages=test_messages, fail=False),
390 f99010b2 Michael Hanselmann
        ]
391 f99010b2 Michael Hanselmann
      expect_messages = 2 * [test_messages]
392 f99010b2 Michael Hanselmann
      expect_opstatus = [
393 f99010b2 Michael Hanselmann
        constants.OP_STATUS_SUCCESS,
394 f99010b2 Michael Hanselmann
        constants.OP_STATUS_SUCCESS,
395 f99010b2 Michael Hanselmann
        ]
396 f99010b2 Michael Hanselmann
      expect_resultlen = 2
397 e58f87a9 Michael Hanselmann
    else:
398 f99010b2 Michael Hanselmann
      if mode == TM_SUCCESS:
399 f99010b2 Michael Hanselmann
        ToStdout("Testing job success")
400 f99010b2 Michael Hanselmann
        expect_opstatus = [constants.OP_STATUS_SUCCESS]
401 f99010b2 Michael Hanselmann
      elif mode == TM_FAIL:
402 f99010b2 Michael Hanselmann
        ToStdout("Testing job failure")
403 f99010b2 Michael Hanselmann
        expect_opstatus = [constants.OP_STATUS_ERROR]
404 f99010b2 Michael Hanselmann
      else:
405 f99010b2 Michael Hanselmann
        raise errors.ProgrammerError("Unknown test mode %s" % mode)
406 f99010b2 Michael Hanselmann
407 f99010b2 Michael Hanselmann
      ops = [
408 b469eb4d Iustin Pop
        opcodes.OpTestJqueue(notify_waitlock=True,
409 b469eb4d Iustin Pop
                             notify_exec=True,
410 b469eb4d Iustin Pop
                             log_messages=test_messages,
411 b469eb4d Iustin Pop
                             fail=fail)
412 f99010b2 Michael Hanselmann
        ]
413 f99010b2 Michael Hanselmann
      expect_messages = [test_messages]
414 f99010b2 Michael Hanselmann
      expect_resultlen = 1
415 f99010b2 Michael Hanselmann
416 f99010b2 Michael Hanselmann
    cl = cli.GetClient()
417 f99010b2 Michael Hanselmann
    cli.SetGenericOpcodeOpts(ops, opts)
418 f99010b2 Michael Hanselmann
419 f99010b2 Michael Hanselmann
    # Send job to master daemon
420 f99010b2 Michael Hanselmann
    job_id = cli.SendJob(ops, cl=cl)
421 e58f87a9 Michael Hanselmann
422 e58f87a9 Michael Hanselmann
    reporter = _JobQueueTestReporter()
423 f99010b2 Michael Hanselmann
    results = None
424 f99010b2 Michael Hanselmann
425 e58f87a9 Michael Hanselmann
    try:
426 f99010b2 Michael Hanselmann
      results = cli.PollJob(job_id, cl=cl, reporter=reporter)
427 f99010b2 Michael Hanselmann
    except errors.OpExecError, err:
428 e58f87a9 Michael Hanselmann
      if not fail:
429 e58f87a9 Michael Hanselmann
        raise
430 f99010b2 Michael Hanselmann
      ToStdout("Ignoring error: %s", err)
431 e58f87a9 Michael Hanselmann
    else:
432 e58f87a9 Michael Hanselmann
      if fail:
433 e58f87a9 Michael Hanselmann
        raise errors.OpExecError("Job didn't fail when it should")
434 e58f87a9 Michael Hanselmann
435 f99010b2 Michael Hanselmann
    # Check length of result
436 f99010b2 Michael Hanselmann
    if fail:
437 f99010b2 Michael Hanselmann
      if results is not None:
438 f99010b2 Michael Hanselmann
        raise errors.OpExecError("Received result from failed job")
439 f99010b2 Michael Hanselmann
    elif len(results) != expect_resultlen:
440 f99010b2 Michael Hanselmann
      raise errors.OpExecError("Received %s results (%s), expected %s" %
441 f99010b2 Michael Hanselmann
                               (len(results), results, expect_resultlen))
442 f99010b2 Michael Hanselmann
443 e58f87a9 Michael Hanselmann
    # Check received log messages
444 f99010b2 Michael Hanselmann
    all_messages = [i for j in expect_messages for i in j]
445 f99010b2 Michael Hanselmann
    if reporter.GetTestMessages() != all_messages:
446 e58f87a9 Michael Hanselmann
      raise errors.OpExecError("Received test messages don't match input"
447 e58f87a9 Michael Hanselmann
                               " (input %r, received %r)" %
448 f99010b2 Michael Hanselmann
                               (all_messages, reporter.GetTestMessages()))
449 e58f87a9 Michael Hanselmann
450 e58f87a9 Michael Hanselmann
    # Check final status
451 f99010b2 Michael Hanselmann
    reported_job_id = reporter.GetJobId()
452 f99010b2 Michael Hanselmann
    if reported_job_id != job_id:
453 f99010b2 Michael Hanselmann
      raise errors.OpExecError("Reported job ID %s doesn't match"
454 f99010b2 Michael Hanselmann
                               "submission job ID %s" %
455 f99010b2 Michael Hanselmann
                               (reported_job_id, job_id))
456 e58f87a9 Michael Hanselmann
457 f99010b2 Michael Hanselmann
    jobdetails = cli.GetClient().QueryJobs([job_id], ["status", "opstatus"])[0]
458 e58f87a9 Michael Hanselmann
    if not jobdetails:
459 e58f87a9 Michael Hanselmann
      raise errors.OpExecError("Can't find job %s" % job_id)
460 e58f87a9 Michael Hanselmann
461 e58f87a9 Michael Hanselmann
    if fail:
462 e58f87a9 Michael Hanselmann
      exp_status = constants.JOB_STATUS_ERROR
463 e58f87a9 Michael Hanselmann
    else:
464 e58f87a9 Michael Hanselmann
      exp_status = constants.JOB_STATUS_SUCCESS
465 e58f87a9 Michael Hanselmann
466 f99010b2 Michael Hanselmann
    (final_status, final_opstatus) = jobdetails
467 e58f87a9 Michael Hanselmann
    if final_status != exp_status:
468 e58f87a9 Michael Hanselmann
      raise errors.OpExecError("Final job status is %s, not %s as expected" %
469 e58f87a9 Michael Hanselmann
                               (final_status, exp_status))
470 f99010b2 Michael Hanselmann
    if len(final_opstatus) != len(ops):
471 f99010b2 Michael Hanselmann
      raise errors.OpExecError("Did not receive status for all opcodes (got %s,"
472 f99010b2 Michael Hanselmann
                               " expected %s)" %
473 f99010b2 Michael Hanselmann
                               (len(final_opstatus), len(ops)))
474 f99010b2 Michael Hanselmann
    if final_opstatus != expect_opstatus:
475 f99010b2 Michael Hanselmann
      raise errors.OpExecError("Opcode status is %s, expected %s" %
476 f99010b2 Michael Hanselmann
                               (final_opstatus, expect_opstatus))
477 f99010b2 Michael Hanselmann
478 f99010b2 Michael Hanselmann
  ToStdout("Job queue test successful")
479 e58f87a9 Michael Hanselmann
480 e58f87a9 Michael Hanselmann
  return 0
481 e58f87a9 Michael Hanselmann
482 e58f87a9 Michael Hanselmann
483 19b9ba9a Michael Hanselmann
def ListLocks(opts, args): # pylint: disable-msg=W0613
484 19b9ba9a Michael Hanselmann
  """List all locks.
485 19b9ba9a Michael Hanselmann

486 19b9ba9a Michael Hanselmann
  @param opts: the command line options selected by the user
487 19b9ba9a Michael Hanselmann
  @type args: list
488 19b9ba9a Michael Hanselmann
  @param args: should be an empty list
489 19b9ba9a Michael Hanselmann
  @rtype: int
490 19b9ba9a Michael Hanselmann
  @return: the desired exit code
491 19b9ba9a Michael Hanselmann

492 19b9ba9a Michael Hanselmann
  """
493 19b9ba9a Michael Hanselmann
  selected_fields = ParseFields(opts.output, _LIST_LOCKS_DEF_FIELDS)
494 19b9ba9a Michael Hanselmann
495 24d16f76 Michael Hanselmann
  def _DashIfNone(fn):
496 24d16f76 Michael Hanselmann
    def wrapper(value):
497 24d16f76 Michael Hanselmann
      if not value:
498 24d16f76 Michael Hanselmann
        return "-"
499 24d16f76 Michael Hanselmann
      return fn(value)
500 24d16f76 Michael Hanselmann
    return wrapper
501 24d16f76 Michael Hanselmann
502 24d16f76 Michael Hanselmann
  def _FormatPending(value):
503 24d16f76 Michael Hanselmann
    """Format pending acquires.
504 24d16f76 Michael Hanselmann

505 24d16f76 Michael Hanselmann
    """
506 24d16f76 Michael Hanselmann
    return utils.CommaJoin("%s:%s" % (mode, ",".join(threads))
507 24d16f76 Michael Hanselmann
                           for mode, threads in value)
508 24d16f76 Michael Hanselmann
509 24d16f76 Michael Hanselmann
  # Format raw values
510 24d16f76 Michael Hanselmann
  fmtoverride = {
511 24d16f76 Michael Hanselmann
    "mode": (_DashIfNone(str), False),
512 24d16f76 Michael Hanselmann
    "owner": (_DashIfNone(",".join), False),
513 24d16f76 Michael Hanselmann
    "pending": (_DashIfNone(_FormatPending), False),
514 24d16f76 Michael Hanselmann
    }
515 19b9ba9a Michael Hanselmann
516 19b9ba9a Michael Hanselmann
  while True:
517 24d16f76 Michael Hanselmann
    ret = GenericList(constants.QR_LOCK, selected_fields, None, None,
518 24d16f76 Michael Hanselmann
                      opts.separator, not opts.no_headers,
519 f0b1bafe Iustin Pop
                      format_override=fmtoverride, verbose=opts.verbose)
520 24d16f76 Michael Hanselmann
521 24d16f76 Michael Hanselmann
    if ret != constants.EXIT_SUCCESS:
522 24d16f76 Michael Hanselmann
      return ret
523 19b9ba9a Michael Hanselmann
524 19b9ba9a Michael Hanselmann
    if not opts.interval:
525 19b9ba9a Michael Hanselmann
      break
526 19b9ba9a Michael Hanselmann
527 19b9ba9a Michael Hanselmann
    ToStdout("")
528 19b9ba9a Michael Hanselmann
    time.sleep(opts.interval)
529 19b9ba9a Michael Hanselmann
530 19b9ba9a Michael Hanselmann
  return 0
531 19b9ba9a Michael Hanselmann
532 19b9ba9a Michael Hanselmann
533 fd3ee040 Iustin Pop
commands = {
534 6ea815cf Iustin Pop
  'delay': (
535 6ea815cf Iustin Pop
    Delay, [ArgUnknown(min=1, max=1)],
536 064c21f8 Iustin Pop
    [cli_option("--no-master", dest="on_master", default=True,
537 6ea815cf Iustin Pop
                action="store_false", help="Do not sleep in the master code"),
538 6ea815cf Iustin Pop
     cli_option("-n", dest="on_nodes", default=[],
539 6ea815cf Iustin Pop
                action="append", help="Select nodes to sleep on"),
540 85a87e21 Guido Trotter
     cli_option("-r", "--repeat", type="int", default="0", dest="repeat",
541 85a87e21 Guido Trotter
                help="Number of times to repeat the sleep"),
542 aa06f8c6 Michael Hanselmann
     DRY_RUN_OPT, PRIORITY_OPT,
543 6ea815cf Iustin Pop
     ],
544 6ea815cf Iustin Pop
    "[opts...] <duration>", "Executes a TestDelay OpCode"),
545 6ea815cf Iustin Pop
  'submit-job': (
546 6ea815cf Iustin Pop
    GenericOpCodes, [ArgFile(min=1)],
547 064c21f8 Iustin Pop
    [VERBOSE_OPT,
548 6ea815cf Iustin Pop
     cli_option("--op-repeat", type="int", default="1", dest="rep_op",
549 6ea815cf Iustin Pop
                help="Repeat the opcode sequence this number of times"),
550 6ea815cf Iustin Pop
     cli_option("--job-repeat", type="int", default="1", dest="rep_job",
551 6ea815cf Iustin Pop
                help="Repeat the job this number of times"),
552 6ea815cf Iustin Pop
     cli_option("--timing-stats", default=False,
553 6ea815cf Iustin Pop
                action="store_true", help="Show timing stats"),
554 66ecc479 Guido Trotter
     cli_option("--each", default=False, action="store_true",
555 66ecc479 Guido Trotter
                help="Submit each job separately"),
556 aa06f8c6 Michael Hanselmann
     DRY_RUN_OPT, PRIORITY_OPT,
557 6ea815cf Iustin Pop
     ],
558 6ea815cf Iustin Pop
    "<op_list_file...>", "Submits jobs built from json files"
559 6ea815cf Iustin Pop
    " containing a list of serialized opcodes"),
560 3f1e065d Iustin Pop
  'iallocator': (
561 823a72bc Iustin Pop
    TestAllocator, [ArgUnknown(min=1)],
562 9133387e Michael Hanselmann
    [cli_option("--dir", dest="direction", default=constants.IALLOCATOR_DIR_IN,
563 9133387e Michael Hanselmann
                choices=list(constants.VALID_IALLOCATOR_DIRECTIONS),
564 6ea815cf Iustin Pop
                help="Show allocator input (in) or allocator"
565 6ea815cf Iustin Pop
                " results (out)"),
566 6ea815cf Iustin Pop
     IALLOCATOR_OPT,
567 6ea815cf Iustin Pop
     cli_option("-m", "--mode", default="relocate",
568 42c161cf Michael Hanselmann
                choices=list(constants.VALID_IALLOCATOR_MODES),
569 42c161cf Michael Hanselmann
                help=("Request mode (one of %s)" %
570 42c161cf Michael Hanselmann
                      utils.CommaJoin(constants.VALID_IALLOCATOR_MODES))),
571 dd47a0f0 Iustin Pop
     cli_option("--memory", default=128, type="unit",
572 6ea815cf Iustin Pop
                help="Memory size for the instance (MiB)"),
573 6ea815cf Iustin Pop
     cli_option("--disks", default="4096,4096",
574 6ea815cf Iustin Pop
                help="Comma separated list of disk sizes (MiB)"),
575 6ea815cf Iustin Pop
     DISK_TEMPLATE_OPT,
576 6ea815cf Iustin Pop
     cli_option("--nics", default="00:11:22:33:44:55",
577 6ea815cf Iustin Pop
                help="Comma separated list of nics, each nic"
578 6ea815cf Iustin Pop
                " definition is of form mac/ip/bridge, if"
579 6ea815cf Iustin Pop
                " missing values are replace by None"),
580 6ea815cf Iustin Pop
     OS_OPT,
581 6ea815cf Iustin Pop
     cli_option("-p", "--vcpus", default=1, type="int",
582 6ea815cf Iustin Pop
                help="Select number of VCPUs for the instance"),
583 6ea815cf Iustin Pop
     cli_option("--tags", default=None,
584 6ea815cf Iustin Pop
                help="Comma separated list of tags"),
585 42c161cf Michael Hanselmann
     cli_option("--reloc-mode", default=constants.IALLOCATOR_MRELOC_ANY,
586 42c161cf Michael Hanselmann
                choices=list(constants.IALLOCATOR_MRELOC_MODES),
587 42c161cf Michael Hanselmann
                help=("Instance relocation mode (one of %s)" %
588 42c161cf Michael Hanselmann
                      utils.CommaJoin(constants.IALLOCATOR_MRELOC_MODES))),
589 42c161cf Michael Hanselmann
     cli_option("--target-groups", help="Target groups for relocation"),
590 aa06f8c6 Michael Hanselmann
     DRY_RUN_OPT, PRIORITY_OPT,
591 6ea815cf Iustin Pop
     ],
592 6ea815cf Iustin Pop
    "{opts...} <instance>", "Executes a TestAllocator OpCode"),
593 e58f87a9 Michael Hanselmann
  "test-jobqueue": (
594 aa06f8c6 Michael Hanselmann
    TestJobqueue, ARGS_NONE, [PRIORITY_OPT],
595 19b9ba9a Michael Hanselmann
    "", "Test a few aspects of the job queue"),
596 19b9ba9a Michael Hanselmann
  "locks": (
597 f0b1bafe Iustin Pop
    ListLocks, ARGS_NONE,
598 f0b1bafe Iustin Pop
    [NOHDR_OPT, SEP_OPT, FIELDS_OPT, INTERVAL_OPT, VERBOSE_OPT],
599 19b9ba9a Michael Hanselmann
    "[--interval N]", "Show a list of locks in the master daemon"),
600 fd3ee040 Iustin Pop
  }
601 fd3ee040 Iustin Pop
602 3f1e065d Iustin Pop
#: dictionary with aliases for commands
603 3f1e065d Iustin Pop
aliases = {
604 3f1e065d Iustin Pop
  "allocator": "iallocator",
605 3f1e065d Iustin Pop
  }
606 fd3ee040 Iustin Pop
607 c2855a12 Michael Hanselmann
def Main():
608 3f1e065d Iustin Pop
  return GenericMain(commands, aliases=aliases)