Statistics
| Branch: | Tag: | Revision:

root / qa / qa_instance.py @ fcc27323

History | View | Annotate | Download (43.8 kB)

1 c68d1f43 Michael Hanselmann
#
2 c68d1f43 Michael Hanselmann
#
3 c68d1f43 Michael Hanselmann
4 deaa347b Bernardo Dal Seno
# Copyright (C) 2007, 2011, 2012, 2013 Google Inc.
5 cec9845c Michael Hanselmann
#
6 cec9845c Michael Hanselmann
# This program is free software; you can redistribute it and/or modify
7 cec9845c Michael Hanselmann
# it under the terms of the GNU General Public License as published by
8 cec9845c Michael Hanselmann
# the Free Software Foundation; either version 2 of the License, or
9 cec9845c Michael Hanselmann
# (at your option) any later version.
10 cec9845c Michael Hanselmann
#
11 cec9845c Michael Hanselmann
# This program is distributed in the hope that it will be useful, but
12 cec9845c Michael Hanselmann
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 cec9845c Michael Hanselmann
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 cec9845c Michael Hanselmann
# General Public License for more details.
15 cec9845c Michael Hanselmann
#
16 cec9845c Michael Hanselmann
# You should have received a copy of the GNU General Public License
17 cec9845c Michael Hanselmann
# along with this program; if not, write to the Free Software
18 cec9845c Michael Hanselmann
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 cec9845c Michael Hanselmann
# 02110-1301, USA.
20 cec9845c Michael Hanselmann
21 cec9845c Michael Hanselmann
22 cec9845c Michael Hanselmann
"""Instance related QA tests.
23 cec9845c Michael Hanselmann

24 cec9845c Michael Hanselmann
"""
25 cec9845c Michael Hanselmann
26 d0a44ec0 Klaus Aehlig
import os
27 e8ae0c20 Michael Hanselmann
import re
28 51958d2a Jose A. Lopes
import time
29 e8ae0c20 Michael Hanselmann
30 cec9845c Michael Hanselmann
from ganeti import utils
31 5d640672 Michael Hanselmann
from ganeti import constants
32 288d6440 Michael Hanselmann
from ganeti import query
33 304d9f02 Michael Hanselmann
from ganeti import pathutils
34 cec9845c Michael Hanselmann
35 cec9845c Michael Hanselmann
import qa_config
36 5d640672 Michael Hanselmann
import qa_utils
37 e8ae0c20 Michael Hanselmann
import qa_error
38 e8ae0c20 Michael Hanselmann
39 8fada090 Michele Tartara
from qa_utils import AssertCommand, AssertEqual
40 5fa0375e Michael Hanselmann
from qa_utils import InstanceCheck, INST_DOWN, INST_UP, FIRST_ARG, RETURN_VALUE
41 8fada090 Michele Tartara
from qa_instance_utils import CheckSsconfInstanceList, \
42 8fada090 Michele Tartara
                              CreateInstanceDrbd8, \
43 8fada090 Michele Tartara
                              CreateInstanceByDiskTemplate, \
44 8fada090 Michele Tartara
                              CreateInstanceByDiskTemplateOneNode, \
45 8fada090 Michele Tartara
                              GetGenericAddParameters
46 cec9845c Michael Hanselmann
47 e8ae0c20 Michael Hanselmann
48 e8ae0c20 Michael Hanselmann
def _GetDiskStatePath(disk):
49 e8ae0c20 Michael Hanselmann
  return "/sys/block/%s/device/state" % disk
50 cec9845c Michael Hanselmann
51 cec9845c Michael Hanselmann
52 7af293d7 Thomas Thrainer
def GetInstanceInfo(instance):
53 cc4b14f0 Bernardo Dal Seno
  """Return information about the actual state of an instance.
54 82d2f3df Bernardo Dal Seno

55 b07afbb3 Iustin Pop
  @type instance: string
56 b07afbb3 Iustin Pop
  @param instance: the instance name
57 f006f110 Bernardo Dal Seno
  @return: a dictionary with the following keys:
58 b07afbb3 Iustin Pop
      - "nodes": instance nodes, a list of strings
59 b07afbb3 Iustin Pop
      - "volumes": instance volume IDs, a list of strings
60 f006f110 Bernardo Dal Seno
      - "drbd-minors": DRBD minors used by the instance, a dictionary where
61 f006f110 Bernardo Dal Seno
        keys are nodes, and values are lists of integers (or an empty
62 f006f110 Bernardo Dal Seno
        dictionary for non-DRBD instances)
63 1012ecf4 Guido Trotter
      - "disk-template": instance disk template
64 1012ecf4 Guido Trotter
      - "storage-type": storage type associated with the instance disk template
65 82d2f3df Bernardo Dal Seno

66 82d2f3df Bernardo Dal Seno
  """
67 82d2f3df Bernardo Dal Seno
  node_elem = r"([^,()]+)(?:\s+\([^)]+\))?"
68 82d2f3df Bernardo Dal Seno
  # re_nodelist matches a list of nodes returned by gnt-instance info, e.g.:
69 82d2f3df Bernardo Dal Seno
  #  node1.fqdn
70 82d2f3df Bernardo Dal Seno
  #  node2.fqdn,node3.fqdn
71 82d2f3df Bernardo Dal Seno
  #  node4.fqdn (group mygroup, group UUID 01234567-abcd-0123-4567-0123456789ab)
72 82d2f3df Bernardo Dal Seno
  # FIXME This works with no more than 2 secondaries
73 82d2f3df Bernardo Dal Seno
  re_nodelist = re.compile(node_elem + "(?:," + node_elem + ")?$")
74 2cbcf95d Bernardo Dal Seno
75 2cbcf95d Bernardo Dal Seno
  info = qa_utils.GetObjectInfo(["gnt-instance", "info", instance])[0]
76 82d2f3df Bernardo Dal Seno
  nodes = []
77 2cbcf95d Bernardo Dal Seno
  for nodeinfo in info["Nodes"]:
78 2cbcf95d Bernardo Dal Seno
    if "primary" in nodeinfo:
79 2cbcf95d Bernardo Dal Seno
      nodes.append(nodeinfo["primary"])
80 2cbcf95d Bernardo Dal Seno
    elif "secondaries" in nodeinfo:
81 2cbcf95d Bernardo Dal Seno
      nodestr = nodeinfo["secondaries"]
82 2cbcf95d Bernardo Dal Seno
      if nodestr:
83 2cbcf95d Bernardo Dal Seno
        m = re_nodelist.match(nodestr)
84 2cbcf95d Bernardo Dal Seno
        if m:
85 2cbcf95d Bernardo Dal Seno
          nodes.extend(filter(None, m.groups()))
86 2cbcf95d Bernardo Dal Seno
        else:
87 2cbcf95d Bernardo Dal Seno
          nodes.append(nodestr)
88 2cbcf95d Bernardo Dal Seno
89 1012ecf4 Guido Trotter
  disk_template = info["Disk template"]
90 1012ecf4 Guido Trotter
  if not disk_template:
91 1012ecf4 Guido Trotter
    raise qa_error.Error("Can't get instance disk template")
92 615551b2 Helga Velroyen
  storage_type = constants.MAP_DISK_TEMPLATE_STORAGE_TYPE[disk_template]
93 1012ecf4 Guido Trotter
94 2cbcf95d Bernardo Dal Seno
  re_drbdnode = re.compile(r"^([^\s,]+),\s+minor=([0-9]+)$")
95 82d2f3df Bernardo Dal Seno
  vols = []
96 f006f110 Bernardo Dal Seno
  drbd_min = {}
97 2cbcf95d Bernardo Dal Seno
  for (count, diskinfo) in enumerate(info["Disks"]):
98 2cbcf95d Bernardo Dal Seno
    (dtype, _) = diskinfo["disk/%s" % count].split(",", 1)
99 cd3b4ff4 Helga Velroyen
    if dtype == constants.DT_DRBD8:
100 2cbcf95d Bernardo Dal Seno
      for child in diskinfo["child devices"]:
101 2cbcf95d Bernardo Dal Seno
        vols.append(child["logical_id"])
102 2cbcf95d Bernardo Dal Seno
      for key in ["nodeA", "nodeB"]:
103 2cbcf95d Bernardo Dal Seno
        m = re_drbdnode.match(diskinfo[key])
104 2cbcf95d Bernardo Dal Seno
        if not m:
105 2cbcf95d Bernardo Dal Seno
          raise qa_error.Error("Cannot parse DRBD info: %s" % diskinfo[key])
106 2cbcf95d Bernardo Dal Seno
        node = m.group(1)
107 2cbcf95d Bernardo Dal Seno
        minor = int(m.group(2))
108 2cbcf95d Bernardo Dal Seno
        minorlist = drbd_min.setdefault(node, [])
109 2cbcf95d Bernardo Dal Seno
        minorlist.append(minor)
110 cd3b4ff4 Helga Velroyen
    elif dtype == constants.DT_PLAIN:
111 2cbcf95d Bernardo Dal Seno
      vols.append(diskinfo["logical_id"])
112 b296c810 Michael Hanselmann
113 82d2f3df Bernardo Dal Seno
  assert nodes
114 b296c810 Michael Hanselmann
  assert len(nodes) < 2 or vols
115 1a6db3df Michael Hanselmann
  return {
116 1a6db3df Michael Hanselmann
    "nodes": nodes,
117 1a6db3df Michael Hanselmann
    "volumes": vols,
118 1a6db3df Michael Hanselmann
    "drbd-minors": drbd_min,
119 1012ecf4 Guido Trotter
    "disk-template": disk_template,
120 1012ecf4 Guido Trotter
    "storage-type": storage_type,
121 1a6db3df Michael Hanselmann
    }
122 cc4b14f0 Bernardo Dal Seno
123 cc4b14f0 Bernardo Dal Seno
124 cc2a70b1 Guido Trotter
def _DestroyInstanceDisks(instance):
125 cc2a70b1 Guido Trotter
  """Remove all the backend disks of an instance.
126 cc4b14f0 Bernardo Dal Seno

127 cc4b14f0 Bernardo Dal Seno
  This is used to simulate HW errors (dead nodes, broken disks...); the
128 cc4b14f0 Bernardo Dal Seno
  configuration of the instance is not affected.
129 cc4b14f0 Bernardo Dal Seno
  @type instance: dictionary
130 cc4b14f0 Bernardo Dal Seno
  @param instance: the instance
131 cc4b14f0 Bernardo Dal Seno

132 cc4b14f0 Bernardo Dal Seno
  """
133 7af293d7 Thomas Thrainer
  info = GetInstanceInfo(instance.name)
134 cc2a70b1 Guido Trotter
  # FIXME: destruction/removal should be part of the disk class
135 cc2a70b1 Guido Trotter
  if info["storage-type"] == constants.ST_LVM_VG:
136 cc2a70b1 Guido Trotter
    vols = info["volumes"]
137 cc2a70b1 Guido Trotter
    for node in info["nodes"]:
138 cc2a70b1 Guido Trotter
      AssertCommand(["lvremove", "-f"] + vols, node=node)
139 5a904197 Santi Raffa
  elif info["storage-type"] in (constants.ST_FILE, constants.ST_SHARED_FILE):
140 cc2a70b1 Guido Trotter
    # Note that this works for both file and sharedfile, and this is intended.
141 5949c31c Helga Velroyen
    storage_dir = qa_config.get("file-storage-dir",
142 5949c31c Helga Velroyen
                                pathutils.DEFAULT_FILE_STORAGE_DIR)
143 5949c31c Helga Velroyen
    idir = os.path.join(storage_dir, instance.name)
144 cc2a70b1 Guido Trotter
    for node in info["nodes"]:
145 b0b7bf8f Guido Trotter
      AssertCommand(["rm", "-rf", idir], node=node)
146 cc2a70b1 Guido Trotter
  elif info["storage-type"] == constants.ST_DISKLESS:
147 cc2a70b1 Guido Trotter
    pass
148 82d2f3df Bernardo Dal Seno
149 82d2f3df Bernardo Dal Seno
150 ab4832d1 Bernardo Dal Seno
def _GetInstanceField(instance, field):
151 ab4832d1 Bernardo Dal Seno
  """Get the value of a field of an instance.
152 d55408b0 Bernardo Dal Seno

153 d55408b0 Bernardo Dal Seno
  @type instance: string
154 d55408b0 Bernardo Dal Seno
  @param instance: Instance name
155 d55408b0 Bernardo Dal Seno
  @type field: string
156 d55408b0 Bernardo Dal Seno
  @param field: Name of the field
157 ab4832d1 Bernardo Dal Seno
  @rtype: string
158 d55408b0 Bernardo Dal Seno

159 d55408b0 Bernardo Dal Seno
  """
