Statistics
| Branch: | Tag: | Revision:

root / lib / cmdlib / test.py @ 18397489

History | View | Annotate | Download (12.1 kB)

1 1d870e0d Thomas Thrainer
#
2 1d870e0d Thomas Thrainer
#
3 1d870e0d Thomas Thrainer
4 1d870e0d Thomas Thrainer
# Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Google Inc.
5 1d870e0d Thomas Thrainer
#
6 1d870e0d Thomas Thrainer
# This program is free software; you can redistribute it and/or modify
7 1d870e0d Thomas Thrainer
# it under the terms of the GNU General Public License as published by
8 1d870e0d Thomas Thrainer
# the Free Software Foundation; either version 2 of the License, or
9 1d870e0d Thomas Thrainer
# (at your option) any later version.
10 1d870e0d Thomas Thrainer
#
11 1d870e0d Thomas Thrainer
# This program is distributed in the hope that it will be useful, but
12 1d870e0d Thomas Thrainer
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 1d870e0d Thomas Thrainer
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 1d870e0d Thomas Thrainer
# General Public License for more details.
15 1d870e0d Thomas Thrainer
#
16 1d870e0d Thomas Thrainer
# You should have received a copy of the GNU General Public License
17 1d870e0d Thomas Thrainer
# along with this program; if not, write to the Free Software
18 1d870e0d Thomas Thrainer
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 1d870e0d Thomas Thrainer
# 02110-1301, USA.
20 1d870e0d Thomas Thrainer
21 1d870e0d Thomas Thrainer
22 1d870e0d Thomas Thrainer
"""Test logical units."""
23 1d870e0d Thomas Thrainer
24 1d870e0d Thomas Thrainer
import logging
25 1d870e0d Thomas Thrainer
import shutil
26 1d870e0d Thomas Thrainer
import socket
27 1d870e0d Thomas Thrainer
import tempfile
28 1d870e0d Thomas Thrainer
29 1d870e0d Thomas Thrainer
from ganeti import compat
30 1d870e0d Thomas Thrainer
from ganeti import constants
31 1d870e0d Thomas Thrainer
from ganeti import errors
32 1d870e0d Thomas Thrainer
from ganeti import locking
33 1d870e0d Thomas Thrainer
from ganeti import utils
34 1d870e0d Thomas Thrainer
from ganeti.masterd import iallocator
35 1d870e0d Thomas Thrainer
from ganeti.cmdlib.base import NoHooksLU
36 da4a52a3 Thomas Thrainer
from ganeti.cmdlib.common import ExpandInstanceUuidAndName, GetWantedNodes, \
37 5eacbcae Thomas Thrainer
  GetWantedInstances
38 1d870e0d Thomas Thrainer
39 1d870e0d Thomas Thrainer
40 1d870e0d Thomas Thrainer
class LUTestDelay(NoHooksLU):
41 1d870e0d Thomas Thrainer
  """Sleep for a specified amount of time.
42 1d870e0d Thomas Thrainer

43 1d870e0d Thomas Thrainer
  This LU sleeps on the master and/or nodes for a specified amount of
44 1d870e0d Thomas Thrainer
  time.
45 1d870e0d Thomas Thrainer

46 1d870e0d Thomas Thrainer
  """
47 1d870e0d Thomas Thrainer
  REQ_BGL = False
48 1d870e0d Thomas Thrainer
49 1d870e0d Thomas Thrainer
  def ExpandNames(self):
50 1d870e0d Thomas Thrainer
    """Expand names and set required locks.
51 1d870e0d Thomas Thrainer

52 1d870e0d Thomas Thrainer
    This expands the node list, if any.
53 1d870e0d Thomas Thrainer

54 1d870e0d Thomas Thrainer
    """
55 1d870e0d Thomas Thrainer
    self.needed_locks = {}
56 1d870e0d Thomas Thrainer
    if self.op.on_nodes:
