Statistics
| Branch: | Tag: | Revision:

root / qa / qa_instance.py @ 82ce55fa

History | View | Annotate | Download (43.4 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 e8ae0c20 Michael Hanselmann
29 cec9845c Michael Hanselmann
from ganeti import utils
30 5d640672 Michael Hanselmann
from ganeti import constants
31 288d6440 Michael Hanselmann
from ganeti import query
32 304d9f02 Michael Hanselmann
from ganeti import pathutils
33 cec9845c Michael Hanselmann
34 cec9845c Michael Hanselmann
import qa_config
35 5d640672 Michael Hanselmann
import qa_utils
36 e8ae0c20 Michael Hanselmann
import qa_error
37 e8ae0c20 Michael Hanselmann
38 8fada090 Michele Tartara
from qa_utils import AssertCommand, AssertEqual
39 5fa0375e Michael Hanselmann
from qa_utils import InstanceCheck, INST_DOWN, INST_UP, FIRST_ARG, RETURN_VALUE
40 8fada090 Michele Tartara
from qa_instance_utils import CheckSsconfInstanceList, \
41 8fada090 Michele Tartara
                              CreateInstanceDrbd8, \
42 8fada090 Michele Tartara
                              CreateInstanceByDiskTemplate, \
43 8fada090 Michele Tartara
                              CreateInstanceByDiskTemplateOneNode, \
44 8fada090 Michele Tartara
                              GetGenericAddParameters
45 cec9845c Michael Hanselmann
46 e8ae0c20 Michael Hanselmann
47 e8ae0c20 Michael Hanselmann
def _GetDiskStatePath(disk):
48 e8ae0c20 Michael Hanselmann
  return "/sys/block/%s/device/state" % disk
49 cec9845c Michael Hanselmann
50 cec9845c Michael Hanselmann
51 7af293d7 Thomas Thrainer
def GetInstanceInfo(instance):
52 cc4b14f0 Bernardo Dal Seno
  """Return information about the actual state of an instance.
53 82d2f3df Bernardo Dal Seno

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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