160 d55408b0 Bernardo Dal Seno
  master = qa_config.GetMasterNode()
161 d55408b0 Bernardo Dal Seno
  infocmd = utils.ShellQuoteArgs(["gnt-instance", "list", "--no-headers",
162 ab4832d1 Bernardo Dal Seno
                                  "--units", "m", "-o", field, instance])
163 46d21495 Bernardo Dal Seno
  return qa_utils.GetCommandOutput(master.primary, infocmd).strip()
164 ab4832d1 Bernardo Dal Seno
165 ab4832d1 Bernardo Dal Seno
166 ab4832d1 Bernardo Dal Seno
def _GetBoolInstanceField(instance, field):
167 ab4832d1 Bernardo Dal Seno
  """Get the Boolean value of a field of an instance.
168 ab4832d1 Bernardo Dal Seno

169 ab4832d1 Bernardo Dal Seno
  @type instance: string
170 ab4832d1 Bernardo Dal Seno
  @param instance: Instance name
171 ab4832d1 Bernardo Dal Seno
  @type field: string
172 ab4832d1 Bernardo Dal Seno
  @param field: Name of the field
173 ab4832d1 Bernardo Dal Seno
  @rtype: bool
174 ab4832d1 Bernardo Dal Seno

175 ab4832d1 Bernardo Dal Seno
  """
176 ab4832d1 Bernardo Dal Seno
  info_out = _GetInstanceField(instance, field)
177 d55408b0 Bernardo Dal Seno
  if info_out == "Y":
178 d55408b0 Bernardo Dal Seno
    return True
179 d55408b0 Bernardo Dal Seno
  elif info_out == "N":
180 d55408b0 Bernardo Dal Seno
    return False
181 d55408b0 Bernardo Dal Seno
  else:
182 d55408b0 Bernardo Dal Seno
    raise qa_error.Error("Field %s of instance %s has a non-Boolean value:"
183 d55408b0 Bernardo Dal Seno
                         " %s" % (field, instance, info_out))
184 d55408b0 Bernardo Dal Seno
185 d55408b0 Bernardo Dal Seno
186 ab4832d1 Bernardo Dal Seno
def _GetNumInstanceField(instance, field):
187 ab4832d1 Bernardo Dal Seno
  """Get a numeric value of a field of an instance.
188 ab4832d1 Bernardo Dal Seno

189 ab4832d1 Bernardo Dal Seno
  @type instance: string
190 ab4832d1 Bernardo Dal Seno
  @param instance: Instance name
191 ab4832d1 Bernardo Dal Seno
  @type field: string
192 ab4832d1 Bernardo Dal Seno
  @param field: Name of the field
193 ab4832d1 Bernardo Dal Seno
  @rtype: int or float
194 ab4832d1 Bernardo Dal Seno

195 ab4832d1 Bernardo Dal Seno
  """
196 ab4832d1 Bernardo Dal Seno
  info_out = _GetInstanceField(instance, field)
197 ab4832d1 Bernardo Dal Seno
  try:
198 ab4832d1 Bernardo Dal Seno
    ret = int(info_out)
199 ab4832d1 Bernardo Dal Seno
  except ValueError:
200 ab4832d1 Bernardo Dal Seno
    try:
201 ab4832d1 Bernardo Dal Seno
      ret = float(info_out)
202 ab4832d1 Bernardo Dal Seno
    except ValueError:
203 ab4832d1 Bernardo Dal Seno
      raise qa_error.Error("Field %s of instance %s has a non-numeric value:"
204 ab4832d1 Bernardo Dal Seno
                           " %s" % (field, instance, info_out))
205 ab4832d1 Bernardo Dal Seno
  return ret
206 ab4832d1 Bernardo Dal Seno
207 ab4832d1 Bernardo Dal Seno
208 ab4832d1 Bernardo Dal Seno
def GetInstanceSpec(instance, spec):
209 ab4832d1 Bernardo Dal Seno
  """Return the current spec for the given parameter.
210 ab4832d1 Bernardo Dal Seno

211 ab4832d1 Bernardo Dal Seno
  @type instance: string
212 ab4832d1 Bernardo Dal Seno
  @param instance: Instance name
213 ab4832d1 Bernardo Dal Seno
  @type spec: string
214 cb178a1e Bernardo Dal Seno
  @param spec: one of the supported parameters: "memory-size", "cpu-count",
215 ab4832d1 Bernardo Dal Seno
      "disk-count", "disk-size", "nic-count"
216 ab4832d1 Bernardo Dal Seno
  @rtype: tuple
217 ab4832d1 Bernardo Dal Seno
  @return: (minspec, maxspec); minspec and maxspec can be different only for
218 ab4832d1 Bernardo Dal Seno
      memory and disk size
219 ab4832d1 Bernardo Dal Seno

220 ab4832d1 Bernardo Dal Seno
  """
221 ab4832d1 Bernardo Dal Seno
  specmap = {
222 cb178a1e Bernardo Dal Seno
    "memory-size": ["be/minmem", "be/maxmem"],
223 ab4832d1 Bernardo Dal Seno
    "cpu-count": ["vcpus"],
224 ab4832d1 Bernardo Dal Seno
    "disk-count": ["disk.count"],
225 ab4832d1 Bernardo Dal Seno
    "disk-size": ["disk.size/ "],
226 ab4832d1 Bernardo Dal Seno
    "nic-count": ["nic.count"],
227 ab4832d1 Bernardo Dal Seno
    }
228 ab4832d1 Bernardo Dal Seno
  # For disks, first we need the number of disks
229 ab4832d1 Bernardo Dal Seno
  if spec == "disk-size":
230 ab4832d1 Bernardo Dal Seno
    (numdisk, _) = GetInstanceSpec(instance, "disk-count")
231 ab4832d1 Bernardo Dal Seno
    fields = ["disk.size/%s" % k for k in range(0, numdisk)]
232 ab4832d1 Bernardo Dal Seno
  else:
233 ab4832d1 Bernardo Dal Seno
    assert spec in specmap, "%s not in %s" % (spec, specmap)
234 ab4832d1 Bernardo Dal Seno
    fields = specmap[spec]
235 ab4832d1 Bernardo Dal Seno
  values = [_GetNumInstanceField(instance, f) for f in fields]
236 ab4832d1 Bernardo Dal Seno
  return (min(values), max(values))
237 ab4832d1 Bernardo Dal Seno
238 ab4832d1 Bernardo Dal Seno
239 5de31440 Bernardo Dal Seno
def IsFailoverSupported(instance):
240 02a5fe0e Michael Hanselmann
  return instance.disk_template in constants.DTS_MIRRORED
241 5de31440 Bernardo Dal Seno
242 5de31440 Bernardo Dal Seno
243 5de31440 Bernardo Dal Seno
def IsMigrationSupported(instance):
244 02a5fe0e Michael Hanselmann
  return instance.disk_template in constants.DTS_MIRRORED
245 5de31440 Bernardo Dal Seno
246 5de31440 Bernardo Dal Seno
247 5de31440 Bernardo Dal Seno
def IsDiskReplacingSupported(instance):
248 02a5fe0e Michael Hanselmann
  return instance.disk_template == constants.DT_DRBD8
249 5de31440 Bernardo Dal Seno
250 5de31440 Bernardo Dal Seno
251 8cd4f8cf Bernardo Dal Seno
def IsDiskSupported(instance):
252 a365b47f Bernardo Dal Seno
  return instance.disk_template != constants.DT_DISKLESS
253 8cd4f8cf Bernardo Dal Seno
254 8cd4f8cf Bernardo Dal Seno
255 fa84c8a4 Bernardo Dal Seno
def TestInstanceAddWithPlainDisk(nodes, fail=False):
256 cec9845c Michael Hanselmann
  """gnt-instance add -t plain"""
257 f41dc024 Helga Velroyen
  if constants.DT_PLAIN in qa_config.GetEnabledDiskTemplates():
258 8fada090 Michele Tartara
    instance = CreateInstanceByDiskTemplateOneNode(nodes, constants.DT_PLAIN,
259 f41dc024 Helga Velroyen
                                                    fail=fail)
260 f41dc024 Helga Velroyen
    if not fail:
261 f41dc024 Helga Velroyen
      qa_utils.RunInstanceCheck(instance, True)
262 f41dc024 Helga Velroyen
    return instance
263 cec9845c Michael Hanselmann
264 cec9845c Michael Hanselmann
265 5fa0375e Michael Hanselmann
@InstanceCheck(None, INST_UP, RETURN_VALUE)
266 c99200a3 Bernardo Dal Seno
def TestInstanceAddWithDrbdDisk(nodes):
267 7d7609a3 Michael Hanselmann
  """gnt-instance add -t drbd"""
268 f41dc024 Helga Velroyen
  if constants.DT_DRBD8 in qa_config.GetEnabledDiskTemplates():
269 8fada090 Michele Tartara
    return CreateInstanceDrbd8(nodes)
270 7d7609a3 Michael Hanselmann
271 7d7609a3 Michael Hanselmann
272 59c75517 Michael Hanselmann
@InstanceCheck(None, INST_UP, RETURN_VALUE)
273 6970c89c Klaus Aehlig
def TestInstanceAddFile(nodes):
274 6970c89c Klaus Aehlig
  """gnt-instance add -t file"""
275 6970c89c Klaus Aehlig
  assert len(nodes) == 1
276 f41dc024 Helga Velroyen
  if constants.DT_FILE in qa_config.GetEnabledDiskTemplates():
277 8fada090 Michele Tartara
    return CreateInstanceByDiskTemplateOneNode(nodes, constants.DT_FILE)
278 6970c89c Klaus Aehlig
279 6970c89c Klaus Aehlig
280 6970c89c Klaus Aehlig
@InstanceCheck(None, INST_UP, RETURN_VALUE)
281 f9b76ed4 Helga Velroyen
def TestInstanceAddSharedFile(nodes):
282 f9b76ed4 Helga Velroyen
  """gnt-instance add -t sharedfile"""
283 f9b76ed4 Helga Velroyen
  assert len(nodes) == 1
284 f9b76ed4 Helga Velroyen
  if constants.DT_SHARED_FILE in qa_config.GetEnabledDiskTemplates():
285 f9b76ed4 Helga Velroyen
    return CreateInstanceByDiskTemplateOneNode(nodes, constants.DT_SHARED_FILE)
286 f9b76ed4 Helga Velroyen
287 f9b76ed4 Helga Velroyen
288 f9b76ed4 Helga Velroyen
@InstanceCheck(None, INST_UP, RETURN_VALUE)
289 59c75517 Michael Hanselmann
def TestInstanceAddDiskless(nodes):
290 59c75517 Michael Hanselmann
  """gnt-instance add -t diskless"""
291 59c75517 Michael Hanselmann
  assert len(nodes) == 1
292 d06e7b3b Thomas Thrainer
  if constants.DT_DISKLESS in qa_config.GetEnabledDiskTemplates():
293 8fada090 Michele Tartara
    return CreateInstanceByDiskTemplateOneNode(nodes, constants.DT_DISKLESS)
294 59c75517 Michael Hanselmann
295 59c75517 Michael Hanselmann
296 5fa0375e Michael Hanselmann
@InstanceCheck(None, INST_DOWN, FIRST_ARG)
297 cec9845c Michael Hanselmann
def TestInstanceRemove(instance):
298 cec9845c Michael Hanselmann
  """gnt-instance remove"""
299 b5f33afa Michael Hanselmann
  AssertCommand(["gnt-instance", "remove", "-f", instance.name])
300 cec9845c Michael Hanselmann
301 cec9845c Michael Hanselmann
302 5fa0375e Michael Hanselmann
@InstanceCheck(INST_DOWN, INST_UP, FIRST_ARG)
303 cec9845c Michael Hanselmann
def TestInstanceStartup(instance):
304 cec9845c Michael Hanselmann
  """gnt-instance startup"""
305 b5f33afa Michael Hanselmann
  AssertCommand(["gnt-instance", "startup", instance.name])
306 cec9845c Michael Hanselmann
307 cec9845c Michael Hanselmann
308 5fa0375e Michael Hanselmann
@InstanceCheck(INST_UP, INST_DOWN, FIRST_ARG)
309 cec9845c Michael Hanselmann
def TestInstanceShutdown(instance):
310 cec9845c Michael Hanselmann
  """gnt-instance shutdown"""
311 b5f33afa Michael Hanselmann
  AssertCommand(["gnt-instance", "shutdown", instance.name])
312 cec9845c Michael Hanselmann
313 cec9845c Michael Hanselmann
314 5fa0375e Michael Hanselmann
@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
315 8a4e8898 Michael Hanselmann
def TestInstanceReboot(instance):
316 8a4e8898 Michael Hanselmann
  """gnt-instance reboot"""