57 1d870e0d Thomas Thrainer
      # _GetWantedNodes can be used here, but is not always appropriate to use
58 1d870e0d Thomas Thrainer
      # this way in ExpandNames. Check LogicalUnit.ExpandNames docstring for
59 1d870e0d Thomas Thrainer
      # more information.
60 1c3231aa Thomas Thrainer
      (self.op.on_node_uuids, self.op.on_nodes) = \
61 1c3231aa Thomas Thrainer
        GetWantedNodes(self, self.op.on_nodes)
62 1c3231aa Thomas Thrainer
      self.needed_locks[locking.LEVEL_NODE] = self.op.on_node_uuids
63 1d870e0d Thomas Thrainer
64 1d870e0d Thomas Thrainer
  def _TestDelay(self):
65 1d870e0d Thomas Thrainer
    """Do the actual sleep.
66 1d870e0d Thomas Thrainer

67 1d870e0d Thomas Thrainer
    """
68 1d870e0d Thomas Thrainer
    if self.op.on_master:
69 1d870e0d Thomas Thrainer
      if not utils.TestDelay(self.op.duration):
70 1d870e0d Thomas Thrainer
        raise errors.OpExecError("Error during master delay test")
71 1c3231aa Thomas Thrainer
    if self.op.on_node_uuids:
72 1c3231aa Thomas Thrainer
      result = self.rpc.call_test_delay(self.op.on_node_uuids, self.op.duration)
73 1c3231aa Thomas Thrainer
      for node_uuid, node_result in result.items():
74 1c3231aa Thomas Thrainer
        node_result.Raise("Failure during rpc call to node %s" %
75 1c3231aa Thomas Thrainer
                          self.cfg.GetNodeName(node_uuid))
76 1d870e0d Thomas Thrainer
77 1d870e0d Thomas Thrainer
  def Exec(self, feedback_fn):
78 1d870e0d Thomas Thrainer
    """Execute the test delay opcode, with the wanted repetitions.
79 1d870e0d Thomas Thrainer

80 1d870e0d Thomas Thrainer
    """
81 1d870e0d Thomas Thrainer
    if self.op.repeat == 0:
82 1d870e0d Thomas Thrainer
      self._TestDelay()
83 1d870e0d Thomas Thrainer
    else:
84 1d870e0d Thomas Thrainer
      top_value = self.op.repeat - 1
85 1d870e0d Thomas Thrainer
      for i in range(self.op.repeat):
86 1d870e0d Thomas Thrainer
        self.LogInfo("Test delay iteration %d/%d", i, top_value)
87 1d870e0d Thomas Thrainer
        self._TestDelay()
88 1d870e0d Thomas Thrainer
89 1d870e0d Thomas Thrainer
90 1d870e0d Thomas Thrainer
class LUTestJqueue(NoHooksLU):
91 1d870e0d Thomas Thrainer
  """Utility LU to test some aspects of the job queue.
92 1d870e0d Thomas Thrainer

93 1d870e0d Thomas Thrainer
  """
94 1d870e0d Thomas Thrainer
  REQ_BGL = False
95 1d870e0d Thomas Thrainer
96 1d870e0d Thomas Thrainer
  # Must be lower than default timeout for WaitForJobChange to see whether it
97 1d870e0d Thomas Thrainer
  # notices changed jobs
98 1d870e0d Thomas Thrainer
  _CLIENT_CONNECT_TIMEOUT = 20.0
99 1d870e0d Thomas Thrainer
  _CLIENT_CONFIRM_TIMEOUT = 60.0
100 1d870e0d Thomas Thrainer
101 1d870e0d Thomas Thrainer
  @classmethod
102 1d870e0d Thomas Thrainer
  def _NotifyUsingSocket(cls, cb, errcls):