317 d0c8c01d Iustin Pop
  options = qa_config.get("options", {})
318 1d103c02 Iustin Pop
  reboot_types = options.get("reboot-types", constants.REBOOT_TYPES)
319 b5f33afa Michael Hanselmann
  name = instance.name
320 1d103c02 Iustin Pop
  for rtype in reboot_types:
321 2f4b4f78 Iustin Pop
    AssertCommand(["gnt-instance", "reboot", "--type=%s" % rtype, name])
322 8a4e8898 Michael Hanselmann
323 cc27265e Renรฉ Nussbaumer
  AssertCommand(["gnt-instance", "shutdown", name])
324 5fa0375e Michael Hanselmann
  qa_utils.RunInstanceCheck(instance, False)
325 cc27265e Renรฉ Nussbaumer
  AssertCommand(["gnt-instance", "reboot", name])
326 cc27265e Renรฉ Nussbaumer
327 cc27265e Renรฉ Nussbaumer
  master = qa_config.GetMasterNode()
328 58ea8d17 Michael Hanselmann
  cmd = ["gnt-instance", "list", "--no-headers", "-o", "status", name]
329 aecba21e Michael Hanselmann
  result_output = qa_utils.GetCommandOutput(master.primary,
330 cc27265e Renรฉ Nussbaumer
                                            utils.ShellQuoteArgs(cmd))
331 cc27265e Renรฉ Nussbaumer
  AssertEqual(result_output.strip(), constants.INSTST_RUNNING)
332 cc27265e Renรฉ Nussbaumer
333 8a4e8898 Michael Hanselmann
334 5fa0375e Michael Hanselmann
@InstanceCheck(INST_DOWN, INST_DOWN, FIRST_ARG)
335 283f9d4c Michael Hanselmann
def TestInstanceReinstall(instance):
336 283f9d4c Michael Hanselmann
  """gnt-instance reinstall"""
337 a90636b2 Michael Hanselmann
  if instance.disk_template == constants.DT_DISKLESS:
338 a90636b2 Michael Hanselmann
    print qa_utils.FormatInfo("Test not supported for diskless instances")
339 a90636b2 Michael Hanselmann
    return
340 a90636b2 Michael Hanselmann
341 b5f33afa Michael Hanselmann
  AssertCommand(["gnt-instance", "reinstall", "-f", instance.name])
342 283f9d4c Michael Hanselmann
343 64be07b1 Michael Hanselmann
  # Test with non-existant OS definition
344 64be07b1 Michael Hanselmann
  AssertCommand(["gnt-instance", "reinstall", "-f",
345 64be07b1 Michael Hanselmann
                 "--os-type=NonExistantOsForQa",
346 b5f33afa Michael Hanselmann
                 instance.name],
347 64be07b1 Michael Hanselmann
                fail=True)
348 64be07b1 Michael Hanselmann
349 283f9d4c Michael Hanselmann
350 51131cad Michael Hanselmann
@InstanceCheck(INST_DOWN, INST_DOWN, FIRST_ARG)
351 4c1a464b Iustin Pop
def TestInstanceRenameAndBack(rename_source, rename_target):
352 4c1a464b Iustin Pop
  """gnt-instance rename
353 4c1a464b Iustin Pop

354 4c1a464b Iustin Pop
  This must leave the instance with the original name, not the target
355 4c1a464b Iustin Pop
  name.
356 4c1a464b Iustin Pop

357 4c1a464b Iustin Pop
  """
358 8fada090 Michele Tartara
  CheckSsconfInstanceList(rename_source)
359 5fa0375e Michael Hanselmann
360 4c1a464b Iustin Pop
  # first do a rename to a different actual name, expecting it to fail
361 31fe5102 Renรฉ Nussbaumer
  qa_utils.AddToEtcHosts(["meeeeh-not-exists", rename_target])
362 31fe5102 Renรฉ Nussbaumer
  try:
363 31fe5102 Renรฉ Nussbaumer
    AssertCommand(["gnt-instance", "rename", rename_source, rename_target],
364 31fe5102 Renรฉ Nussbaumer
                  fail=True)
365 8fada090 Michele Tartara
    CheckSsconfInstanceList(rename_source)
366 31fe5102 Renรฉ Nussbaumer
  finally:
367 31fe5102 Renรฉ Nussbaumer
    qa_utils.RemoveFromEtcHosts(["meeeeh-not-exists", rename_target])
368 5fa0375e Michael Hanselmann
369 7af293d7 Thomas Thrainer
  info = GetInstanceInfo(rename_source)
370 1012ecf4 Guido Trotter
371 1012ecf4 Guido Trotter
  # Check instance volume tags correctly updated. Note that this check is lvm
372 1012ecf4 Guido Trotter
  # specific, so we skip it for non-lvm-based instances.
373 1012ecf4 Guido Trotter
  # FIXME: This will need updating when instances will be able to have
374 1012ecf4 Guido Trotter
  # different disks living on storage pools with etherogeneous storage types.
375 1012ecf4 Guido Trotter
  # FIXME: This check should be put inside the disk/storage class themselves,
376 1012ecf4 Guido Trotter
  # rather than explicitly called here.
377 1012ecf4 Guido Trotter
  if info["storage-type"] == constants.ST_LVM_VG:
378 1012ecf4 Guido Trotter
    # In the lvm world we can check for tags on the logical volume
379 1012ecf4 Guido Trotter
    tags_cmd = ("lvs -o tags --noheadings %s | grep " %
380 1012ecf4 Guido Trotter
                (" ".join(info["volumes"]), ))
381 1012ecf4 Guido Trotter
  else:
382 1012ecf4 Guido Trotter
    # Other storage types don't have tags, so we use an always failing command,
383 1012ecf4 Guido Trotter
    # to make sure it never gets executed
384 1012ecf4 Guido Trotter
    tags_cmd = "false"
385 b07afbb3 Iustin Pop
386 4c1a464b Iustin Pop
  # and now rename instance to rename_target...
387 31fe5102 Renรฉ Nussbaumer
  AssertCommand(["gnt-instance", "rename", rename_source, rename_target])
388 8fada090 Michele Tartara
  CheckSsconfInstanceList(rename_target)
389 5fa0375e Michael Hanselmann
  qa_utils.RunInstanceCheck(rename_source, False)
390 51131cad Michael Hanselmann
  qa_utils.RunInstanceCheck(rename_target, False)
391 5fa0375e Michael Hanselmann
392 b07afbb3 Iustin Pop
  # NOTE: tags might not be the exactly as the instance name, due to
393 b07afbb3 Iustin Pop
  # charset restrictions; hence the test might be flaky
394 1012ecf4 Guido Trotter
  if (rename_source != rename_target and
395 1012ecf4 Guido Trotter
      info["storage-type"] == constants.ST_LVM_VG):
396 b07afbb3 Iustin Pop
    for node in info["nodes"]:
397 b07afbb3 Iustin Pop
      AssertCommand(tags_cmd + rename_source, node=node, fail=True)
398 b07afbb3 Iustin Pop
      AssertCommand(tags_cmd + rename_target, node=node, fail=False)
399 b07afbb3 Iustin Pop
400 4c1a464b Iustin Pop
  # and back
401 4c1a464b Iustin Pop
  AssertCommand(["gnt-instance", "rename", rename_target, rename_source])
402 8fada090 Michele Tartara
  CheckSsconfInstanceList(rename_source)
403 5fa0375e Michael Hanselmann
  qa_utils.RunInstanceCheck(rename_target, False)
404 18337ca9 Iustin Pop
405 1012ecf4 Guido Trotter
  if (rename_source != rename_target and
406 1012ecf4 Guido Trotter
      info["storage-type"] == constants.ST_LVM_VG):
407 b07afbb3 Iustin Pop
    for node in info["nodes"]:
408 b07afbb3 Iustin Pop
      AssertCommand(tags_cmd + rename_source, node=node, fail=False)
409 b07afbb3 Iustin Pop
      AssertCommand(tags_cmd + rename_target, node=node, fail=True)
410 b07afbb3 Iustin Pop
411 18337ca9 Iustin Pop
412 5fa0375e Michael Hanselmann
@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
413 cec9845c Michael Hanselmann
def TestInstanceFailover(instance):
414 cec9845c Michael Hanselmann
  """gnt-instance failover"""
415 5de31440 Bernardo Dal Seno
  if not IsFailoverSupported(instance):
416 5de31440 Bernardo Dal Seno
    print qa_utils.FormatInfo("Instance doesn't support failover, skipping"
417 5de31440 Bernardo Dal Seno
                              " test")
418 5de31440 Bernardo Dal Seno
    return
419 5de31440 Bernardo Dal Seno
420 b5f33afa Michael Hanselmann
  cmd = ["gnt-instance", "failover", "--force", instance.name]
421 5fa0375e Michael Hanselmann
422 2f4b4f78 Iustin Pop
  # failover ...
423 2f4b4f78 Iustin Pop
  AssertCommand(cmd)
424 5fa0375e Michael Hanselmann
  qa_utils.RunInstanceCheck(instance, True)
425 5fa0375e Michael Hanselmann
426 76f59a32 Michael Hanselmann
  # ... and back
427 2f4b4f78 Iustin Pop
  AssertCommand(cmd)
428 76f59a32 Michael Hanselmann
429 cec9845c Michael Hanselmann
430 5fa0375e Michael Hanselmann
@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
431 d55408b0 Bernardo Dal Seno
def TestInstanceMigrate(instance, toggle_always_failover=True):
432 938bde86 Michael Hanselmann
  """gnt-instance migrate"""
433 5de31440 Bernardo Dal Seno
  if not IsMigrationSupported(instance):
434 5de31440 Bernardo Dal Seno
    print qa_utils.FormatInfo("Instance doesn't support migration, skipping"
435 5de31440 Bernardo Dal Seno
                              " test")
436 5de31440 Bernardo Dal Seno
    return
437 5de31440 Bernardo Dal Seno
438 b5f33afa Michael Hanselmann
  cmd = ["gnt-instance", "migrate", "--force", instance.name]
439 d55408b0 Bernardo Dal Seno
  af_par = constants.BE_ALWAYS_FAILOVER
440 d55408b0 Bernardo Dal Seno
  af_field = "be/" + constants.BE_ALWAYS_FAILOVER
441 b5f33afa Michael Hanselmann
  af_init_val = _GetBoolInstanceField(instance.name, af_field)
442 5fa0375e Michael Hanselmann
443 2f4b4f78 Iustin Pop
  # migrate ...
444 2f4b4f78 Iustin Pop
  AssertCommand(cmd)
445 d55408b0 Bernardo Dal Seno
  # TODO: Verify the choice between failover and migration
446 5fa0375e Michael Hanselmann
  qa_utils.RunInstanceCheck(instance, True)
447 5fa0375e Michael Hanselmann
448 d55408b0 Bernardo Dal Seno
  # ... and back (possibly with always_failover toggled)
449 d55408b0 Bernardo Dal Seno
  if toggle_always_failover:
450 d55408b0 Bernardo Dal Seno
    AssertCommand(["gnt-instance", "modify", "-B",
451 d55408b0 Bernardo Dal Seno
                   ("%s=%s" % (af_par, not af_init_val)),
452 b5f33afa Michael Hanselmann
                   instance.name])
453 2f4b4f78 Iustin Pop
  AssertCommand(cmd)
454 d55408b0 Bernardo Dal Seno
  # TODO: Verify the choice between failover and migration
455 d55408b0 Bernardo Dal Seno
  qa_utils.RunInstanceCheck(instance, True)
456 d55408b0 Bernardo Dal Seno
  if toggle_always_failover:
457 d55408b0 Bernardo Dal Seno
    AssertCommand(["gnt-instance", "modify", "-B",
458 b5f33afa Michael Hanselmann
                   ("%s=%s" % (af_par, af_init_val)), instance.name])
459 5fa0375e Michael Hanselmann
460 5fa0375e Michael Hanselmann
  # TODO: Split into multiple tests
461 b5f33afa Michael Hanselmann
  AssertCommand(["gnt-instance", "shutdown", instance.name])
462 5fa0375e Michael Hanselmann
  qa_utils.RunInstanceCheck(instance, False)
463 e9c487be Renรฉ Nussbaumer
  AssertCommand(cmd, fail=True)
464 e9c487be Renรฉ Nussbaumer
  AssertCommand(["gnt-instance", "migrate", "--force", "--allow-failover",
465 b5f33afa Michael Hanselmann
                 instance.name])
466 b5f33afa Michael Hanselmann
  AssertCommand(["gnt-instance", "start", instance.name])
467 e9c487be Renรฉ Nussbaumer
  AssertCommand(cmd)
468 d55408b0 Bernardo Dal Seno
  # @InstanceCheck enforces the check that the instance is running
469 5fa0375e Michael Hanselmann
  qa_utils.RunInstanceCheck(instance, True)
470 5fa0375e Michael Hanselmann
471 42a769f9 Bernardo Dal Seno
  AssertCommand(["gnt-instance", "modify", "-B",
472 42a769f9 Bernardo Dal Seno
                 ("%s=%s" %
473 42a769f9 Bernardo Dal Seno
                  (constants.BE_ALWAYS_FAILOVER, constants.VALUE_TRUE)),
474 b5f33afa Michael Hanselmann
                 instance.name])
475 5fa0375e Michael Hanselmann
476 320a5dae Bernardo Dal Seno
  AssertCommand(cmd)
477 5fa0375e Michael Hanselmann
  qa_utils.RunInstanceCheck(instance, True)
478 320a5dae Bernardo Dal Seno
  # TODO: Verify that a failover has been done instead of a migration
479 5fa0375e Michael Hanselmann
480 5fa0375e Michael Hanselmann
  # TODO: Verify whether the default value is restored here (not hardcoded)
481 42a769f9 Bernardo Dal Seno
  AssertCommand(["gnt-instance", "modify", "-B",
482 42a769f9 Bernardo Dal Seno
                 ("%s=%s" %
483 42a769f9 Bernardo Dal Seno
                  (constants.BE_ALWAYS_FAILOVER, constants.VALUE_FALSE)),
484 b5f33afa Michael Hanselmann
                 instance.name])
485 5fa0375e Michael Hanselmann
486 42a769f9 Bernardo Dal Seno
  AssertCommand(cmd)
487 5fa0375e Michael Hanselmann
  qa_utils.RunInstanceCheck(instance, True)
488 938bde86 Michael Hanselmann
489 938bde86 Michael Hanselmann
490 cec9845c Michael Hanselmann
def TestInstanceInfo(instance):
491 cec9845c Michael Hanselmann
  """gnt-instance info"""
492 b5f33afa Michael Hanselmann
  AssertCommand(["gnt-instance", "info", instance.name])
493 5d640672 Michael Hanselmann
494 5d640672 Michael Hanselmann
495 5fa0375e Michael Hanselmann
@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
496 c0f74c55 Iustin Pop
def TestInstanceModify(instance):
497 c0f74c55 Iustin Pop
  """gnt-instance modify"""
498 d488adb6 Michael Hanselmann
  default_hv = qa_config.GetDefaultHypervisor()
499 d488adb6 Michael Hanselmann
500 1d693311 Michael Hanselmann
  # Assume /sbin/init exists on all systems
501 1d693311 Michael Hanselmann
  test_kernel = "/sbin/init"
502 1d693311 Michael Hanselmann
  test_initrd = test_kernel
503 1d693311 Michael Hanselmann
504 8ccbbe4b Guido Trotter
  orig_maxmem = qa_config.get(constants.BE_MAXMEM)
505 8ccbbe4b Guido Trotter
  orig_minmem = qa_config.get(constants.BE_MINMEM)
506 2f4b4f78 Iustin Pop
  #orig_bridge = qa_config.get("bridge", "xen-br0")
507 d488adb6 Michael Hanselmann
508 c0f74c55 Iustin Pop
  args = [
509 8ccbbe4b Guido Trotter
    ["-B", "%s=128" % constants.BE_MINMEM],
510 8ccbbe4b Guido Trotter
    ["-B", "%s=128" % constants.BE_MAXMEM],
511 8ccbbe4b Guido Trotter
    ["-B", "%s=%s,%s=%s" % (constants.BE_MINMEM, orig_minmem,
512 8ccbbe4b Guido Trotter
                            constants.BE_MAXMEM, orig_maxmem)],
513 1d693311 Michael Hanselmann
    ["-B", "%s=2" % constants.BE_VCPUS],
514 1d693311 Michael Hanselmann
    ["-B", "%s=1" % constants.BE_VCPUS],
515 1d693311 Michael Hanselmann
    ["-B", "%s=%s" % (constants.BE_VCPUS, constants.VALUE_DEFAULT)],
516 42a769f9 Bernardo Dal Seno
    ["-B", "%s=%s" % (constants.BE_ALWAYS_FAILOVER, constants.VALUE_TRUE)],
517 42a769f9 Bernardo Dal Seno
    ["-B", "%s=%s" % (constants.BE_ALWAYS_FAILOVER, constants.VALUE_DEFAULT)],
518 1d693311 Michael Hanselmann
519 1d693311 Michael Hanselmann
    ["-H", "%s=%s" % (constants.HV_KERNEL_PATH, test_kernel)],
520 1d693311 Michael Hanselmann
    ["-H", "%s=%s" % (constants.HV_KERNEL_PATH, constants.VALUE_DEFAULT)],
521 1d693311 Michael Hanselmann
522 1d693311 Michael Hanselmann
    # TODO: bridge tests
523 1d693311 Michael Hanselmann
    #["--bridge", "xen-br1"],
524 1d693311 Michael Hanselmann
    #["--bridge", orig_bridge],
525 c0f74c55 Iustin Pop
    ]
526 d488adb6 Michael Hanselmann
527 d488adb6 Michael Hanselmann
  if default_hv == constants.HT_XEN_PVM:
528 d488adb6 Michael Hanselmann
    args.extend([
529 d488adb6 Michael Hanselmann
      ["-H", "%s=%s" % (constants.HV_INITRD_PATH, test_initrd)],
530 d488adb6 Michael Hanselmann
      ["-H", "no_%s" % (constants.HV_INITRD_PATH, )],
531 d488adb6 Michael Hanselmann
      ["-H", "%s=%s" % (constants.HV_INITRD_PATH, constants.VALUE_DEFAULT)],
532 d488adb6 Michael Hanselmann
      ])
533 d488adb6 Michael Hanselmann
  elif default_hv == constants.HT_XEN_HVM:
534 d488adb6 Michael Hanselmann
    args.extend([
535 d488adb6 Michael Hanselmann
      ["-H", "%s=acn" % constants.HV_BOOT_ORDER],
536 d488adb6 Michael Hanselmann
      ["-H", "%s=%s" % (constants.HV_BOOT_ORDER, constants.VALUE_DEFAULT)],
537 d488adb6 Michael Hanselmann
      ])
538 e61c0f24 Dimitris Aragiorgis
  elif default_hv == constants.HT_KVM and \
539 e61c0f24 Dimitris Aragiorgis
    qa_config.TestEnabled("instance-device-hotplug"):
540 e61c0f24 Dimitris Aragiorgis
    args.extend([
541 e61c0f24 Dimitris Aragiorgis
      ["--net", "-1:add", "--hotplug"],
542 e15a00dc Dimitris Aragiorgis
      ["--net", "-1:modify,mac=aa:bb:cc:dd:ee:ff", "--hotplug", "--force"],
543 e61c0f24 Dimitris Aragiorgis
      ["--net", "-1:remove", "--hotplug"],
544 e61c0f24 Dimitris Aragiorgis
      ["--disk", "-1:add,size=1G", "--hotplug"],
545 e61c0f24 Dimitris Aragiorgis
      ["--disk", "-1:remove", "--hotplug"],
546 e61c0f24 Dimitris Aragiorgis
      ])
547 d488adb6 Michael Hanselmann
548 c0f74c55 Iustin Pop
  for alist in args:
549 b5f33afa Michael Hanselmann
    AssertCommand(["gnt-instance", "modify"] + alist + [instance.name])
550 c0f74c55 Iustin Pop
551 c0f74c55 Iustin Pop
  # check no-modify
552 b5f33afa Michael Hanselmann
  AssertCommand(["gnt-instance", "modify", instance.name], fail=True)
553 c0f74c55 Iustin Pop
554 1ba25bad Guido Trotter
  # Marking offline while instance is running must fail...
555 b5f33afa Michael Hanselmann
  AssertCommand(["gnt-instance", "modify", "--offline", instance.name],
556 1ba25bad Guido Trotter
                 fail=True)
557 1ba25bad Guido Trotter
558 1ba25bad Guido Trotter
  # ...while making it online is ok, and should work
559 b5f33afa Michael Hanselmann
  AssertCommand(["gnt-instance", "modify", "--online", instance.name])
560 3016bc1f Michael Hanselmann
561 3016bc1f Michael Hanselmann
562 d0a44ec0 Klaus Aehlig
@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
563 d0a44ec0 Klaus Aehlig
def TestInstanceModifyPrimaryAndBack(instance, currentnode, othernode):
564 d0a44ec0 Klaus Aehlig
  """gnt-instance modify --new-primary
565 d0a44ec0 Klaus Aehlig

566 d0a44ec0 Klaus Aehlig
  This will leave the instance on its original primary node, not other node.
567 d0a44ec0 Klaus Aehlig

568 d0a44ec0 Klaus Aehlig
  """
569 d0a44ec0 Klaus Aehlig
  if instance.disk_template != constants.DT_FILE:
570 d0a44ec0 Klaus Aehlig
    print qa_utils.FormatInfo("Test only supported for the file disk template")
571 d0a44ec0 Klaus Aehlig
    return
572 d0a44ec0 Klaus Aehlig
573 049a6c6b Guido Trotter
  cluster_name = qa_config.get("name")
574 049a6c6b Guido Trotter
575 d0a44ec0 Klaus Aehlig
  name = instance.name
576 d0a44ec0 Klaus Aehlig
  current = currentnode.primary
577 d0a44ec0 Klaus Aehlig
  other = othernode.primary
578 d0a44ec0 Klaus Aehlig
579 5949c31c Helga Velroyen
  filestorage = qa_config.get("file-storage-dir",
580 5949c31c Helga Velroyen
                              pathutils.DEFAULT_FILE_STORAGE_DIR)
581 d0a44ec0 Klaus Aehlig
  disk = os.path.join(filestorage, name)
582 d0a44ec0 Klaus Aehlig
583 d0a44ec0 Klaus Aehlig
  AssertCommand(["gnt-instance", "modify", "--new-primary=%s" % other, name],
584 d0a44ec0 Klaus Aehlig
                fail=True)
585 d0a44ec0 Klaus Aehlig
  AssertCommand(["gnt-instance", "shutdown", name])
586 049a6c6b Guido Trotter
  AssertCommand(["scp", "-oGlobalKnownHostsFile=%s" %
587 049a6c6b Guido Trotter
                 pathutils.SSH_KNOWN_HOSTS_FILE,
588 049a6c6b Guido Trotter
                 "-oCheckHostIp=no", "-oStrictHostKeyChecking=yes",
589 049a6c6b Guido Trotter
                 "-oHashKnownHosts=no", "-oHostKeyAlias=%s" % cluster_name,
590 f0ed67ed Guido Trotter
                 "-r", disk, "%s:%s" % (other, filestorage)], node=current)
591 d0a44ec0 Klaus Aehlig
  AssertCommand(["gnt-instance", "modify", "--new-primary=%s" % other, name])
592 d0a44ec0 Klaus Aehlig
  AssertCommand(["gnt-instance", "startup", name])
593 d0a44ec0 Klaus Aehlig
594 d0a44ec0 Klaus Aehlig
  # and back
595 d0a44ec0 Klaus Aehlig
  AssertCommand(["gnt-instance", "shutdown", name])
596 d0a44ec0 Klaus Aehlig
  AssertCommand(["rm", "-rf", disk], node=other)
597 d0a44ec0 Klaus Aehlig
  AssertCommand(["gnt-instance", "modify", "--new-primary=%s" % current, name])
598 d0a44ec0 Klaus Aehlig
  AssertCommand(["gnt-instance", "startup", name])
599 d0a44ec0 Klaus Aehlig
600 d0a44ec0 Klaus Aehlig
601 5fa0375e Michael Hanselmann
@InstanceCheck(INST_DOWN, INST_DOWN, FIRST_ARG)
602 3016bc1f Michael Hanselmann
def TestInstanceStoppedModify(instance):
603 3016bc1f Michael Hanselmann
  """gnt-instance modify (stopped instance)"""
604 b5f33afa Michael Hanselmann
  name = instance.name
605 3016bc1f Michael Hanselmann
606 58f0ce16 Michael Hanselmann
  # Instance was not marked offline; try marking it online once more
607 58f0ce16 Michael Hanselmann
  AssertCommand(["gnt-instance", "modify", "--online", name])
608 3016bc1f Michael Hanselmann
609 3016bc1f Michael Hanselmann
  # Mark instance as offline