103 1d870e0d Thomas Thrainer
    """Opens a Unix socket and waits for another program to connect.
104 1d870e0d Thomas Thrainer

105 1d870e0d Thomas Thrainer
    @type cb: callable
106 1d870e0d Thomas Thrainer
    @param cb: Callback to send socket name to client
107 1d870e0d Thomas Thrainer
    @type errcls: class
108 1d870e0d Thomas Thrainer
    @param errcls: Exception class to use for errors
109 1d870e0d Thomas Thrainer

110 1d870e0d Thomas Thrainer
    """
111 1d870e0d Thomas Thrainer
    # Using a temporary directory as there's no easy way to create temporary
112 1d870e0d Thomas Thrainer
    # sockets without writing a custom loop around tempfile.mktemp and
113 1d870e0d Thomas Thrainer
    # socket.bind
114 1d870e0d Thomas Thrainer
    tmpdir = tempfile.mkdtemp()
115 1d870e0d Thomas Thrainer
    try:
116 1d870e0d Thomas Thrainer
      tmpsock = utils.PathJoin(tmpdir, "sock")
117 1d870e0d Thomas Thrainer
118 1d870e0d Thomas Thrainer
      logging.debug("Creating temporary socket at %s", tmpsock)
119 1d870e0d Thomas Thrainer
      sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
120 1d870e0d Thomas Thrainer
      try:
121 1d870e0d Thomas Thrainer
        sock.bind(tmpsock)
122 1d870e0d Thomas Thrainer
        sock.listen(1)
123 1d870e0d Thomas Thrainer
124 1d870e0d Thomas Thrainer
        # Send details to client
125 1d870e0d Thomas Thrainer
        cb(tmpsock)
126 1d870e0d Thomas Thrainer
127 1d870e0d Thomas Thrainer
        # Wait for client to connect before continuing
128 1d870e0d Thomas Thrainer
        sock.settimeout(cls._CLIENT_CONNECT_TIMEOUT)
129 1d870e0d Thomas Thrainer
        try:
130 1d870e0d Thomas Thrainer
          (conn, _) = sock.accept()
131 1d870e0d Thomas Thrainer
        except socket.error, err:
132 1d870e0d Thomas Thrainer
          raise errcls("Client didn't connect in time (%s)" % err)
133 1d870e0d Thomas Thrainer
      finally:
134 1d870e0d Thomas Thrainer
        sock.close()
135 1d870e0d Thomas Thrainer
    finally:
136 1d870e0d Thomas Thrainer
      # Remove as soon as client is connected
137 1d870e0d Thomas Thrainer
      shutil.rmtree(tmpdir)
138 1d870e0d Thomas Thrainer
139 1d870e0d Thomas Thrainer
    # Wait for client to close
140 1d870e0d Thomas Thrainer
    try:
141 1d870e0d Thomas Thrainer
      try:
142 1d870e0d Thomas Thrainer
        # pylint: disable=E1101
143 1d870e0d Thomas Thrainer
        # Instance of '_socketobject' has no ... member
144 1d870e0d Thomas Thrainer
        conn.settimeout(cls._CLIENT_CONFIRM_TIMEOUT)
145 1d870e0d Thomas Thrainer
        conn.recv(1)
146 1d870e0d Thomas Thrainer
      except socket.error, err:
147 1d870e0d Thomas Thrainer
        raise errcls("Client failed to confirm notification (%s)" % err)
148 1d870e0d Thomas Thrainer
    finally:
149 1d870e0d Thomas Thrainer
      conn.close()
150 1d870e0d Thomas Thrainer
151 1d870e0d Thomas Thrainer
  def _SendNotification(self, test, arg, sockname):
152 1d870e0d Thomas Thrainer
    """Sends a notification to the client.
153 1d870e0d Thomas Thrainer

154 1d870e0d Thomas Thrainer
    @type test: string
155 1d870e0d Thomas Thrainer
    @param test: Test name
156 1d870e0d Thomas Thrainer
    @param arg: Test argument (depends on test)
157 1d870e0d Thomas Thrainer
    @type sockname: string
158 1d870e0d Thomas Thrainer
    @param sockname: Socket path
159 1d870e0d Thomas Thrainer

160 1d870e0d Thomas Thrainer
    """