610 3016bc1f Michael Hanselmann
  AssertCommand(["gnt-instance", "modify", "--offline", name])
611 3016bc1f Michael Hanselmann
612 1ba25bad Guido Trotter
  # When the instance is offline shutdown should only work with --force,
613 1ba25bad Guido Trotter
  # while start should never work
614 1ba25bad Guido Trotter
  AssertCommand(["gnt-instance", "shutdown", name], fail=True)
615 1ba25bad Guido Trotter
  AssertCommand(["gnt-instance", "shutdown", "--force", name])
616 1ba25bad Guido Trotter
  AssertCommand(["gnt-instance", "start", name], fail=True)
617 1ba25bad Guido Trotter
  AssertCommand(["gnt-instance", "start", "--force", name], fail=True)
618 1ba25bad Guido Trotter
619 1ba25bad Guido Trotter
  # Also do offline to offline
620 1ba25bad Guido Trotter
  AssertCommand(["gnt-instance", "modify", "--offline", name])
621 1ba25bad Guido Trotter
622 3016bc1f Michael Hanselmann
  # And online again
623 3016bc1f Michael Hanselmann
  AssertCommand(["gnt-instance", "modify", "--online", name])
624 3016bc1f Michael Hanselmann
625 c0f74c55 Iustin Pop
626 5fa0375e Michael Hanselmann
@InstanceCheck(INST_DOWN, INST_DOWN, FIRST_ARG)
627 c99200a3 Bernardo Dal Seno
def TestInstanceConvertDiskToPlain(instance, inodes):
628 7f69aabb Iustin Pop
  """gnt-instance modify -t"""
629 b5f33afa Michael Hanselmann
  name = instance.name
630 68c8c3df Michael Hanselmann
631 02a5fe0e Michael Hanselmann
  template = instance.disk_template
632 68c8c3df Michael Hanselmann
  if template != constants.DT_DRBD8:
633 5de31440 Bernardo Dal Seno
    print qa_utils.FormatInfo("Unsupported template %s, skipping conversion"
634 5de31440 Bernardo Dal Seno
                              " test" % template)
635 5de31440 Bernardo Dal Seno
    return
636 68c8c3df Michael Hanselmann
637 c99200a3 Bernardo Dal Seno
  assert len(inodes) == 2
638 68c8c3df Michael Hanselmann
  AssertCommand(["gnt-instance", "modify", "-t", constants.DT_PLAIN, name])
639 68c8c3df Michael Hanselmann
  AssertCommand(["gnt-instance", "modify", "-t", constants.DT_DRBD8,
640 aecba21e Michael Hanselmann
                 "-n", inodes[1].primary, name])
641 7f69aabb Iustin Pop
642 7f69aabb Iustin Pop
643 8cd4f8cf Bernardo Dal Seno
@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
644 8cd4f8cf Bernardo Dal Seno
def TestInstanceModifyDisks(instance):
645 8cd4f8cf Bernardo Dal Seno
  """gnt-instance modify --disk"""
646 8cd4f8cf Bernardo Dal Seno
  if not IsDiskSupported(instance):
647 8cd4f8cf Bernardo Dal Seno
    print qa_utils.FormatInfo("Instance doesn't support disks, skipping test")
648 8cd4f8cf Bernardo Dal Seno
    return
649 8cd4f8cf Bernardo Dal Seno
650 7c848a6a Bernardo Dal Seno
  disk_conf = qa_config.GetDiskOptions()[-1]
651 7c848a6a Bernardo Dal Seno
  size = disk_conf.get("size")
652 a365b47f Bernardo Dal Seno
  name = instance.name
653 8cd4f8cf Bernardo Dal Seno
  build_cmd = lambda arg: ["gnt-instance", "modify", "--disk", arg, name]
654 7c848a6a Bernardo Dal Seno
  if qa_config.AreSpindlesSupported():
655 7c848a6a Bernardo Dal Seno
    spindles = disk_conf.get("spindles")
656 7c848a6a Bernardo Dal Seno
    spindles_supported = True
657 7c848a6a Bernardo Dal Seno
  else:
658 7c848a6a Bernardo Dal Seno
    # Any number is good for spindles in this case
659 7c848a6a Bernardo Dal Seno
    spindles = 1
660 7c848a6a Bernardo Dal Seno
    spindles_supported = False
661 7c848a6a Bernardo Dal Seno
  AssertCommand(build_cmd("add:size=%s,spindles=%s" % (size, spindles)),
662 7c848a6a Bernardo Dal Seno
                fail=not spindles_supported)
663 7c848a6a Bernardo Dal Seno
  AssertCommand(build_cmd("add:size=%s" % size),
664 7c848a6a Bernardo Dal Seno
                fail=spindles_supported)
665 7c848a6a Bernardo Dal Seno
  # Exactly one of the above commands has succeded, so we need one remove
666 8cd4f8cf Bernardo Dal Seno
  AssertCommand(build_cmd("remove"))
667 8cd4f8cf Bernardo Dal Seno
668 8cd4f8cf Bernardo Dal Seno
669 5fa0375e Michael Hanselmann
@InstanceCheck(INST_DOWN, INST_DOWN, FIRST_ARG)
670 26a5056d Iustin Pop
def TestInstanceGrowDisk(instance):
671 26a5056d Iustin Pop
  """gnt-instance grow-disk"""
672 59c75517 Michael Hanselmann
  if instance.disk_template == constants.DT_DISKLESS:
673 59c75517 Michael Hanselmann
    print qa_utils.FormatInfo("Test not supported for diskless instances")
674 59c75517 Michael Hanselmann
    return
675 59c75517 Michael Hanselmann
676 b5f33afa Michael Hanselmann
  name = instance.name
677 090128b6 Christos Stavrakakis
  disks = qa_config.GetDiskOptions()
678 090128b6 Christos Stavrakakis
  all_size = [d.get("size") for d in disks]
679 090128b6 Christos Stavrakakis
  all_grow = [d.get("growth") for d in disks]
680 59c75517 Michael Hanselmann
681 26a5056d Iustin Pop
  if not all_grow:
682 26a5056d Iustin Pop
    # missing disk sizes but instance grow disk has been enabled,
683 26a5056d Iustin Pop
    # let's set fixed/nomimal growth
684 26a5056d Iustin Pop
    all_grow = ["128M" for _ in all_size]
685 59c75517 Michael Hanselmann
686 26a5056d Iustin Pop
  for idx, (size, grow) in enumerate(zip(all_size, all_grow)):
687 26a5056d Iustin Pop
    # succeed in grow by amount
688 26a5056d Iustin Pop
    AssertCommand(["gnt-instance", "grow-disk", name, str(idx), grow])
689 26a5056d Iustin Pop
    # fail in grow to the old size
690 26a5056d Iustin Pop
    AssertCommand(["gnt-instance", "grow-disk", "--absolute", name, str(idx),
691 26a5056d Iustin Pop
                   size], fail=True)
692 26a5056d Iustin Pop
    # succeed to grow to old size + 2 * growth
693 26a5056d Iustin Pop
    int_size = utils.ParseUnit(size)
694 26a5056d Iustin Pop
    int_grow = utils.ParseUnit(grow)
695 26a5056d Iustin Pop
    AssertCommand(["gnt-instance", "grow-disk", "--absolute", name, str(idx),
696 26a5056d Iustin Pop
                   str(int_size + 2 * int_grow)])
697 26a5056d Iustin Pop
698 26a5056d Iustin Pop
699 090128b6 Christos Stavrakakis
@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
700 090128b6 Christos Stavrakakis
def TestInstanceDeviceNames(instance):
701 090128b6 Christos Stavrakakis
  if instance.disk_template == constants.DT_DISKLESS:
702 090128b6 Christos Stavrakakis
    print qa_utils.FormatInfo("Test not supported for diskless instances")
703 090128b6 Christos Stavrakakis
    return
704 090128b6 Christos Stavrakakis
705 090128b6 Christos Stavrakakis
  name = instance.name
706 090128b6 Christos Stavrakakis
  for dev_type in ["disk", "net"]:
707 090128b6 Christos Stavrakakis
    if dev_type == "disk":
708 090128b6 Christos Stavrakakis
      options = ",size=512M"
709 7c848a6a Bernardo Dal Seno
      if qa_config.AreSpindlesSupported():
710 7c848a6a Bernardo Dal Seno
        options += ",spindles=1"
711 090128b6 Christos Stavrakakis
    else:
712 090128b6 Christos Stavrakakis
      options = ""
713 090128b6 Christos Stavrakakis
    # succeed in adding a device named 'test_device'
714 090128b6 Christos Stavrakakis
    AssertCommand(["gnt-instance", "modify",
715 090128b6 Christos Stavrakakis
                   "--%s=-1:add,name=test_device%s" % (dev_type, options),
716 090128b6 Christos Stavrakakis
                   name])
717 090128b6 Christos Stavrakakis
    # succeed in removing the 'test_device'
718 090128b6 Christos Stavrakakis
    AssertCommand(["gnt-instance", "modify",
719 090128b6 Christos Stavrakakis
                   "--%s=test_device:remove" % dev_type,
720 090128b6 Christos Stavrakakis
                   name])
721 090128b6 Christos Stavrakakis
    # fail to add two devices with the same name
722 090128b6 Christos Stavrakakis
    AssertCommand(["gnt-instance", "modify",
723 090128b6 Christos Stavrakakis
                   "--%s=-1:add,name=test_device%s" % (dev_type, options),
724 090128b6 Christos Stavrakakis
                   "--%s=-1:add,name=test_device%s" % (dev_type, options),
725 090128b6 Christos Stavrakakis
                   name], fail=True)
726 090128b6 Christos Stavrakakis
    # fail to add a device with invalid name
727 090128b6 Christos Stavrakakis
    AssertCommand(["gnt-instance", "modify",
728 090128b6 Christos Stavrakakis
                   "--%s=-1:add,name=2%s" % (dev_type, options),
729 090128b6 Christos Stavrakakis
                   name], fail=True)
730 090128b6 Christos Stavrakakis
  # Rename disks
731 090128b6 Christos Stavrakakis
  disks = qa_config.GetDiskOptions()
732 090128b6 Christos Stavrakakis
  disk_names = [d.get("name") for d in disks]
733 090128b6 Christos Stavrakakis
  for idx, disk_name in enumerate(disk_names):
734 090128b6 Christos Stavrakakis
    # Refer to disk by idx
735 090128b6 Christos Stavrakakis
    AssertCommand(["gnt-instance", "modify",
736 090128b6 Christos Stavrakakis
                   "--disk=%s:modify,name=renamed" % idx,
737 090128b6 Christos Stavrakakis
                   name])
738 090128b6 Christos Stavrakakis
    # Refer to by name and rename to original name
739 090128b6 Christos Stavrakakis
    AssertCommand(["gnt-instance", "modify",
740 090128b6 Christos Stavrakakis
                   "--disk=renamed:modify,name=%s" % disk_name,
741 090128b6 Christos Stavrakakis
                   name])
742 090128b6 Christos Stavrakakis
  if len(disks) >= 2:
743 090128b6 Christos Stavrakakis
    # fail in renaming to disks to the same name
744 090128b6 Christos Stavrakakis
    AssertCommand(["gnt-instance", "modify",
745 090128b6 Christos Stavrakakis
                   "--disk=0:modify,name=same_name",
746 090128b6 Christos Stavrakakis
                   "--disk=1:modify,name=same_name",
747 090128b6 Christos Stavrakakis
                   name], fail=True)
748 090128b6 Christos Stavrakakis
749 090128b6 Christos Stavrakakis
750 283f9d4c Michael Hanselmann
def TestInstanceList():
751 283f9d4c Michael Hanselmann
  """gnt-instance list"""
752 288d6440 Michael Hanselmann
  qa_utils.GenericQueryTest("gnt-instance", query.INSTANCE_FIELDS.keys())
753 283f9d4c Michael Hanselmann
754 283f9d4c Michael Hanselmann
755 2214cf14 Michael Hanselmann
def TestInstanceListFields():
756 2214cf14 Michael Hanselmann
  """gnt-instance list-fields"""
757 2214cf14 Michael Hanselmann
  qa_utils.GenericQueryFieldsTest("gnt-instance", query.INSTANCE_FIELDS.keys())
758 2214cf14 Michael Hanselmann
759 2214cf14 Michael Hanselmann
760 5fa0375e Michael Hanselmann
@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
761 4379b1fa Michael Hanselmann
def TestInstanceConsole(instance):
762 4379b1fa Michael Hanselmann
  """gnt-instance console"""
763 b5f33afa Michael Hanselmann
  AssertCommand(["gnt-instance", "console", "--show-cmd", instance.name])
764 4379b1fa Michael Hanselmann
765 4379b1fa Michael Hanselmann
766 5fa0375e Michael Hanselmann
@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
767 c99200a3 Bernardo Dal Seno
def TestReplaceDisks(instance, curr_nodes, other_nodes):
768 7910e7a5 Michael Hanselmann
  """gnt-instance replace-disks"""
769 7910e7a5 Michael Hanselmann
  def buildcmd(args):
770 d0c8c01d Iustin Pop
    cmd = ["gnt-instance", "replace-disks"]
771 7910e7a5 Michael Hanselmann
    cmd.extend(args)
772 b5f33afa Michael Hanselmann
    cmd.append(instance.name)
773 7910e7a5 Michael Hanselmann
    return cmd
774 7910e7a5 Michael Hanselmann
775 5de31440 Bernardo Dal Seno
  if not IsDiskReplacingSupported(instance):
776 5de31440 Bernardo Dal Seno
    print qa_utils.FormatInfo("Instance doesn't support disk replacing,"
777 5de31440 Bernardo Dal Seno
                              " skipping test")
778 5de31440 Bernardo Dal Seno
    return
779 5de31440 Bernardo Dal Seno
780 c99200a3 Bernardo Dal Seno
  # Currently all supported templates have one primary and one secondary node
781 c99200a3 Bernardo Dal Seno
  assert len(curr_nodes) == 2
782 c99200a3 Bernardo Dal Seno
  snode = curr_nodes[1]
783 c99200a3 Bernardo Dal Seno
  assert len(other_nodes) == 1
784 c99200a3 Bernardo Dal Seno
  othernode = other_nodes[0]
785 c99200a3 Bernardo Dal Seno
786 e85be22a Bernardo Dal Seno
  options = qa_config.get("options", {})
787 e85be22a Bernardo Dal Seno
  use_ialloc = options.get("use-iallocators", True)
788 2f4b4f78 Iustin Pop
  for data in [
789 2f4b4f78 Iustin Pop
    ["-p"],
790 2f4b4f78 Iustin Pop
    ["-s"],
791 e85be22a Bernardo Dal Seno
    # A placeholder; the actual command choice depends on use_ialloc
792 e85be22a Bernardo Dal Seno
    None,
793 e85be22a Bernardo Dal Seno
    # Restore the original secondary
794 aecba21e Michael Hanselmann
    ["--new-secondary=%s" % snode.primary],
795 2f4b4f78 Iustin Pop
    ]:
796 e85be22a Bernardo Dal Seno
    if data is None:
797 e85be22a Bernardo Dal Seno
      if use_ialloc:
798 e85be22a Bernardo Dal Seno
        data = ["-I", constants.DEFAULT_IALLOCATOR_SHORTCUT]
799 e85be22a Bernardo Dal Seno
      else:
800 aecba21e Michael Hanselmann
        data = ["--new-secondary=%s" % othernode.primary]
801 2f4b4f78 Iustin Pop
    AssertCommand(buildcmd(data))
802 7910e7a5 Michael Hanselmann
803 9026e935 Renรฉ Nussbaumer
  AssertCommand(buildcmd(["-a"]))
804 b5f33afa Michael Hanselmann
  AssertCommand(["gnt-instance", "stop", instance.name])
805 9026e935 Renรฉ Nussbaumer
  AssertCommand(buildcmd(["-a"]), fail=True)
806 b5f33afa Michael Hanselmann
  AssertCommand(["gnt-instance", "activate-disks", instance.name])
807 32da72f3 Iustin Pop
  AssertCommand(["gnt-instance", "activate-disks", "--wait-for-sync",
808 b5f33afa Michael Hanselmann
                 instance.name])
809 9026e935 Renรฉ Nussbaumer
  AssertCommand(buildcmd(["-a"]))
810 b5f33afa Michael Hanselmann
  AssertCommand(["gnt-instance", "start", instance.name])
811 9026e935 Renรฉ Nussbaumer
812 7910e7a5 Michael Hanselmann
813 83180411 Bernardo Dal Seno
def _AssertRecreateDisks(cmdargs, instance, fail=False, check=True,
814 83180411 Bernardo Dal Seno
                         destroy=True):
815 83180411 Bernardo Dal Seno
  """Execute gnt-instance recreate-disks and check the result
816 83180411 Bernardo Dal Seno

817 83180411 Bernardo Dal Seno
  @param cmdargs: Arguments (instance name excluded)
818 83180411 Bernardo Dal Seno
  @param instance: Instance to operate on
819 83180411 Bernardo Dal Seno
  @param fail: True if the command is expected to fail
820 83180411 Bernardo Dal Seno
  @param check: If True and fail is False, check that the disks work
821 83180411 Bernardo Dal Seno
  @prama destroy: If True, destroy the old disks first
822 83180411 Bernardo Dal Seno

823 83180411 Bernardo Dal Seno
  """
824 83180411 Bernardo Dal Seno
  if destroy:
825 cc2a70b1 Guido Trotter
    _DestroyInstanceDisks(instance)
826 83180411 Bernardo Dal Seno
  AssertCommand((["gnt-instance", "recreate-disks"] + cmdargs +
827 b5f33afa Michael Hanselmann
                 [instance.name]), fail)
828 83180411 Bernardo Dal Seno
  if not fail and check:
829 83180411 Bernardo Dal Seno
    # Quick check that the disks are there
830 b5f33afa Michael Hanselmann
    AssertCommand(["gnt-instance", "activate-disks", instance.name])
831 32da72f3 Iustin Pop
    AssertCommand(["gnt-instance", "activate-disks", "--wait-for-sync",
832 b5f33afa Michael Hanselmann
                   instance.name])
833 b5f33afa Michael Hanselmann
    AssertCommand(["gnt-instance", "deactivate-disks", instance.name])
834 83180411 Bernardo Dal Seno
835 a1cd2ecf Bernardo Dal Seno
836 7c848a6a Bernardo Dal Seno
def _BuildRecreateDisksOpts(en_disks, with_spindles, with_growth,
837 7c848a6a Bernardo Dal Seno
                            spindles_supported):
838 7c848a6a Bernardo Dal Seno
  if with_spindles:
839 7c848a6a Bernardo Dal Seno
    if spindles_supported:
840 7c848a6a Bernardo Dal Seno
      if with_growth:
841 7c848a6a Bernardo Dal Seno
        build_spindles_opt = (lambda disk:
842 7c848a6a Bernardo Dal Seno
                              ",spindles=%s" %
843 7c848a6a Bernardo Dal Seno
                              (disk["spindles"] + disk["spindles-growth"]))
844 7c848a6a Bernardo Dal Seno
      else:
845 7c848a6a Bernardo Dal Seno
        build_spindles_opt = (lambda disk:
846 7c848a6a Bernardo Dal Seno
                              ",spindles=%s" % disk["spindles"])
847 7c848a6a Bernardo Dal Seno
    else:
848 7c848a6a Bernardo Dal Seno
      build_spindles_opt = (lambda _: ",spindles=1")
849 7c848a6a Bernardo Dal Seno
  else:
850 7c848a6a Bernardo Dal Seno
    build_spindles_opt = (lambda _: "")
851 7c848a6a Bernardo Dal Seno
  if with_growth:
852 7c848a6a Bernardo Dal Seno
    build_size_opt = (lambda disk:
853 7c848a6a Bernardo Dal Seno
                      "size=%s" % (utils.ParseUnit(disk["size"]) +
854 7c848a6a Bernardo Dal Seno
                                   utils.ParseUnit(disk["growth"])))
855 7c848a6a Bernardo Dal Seno
  else:
856 7c848a6a Bernardo Dal Seno
    build_size_opt = (lambda disk: "size=%s" % disk["size"])
857 7c848a6a Bernardo Dal Seno
  build_disk_opt = (lambda (idx, disk):
858 7c848a6a Bernardo Dal Seno
                    "--disk=%s:%s%s" % (idx, build_size_opt(disk),
859 7c848a6a Bernardo Dal Seno
                                        build_spindles_opt(disk)))
860 7c848a6a Bernardo Dal Seno
  return map(build_disk_opt, en_disks)
861 7c848a6a Bernardo Dal Seno
862 7c848a6a Bernardo Dal Seno
863 83180411 Bernardo Dal Seno
@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
864 c99200a3 Bernardo Dal Seno
def TestRecreateDisks(instance, inodes, othernodes):
865 83180411 Bernardo Dal Seno
  """gnt-instance recreate-disks
866 83180411 Bernardo Dal Seno

867 83180411 Bernardo Dal Seno
  @param instance: Instance to work on
868 c99200a3 Bernardo Dal Seno
  @param inodes: List of the current nodes of the instance
869 83180411 Bernardo Dal Seno
  @param othernodes: list/tuple of nodes where to temporarily recreate disks
870 83180411 Bernardo Dal Seno

871 83180411 Bernardo Dal Seno
  """
872 e85be22a Bernardo Dal Seno
  options = qa_config.get("options", {})
873 e85be22a Bernardo Dal Seno
  use_ialloc = options.get("use-iallocators", True)
874 aecba21e Michael Hanselmann
  other_seq = ":".join([n.primary for n in othernodes])
875 aecba21e Michael Hanselmann
  orig_seq = ":".join([n.primary for n in inodes])
876 a085d96d Bernardo Dal Seno
  # These fail because the instance is running
877 83180411 Bernardo Dal Seno
  _AssertRecreateDisks(["-n", other_seq], instance, fail=True, destroy=False)
878 e85be22a Bernardo Dal Seno
  if use_ialloc:
879 e85be22a Bernardo Dal Seno
    _AssertRecreateDisks(["-I", "hail"], instance, fail=True, destroy=False)
880 e85be22a Bernardo Dal Seno
  else:
881 e85be22a Bernardo Dal Seno
    _AssertRecreateDisks(["-n", other_seq], instance, fail=True, destroy=False)
882 b5f33afa Michael Hanselmann
  AssertCommand(["gnt-instance", "stop", instance.name])
883 83180411 Bernardo Dal Seno
  # Disks exist: this should fail
884 83180411 Bernardo Dal Seno
  _AssertRecreateDisks([], instance, fail=True, destroy=False)
885 345d395d Bernardo Dal Seno
  # Unsupported spindles parameters: fail
886 345d395d Bernardo Dal Seno
  if not qa_config.AreSpindlesSupported():
887 345d395d Bernardo Dal Seno
    _AssertRecreateDisks(["--disk=0:spindles=2"], instance,
888 345d395d Bernardo Dal Seno
                         fail=True, destroy=False)
889 83180411 Bernardo Dal Seno
  # Recreate disks in place
890 83180411 Bernardo Dal Seno
  _AssertRecreateDisks([], instance)
891 83180411 Bernardo Dal Seno
  # Move disks away
892 e85be22a Bernardo Dal Seno
  if use_ialloc:
893 e85be22a Bernardo Dal Seno
    _AssertRecreateDisks(["-I", "hail"], instance)
894 e85be22a Bernardo Dal Seno
    # Move disks somewhere else
895 e85be22a Bernardo Dal Seno
    _AssertRecreateDisks(["-I", constants.DEFAULT_IALLOCATOR_SHORTCUT],
896 e85be22a Bernardo Dal Seno
                         instance)
897 e85be22a Bernardo Dal Seno
  else:
898 e85be22a Bernardo Dal Seno
    _AssertRecreateDisks(["-n", other_seq], instance)
899 83180411 Bernardo Dal Seno
  # Move disks back
900 e2e98c6e Bernardo Dal Seno
  _AssertRecreateDisks(["-n", orig_seq], instance)
901 345d395d Bernardo Dal Seno
  # Recreate resized disks
902 7c848a6a Bernardo Dal Seno
  # One of the two commands fails because either spindles are given when they
903 7c848a6a Bernardo Dal Seno
  # should not or vice versa
904 345d395d Bernardo Dal Seno
  alldisks = qa_config.GetDiskOptions()
905 7c848a6a Bernardo Dal Seno
  spindles_supported = qa_config.AreSpindlesSupported()
906 7c848a6a Bernardo Dal Seno
  disk_opts = _BuildRecreateDisksOpts(enumerate(alldisks), True, True,
907 7c848a6a Bernardo Dal Seno
                                      spindles_supported)
908 7c848a6a Bernardo Dal Seno
  _AssertRecreateDisks(disk_opts, instance, destroy=True,
909 7c848a6a Bernardo Dal Seno
                       fail=not spindles_supported)
910 7c848a6a Bernardo Dal Seno
  disk_opts = _BuildRecreateDisksOpts(enumerate(alldisks), False, True,
911 7c848a6a Bernardo Dal Seno
                                      spindles_supported)