161 1d870e0d Thomas Thrainer
    self.Log(constants.ELOG_JQUEUE_TEST, (sockname, test, arg))
162 1d870e0d Thomas Thrainer
163 1d870e0d Thomas Thrainer
  def _Notify(self, prereq, test, arg):
164 1d870e0d Thomas Thrainer
    """Notifies the client of a test.
165 1d870e0d Thomas Thrainer

166 1d870e0d Thomas Thrainer
    @type prereq: bool
167 1d870e0d Thomas Thrainer
    @param prereq: Whether this is a prereq-phase test
168 1d870e0d Thomas Thrainer
    @type test: string
169 1d870e0d Thomas Thrainer
    @param test: Test name
170 1d870e0d Thomas Thrainer
    @param arg: Test argument (depends on test)
171 1d870e0d Thomas Thrainer

172 1d870e0d Thomas Thrainer
    """
173 1d870e0d Thomas Thrainer
    if prereq:
174 1d870e0d Thomas Thrainer
      errcls = errors.OpPrereqError
175 1d870e0d Thomas Thrainer
    else:
176 1d870e0d Thomas Thrainer
      errcls = errors.OpExecError
177 1d870e0d Thomas Thrainer
178 1d870e0d Thomas Thrainer
    return self._NotifyUsingSocket(compat.partial(self._SendNotification,
179 1d870e0d Thomas Thrainer
                                                  test, arg),
180 1d870e0d Thomas Thrainer
                                   errcls)
181 1d870e0d Thomas Thrainer
182 1d870e0d Thomas Thrainer
  def CheckArguments(self):
183 1d870e0d Thomas Thrainer
    self.checkargs_calls = getattr(self, "checkargs_calls", 0) + 1
184 1d870e0d Thomas Thrainer
    self.expandnames_calls = 0
185 1d870e0d Thomas Thrainer
186 1d870e0d Thomas Thrainer
  def ExpandNames(self):
187 1d870e0d Thomas Thrainer
    checkargs_calls = getattr(self, "checkargs_calls", 0)
188 1d870e0d Thomas Thrainer
    if checkargs_calls < 1:
189 1d870e0d Thomas Thrainer
      raise errors.ProgrammerError("CheckArguments was not called")
190 1d870e0d Thomas Thrainer
191 1d870e0d Thomas Thrainer
    self.expandnames_calls += 1
192 1d870e0d Thomas Thrainer
193 1d870e0d Thomas Thrainer
    if self.op.notify_waitlock:
194 1d870e0d Thomas Thrainer
      self._Notify(True, constants.JQT_EXPANDNAMES, None)
195 1d870e0d Thomas Thrainer
196 1d870e0d Thomas Thrainer
    self.LogInfo("Expanding names")
197 1d870e0d Thomas Thrainer
198 1d870e0d Thomas Thrainer
    # Get lock on master node (just to get a lock, not for a particular reason)
199 1d870e0d Thomas Thrainer
    self.needed_locks = {
200 1d870e0d Thomas Thrainer
      locking.LEVEL_NODE: self.cfg.GetMasterNode(),
201 1d870e0d Thomas Thrainer
      }
202 1d870e0d Thomas Thrainer
203 1d870e0d Thomas Thrainer
  def Exec(self, feedback_fn):
204 1d870e0d Thomas Thrainer
    if self.expandnames_calls < 1:
205 1d870e0d Thomas Thrainer
      raise errors.ProgrammerError("ExpandNames was not called")
206 1d870e0d Thomas Thrainer
207 1d870e0d Thomas Thrainer
    if self.op.notify_exec:
208 1d870e0d Thomas Thrainer
      self._Notify(False, constants.JQT_EXEC, None)
209 1d870e0d Thomas Thrainer
210 1d870e0d Thomas Thrainer
    self.LogInfo("Executing")