912 7c848a6a Bernardo Dal Seno
  _AssertRecreateDisks(disk_opts, instance, destroy=False,
913 7c848a6a Bernardo Dal Seno
                       fail=spindles_supported)
914 345d395d Bernardo Dal Seno
  # Recreate the disks one by one (with the original size)
915 345d395d Bernardo Dal Seno
  for (idx, disk) in enumerate(alldisks):
916 e2e98c6e Bernardo Dal Seno
    # Only the first call should destroy all the disk
917 e2e98c6e Bernardo Dal Seno
    destroy = (idx == 0)
918 7c848a6a Bernardo Dal Seno
    # Again, one of the two commands is expected to fail
919 7c848a6a Bernardo Dal Seno
    disk_opts = _BuildRecreateDisksOpts([(idx, disk)], True, False,
920 7c848a6a Bernardo Dal Seno
                                        spindles_supported)
921 7c848a6a Bernardo Dal Seno
    _AssertRecreateDisks(disk_opts, instance, destroy=destroy, check=False,
922 7c848a6a Bernardo Dal Seno
                         fail=not spindles_supported)
923 7c848a6a Bernardo Dal Seno
    disk_opts = _BuildRecreateDisksOpts([(idx, disk)], False, False,
924 7c848a6a Bernardo Dal Seno
                                        spindles_supported)
925 7c848a6a Bernardo Dal Seno
    _AssertRecreateDisks(disk_opts, instance, destroy=False, check=False,
926 7c848a6a Bernardo Dal Seno
                         fail=spindles_supported)
927 83180411 Bernardo Dal Seno
  # This and InstanceCheck decoration check that the disks are working
928 b5f33afa Michael Hanselmann
  AssertCommand(["gnt-instance", "reinstall", "-f", instance.name])
929 b5f33afa Michael Hanselmann
  AssertCommand(["gnt-instance", "start", instance.name])
930 83180411 Bernardo Dal Seno
931 83180411 Bernardo Dal Seno
932 5fa0375e Michael Hanselmann
@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
933 5d640672 Michael Hanselmann
def TestInstanceExport(instance, node):
934 bc696589 Michael Hanselmann
  """gnt-backup export -n ..."""
935 b5f33afa Michael Hanselmann
  name = instance.name
936 f9b76ed4 Helga Velroyen
  # Export does not work for file-based templates, thus we skip the test
937 f9b76ed4 Helga Velroyen
  if instance.disk_template in [constants.DT_FILE, constants.DT_SHARED_FILE]:
938 f9b76ed4 Helga Velroyen
    return
939 aecba21e Michael Hanselmann
  AssertCommand(["gnt-backup", "export", "-n", node.primary, name])
940 2f4b4f78 Iustin Pop
  return qa_utils.ResolveInstanceName(name)
941 5d640672 Michael Hanselmann
942 5d640672 Michael Hanselmann
943 51131cad Michael Hanselmann
@InstanceCheck(None, INST_DOWN, FIRST_ARG)
944 8d8d650c Michael Hanselmann
def TestInstanceExportWithRemove(instance, node):
945 8d8d650c Michael Hanselmann
  """gnt-backup export --remove-instance"""
946 aecba21e Michael Hanselmann
  AssertCommand(["gnt-backup", "export", "-n", node.primary,
947 b5f33afa Michael Hanselmann
                 "--remove-instance", instance.name])
948 8d8d650c Michael Hanselmann
949 8d8d650c Michael Hanselmann
950 5fa0375e Michael Hanselmann
@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
951 bc696589 Michael Hanselmann
def TestInstanceExportNoTarget(instance):
952 bc696589 Michael Hanselmann
  """gnt-backup export (without target node, should fail)"""
953 b5f33afa Michael Hanselmann
  AssertCommand(["gnt-backup", "export", instance.name], fail=True)
954 bc696589 Michael Hanselmann
955 bc696589 Michael Hanselmann
956 51131cad Michael Hanselmann
@InstanceCheck(None, INST_DOWN, FIRST_ARG)
957 5fa0375e Michael Hanselmann
def TestInstanceImport(newinst, node, expnode, name):
958 5d640672 Michael Hanselmann
  """gnt-backup import"""
959 906a0346 Bernardo Dal Seno
  templ = constants.DT_PLAIN
960 f9b76ed4 Helga Velroyen
  if not qa_config.IsTemplateSupported(templ):
961 f9b76ed4 Helga Velroyen
    return
962 d0c8c01d Iustin Pop
  cmd = (["gnt-backup", "import",
963 906a0346 Bernardo Dal Seno
          "--disk-template=%s" % templ,
964 d0c8c01d Iustin Pop
          "--no-ip-check",
965 aecba21e Michael Hanselmann
          "--src-node=%s" % expnode.primary,
966 304d9f02 Michael Hanselmann
          "--src-dir=%s/%s" % (pathutils.EXPORT_DIR, name),
967 aecba21e Michael Hanselmann
          "--node=%s" % node.primary] +
968 8fada090 Michele Tartara
         GetGenericAddParameters(newinst, templ,
969 59c75517 Michael Hanselmann
                                  force_mac=constants.VALUE_GENERATE))
970 b5f33afa Michael Hanselmann
  cmd.append(newinst.name)
971 2f4b4f78 Iustin Pop
  AssertCommand(cmd)
972 02a5fe0e Michael Hanselmann
  newinst.SetDiskTemplate(templ)
973 283f9d4c Michael Hanselmann
974 283f9d4c Michael Hanselmann
975 283f9d4c Michael Hanselmann
def TestBackupList(expnode):
976 283f9d4c Michael Hanselmann
  """gnt-backup list"""
977 aecba21e Michael Hanselmann
  AssertCommand(["gnt-backup", "list", "--node=%s" % expnode.primary])
978 e8ae0c20 Michael Hanselmann
979 0fdf247d Michael Hanselmann
  qa_utils.GenericQueryTest("gnt-backup", query.EXPORT_FIELDS.keys(),
980 0fdf247d Michael Hanselmann
                            namefield=None, test_unknown=False)
981 0fdf247d Michael Hanselmann
982 0fdf247d Michael Hanselmann
983 0fdf247d Michael Hanselmann
def TestBackupListFields():
984 0fdf247d Michael Hanselmann
  """gnt-backup list-fields"""
985 0fdf247d Michael Hanselmann
  qa_utils.GenericQueryFieldsTest("gnt-backup", query.EXPORT_FIELDS.keys())
986 f006f110 Bernardo Dal Seno
987 f006f110 Bernardo Dal Seno
988 f006f110 Bernardo Dal Seno
def TestRemoveInstanceOfflineNode(instance, snode, set_offline, set_online):
989 318bbaa9 Guido Trotter
  """gnt-instance remove with an off-line node
990 f006f110 Bernardo Dal Seno

991 f006f110 Bernardo Dal Seno
  @param instance: instance
992 f006f110 Bernardo Dal Seno
  @param snode: secondary node, to be set offline
993 f006f110 Bernardo Dal Seno
  @param set_offline: function to call to set the node off-line
994 f006f110 Bernardo Dal Seno
  @param set_online: function to call to set the node on-line
995 f006f110 Bernardo Dal Seno

996 f006f110 Bernardo Dal Seno
  """
997 7af293d7 Thomas Thrainer
  info = GetInstanceInfo(instance.name)
998 f006f110 Bernardo Dal Seno
  set_offline(snode)
999 f006f110 Bernardo Dal Seno
  try:
1000 f006f110 Bernardo Dal Seno
    TestInstanceRemove(instance)
1001 f006f110 Bernardo Dal Seno
  finally:
1002 f006f110 Bernardo Dal Seno
    set_online(snode)
1003 318bbaa9 Guido Trotter
1004 318bbaa9 Guido Trotter
  # Clean up the disks on the offline node, if necessary
1005 318bbaa9 Guido Trotter
  if instance.disk_template not in constants.DTS_EXT_MIRROR:
1006 318bbaa9 Guido Trotter
    # FIXME: abstract the cleanup inside the disks
1007 318bbaa9 Guido Trotter
    if info["storage-type"] == constants.ST_LVM_VG:
1008 318bbaa9 Guido Trotter
      for minor in info["drbd-minors"][snode.primary]:
1009 2e462e19 Thomas Thrainer
        # DRBD 8.3 syntax comes first, then DRBD 8.4 syntax. The 8.4 syntax
1010 2e462e19 Thomas Thrainer
        # relies on the fact that we always create a resources for each minor,
1011 2e462e19 Thomas Thrainer
        # and that this resources is always named resource{minor}.
1012 2e462e19 Thomas Thrainer
        # As 'drbdsetup 0 down' does return success (even though that's invalid
1013 2e462e19 Thomas Thrainer
        # syntax), we always have to perform both commands and ignore the
1014 2e462e19 Thomas Thrainer
        # output.
1015 2e462e19 Thomas Thrainer
        drbd_shutdown_cmd = \
1016 7af293d7 Thomas Thrainer
          "(drbdsetup %d down >/dev/null 2>&1;" \
1017 7af293d7 Thomas Thrainer
          " drbdsetup down resource%d >/dev/null 2>&1) || /bin/true" % \
1018 2e462e19 Thomas Thrainer
            (minor, minor)
1019 2e462e19 Thomas Thrainer
        AssertCommand(drbd_shutdown_cmd, node=snode)
1020 318bbaa9 Guido Trotter
      AssertCommand(["lvremove", "-f"] + info["volumes"], node=snode)
1021 318bbaa9 Guido Trotter
    elif info["storage-type"] == constants.ST_FILE:
1022 5949c31c Helga Velroyen
      filestorage = qa_config.get("file-storage-dir",
1023 5949c31c Helga Velroyen
                                  pathutils.DEFAULT_FILE_STORAGE_DIR)
1024 318bbaa9 Guido Trotter
      disk = os.path.join(filestorage, instance.name)
1025 318bbaa9 Guido Trotter
      AssertCommand(["rm", "-rf", disk], node=snode)
1026 6f665bf7 Helga Velroyen
1027 6f665bf7 Helga Velroyen
1028 6f665bf7 Helga Velroyen
def TestInstanceCreationRestrictedByDiskTemplates():
1029 e75f80b9 Bernardo Dal Seno
  """Test adding instances for disabled disk templates."""
1030 2b5b6da1 Helga Velroyen
  if qa_config.TestEnabled("cluster-exclusive-storage"):
1031 2b5b6da1 Helga Velroyen
    # These tests are valid only for non-exclusive storage
1032 2b5b6da1 Helga Velroyen
    return
1033 2b5b6da1 Helga Velroyen
1034 6f665bf7 Helga Velroyen
  enabled_disk_templates = qa_config.GetEnabledDiskTemplates()
1035 6f665bf7 Helga Velroyen
  nodes = qa_config.AcquireManyNodes(2)
1036 6f665bf7 Helga Velroyen
1037 6f665bf7 Helga Velroyen
  # Setup the cluster with the enabled_disk_templates
1038 6f665bf7 Helga Velroyen
  AssertCommand(
1039 6f665bf7 Helga Velroyen
    ["gnt-cluster", "modify",
1040 eb161df2 Helga Velroyen
     "--enabled-disk-templates=%s" % ",".join(enabled_disk_templates),
1041 eb161df2 Helga Velroyen
     "--ipolicy-disk-templates=%s" % ",".join(enabled_disk_templates)],
1042 6f665bf7 Helga Velroyen
    fail=False)
1043 6f665bf7 Helga Velroyen
1044 6f665bf7 Helga Velroyen
  # Test instance creation for enabled disk templates
1045 6f665bf7 Helga Velroyen
  for disk_template in enabled_disk_templates:
1046 e75f80b9 Bernardo Dal Seno
    instance = CreateInstanceByDiskTemplate(nodes, disk_template, fail=False)
1047 6f665bf7 Helga Velroyen
    TestInstanceRemove(instance)
1048 e75f80b9 Bernardo Dal Seno
    instance.Release()
1049 6f665bf7 Helga Velroyen
1050 6f665bf7 Helga Velroyen
  # Test that instance creation fails for disabled disk templates
1051 6f665bf7 Helga Velroyen
  disabled_disk_templates = list(constants.DISK_TEMPLATES
1052 6f665bf7 Helga Velroyen
                                 - set(enabled_disk_templates))
1053 6f665bf7 Helga Velroyen
  for disk_template in disabled_disk_templates:
1054 e75f80b9 Bernardo Dal Seno
    instance = CreateInstanceByDiskTemplate(nodes, disk_template, fail=True)
1055 6f665bf7 Helga Velroyen
1056 6f665bf7 Helga Velroyen
  # Test instance creation for after disabling enabled disk templates
1057 6f665bf7 Helga Velroyen
  if (len(enabled_disk_templates) > 1):