211 1d870e0d Thomas Thrainer
212 1d870e0d Thomas Thrainer
    if self.op.log_messages:
213 1d870e0d Thomas Thrainer
      self._Notify(False, constants.JQT_STARTMSG, len(self.op.log_messages))
214 1d870e0d Thomas Thrainer
      for idx, msg in enumerate(self.op.log_messages):
215 1d870e0d Thomas Thrainer
        self.LogInfo("Sending log message %s", idx + 1)
216 1d870e0d Thomas Thrainer
        feedback_fn(constants.JQT_MSGPREFIX + msg)
217 1d870e0d Thomas Thrainer
        # Report how many test messages have been sent
218 1d870e0d Thomas Thrainer
        self._Notify(False, constants.JQT_LOGMSG, idx + 1)
219 1d870e0d Thomas Thrainer
220 1d870e0d Thomas Thrainer
    if self.op.fail:
221 1d870e0d Thomas Thrainer
      raise errors.OpExecError("Opcode failure was requested")
222 1d870e0d Thomas Thrainer
223 1d870e0d Thomas Thrainer
    return True
224 1d870e0d Thomas Thrainer
225 1d870e0d Thomas Thrainer
226 1d870e0d Thomas Thrainer
class LUTestAllocator(NoHooksLU):
227 1d870e0d Thomas Thrainer
  """Run allocator tests.
228 1d870e0d Thomas Thrainer

229 1d870e0d Thomas Thrainer
  This LU runs the allocator tests
230 1d870e0d Thomas Thrainer

231 1d870e0d Thomas Thrainer
  """
232 1d870e0d Thomas Thrainer
  def CheckPrereq(self):
233 1d870e0d Thomas Thrainer
    """Check prerequisites.
234 1d870e0d Thomas Thrainer

235 1d870e0d Thomas Thrainer
    This checks the opcode parameters depending on the director and mode test.
236 1d870e0d Thomas Thrainer

237 1d870e0d Thomas Thrainer
    """
238 1d870e0d Thomas Thrainer
    if self.op.mode in (constants.IALLOCATOR_MODE_ALLOC,
239 1d870e0d Thomas Thrainer
                        constants.IALLOCATOR_MODE_MULTI_ALLOC):
240 1d870e0d Thomas Thrainer
      for attr in ["memory", "disks", "disk_template",
241 1d870e0d Thomas Thrainer
                   "os", "tags", "nics", "vcpus"]:
242 1d870e0d Thomas Thrainer
        if not hasattr(self.op, attr):
243 1d870e0d Thomas Thrainer
          raise errors.OpPrereqError("Missing attribute '%s' on opcode input" %
244 1d870e0d Thomas Thrainer
                                     attr, errors.ECODE_INVAL)
245 da4a52a3 Thomas Thrainer
      (self.inst_uuid, iname) = self.cfg.ExpandInstanceName(self.op.name)
246 1d870e0d Thomas Thrainer
      if iname is not None:
247 1d870e0d Thomas Thrainer
        raise errors.OpPrereqError("Instance '%s' already in the cluster" %
248 1d870e0d Thomas Thrainer
                                   iname, errors.ECODE_EXISTS)
249 1d870e0d Thomas Thrainer
      if not isinstance(self.op.nics, list):
250 1d870e0d Thomas Thrainer
        raise errors.OpPrereqError("Invalid parameter 'nics'",
251 1d870e0d Thomas Thrainer
                                   errors.ECODE_INVAL)
252 1d870e0d Thomas Thrainer
      if not isinstance(self.op.disks, list):
253 1d870e0d Thomas Thrainer
        raise errors.OpPrereqError("Invalid parameter 'disks'",
254 1d870e0d Thomas Thrainer
                                   errors.ECODE_INVAL)
255 1d870e0d Thomas Thrainer
      for row in self.op.disks:
256 1d870e0d Thomas Thrainer
        if (not isinstance(row, dict) or
257 1d870e0d Thomas Thrainer
            constants.IDISK_SIZE not in row or
258 1d870e0d Thomas Thrainer
            not isinstance(row[constants.IDISK_SIZE], int) or
259 1d870e0d Thomas Thrainer
            constants.IDISK_MODE not in row or
260 1d870e0d Thomas Thrainer
            row[constants.IDISK_MODE] not in constants.DISK_ACCESS_SET):
261 1d870e0d Thomas Thrainer
          raise errors.OpPrereqError("Invalid contents of the 'disks'"
262 1d870e0d Thomas Thrainer
                                     " parameter", errors.ECODE_INVAL)
263 1d870e0d Thomas Thrainer
      if self.op.hypervisor is None:
264 1d870e0d Thomas Thrainer
        self.op.hypervisor = self.cfg.GetHypervisorType()
265 1d870e0d Thomas Thrainer
    elif self.op.mode == constants.IALLOCATOR_MODE_RELOC:
266 da4a52a3 Thomas Thrainer
      (fuuid, fname) = ExpandInstanceUuidAndName(self.cfg, None, self.op.name)
267 1d870e0d Thomas Thrainer
      self.op.name = fname
268 1c3231aa Thomas Thrainer
      self.relocate_from_node_uuids = \
269 da4a52a3 Thomas Thrainer
          list(self.cfg.GetInstanceInfo(fuuid).secondary_nodes)
270 1d870e0d Thomas Thrainer
    elif self.op.mode in (constants.IALLOCATOR_MODE_CHG_GROUP,
271 1d870e0d Thomas Thrainer
                          constants.IALLOCATOR_MODE_NODE_EVAC):
272 1d870e0d Thomas Thrainer
      if not self.op.instances:
273 1d870e0d Thomas Thrainer
        raise errors.OpPrereqError("Missing instances", errors.ECODE_INVAL)
274 da4a52a3 Thomas Thrainer
      (_, self.op.instances) = GetWantedInstances(self, self.op.instances)
275 1d870e0d Thomas Thrainer
    else:
276 1d870e0d Thomas Thrainer
      raise errors.OpPrereqError("Invalid test allocator mode '%s'" %
277 1d870e0d Thomas Thrainer
                                 self.op.mode, errors.ECODE_INVAL)
278 1d870e0d Thomas Thrainer
279 1d870e0d Thomas Thrainer
    if self.op.direction == constants.IALLOCATOR_DIR_OUT:
280 1d870e0d Thomas Thrainer
      if self.op.iallocator is None:
281 1d870e0d Thomas Thrainer
        raise errors.OpPrereqError("Missing allocator name",
282 1d870e0d Thomas Thrainer
                                   errors.ECODE_INVAL)
283 1d870e0d Thomas Thrainer
    elif self.op.direction != constants.IALLOCATOR_DIR_IN:
284 1d870e0d Thomas Thrainer
      raise errors.OpPrereqError("Wrong allocator test '%s'" %
285 1d870e0d Thomas Thrainer
                                 self.op.direction, errors.ECODE_INVAL)
286 1d870e0d Thomas Thrainer
287 1d870e0d Thomas Thrainer
  def Exec(self, feedback_fn):
288 1d870e0d Thomas Thrainer
    """Run the allocator test.
289 1d870e0d Thomas Thrainer

290 1d870e0d Thomas Thrainer
    """
291 1d870e0d Thomas Thrainer
    if self.op.mode == constants.IALLOCATOR_MODE_ALLOC:
292 1d870e0d Thomas Thrainer
      req = iallocator.IAReqInstanceAlloc(name=self.op.name,
293 1d870e0d Thomas Thrainer
                                          memory=self.op.memory,
294 1d870e0d Thomas Thrainer
                                          disks=self.op.disks,
295 1d870e0d Thomas Thrainer
                                          disk_template=self.op.disk_template,
296 1d870e0d Thomas Thrainer
                                          os=self.op.os,
297 1d870e0d Thomas Thrainer
                                          tags=self.op.tags,
298 1d870e0d Thomas Thrainer
                                          nics=self.op.nics,
299 1d870e0d Thomas Thrainer
                                          vcpus=self.op.vcpus,
300 1d870e0d Thomas Thrainer
                                          spindle_use=self.op.spindle_use,
301 1d870e0d Thomas Thrainer
                                          hypervisor=self.op.hypervisor,
302 1d870e0d Thomas Thrainer
                                          node_whitelist=None)
303 1d870e0d Thomas Thrainer
    elif self.op.mode == constants.IALLOCATOR_MODE_RELOC:
304 1c3231aa Thomas Thrainer
      req = iallocator.IAReqRelocate(
305 da4a52a3 Thomas Thrainer
            inst_uuid=self.inst_uuid,
306 1c3231aa Thomas Thrainer
            relocate_from_node_uuids=list(self.relocate_from_node_uuids))
307 1d870e0d Thomas Thrainer
    elif self.op.mode == constants.IALLOCATOR_MODE_CHG_GROUP:
308 1d870e0d Thomas Thrainer
      req = iallocator.IAReqGroupChange(instances=self.op.instances,
309 1d870e0d Thomas Thrainer
                                        target_groups=self.op.target_groups)
310 1d870e0d Thomas Thrainer
    elif self.op.mode == constants.IALLOCATOR_MODE_NODE_EVAC:
311 1d870e0d Thomas Thrainer
      req = iallocator.IAReqNodeEvac(instances=self.op.instances,
312 1d870e0d Thomas Thrainer
                                     evac_mode=self.op.evac_mode)
313 1d870e0d Thomas Thrainer
    elif self.op.mode == constants.IALLOCATOR_MODE_MULTI_ALLOC:
314 1d870e0d Thomas Thrainer
      disk_template = self.op.disk_template
315 1d870e0d Thomas Thrainer
      insts = [iallocator.IAReqInstanceAlloc(name="%s%s" % (self.op.name, idx),
316 1d870e0d Thomas Thrainer
                                             memory=self.op.memory,
317 1d870e0d Thomas Thrainer
                                             disks=self.op.disks,
318 1d870e0d Thomas Thrainer
                                             disk_template=disk_template,
319 1d870e0d Thomas Thrainer
                                             os=self.op.os,
320 1d870e0d Thomas Thrainer
                                             tags=self.op.tags,
321 1d870e0d Thomas Thrainer
                                             nics=self.op.nics,
322 1d870e0d Thomas Thrainer
                                             vcpus=self.op.vcpus,
323 1d870e0d Thomas Thrainer
                                             spindle_use=self.op.spindle_use,
324 1d870e0d Thomas Thrainer
                                             hypervisor=self.op.hypervisor)
325 1d870e0d Thomas Thrainer
               for idx in range(self.op.count)]
326 1d870e0d Thomas Thrainer
      req = iallocator.IAReqMultiInstanceAlloc(instances=insts)
327 1d870e0d Thomas Thrainer
    else:
328 1d870e0d Thomas Thrainer
      raise errors.ProgrammerError("Uncatched mode %s in"
329 1d870e0d Thomas Thrainer
                                   " LUTestAllocator.Exec", self.op.mode)
330 1d870e0d Thomas Thrainer
331 1d870e0d Thomas Thrainer
    ial = iallocator.IAllocator(self.cfg, self.rpc, req)
332 1d870e0d Thomas Thrainer
    if self.op.direction == constants.IALLOCATOR_DIR_IN:
333 1d870e0d Thomas Thrainer
      result = ial.in_text
334 1d870e0d Thomas Thrainer
    else:
335 1d870e0d Thomas Thrainer
      ial.Run(self.op.iallocator, validate=False)
336 1d870e0d Thomas Thrainer
      result = ial.out_text
337 1d870e0d Thomas Thrainer
    return result