1058 6f665bf7 Helga Velroyen
    # Partition the disk templates, enable them separately and check if the
1059 6f665bf7 Helga Velroyen
    # disabled ones cannot be used by instances.
1060 6f665bf7 Helga Velroyen
    middle = len(enabled_disk_templates) / 2
1061 6f665bf7 Helga Velroyen
    templates1 = enabled_disk_templates[:middle]
1062 6f665bf7 Helga Velroyen
    templates2 = enabled_disk_templates[middle:]
1063 6f665bf7 Helga Velroyen
1064 6f665bf7 Helga Velroyen
    for (enabled, disabled) in [(templates1, templates2),
1065 6f665bf7 Helga Velroyen
                                (templates2, templates1)]:
1066 6f665bf7 Helga Velroyen
      AssertCommand(["gnt-cluster", "modify",
1067 eb161df2 Helga Velroyen
                     "--enabled-disk-templates=%s" % ",".join(enabled),
1068 eb161df2 Helga Velroyen
                     "--ipolicy-disk-templates=%s" % ",".join(enabled)],
1069 6f665bf7 Helga Velroyen
                    fail=False)
1070 6f665bf7 Helga Velroyen
      for disk_template in disabled:
1071 e75f80b9 Bernardo Dal Seno
        CreateInstanceByDiskTemplate(nodes, disk_template, fail=True)
1072 6f665bf7 Helga Velroyen
  elif (len(enabled_disk_templates) == 1):
1073 6f665bf7 Helga Velroyen
    # If only one disk template is enabled in the QA config, we have to enable
1074 d101b7be Thomas Thrainer
    # some other templates in order to test if the disabling the only enabled
1075 d101b7be Thomas Thrainer
    # disk template prohibits creating instances of that template.
1076 d101b7be Thomas Thrainer
    other_disk_templates = list(
1077 ec4341d7 Thomas Thrainer
                             set([constants.DT_DISKLESS, constants.DT_BLOCK]) -
1078 ec4341d7 Thomas Thrainer
                             set(enabled_disk_templates))
1079 6f665bf7 Helga Velroyen
    AssertCommand(["gnt-cluster", "modify",
1080 ae591749 Helga Velroyen
                   "--enabled-disk-templates=%s" %
1081 eb161df2 Helga Velroyen
                     ",".join(other_disk_templates),
1082 eb161df2 Helga Velroyen
                   "--ipolicy-disk-templates=%s" %
1083 d101b7be Thomas Thrainer
                     ",".join(other_disk_templates)],
1084 6f665bf7 Helga Velroyen
                  fail=False)
1085 e75f80b9 Bernardo Dal Seno
    CreateInstanceByDiskTemplate(nodes, enabled_disk_templates[0], fail=True)
1086 6f665bf7 Helga Velroyen
  else:
1087 6f665bf7 Helga Velroyen
    raise qa_error.Error("Please enable at least one disk template"
1088 6f665bf7 Helga Velroyen
                         " in your QA setup.")
1089 6f665bf7 Helga Velroyen
1090 6f665bf7 Helga Velroyen
  # Restore initially enabled disk templates
1091 6f665bf7 Helga Velroyen
  AssertCommand(["gnt-cluster", "modify",
1092 ae591749 Helga Velroyen
                 "--enabled-disk-templates=%s" %
1093 eb161df2 Helga Velroyen
                   ",".join(enabled_disk_templates),
1094 eb161df2 Helga Velroyen
                 "--ipolicy-disk-templates=%s" %
1095 6f665bf7 Helga Velroyen
                   ",".join(enabled_disk_templates)],
1096 6f665bf7 Helga Velroyen
                 fail=False)
1097 37889387 Klaus Aehlig
1098 24c530df Jose A. Lopes
1099 24c530df Jose A. Lopes
@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
1100 24c530df Jose A. Lopes
def _TestInstanceUserDown(instance, master, hv_shutdown_fn):
1101 51958d2a Jose A. Lopes
  # Shutdown instance and bring instance status to 'USER_down'
1102 24c530df Jose A. Lopes
  hv_shutdown_fn()
1103 24c530df Jose A. Lopes
1104 24c530df Jose A. Lopes
  cmd = ["gnt-instance", "list", "--no-headers", "-o", "status", instance.name]
1105 24c530df Jose A. Lopes
  result_output = qa_utils.GetCommandOutput(master.primary,
1106 24c530df Jose A. Lopes
                                            utils.ShellQuoteArgs(cmd))
1107 24c530df Jose A. Lopes
  AssertEqual(result_output.strip(), constants.INSTST_USERDOWN)
1108 24c530df Jose A. Lopes
1109 24c530df Jose A. Lopes
  # Fail to bring instance status to 'running'
1110 24c530df Jose A. Lopes
  AssertCommand(["gnt-instance", "start", instance.name], fail=True)
1111 24c530df Jose A. Lopes
1112 24c530df Jose A. Lopes
  cmd = ["gnt-instance", "list", "--no-headers", "-o", "status", instance.name]
1113 24c530df Jose A. Lopes
  result_output = qa_utils.GetCommandOutput(master.primary,
1114 24c530df Jose A. Lopes
                                            utils.ShellQuoteArgs(cmd))
1115 24c530df Jose A. Lopes
  AssertEqual(result_output.strip(), constants.INSTST_USERDOWN)
1116 24c530df Jose A. Lopes
1117 24c530df Jose A. Lopes
  # Bring instance status to 'ADMIN_down'
1118 24c530df Jose A. Lopes
  AssertCommand(["gnt-instance", "shutdown", instance.name])
1119 24c530df Jose A. Lopes
1120 24c530df Jose A. Lopes
  cmd = ["gnt-instance", "list", "--no-headers", "-o", "status", instance.name]
1121 24c530df Jose A. Lopes
  result_output = qa_utils.GetCommandOutput(master.primary,
1122 24c530df Jose A. Lopes
                                            utils.ShellQuoteArgs(cmd))
1123 24c530df Jose A. Lopes
  AssertEqual(result_output.strip(), constants.INSTST_ADMINDOWN)
1124 24c530df Jose A. Lopes
1125 24c530df Jose A. Lopes
  # Bring instance status to 'running'
1126 24c530df Jose A. Lopes
  AssertCommand(["gnt-instance", "start", instance.name])
1127 24c530df Jose A. Lopes
1128 24c530df Jose A. Lopes
  cmd = ["gnt-instance", "list", "--no-headers", "-o", "status", instance.name]
1129 24c530df Jose A. Lopes
  result_output = qa_utils.GetCommandOutput(master.primary,
1130 24c530df Jose A. Lopes
                                            utils.ShellQuoteArgs(cmd))
1131 24c530df Jose A. Lopes
  AssertEqual(result_output.strip(), constants.INSTST_RUNNING)
1132 24c530df Jose A. Lopes
1133 24c530df Jose A. Lopes
  # Bring instance status to 'ADMIN_down' forcibly
1134 24c530df Jose A. Lopes
  AssertCommand(["gnt-instance", "shutdown", "-f", instance.name])
1135 24c530df Jose A. Lopes
1136 24c530df Jose A. Lopes
  cmd = ["gnt-instance", "list", "--no-headers", "-o", "status", instance.name]
1137 24c530df Jose A. Lopes
  result_output = qa_utils.GetCommandOutput(master.primary,
1138 24c530df Jose A. Lopes
                                            utils.ShellQuoteArgs(cmd))
1139 24c530df Jose A. Lopes
  AssertEqual(result_output.strip(), constants.INSTST_ADMINDOWN)
1140 24c530df Jose A. Lopes
1141 24c530df Jose A. Lopes
  # Bring instance status to 'running'
1142 24c530df Jose A. Lopes
  AssertCommand(["gnt-instance", "start", instance.name])
1143 24c530df Jose A. Lopes
1144 24c530df Jose A. Lopes
  cmd = ["gnt-instance", "list", "--no-headers", "-o", "status", instance.name]
1145 24c530df Jose A. Lopes
  result_output = qa_utils.GetCommandOutput(master.primary,
1146 24c530df Jose A. Lopes
                                            utils.ShellQuoteArgs(cmd))
1147 24c530df Jose A. Lopes
  AssertEqual(result_output.strip(), constants.INSTST_RUNNING)
1148 24c530df Jose A. Lopes
1149 24c530df Jose A. Lopes
1150 24c530df Jose A. Lopes
@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
1151 24c530df Jose A. Lopes
def _TestInstanceUserDownXen(instance, master):
1152 24c530df Jose A. Lopes
  primary = _GetInstanceField(instance.name, "pnode")
1153 24c530df Jose A. Lopes
  fn = lambda: AssertCommand(["xm", "shutdown", "-w", instance.name],
1154 51958d2a Jose A. Lopes
                             node=primary)
1155 24c530df Jose A. Lopes
  _TestInstanceUserDown(instance, master, fn)
1156 24c530df Jose A. Lopes
1157 24c530df Jose A. Lopes
1158 51958d2a Jose A. Lopes
@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
1159 51958d2a Jose A. Lopes
def _TestInstanceUserDownKvm(instance, master):
1160 51958d2a Jose A. Lopes
  def _StopKVMInstance():
1161 fcc27323 Jose A. Lopes
    AssertCommand("pkill -f \"\\-name %s\"" % instance.name, node=primary)
1162 fcc27323 Jose A. Lopes
    time.sleep(10)
1163 51958d2a Jose A. Lopes
1164 51958d2a Jose A. Lopes
  AssertCommand(["gnt-instance", "modify", "-H", "user_shutdown=true",
1165 51958d2a Jose A. Lopes
                 instance.name])
1166 51958d2a Jose A. Lopes
1167 51958d2a Jose A. Lopes
  # The instance needs to reboot not because the 'user_shutdown'
1168 51958d2a Jose A. Lopes
  # parameter was modified but because the KVM daemon need to be
1169 51958d2a Jose A. Lopes
  # started, given that the instance was first created with user
1170 51958d2a Jose A. Lopes
  # shutdown disabled.
1171 51958d2a Jose A. Lopes
  AssertCommand(["gnt-instance", "reboot", instance.name])
1172 51958d2a Jose A. Lopes
1173 51958d2a Jose A. Lopes
  primary = _GetInstanceField(instance.name, "pnode")
1174 51958d2a Jose A. Lopes
  _TestInstanceUserDown(instance, master, _StopKVMInstance)
1175 24c530df Jose A. Lopes
1176 24c530df Jose A. Lopes
1177 24c530df Jose A. Lopes
def TestInstanceUserDown(instance, master):
1178 24c530df Jose A. Lopes
  """Tests user shutdown"""
1179 24c530df Jose A. Lopes
  enabled_hypervisors = qa_config.GetEnabledHypervisors()
1180 24c530df Jose A. Lopes
1181 24c530df Jose A. Lopes
  for (hv, fn) in [(constants.HT_XEN_PVM, _TestInstanceUserDownXen),
1182 24c530df Jose A. Lopes
                   (constants.HT_XEN_HVM, _TestInstanceUserDownXen),
1183 24c530df Jose A. Lopes
                   (constants.HT_KVM, _TestInstanceUserDownKvm)]:
1184 24c530df Jose A. Lopes
    if hv in enabled_hypervisors:
1185 24c530df Jose A. Lopes
      fn(instance, master)
1186 24c530df Jose A. Lopes
    else:
1187 24c530df Jose A. Lopes
      print "%s hypervisor is not enabled, skipping test for this hypervisor" \
1188 24c530df Jose A. Lopes
          % hv
1189 24c530df Jose A. Lopes
1190 24c530df Jose A. Lopes
1191 37889387 Klaus Aehlig
available_instance_tests = [
1192 37889387 Klaus Aehlig
  ("instance-add-plain-disk", constants.DT_PLAIN,
1193 37889387 Klaus Aehlig
   TestInstanceAddWithPlainDisk, 1),
1194 37889387 Klaus Aehlig
  ("instance-add-drbd-disk", constants.DT_DRBD8,
1195 37889387 Klaus Aehlig
   TestInstanceAddWithDrbdDisk, 2),
1196 37889387 Klaus Aehlig
  ("instance-add-diskless", constants.DT_DISKLESS,
1197 37889387 Klaus Aehlig
   TestInstanceAddDiskless, 1),
1198 37889387 Klaus Aehlig
  ("instance-add-file", constants.DT_FILE,
1199 37889387 Klaus Aehlig
   TestInstanceAddFile, 1),
1200 37889387 Klaus Aehlig
  ("instance-add-shared-file", constants.DT_SHARED_FILE,
1201 37889387 Klaus Aehlig
   TestInstanceAddSharedFile, 1),
1202 37889387 Klaus Aehlig
  ]