Statistics
| Branch: | Tag: | Revision:

root / qa / qa_instance.py @ b0b7bf8f

History | View | Annotate | Download (30.9 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 c99200a3 Bernardo Dal Seno
import operator
27 d0a44ec0 Klaus Aehlig
import os
28 e8ae0c20 Michael Hanselmann
import re
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 cc27265e René Nussbaumer
from qa_utils import AssertIn, AssertCommand, AssertEqual
40 5fa0375e Michael Hanselmann
from qa_utils import InstanceCheck, INST_DOWN, INST_UP, FIRST_ARG, RETURN_VALUE
41 cec9845c Michael Hanselmann
42 e8ae0c20 Michael Hanselmann
43 e8ae0c20 Michael Hanselmann
def _GetDiskStatePath(disk):
44 e8ae0c20 Michael Hanselmann
  return "/sys/block/%s/device/state" % disk
45 cec9845c Michael Hanselmann
46 cec9845c Michael Hanselmann
47 59c75517 Michael Hanselmann
def _GetGenericAddParameters(inst, disk_template, force_mac=None):
48 8ccbbe4b Guido Trotter
  params = ["-B"]
49 8ccbbe4b Guido Trotter
  params.append("%s=%s,%s=%s" % (constants.BE_MINMEM,
50 8ccbbe4b Guido Trotter
                                 qa_config.get(constants.BE_MINMEM),
51 8ccbbe4b Guido Trotter
                                 constants.BE_MAXMEM,
52 8ccbbe4b Guido Trotter
                                 qa_config.get(constants.BE_MAXMEM)))
53 59c75517 Michael Hanselmann
54 59c75517 Michael Hanselmann
  if disk_template != constants.DT_DISKLESS:
55 59c75517 Michael Hanselmann
    for idx, size in enumerate(qa_config.get("disk")):
56 59c75517 Michael Hanselmann
      params.extend(["--disk", "%s:size=%s" % (idx, size)])
57 f346a7d9 Michael Hanselmann
58 f346a7d9 Michael Hanselmann
  # Set static MAC address if configured
59 1c573fb4 Iustin Pop
  if force_mac:
60 1c573fb4 Iustin Pop
    nic0_mac = force_mac
61 1c573fb4 Iustin Pop
  else:
62 0afce24e Michael Hanselmann
    nic0_mac = inst.GetNicMacAddr(0, None)
63 0afce24e Michael Hanselmann
64 f346a7d9 Michael Hanselmann
  if nic0_mac:
65 f346a7d9 Michael Hanselmann
    params.extend(["--net", "0:mac=%s" % nic0_mac])
66 f346a7d9 Michael Hanselmann
67 1d693311 Michael Hanselmann
  return params
68 5d640672 Michael Hanselmann
69 5d640672 Michael Hanselmann
70 fa84c8a4 Bernardo Dal Seno
def _DiskTest(node, disk_template, fail=False):
71 cec9845c Michael Hanselmann
  instance = qa_config.AcquireInstance()
72 cec9845c Michael Hanselmann
  try:
73 d0c8c01d Iustin Pop
    cmd = (["gnt-instance", "add",
74 d0c8c01d Iustin Pop
            "--os-type=%s" % qa_config.get("os"),
75 d0c8c01d Iustin Pop
            "--disk-template=%s" % disk_template,
76 d0c8c01d Iustin Pop
            "--node=%s" % node] +
77 59c75517 Michael Hanselmann
           _GetGenericAddParameters(instance, disk_template))
78 b5f33afa Michael Hanselmann
    cmd.append(instance.name)
79 cec9845c Michael Hanselmann
80 fa84c8a4 Bernardo Dal Seno
    AssertCommand(cmd, fail=fail)
81 6a343475 Michael Hanselmann
82 fa84c8a4 Bernardo Dal Seno
    if not fail:
83 46d21495 Bernardo Dal Seno
      _CheckSsconfInstanceList(instance.name)
84 46d21495 Bernardo Dal Seno
      instance.SetDiskTemplate(disk_template)
85 6a343475 Michael Hanselmann
86 fa84c8a4 Bernardo Dal Seno
      return instance
87 cec9845c Michael Hanselmann
  except:
88 6f88e076 Michael Hanselmann
    instance.Release()
89 cec9845c Michael Hanselmann
    raise
90 cec9845c Michael Hanselmann
91 fa84c8a4 Bernardo Dal Seno
  # Handle the case where creation is expected to fail
92 fa84c8a4 Bernardo Dal Seno
  assert fail
93 46d21495 Bernardo Dal Seno
  instance.Release()
94 fa84c8a4 Bernardo Dal Seno
  return None
95 fa84c8a4 Bernardo Dal Seno
96 cec9845c Michael Hanselmann
97 cc4b14f0 Bernardo Dal Seno
def _GetInstanceInfo(instance):
98 cc4b14f0 Bernardo Dal Seno
  """Return information about the actual state of an instance.
99 82d2f3df Bernardo Dal Seno

100 b07afbb3 Iustin Pop
  @type instance: string
101 b07afbb3 Iustin Pop
  @param instance: the instance name
102 f006f110 Bernardo Dal Seno
  @return: a dictionary with the following keys:
103 b07afbb3 Iustin Pop
      - "nodes": instance nodes, a list of strings
104 b07afbb3 Iustin Pop
      - "volumes": instance volume IDs, a list of strings
105 f006f110 Bernardo Dal Seno
      - "drbd-minors": DRBD minors used by the instance, a dictionary where
106 f006f110 Bernardo Dal Seno
        keys are nodes, and values are lists of integers (or an empty
107 f006f110 Bernardo Dal Seno
        dictionary for non-DRBD instances)
108 1012ecf4 Guido Trotter
      - "disk-template": instance disk template
109 1012ecf4 Guido Trotter
      - "storage-type": storage type associated with the instance disk template
110 82d2f3df Bernardo Dal Seno

111 82d2f3df Bernardo Dal Seno
  """
112 82d2f3df Bernardo Dal Seno
  node_elem = r"([^,()]+)(?:\s+\([^)]+\))?"
113 82d2f3df Bernardo Dal Seno
  # re_nodelist matches a list of nodes returned by gnt-instance info, e.g.:
114 82d2f3df Bernardo Dal Seno
  #  node1.fqdn
115 82d2f3df Bernardo Dal Seno
  #  node2.fqdn,node3.fqdn
116 82d2f3df Bernardo Dal Seno
  #  node4.fqdn (group mygroup, group UUID 01234567-abcd-0123-4567-0123456789ab)
117 82d2f3df Bernardo Dal Seno
  # FIXME This works with no more than 2 secondaries
118 82d2f3df Bernardo Dal Seno
  re_nodelist = re.compile(node_elem + "(?:," + node_elem + ")?$")
119 2cbcf95d Bernardo Dal Seno
120 2cbcf95d Bernardo Dal Seno
  info = qa_utils.GetObjectInfo(["gnt-instance", "info", instance])[0]
121 82d2f3df Bernardo Dal Seno
  nodes = []
122 2cbcf95d Bernardo Dal Seno
  for nodeinfo in info["Nodes"]:
123 2cbcf95d Bernardo Dal Seno
    if "primary" in nodeinfo:
124 2cbcf95d Bernardo Dal Seno
      nodes.append(nodeinfo["primary"])
125 2cbcf95d Bernardo Dal Seno
    elif "secondaries" in nodeinfo:
126 2cbcf95d Bernardo Dal Seno
      nodestr = nodeinfo["secondaries"]
127 2cbcf95d Bernardo Dal Seno
      if nodestr:
128 2cbcf95d Bernardo Dal Seno
        m = re_nodelist.match(nodestr)
129 2cbcf95d Bernardo Dal Seno
        if m:
130 2cbcf95d Bernardo Dal Seno
          nodes.extend(filter(None, m.groups()))
131 2cbcf95d Bernardo Dal Seno
        else:
132 2cbcf95d Bernardo Dal Seno
          nodes.append(nodestr)
133 2cbcf95d Bernardo Dal Seno
134 1012ecf4 Guido Trotter
  disk_template = info["Disk template"]
135 1012ecf4 Guido Trotter
  if not disk_template:
136 1012ecf4 Guido Trotter
    raise qa_error.Error("Can't get instance disk template")
137 1012ecf4 Guido Trotter
  storage_type = constants.DISK_TEMPLATES_STORAGE_TYPE[disk_template]
138 1012ecf4 Guido Trotter
139 2cbcf95d Bernardo Dal Seno
  re_drbdnode = re.compile(r"^([^\s,]+),\s+minor=([0-9]+)$")
140 82d2f3df Bernardo Dal Seno
  vols = []
141 f006f110 Bernardo Dal Seno
  drbd_min = {}
142 2cbcf95d Bernardo Dal Seno
  for (count, diskinfo) in enumerate(info["Disks"]):
143 2cbcf95d Bernardo Dal Seno
    (dtype, _) = diskinfo["disk/%s" % count].split(",", 1)
144 2cbcf95d Bernardo Dal Seno
    if dtype == constants.LD_DRBD8:
145 2cbcf95d Bernardo Dal Seno
      for child in diskinfo["child devices"]:
146 2cbcf95d Bernardo Dal Seno
        vols.append(child["logical_id"])
147 2cbcf95d Bernardo Dal Seno
      for key in ["nodeA", "nodeB"]:
148 2cbcf95d Bernardo Dal Seno
        m = re_drbdnode.match(diskinfo[key])
149 2cbcf95d Bernardo Dal Seno
        if not m:
150 2cbcf95d Bernardo Dal Seno
          raise qa_error.Error("Cannot parse DRBD info: %s" % diskinfo[key])
151 2cbcf95d Bernardo Dal Seno
        node = m.group(1)
152 2cbcf95d Bernardo Dal Seno
        minor = int(m.group(2))
153 2cbcf95d Bernardo Dal Seno
        minorlist = drbd_min.setdefault(node, [])
154 2cbcf95d Bernardo Dal Seno
        minorlist.append(minor)
155 2cbcf95d Bernardo Dal Seno
    elif dtype == constants.LD_LV:
156 2cbcf95d Bernardo Dal Seno
      vols.append(diskinfo["logical_id"])
157 b296c810 Michael Hanselmann
158 82d2f3df Bernardo Dal Seno
  assert nodes
159 b296c810 Michael Hanselmann
  assert len(nodes) < 2 or vols
160 1a6db3df Michael Hanselmann
  return {
161 1a6db3df Michael Hanselmann
    "nodes": nodes,
162 1a6db3df Michael Hanselmann
    "volumes": vols,
163 1a6db3df Michael Hanselmann
    "drbd-minors": drbd_min,
164 1012ecf4 Guido Trotter
    "disk-template": disk_template,
165 1012ecf4 Guido Trotter
    "storage-type": storage_type,
166 1a6db3df Michael Hanselmann
    }
167 cc4b14f0 Bernardo Dal Seno
168 cc4b14f0 Bernardo Dal Seno
169 cc2a70b1 Guido Trotter
def _DestroyInstanceDisks(instance):
170 cc2a70b1 Guido Trotter
  """Remove all the backend disks of an instance.
171 cc4b14f0 Bernardo Dal Seno

172 cc4b14f0 Bernardo Dal Seno
  This is used to simulate HW errors (dead nodes, broken disks...); the
173 cc4b14f0 Bernardo Dal Seno
  configuration of the instance is not affected.
174 cc4b14f0 Bernardo Dal Seno
  @type instance: dictionary
175 cc4b14f0 Bernardo Dal Seno
  @param instance: the instance
176 cc4b14f0 Bernardo Dal Seno

177 cc4b14f0 Bernardo Dal Seno
  """
178 b5f33afa Michael Hanselmann
  info = _GetInstanceInfo(instance.name)
179 cc2a70b1 Guido Trotter
  # FIXME: destruction/removal should be part of the disk class
180 cc2a70b1 Guido Trotter
  if info["storage-type"] == constants.ST_LVM_VG:
181 cc2a70b1 Guido Trotter
    vols = info["volumes"]
182 cc2a70b1 Guido Trotter
    for node in info["nodes"]:
183 cc2a70b1 Guido Trotter
      AssertCommand(["lvremove", "-f"] + vols, node=node)
184 cc2a70b1 Guido Trotter
  elif info["storage-type"] == constants.ST_FILE:
185 cc2a70b1 Guido Trotter
    # FIXME: file storage dir not configurable in qa
186 cc2a70b1 Guido Trotter
    # Note that this works for both file and sharedfile, and this is intended.
187 cc2a70b1 Guido Trotter
    filestorage = pathutils.DEFAULT_FILE_STORAGE_DIR
188 cc2a70b1 Guido Trotter
    idir = os.path.join(filestorage, instance.name)
189 cc2a70b1 Guido Trotter
    for node in info["nodes"]:
190 b0b7bf8f Guido Trotter
      AssertCommand(["rm", "-rf", idir], node=node)
191 cc2a70b1 Guido Trotter
  elif info["storage-type"] == constants.ST_DISKLESS:
192 cc2a70b1 Guido Trotter
    pass
193 82d2f3df Bernardo Dal Seno
194 82d2f3df Bernardo Dal Seno
195 ab4832d1 Bernardo Dal Seno
def _GetInstanceField(instance, field):
196 ab4832d1 Bernardo Dal Seno
  """Get the value of a field of an instance.
197 d55408b0 Bernardo Dal Seno

198 d55408b0 Bernardo Dal Seno
  @type instance: string
199 d55408b0 Bernardo Dal Seno
  @param instance: Instance name
200 d55408b0 Bernardo Dal Seno
  @type field: string
201 d55408b0 Bernardo Dal Seno
  @param field: Name of the field
202 ab4832d1 Bernardo Dal Seno
  @rtype: string
203 d55408b0 Bernardo Dal Seno

204 d55408b0 Bernardo Dal Seno
  """
205 d55408b0 Bernardo Dal Seno
  master = qa_config.GetMasterNode()
206 d55408b0 Bernardo Dal Seno
  infocmd = utils.ShellQuoteArgs(["gnt-instance", "list", "--no-headers",
207 ab4832d1 Bernardo Dal Seno
                                  "--units", "m", "-o", field, instance])
208 46d21495 Bernardo Dal Seno
  return qa_utils.GetCommandOutput(master.primary, infocmd).strip()
209 ab4832d1 Bernardo Dal Seno
210 ab4832d1 Bernardo Dal Seno
211 ab4832d1 Bernardo Dal Seno
def _GetBoolInstanceField(instance, field):
212 ab4832d1 Bernardo Dal Seno
  """Get the Boolean value of a field of an instance.
213 ab4832d1 Bernardo Dal Seno

214 ab4832d1 Bernardo Dal Seno
  @type instance: string
215 ab4832d1 Bernardo Dal Seno
  @param instance: Instance name
216 ab4832d1 Bernardo Dal Seno
  @type field: string
217 ab4832d1 Bernardo Dal Seno
  @param field: Name of the field
218 ab4832d1 Bernardo Dal Seno
  @rtype: bool
219 ab4832d1 Bernardo Dal Seno

220 ab4832d1 Bernardo Dal Seno
  """
221 ab4832d1 Bernardo Dal Seno
  info_out = _GetInstanceField(instance, field)
222 d55408b0 Bernardo Dal Seno
  if info_out == "Y":
223 d55408b0 Bernardo Dal Seno
    return True
224 d55408b0 Bernardo Dal Seno
  elif info_out == "N":
225 d55408b0 Bernardo Dal Seno
    return False
226 d55408b0 Bernardo Dal Seno
  else:
227 d55408b0 Bernardo Dal Seno
    raise qa_error.Error("Field %s of instance %s has a non-Boolean value:"
228 d55408b0 Bernardo Dal Seno
                         " %s" % (field, instance, info_out))
229 d55408b0 Bernardo Dal Seno
230 d55408b0 Bernardo Dal Seno
231 ab4832d1 Bernardo Dal Seno
def _GetNumInstanceField(instance, field):
232 ab4832d1 Bernardo Dal Seno
  """Get a numeric value of a field of an instance.
233 ab4832d1 Bernardo Dal Seno

234 ab4832d1 Bernardo Dal Seno
  @type instance: string
235 ab4832d1 Bernardo Dal Seno
  @param instance: Instance name
236 ab4832d1 Bernardo Dal Seno
  @type field: string
237 ab4832d1 Bernardo Dal Seno
  @param field: Name of the field
238 ab4832d1 Bernardo Dal Seno
  @rtype: int or float
239 ab4832d1 Bernardo Dal Seno

240 ab4832d1 Bernardo Dal Seno
  """
241 ab4832d1 Bernardo Dal Seno
  info_out = _GetInstanceField(instance, field)
242 ab4832d1 Bernardo Dal Seno
  try:
243 ab4832d1 Bernardo Dal Seno
    ret = int(info_out)
244 ab4832d1 Bernardo Dal Seno
  except ValueError:
245 ab4832d1 Bernardo Dal Seno
    try:
246 ab4832d1 Bernardo Dal Seno
      ret = float(info_out)
247 ab4832d1 Bernardo Dal Seno
    except ValueError:
248 ab4832d1 Bernardo Dal Seno
      raise qa_error.Error("Field %s of instance %s has a non-numeric value:"
249 ab4832d1 Bernardo Dal Seno
                           " %s" % (field, instance, info_out))
250 ab4832d1 Bernardo Dal Seno
  return ret
251 ab4832d1 Bernardo Dal Seno
252 ab4832d1 Bernardo Dal Seno
253 ab4832d1 Bernardo Dal Seno
def GetInstanceSpec(instance, spec):
254 ab4832d1 Bernardo Dal Seno
  """Return the current spec for the given parameter.
255 ab4832d1 Bernardo Dal Seno

256 ab4832d1 Bernardo Dal Seno
  @type instance: string
257 ab4832d1 Bernardo Dal Seno
  @param instance: Instance name
258 ab4832d1 Bernardo Dal Seno
  @type spec: string
259 ab4832d1 Bernardo Dal Seno
  @param spec: one of the supported parameters: "mem-size", "cpu-count",
260 ab4832d1 Bernardo Dal Seno
      "disk-count", "disk-size", "nic-count"
261 ab4832d1 Bernardo Dal Seno
  @rtype: tuple
262 ab4832d1 Bernardo Dal Seno
  @return: (minspec, maxspec); minspec and maxspec can be different only for
263 ab4832d1 Bernardo Dal Seno
      memory and disk size
264 ab4832d1 Bernardo Dal Seno

265 ab4832d1 Bernardo Dal Seno
  """
266 ab4832d1 Bernardo Dal Seno
  specmap = {
267 ab4832d1 Bernardo Dal Seno
    "mem-size": ["be/minmem", "be/maxmem"],
268 ab4832d1 Bernardo Dal Seno
    "cpu-count": ["vcpus"],
269 ab4832d1 Bernardo Dal Seno
    "disk-count": ["disk.count"],
270 ab4832d1 Bernardo Dal Seno
    "disk-size": ["disk.size/ "],
271 ab4832d1 Bernardo Dal Seno
    "nic-count": ["nic.count"],
272 ab4832d1 Bernardo Dal Seno
    }
273 ab4832d1 Bernardo Dal Seno
  # For disks, first we need the number of disks
274 ab4832d1 Bernardo Dal Seno
  if spec == "disk-size":
275 ab4832d1 Bernardo Dal Seno
    (numdisk, _) = GetInstanceSpec(instance, "disk-count")
276 ab4832d1 Bernardo Dal Seno
    fields = ["disk.size/%s" % k for k in range(0, numdisk)]
277 ab4832d1 Bernardo Dal Seno
  else:
278 ab4832d1 Bernardo Dal Seno
    assert spec in specmap, "%s not in %s" % (spec, specmap)
279 ab4832d1 Bernardo Dal Seno
    fields = specmap[spec]
280 ab4832d1 Bernardo Dal Seno
  values = [_GetNumInstanceField(instance, f) for f in fields]
281 ab4832d1 Bernardo Dal Seno
  return (min(values), max(values))
282 ab4832d1 Bernardo Dal Seno
283 ab4832d1 Bernardo Dal Seno
284 5de31440 Bernardo Dal Seno
def IsFailoverSupported(instance):
285 02a5fe0e Michael Hanselmann
  return instance.disk_template in constants.DTS_MIRRORED
286 5de31440 Bernardo Dal Seno
287 5de31440 Bernardo Dal Seno
288 5de31440 Bernardo Dal Seno
def IsMigrationSupported(instance):
289 02a5fe0e Michael Hanselmann
  return instance.disk_template in constants.DTS_MIRRORED
290 5de31440 Bernardo Dal Seno
291 5de31440 Bernardo Dal Seno
292 5de31440 Bernardo Dal Seno
def IsDiskReplacingSupported(instance):
293 02a5fe0e Michael Hanselmann
  return instance.disk_template == constants.DT_DRBD8
294 5de31440 Bernardo Dal Seno
295 5de31440 Bernardo Dal Seno
296 fa84c8a4 Bernardo Dal Seno
def TestInstanceAddWithPlainDisk(nodes, fail=False):
297 cec9845c Michael Hanselmann
  """gnt-instance add -t plain"""
298 c99200a3 Bernardo Dal Seno
  assert len(nodes) == 1
299 46d21495 Bernardo Dal Seno
  instance = _DiskTest(nodes[0].primary, constants.DT_PLAIN, fail=fail)
300 fa84c8a4 Bernardo Dal Seno
  if not fail:
301 fa84c8a4 Bernardo Dal Seno
    qa_utils.RunInstanceCheck(instance, True)
302 fa84c8a4 Bernardo Dal Seno
  return instance
303 cec9845c Michael Hanselmann
304 cec9845c Michael Hanselmann
305 5fa0375e Michael Hanselmann
@InstanceCheck(None, INST_UP, RETURN_VALUE)
306 c99200a3 Bernardo Dal Seno
def TestInstanceAddWithDrbdDisk(nodes):
307 7d7609a3 Michael Hanselmann
  """gnt-instance add -t drbd"""
308 c99200a3 Bernardo Dal Seno
  assert len(nodes) == 2
309 aecba21e Michael Hanselmann
  return _DiskTest(":".join(map(operator.attrgetter("primary"), nodes)),
310 68c8c3df Michael Hanselmann
                   constants.DT_DRBD8)
311 7d7609a3 Michael Hanselmann
312 7d7609a3 Michael Hanselmann
313 59c75517 Michael Hanselmann
@InstanceCheck(None, INST_UP, RETURN_VALUE)
314 6970c89c Klaus Aehlig
def TestInstanceAddFile(nodes):
315 6970c89c Klaus Aehlig
  """gnt-instance add -t file"""
316 6970c89c Klaus Aehlig
  assert len(nodes) == 1
317 6970c89c Klaus Aehlig
  return _DiskTest(nodes[0].primary, constants.DT_FILE)
318 6970c89c Klaus Aehlig
319 6970c89c Klaus Aehlig
320 6970c89c Klaus Aehlig
@InstanceCheck(None, INST_UP, RETURN_VALUE)
321 59c75517 Michael Hanselmann
def TestInstanceAddDiskless(nodes):
322 59c75517 Michael Hanselmann
  """gnt-instance add -t diskless"""
323 59c75517 Michael Hanselmann
  assert len(nodes) == 1
324 59c75517 Michael Hanselmann
  return _DiskTest(nodes[0].primary, constants.DT_DISKLESS)
325 59c75517 Michael Hanselmann
326 59c75517 Michael Hanselmann
327 5fa0375e Michael Hanselmann
@InstanceCheck(None, INST_DOWN, FIRST_ARG)
328 cec9845c Michael Hanselmann
def TestInstanceRemove(instance):
329 cec9845c Michael Hanselmann
  """gnt-instance remove"""
330 b5f33afa Michael Hanselmann
  AssertCommand(["gnt-instance", "remove", "-f", instance.name])
331 cec9845c Michael Hanselmann
332 cec9845c Michael Hanselmann
333 5fa0375e Michael Hanselmann
@InstanceCheck(INST_DOWN, INST_UP, FIRST_ARG)
334 cec9845c Michael Hanselmann
def TestInstanceStartup(instance):
335 cec9845c Michael Hanselmann
  """gnt-instance startup"""
336 b5f33afa Michael Hanselmann
  AssertCommand(["gnt-instance", "startup", instance.name])
337 cec9845c Michael Hanselmann
338 cec9845c Michael Hanselmann
339 5fa0375e Michael Hanselmann
@InstanceCheck(INST_UP, INST_DOWN, FIRST_ARG)
340 cec9845c Michael Hanselmann
def TestInstanceShutdown(instance):
341 cec9845c Michael Hanselmann
  """gnt-instance shutdown"""
342 b5f33afa Michael Hanselmann
  AssertCommand(["gnt-instance", "shutdown", instance.name])
343 cec9845c Michael Hanselmann
344 cec9845c Michael Hanselmann
345 5fa0375e Michael Hanselmann
@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
346 8a4e8898 Michael Hanselmann
def TestInstanceReboot(instance):
347 8a4e8898 Michael Hanselmann
  """gnt-instance reboot"""
348 d0c8c01d Iustin Pop
  options = qa_config.get("options", {})
349 1d103c02 Iustin Pop
  reboot_types = options.get("reboot-types", constants.REBOOT_TYPES)
350 b5f33afa Michael Hanselmann
  name = instance.name
351 1d103c02 Iustin Pop
  for rtype in reboot_types:
352 2f4b4f78 Iustin Pop
    AssertCommand(["gnt-instance", "reboot", "--type=%s" % rtype, name])
353 8a4e8898 Michael Hanselmann
354 cc27265e René Nussbaumer
  AssertCommand(["gnt-instance", "shutdown", name])
355 5fa0375e Michael Hanselmann
  qa_utils.RunInstanceCheck(instance, False)
356 cc27265e René Nussbaumer
  AssertCommand(["gnt-instance", "reboot", name])
357 cc27265e René Nussbaumer
358 cc27265e René Nussbaumer
  master = qa_config.GetMasterNode()
359 58ea8d17 Michael Hanselmann
  cmd = ["gnt-instance", "list", "--no-headers", "-o", "status", name]
360 aecba21e Michael Hanselmann
  result_output = qa_utils.GetCommandOutput(master.primary,
361 cc27265e René Nussbaumer
                                            utils.ShellQuoteArgs(cmd))
362 cc27265e René Nussbaumer
  AssertEqual(result_output.strip(), constants.INSTST_RUNNING)
363 cc27265e René Nussbaumer
364 8a4e8898 Michael Hanselmann
365 5fa0375e Michael Hanselmann
@InstanceCheck(INST_DOWN, INST_DOWN, FIRST_ARG)
366 283f9d4c Michael Hanselmann
def TestInstanceReinstall(instance):
367 283f9d4c Michael Hanselmann
  """gnt-instance reinstall"""
368 a90636b2 Michael Hanselmann
  if instance.disk_template == constants.DT_DISKLESS:
369 a90636b2 Michael Hanselmann
    print qa_utils.FormatInfo("Test not supported for diskless instances")
370 a90636b2 Michael Hanselmann
    return
371 a90636b2 Michael Hanselmann
372 b5f33afa Michael Hanselmann
  AssertCommand(["gnt-instance", "reinstall", "-f", instance.name])
373 283f9d4c Michael Hanselmann
374 64be07b1 Michael Hanselmann
  # Test with non-existant OS definition
375 64be07b1 Michael Hanselmann
  AssertCommand(["gnt-instance", "reinstall", "-f",
376 64be07b1 Michael Hanselmann
                 "--os-type=NonExistantOsForQa",
377 b5f33afa Michael Hanselmann
                 instance.name],
378 64be07b1 Michael Hanselmann
                fail=True)
379 64be07b1 Michael Hanselmann
380 283f9d4c Michael Hanselmann
381 6a343475 Michael Hanselmann
def _ReadSsconfInstanceList():
382 6a343475 Michael Hanselmann
  """Reads ssconf_instance_list from the master node.
383 6a343475 Michael Hanselmann

384 6a343475 Michael Hanselmann
  """
385 6a343475 Michael Hanselmann
  master = qa_config.GetMasterNode()
386 6a343475 Michael Hanselmann
387 e35c341e Michael Hanselmann
  ssconf_path = utils.PathJoin(pathutils.DATA_DIR,
388 e35c341e Michael Hanselmann
                               "ssconf_%s" % constants.SS_INSTANCE_LIST)
389 e35c341e Michael Hanselmann
390 e35c341e Michael Hanselmann
  cmd = ["cat", qa_utils.MakeNodePath(master, ssconf_path)]
391 6a343475 Michael Hanselmann
392 aecba21e Michael Hanselmann
  return qa_utils.GetCommandOutput(master.primary,
393 6a343475 Michael Hanselmann
                                   utils.ShellQuoteArgs(cmd)).splitlines()
394 6a343475 Michael Hanselmann
395 6a343475 Michael Hanselmann
396 6a343475 Michael Hanselmann
def _CheckSsconfInstanceList(instance):
397 6a343475 Michael Hanselmann
  """Checks if a certain instance is in the ssconf instance list.
398 6a343475 Michael Hanselmann

399 6a343475 Michael Hanselmann
  @type instance: string
400 6a343475 Michael Hanselmann
  @param instance: Instance name
401 6a343475 Michael Hanselmann

402 6a343475 Michael Hanselmann
  """
403 6a343475 Michael Hanselmann
  AssertIn(qa_utils.ResolveInstanceName(instance),
404 6a343475 Michael Hanselmann
           _ReadSsconfInstanceList())
405 6a343475 Michael Hanselmann
406 6a343475 Michael Hanselmann
407 51131cad Michael Hanselmann
@InstanceCheck(INST_DOWN, INST_DOWN, FIRST_ARG)
408 4c1a464b Iustin Pop
def TestInstanceRenameAndBack(rename_source, rename_target):
409 4c1a464b Iustin Pop
  """gnt-instance rename
410 4c1a464b Iustin Pop

411 4c1a464b Iustin Pop
  This must leave the instance with the original name, not the target
412 4c1a464b Iustin Pop
  name.
413 4c1a464b Iustin Pop

414 4c1a464b Iustin Pop
  """
415 31fe5102 René Nussbaumer
  _CheckSsconfInstanceList(rename_source)
416 5fa0375e Michael Hanselmann
417 4c1a464b Iustin Pop
  # first do a rename to a different actual name, expecting it to fail
418 31fe5102 René Nussbaumer
  qa_utils.AddToEtcHosts(["meeeeh-not-exists", rename_target])
419 31fe5102 René Nussbaumer
  try:
420 31fe5102 René Nussbaumer
    AssertCommand(["gnt-instance", "rename", rename_source, rename_target],
421 31fe5102 René Nussbaumer
                  fail=True)
422 31fe5102 René Nussbaumer
    _CheckSsconfInstanceList(rename_source)
423 31fe5102 René Nussbaumer
  finally:
424 31fe5102 René Nussbaumer
    qa_utils.RemoveFromEtcHosts(["meeeeh-not-exists", rename_target])
425 5fa0375e Michael Hanselmann
426 b07afbb3 Iustin Pop
  info = _GetInstanceInfo(rename_source)
427 1012ecf4 Guido Trotter
428 1012ecf4 Guido Trotter
  # Check instance volume tags correctly updated. Note that this check is lvm
429 1012ecf4 Guido Trotter
  # specific, so we skip it for non-lvm-based instances.
430 1012ecf4 Guido Trotter
  # FIXME: This will need updating when instances will be able to have
431 1012ecf4 Guido Trotter
  # different disks living on storage pools with etherogeneous storage types.
432 1012ecf4 Guido Trotter
  # FIXME: This check should be put inside the disk/storage class themselves,
433 1012ecf4 Guido Trotter
  # rather than explicitly called here.
434 1012ecf4 Guido Trotter
  if info["storage-type"] == constants.ST_LVM_VG:
435 1012ecf4 Guido Trotter
    # In the lvm world we can check for tags on the logical volume
436 1012ecf4 Guido Trotter
    tags_cmd = ("lvs -o tags --noheadings %s | grep " %
437 1012ecf4 Guido Trotter
                (" ".join(info["volumes"]), ))
438 1012ecf4 Guido Trotter
  else:
439 1012ecf4 Guido Trotter
    # Other storage types don't have tags, so we use an always failing command,
440 1012ecf4 Guido Trotter
    # to make sure it never gets executed
441 1012ecf4 Guido Trotter
    tags_cmd = "false"
442 b07afbb3 Iustin Pop
443 4c1a464b Iustin Pop
  # and now rename instance to rename_target...
444 31fe5102 René Nussbaumer
  AssertCommand(["gnt-instance", "rename", rename_source, rename_target])
445 31fe5102 René Nussbaumer
  _CheckSsconfInstanceList(rename_target)
446 5fa0375e Michael Hanselmann
  qa_utils.RunInstanceCheck(rename_source, False)
447 51131cad Michael Hanselmann
  qa_utils.RunInstanceCheck(rename_target, False)
448 5fa0375e Michael Hanselmann
449 b07afbb3 Iustin Pop
  # NOTE: tags might not be the exactly as the instance name, due to
450 b07afbb3 Iustin Pop
  # charset restrictions; hence the test might be flaky
451 1012ecf4 Guido Trotter
  if (rename_source != rename_target and
452 1012ecf4 Guido Trotter
      info["storage-type"] == constants.ST_LVM_VG):
453 b07afbb3 Iustin Pop
    for node in info["nodes"]:
454 b07afbb3 Iustin Pop
      AssertCommand(tags_cmd + rename_source, node=node, fail=True)
455 b07afbb3 Iustin Pop
      AssertCommand(tags_cmd + rename_target, node=node, fail=False)
456 b07afbb3 Iustin Pop
457 4c1a464b Iustin Pop
  # and back
458 4c1a464b Iustin Pop
  AssertCommand(["gnt-instance", "rename", rename_target, rename_source])
459 4c1a464b Iustin Pop
  _CheckSsconfInstanceList(rename_source)
460 5fa0375e Michael Hanselmann
  qa_utils.RunInstanceCheck(rename_target, False)
461 18337ca9 Iustin Pop
462 1012ecf4 Guido Trotter
  if (rename_source != rename_target and
463 1012ecf4 Guido Trotter
      info["storage-type"] == constants.ST_LVM_VG):
464 b07afbb3 Iustin Pop
    for node in info["nodes"]:
465 b07afbb3 Iustin Pop
      AssertCommand(tags_cmd + rename_source, node=node, fail=False)
466 b07afbb3 Iustin Pop
      AssertCommand(tags_cmd + rename_target, node=node, fail=True)
467 b07afbb3 Iustin Pop
468 18337ca9 Iustin Pop
469 5fa0375e Michael Hanselmann
@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
470 cec9845c Michael Hanselmann
def TestInstanceFailover(instance):
471 cec9845c Michael Hanselmann
  """gnt-instance failover"""
472 5de31440 Bernardo Dal Seno
  if not IsFailoverSupported(instance):
473 5de31440 Bernardo Dal Seno
    print qa_utils.FormatInfo("Instance doesn't support failover, skipping"
474 5de31440 Bernardo Dal Seno
                              " test")
475 5de31440 Bernardo Dal Seno
    return
476 5de31440 Bernardo Dal Seno
477 b5f33afa Michael Hanselmann
  cmd = ["gnt-instance", "failover", "--force", instance.name]
478 5fa0375e Michael Hanselmann
479 2f4b4f78 Iustin Pop
  # failover ...
480 2f4b4f78 Iustin Pop
  AssertCommand(cmd)
481 5fa0375e Michael Hanselmann
  qa_utils.RunInstanceCheck(instance, True)
482 5fa0375e Michael Hanselmann
483 76f59a32 Michael Hanselmann
  # ... and back
484 2f4b4f78 Iustin Pop
  AssertCommand(cmd)
485 76f59a32 Michael Hanselmann
486 cec9845c Michael Hanselmann
487 5fa0375e Michael Hanselmann
@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
488 d55408b0 Bernardo Dal Seno
def TestInstanceMigrate(instance, toggle_always_failover=True):
489 938bde86 Michael Hanselmann
  """gnt-instance migrate"""
490 5de31440 Bernardo Dal Seno
  if not IsMigrationSupported(instance):
491 5de31440 Bernardo Dal Seno
    print qa_utils.FormatInfo("Instance doesn't support migration, skipping"
492 5de31440 Bernardo Dal Seno
                              " test")
493 5de31440 Bernardo Dal Seno
    return
494 5de31440 Bernardo Dal Seno
495 b5f33afa Michael Hanselmann
  cmd = ["gnt-instance", "migrate", "--force", instance.name]
496 d55408b0 Bernardo Dal Seno
  af_par = constants.BE_ALWAYS_FAILOVER
497 d55408b0 Bernardo Dal Seno
  af_field = "be/" + constants.BE_ALWAYS_FAILOVER
498 b5f33afa Michael Hanselmann
  af_init_val = _GetBoolInstanceField(instance.name, af_field)
499 5fa0375e Michael Hanselmann
500 2f4b4f78 Iustin Pop
  # migrate ...
501 2f4b4f78 Iustin Pop
  AssertCommand(cmd)
502 d55408b0 Bernardo Dal Seno
  # TODO: Verify the choice between failover and migration
503 5fa0375e Michael Hanselmann
  qa_utils.RunInstanceCheck(instance, True)
504 5fa0375e Michael Hanselmann
505 d55408b0 Bernardo Dal Seno
  # ... and back (possibly with always_failover toggled)
506 d55408b0 Bernardo Dal Seno
  if toggle_always_failover:
507 d55408b0 Bernardo Dal Seno
    AssertCommand(["gnt-instance", "modify", "-B",
508 d55408b0 Bernardo Dal Seno
                   ("%s=%s" % (af_par, not af_init_val)),
509 b5f33afa Michael Hanselmann
                   instance.name])
510 2f4b4f78 Iustin Pop
  AssertCommand(cmd)
511 d55408b0 Bernardo Dal Seno
  # TODO: Verify the choice between failover and migration
512 d55408b0 Bernardo Dal Seno
  qa_utils.RunInstanceCheck(instance, True)
513 d55408b0 Bernardo Dal Seno
  if toggle_always_failover:
514 d55408b0 Bernardo Dal Seno
    AssertCommand(["gnt-instance", "modify", "-B",
515 b5f33afa Michael Hanselmann
                   ("%s=%s" % (af_par, af_init_val)), instance.name])
516 5fa0375e Michael Hanselmann
517 5fa0375e Michael Hanselmann
  # TODO: Split into multiple tests
518 b5f33afa Michael Hanselmann
  AssertCommand(["gnt-instance", "shutdown", instance.name])
519 5fa0375e Michael Hanselmann
  qa_utils.RunInstanceCheck(instance, False)
520 e9c487be René Nussbaumer
  AssertCommand(cmd, fail=True)
521 e9c487be René Nussbaumer
  AssertCommand(["gnt-instance", "migrate", "--force", "--allow-failover",
522 b5f33afa Michael Hanselmann
                 instance.name])
523 b5f33afa Michael Hanselmann
  AssertCommand(["gnt-instance", "start", instance.name])
524 e9c487be René Nussbaumer
  AssertCommand(cmd)
525 d55408b0 Bernardo Dal Seno
  # @InstanceCheck enforces the check that the instance is running
526 5fa0375e Michael Hanselmann
  qa_utils.RunInstanceCheck(instance, True)
527 5fa0375e Michael Hanselmann
528 42a769f9 Bernardo Dal Seno
  AssertCommand(["gnt-instance", "modify", "-B",
529 42a769f9 Bernardo Dal Seno
                 ("%s=%s" %
530 42a769f9 Bernardo Dal Seno
                  (constants.BE_ALWAYS_FAILOVER, constants.VALUE_TRUE)),
531 b5f33afa Michael Hanselmann
                 instance.name])
532 5fa0375e Michael Hanselmann
533 320a5dae Bernardo Dal Seno
  AssertCommand(cmd)
534 5fa0375e Michael Hanselmann
  qa_utils.RunInstanceCheck(instance, True)
535 320a5dae Bernardo Dal Seno
  # TODO: Verify that a failover has been done instead of a migration
536 5fa0375e Michael Hanselmann
537 5fa0375e Michael Hanselmann
  # TODO: Verify whether the default value is restored here (not hardcoded)
538 42a769f9 Bernardo Dal Seno
  AssertCommand(["gnt-instance", "modify", "-B",
539 42a769f9 Bernardo Dal Seno
                 ("%s=%s" %
540 42a769f9 Bernardo Dal Seno
                  (constants.BE_ALWAYS_FAILOVER, constants.VALUE_FALSE)),
541 b5f33afa Michael Hanselmann
                 instance.name])
542 5fa0375e Michael Hanselmann
543 42a769f9 Bernardo Dal Seno
  AssertCommand(cmd)
544 5fa0375e Michael Hanselmann
  qa_utils.RunInstanceCheck(instance, True)
545 938bde86 Michael Hanselmann
546 938bde86 Michael Hanselmann
547 cec9845c Michael Hanselmann
def TestInstanceInfo(instance):
548 cec9845c Michael Hanselmann
  """gnt-instance info"""
549 b5f33afa Michael Hanselmann
  AssertCommand(["gnt-instance", "info", instance.name])
550 5d640672 Michael Hanselmann
551 5d640672 Michael Hanselmann
552 5fa0375e Michael Hanselmann
@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
553 c0f74c55 Iustin Pop
def TestInstanceModify(instance):
554 c0f74c55 Iustin Pop
  """gnt-instance modify"""
555 d488adb6 Michael Hanselmann
  default_hv = qa_config.GetDefaultHypervisor()
556 d488adb6 Michael Hanselmann
557 1d693311 Michael Hanselmann
  # Assume /sbin/init exists on all systems
558 1d693311 Michael Hanselmann
  test_kernel = "/sbin/init"
559 1d693311 Michael Hanselmann
  test_initrd = test_kernel
560 1d693311 Michael Hanselmann
561 8ccbbe4b Guido Trotter
  orig_maxmem = qa_config.get(constants.BE_MAXMEM)
562 8ccbbe4b Guido Trotter
  orig_minmem = qa_config.get(constants.BE_MINMEM)
563 2f4b4f78 Iustin Pop
  #orig_bridge = qa_config.get("bridge", "xen-br0")
564 d488adb6 Michael Hanselmann
565 c0f74c55 Iustin Pop
  args = [
566 8ccbbe4b Guido Trotter
    ["-B", "%s=128" % constants.BE_MINMEM],
567 8ccbbe4b Guido Trotter
    ["-B", "%s=128" % constants.BE_MAXMEM],
568 8ccbbe4b Guido Trotter
    ["-B", "%s=%s,%s=%s" % (constants.BE_MINMEM, orig_minmem,
569 8ccbbe4b Guido Trotter
                            constants.BE_MAXMEM, orig_maxmem)],
570 1d693311 Michael Hanselmann
    ["-B", "%s=2" % constants.BE_VCPUS],
571 1d693311 Michael Hanselmann
    ["-B", "%s=1" % constants.BE_VCPUS],
572 1d693311 Michael Hanselmann
    ["-B", "%s=%s" % (constants.BE_VCPUS, constants.VALUE_DEFAULT)],
573 42a769f9 Bernardo Dal Seno
    ["-B", "%s=%s" % (constants.BE_ALWAYS_FAILOVER, constants.VALUE_TRUE)],
574 42a769f9 Bernardo Dal Seno
    ["-B", "%s=%s" % (constants.BE_ALWAYS_FAILOVER, constants.VALUE_DEFAULT)],
575 1d693311 Michael Hanselmann
576 1d693311 Michael Hanselmann
    ["-H", "%s=%s" % (constants.HV_KERNEL_PATH, test_kernel)],
577 1d693311 Michael Hanselmann
    ["-H", "%s=%s" % (constants.HV_KERNEL_PATH, constants.VALUE_DEFAULT)],
578 1d693311 Michael Hanselmann
579 1d693311 Michael Hanselmann
    # TODO: bridge tests
580 1d693311 Michael Hanselmann
    #["--bridge", "xen-br1"],
581 1d693311 Michael Hanselmann
    #["--bridge", orig_bridge],
582 c0f74c55 Iustin Pop
    ]
583 d488adb6 Michael Hanselmann
584 d488adb6 Michael Hanselmann
  if default_hv == constants.HT_XEN_PVM:
585 d488adb6 Michael Hanselmann
    args.extend([
586 d488adb6 Michael Hanselmann
      ["-H", "%s=%s" % (constants.HV_INITRD_PATH, test_initrd)],
587 d488adb6 Michael Hanselmann
      ["-H", "no_%s" % (constants.HV_INITRD_PATH, )],
588 d488adb6 Michael Hanselmann
      ["-H", "%s=%s" % (constants.HV_INITRD_PATH, constants.VALUE_DEFAULT)],
589 d488adb6 Michael Hanselmann
      ])
590 d488adb6 Michael Hanselmann
  elif default_hv == constants.HT_XEN_HVM:
591 d488adb6 Michael Hanselmann
    args.extend([
592 d488adb6 Michael Hanselmann
      ["-H", "%s=acn" % constants.HV_BOOT_ORDER],
593 d488adb6 Michael Hanselmann
      ["-H", "%s=%s" % (constants.HV_BOOT_ORDER, constants.VALUE_DEFAULT)],
594 d488adb6 Michael Hanselmann
      ])
595 d488adb6 Michael Hanselmann
596 c0f74c55 Iustin Pop
  for alist in args:
597 b5f33afa Michael Hanselmann
    AssertCommand(["gnt-instance", "modify"] + alist + [instance.name])
598 c0f74c55 Iustin Pop
599 c0f74c55 Iustin Pop
  # check no-modify
600 b5f33afa Michael Hanselmann
  AssertCommand(["gnt-instance", "modify", instance.name], fail=True)
601 c0f74c55 Iustin Pop
602 1ba25bad Guido Trotter
  # Marking offline while instance is running must fail...
603 b5f33afa Michael Hanselmann
  AssertCommand(["gnt-instance", "modify", "--offline", instance.name],
604 1ba25bad Guido Trotter
                 fail=True)
605 1ba25bad Guido Trotter
606 1ba25bad Guido Trotter
  # ...while making it online is ok, and should work
607 b5f33afa Michael Hanselmann
  AssertCommand(["gnt-instance", "modify", "--online", instance.name])
608 3016bc1f Michael Hanselmann
609 3016bc1f Michael Hanselmann
610 d0a44ec0 Klaus Aehlig
@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
611 d0a44ec0 Klaus Aehlig
def TestInstanceModifyPrimaryAndBack(instance, currentnode, othernode):
612 d0a44ec0 Klaus Aehlig
  """gnt-instance modify --new-primary
613 d0a44ec0 Klaus Aehlig

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

616 d0a44ec0 Klaus Aehlig
  """
617 d0a44ec0 Klaus Aehlig
  if instance.disk_template != constants.DT_FILE:
618 d0a44ec0 Klaus Aehlig
    print qa_utils.FormatInfo("Test only supported for the file disk template")
619 d0a44ec0 Klaus Aehlig
    return
620 d0a44ec0 Klaus Aehlig
621 049a6c6b Guido Trotter
  cluster_name = qa_config.get("name")
622 049a6c6b Guido Trotter
623 d0a44ec0 Klaus Aehlig
  name = instance.name
624 d0a44ec0 Klaus Aehlig
  current = currentnode.primary
625 d0a44ec0 Klaus Aehlig
  other = othernode.primary
626 d0a44ec0 Klaus Aehlig
627 0b85e1bd Guido Trotter
  # FIXME: the qa doesn't have a customizable file storage dir parameter. As
628 0b85e1bd Guido Trotter
  # such for now we use the default.
629 0b85e1bd Guido Trotter
  filestorage = pathutils.DEFAULT_FILE_STORAGE_DIR
630 d0a44ec0 Klaus Aehlig
  disk = os.path.join(filestorage, name)
631 d0a44ec0 Klaus Aehlig
632 d0a44ec0 Klaus Aehlig
  AssertCommand(["gnt-instance", "modify", "--new-primary=%s" % other, name],
633 d0a44ec0 Klaus Aehlig
                fail=True)
634 d0a44ec0 Klaus Aehlig
  AssertCommand(["gnt-instance", "shutdown", name])
635 049a6c6b Guido Trotter
  AssertCommand(["scp", "-oGlobalKnownHostsFile=%s" %
636 049a6c6b Guido Trotter
                 pathutils.SSH_KNOWN_HOSTS_FILE,
637 049a6c6b Guido Trotter
                 "-oCheckHostIp=no", "-oStrictHostKeyChecking=yes",
638 049a6c6b Guido Trotter
                 "-oHashKnownHosts=no", "-oHostKeyAlias=%s" % cluster_name,
639 049a6c6b Guido Trotter
                 "-r", disk, "%s:%s" % (other, filestorage)])
640 d0a44ec0 Klaus Aehlig
  AssertCommand(["gnt-instance", "modify", "--new-primary=%s" % other, name])
641 d0a44ec0 Klaus Aehlig
  AssertCommand(["gnt-instance", "startup", name])
642 d0a44ec0 Klaus Aehlig
643 d0a44ec0 Klaus Aehlig
  # and back
644 d0a44ec0 Klaus Aehlig
  AssertCommand(["gnt-instance", "shutdown", name])
645 d0a44ec0 Klaus Aehlig
  AssertCommand(["rm", "-rf", disk], node=other)
646 d0a44ec0 Klaus Aehlig
  AssertCommand(["gnt-instance", "modify", "--new-primary=%s" % current, name])
647 d0a44ec0 Klaus Aehlig
  AssertCommand(["gnt-instance", "startup", name])
648 d0a44ec0 Klaus Aehlig
649 d0a44ec0 Klaus Aehlig
650 5fa0375e Michael Hanselmann
@InstanceCheck(INST_DOWN, INST_DOWN, FIRST_ARG)
651 3016bc1f Michael Hanselmann
def TestInstanceStoppedModify(instance):
652 3016bc1f Michael Hanselmann
  """gnt-instance modify (stopped instance)"""
653 b5f33afa Michael Hanselmann
  name = instance.name
654 3016bc1f Michael Hanselmann
655 58f0ce16 Michael Hanselmann
  # Instance was not marked offline; try marking it online once more
656 58f0ce16 Michael Hanselmann
  AssertCommand(["gnt-instance", "modify", "--online", name])
657 3016bc1f Michael Hanselmann
658 3016bc1f Michael Hanselmann
  # Mark instance as offline
659 3016bc1f Michael Hanselmann
  AssertCommand(["gnt-instance", "modify", "--offline", name])
660 3016bc1f Michael Hanselmann
661 1ba25bad Guido Trotter
  # When the instance is offline shutdown should only work with --force,
662 1ba25bad Guido Trotter
  # while start should never work
663 1ba25bad Guido Trotter
  AssertCommand(["gnt-instance", "shutdown", name], fail=True)
664 1ba25bad Guido Trotter
  AssertCommand(["gnt-instance", "shutdown", "--force", name])
665 1ba25bad Guido Trotter
  AssertCommand(["gnt-instance", "start", name], fail=True)
666 1ba25bad Guido Trotter
  AssertCommand(["gnt-instance", "start", "--force", name], fail=True)
667 1ba25bad Guido Trotter
668 1ba25bad Guido Trotter
  # Also do offline to offline
669 1ba25bad Guido Trotter
  AssertCommand(["gnt-instance", "modify", "--offline", name])
670 1ba25bad Guido Trotter
671 3016bc1f Michael Hanselmann
  # And online again
672 3016bc1f Michael Hanselmann
  AssertCommand(["gnt-instance", "modify", "--online", name])
673 3016bc1f Michael Hanselmann
674 c0f74c55 Iustin Pop
675 5fa0375e Michael Hanselmann
@InstanceCheck(INST_DOWN, INST_DOWN, FIRST_ARG)
676 c99200a3 Bernardo Dal Seno
def TestInstanceConvertDiskToPlain(instance, inodes):
677 7f69aabb Iustin Pop
  """gnt-instance modify -t"""
678 b5f33afa Michael Hanselmann
  name = instance.name
679 68c8c3df Michael Hanselmann
680 02a5fe0e Michael Hanselmann
  template = instance.disk_template
681 68c8c3df Michael Hanselmann
  if template != constants.DT_DRBD8:
682 5de31440 Bernardo Dal Seno
    print qa_utils.FormatInfo("Unsupported template %s, skipping conversion"
683 5de31440 Bernardo Dal Seno
                              " test" % template)
684 5de31440 Bernardo Dal Seno
    return
685 68c8c3df Michael Hanselmann
686 c99200a3 Bernardo Dal Seno
  assert len(inodes) == 2
687 68c8c3df Michael Hanselmann
  AssertCommand(["gnt-instance", "modify", "-t", constants.DT_PLAIN, name])
688 68c8c3df Michael Hanselmann
  AssertCommand(["gnt-instance", "modify", "-t", constants.DT_DRBD8,
689 aecba21e Michael Hanselmann
                 "-n", inodes[1].primary, name])
690 7f69aabb Iustin Pop
691 7f69aabb Iustin Pop
692 5fa0375e Michael Hanselmann
@InstanceCheck(INST_DOWN, INST_DOWN, FIRST_ARG)
693 26a5056d Iustin Pop
def TestInstanceGrowDisk(instance):
694 26a5056d Iustin Pop
  """gnt-instance grow-disk"""
695 5de31440 Bernardo Dal Seno
  if qa_config.GetExclusiveStorage():
696 5de31440 Bernardo Dal Seno
    print qa_utils.FormatInfo("Test not supported with exclusive_storage")
697 5de31440 Bernardo Dal Seno
    return
698 59c75517 Michael Hanselmann
699 59c75517 Michael Hanselmann
  if instance.disk_template == constants.DT_DISKLESS:
700 59c75517 Michael Hanselmann
    print qa_utils.FormatInfo("Test not supported for diskless instances")
701 59c75517 Michael Hanselmann
    return
702 59c75517 Michael Hanselmann
703 b5f33afa Michael Hanselmann
  name = instance.name
704 26a5056d Iustin Pop
  all_size = qa_config.get("disk")
705 26a5056d Iustin Pop
  all_grow = qa_config.get("disk-growth")
706 59c75517 Michael Hanselmann
707 26a5056d Iustin Pop
  if not all_grow:
708 26a5056d Iustin Pop
    # missing disk sizes but instance grow disk has been enabled,
709 26a5056d Iustin Pop
    # let's set fixed/nomimal growth
710 26a5056d Iustin Pop
    all_grow = ["128M" for _ in all_size]
711 59c75517 Michael Hanselmann
712 26a5056d Iustin Pop
  for idx, (size, grow) in enumerate(zip(all_size, all_grow)):
713 26a5056d Iustin Pop
    # succeed in grow by amount
714 26a5056d Iustin Pop
    AssertCommand(["gnt-instance", "grow-disk", name, str(idx), grow])
715 26a5056d Iustin Pop
    # fail in grow to the old size
716 26a5056d Iustin Pop
    AssertCommand(["gnt-instance", "grow-disk", "--absolute", name, str(idx),
717 26a5056d Iustin Pop
                   size], fail=True)
718 26a5056d Iustin Pop
    # succeed to grow to old size + 2 * growth
719 26a5056d Iustin Pop
    int_size = utils.ParseUnit(size)
720 26a5056d Iustin Pop
    int_grow = utils.ParseUnit(grow)
721 26a5056d Iustin Pop
    AssertCommand(["gnt-instance", "grow-disk", "--absolute", name, str(idx),
722 26a5056d Iustin Pop
                   str(int_size + 2 * int_grow)])
723 26a5056d Iustin Pop
724 26a5056d Iustin Pop
725 283f9d4c Michael Hanselmann
def TestInstanceList():
726 283f9d4c Michael Hanselmann
  """gnt-instance list"""
727 288d6440 Michael Hanselmann
  qa_utils.GenericQueryTest("gnt-instance", query.INSTANCE_FIELDS.keys())
728 283f9d4c Michael Hanselmann
729 283f9d4c Michael Hanselmann
730 2214cf14 Michael Hanselmann
def TestInstanceListFields():
731 2214cf14 Michael Hanselmann
  """gnt-instance list-fields"""
732 2214cf14 Michael Hanselmann
  qa_utils.GenericQueryFieldsTest("gnt-instance", query.INSTANCE_FIELDS.keys())
733 2214cf14 Michael Hanselmann
734 2214cf14 Michael Hanselmann
735 5fa0375e Michael Hanselmann
@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
736 4379b1fa Michael Hanselmann
def TestInstanceConsole(instance):
737 4379b1fa Michael Hanselmann
  """gnt-instance console"""
738 b5f33afa Michael Hanselmann
  AssertCommand(["gnt-instance", "console", "--show-cmd", instance.name])
739 4379b1fa Michael Hanselmann
740 4379b1fa Michael Hanselmann
741 5fa0375e Michael Hanselmann
@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
742 c99200a3 Bernardo Dal Seno
def TestReplaceDisks(instance, curr_nodes, other_nodes):
743 7910e7a5 Michael Hanselmann
  """gnt-instance replace-disks"""
744 7910e7a5 Michael Hanselmann
  def buildcmd(args):
745 d0c8c01d Iustin Pop
    cmd = ["gnt-instance", "replace-disks"]
746 7910e7a5 Michael Hanselmann
    cmd.extend(args)
747 b5f33afa Michael Hanselmann
    cmd.append(instance.name)
748 7910e7a5 Michael Hanselmann
    return cmd
749 7910e7a5 Michael Hanselmann
750 5de31440 Bernardo Dal Seno
  if not IsDiskReplacingSupported(instance):
751 5de31440 Bernardo Dal Seno
    print qa_utils.FormatInfo("Instance doesn't support disk replacing,"
752 5de31440 Bernardo Dal Seno
                              " skipping test")
753 5de31440 Bernardo Dal Seno
    return
754 5de31440 Bernardo Dal Seno
755 c99200a3 Bernardo Dal Seno
  # Currently all supported templates have one primary and one secondary node
756 c99200a3 Bernardo Dal Seno
  assert len(curr_nodes) == 2
757 c99200a3 Bernardo Dal Seno
  snode = curr_nodes[1]
758 c99200a3 Bernardo Dal Seno
  assert len(other_nodes) == 1
759 c99200a3 Bernardo Dal Seno
  othernode = other_nodes[0]
760 c99200a3 Bernardo Dal Seno
761 e85be22a Bernardo Dal Seno
  options = qa_config.get("options", {})
762 e85be22a Bernardo Dal Seno
  use_ialloc = options.get("use-iallocators", True)
763 2f4b4f78 Iustin Pop
  for data in [
764 2f4b4f78 Iustin Pop
    ["-p"],
765 2f4b4f78 Iustin Pop
    ["-s"],
766 e85be22a Bernardo Dal Seno
    # A placeholder; the actual command choice depends on use_ialloc
767 e85be22a Bernardo Dal Seno
    None,
768 e85be22a Bernardo Dal Seno
    # Restore the original secondary
769 aecba21e Michael Hanselmann
    ["--new-secondary=%s" % snode.primary],
770 2f4b4f78 Iustin Pop
    ]:
771 e85be22a Bernardo Dal Seno
    if data is None:
772 e85be22a Bernardo Dal Seno
      if use_ialloc:
773 e85be22a Bernardo Dal Seno
        data = ["-I", constants.DEFAULT_IALLOCATOR_SHORTCUT]
774 e85be22a Bernardo Dal Seno
      else:
775 aecba21e Michael Hanselmann
        data = ["--new-secondary=%s" % othernode.primary]
776 2f4b4f78 Iustin Pop
    AssertCommand(buildcmd(data))
777 7910e7a5 Michael Hanselmann
778 9026e935 René Nussbaumer
  AssertCommand(buildcmd(["-a"]))
779 b5f33afa Michael Hanselmann
  AssertCommand(["gnt-instance", "stop", instance.name])
780 9026e935 René Nussbaumer
  AssertCommand(buildcmd(["-a"]), fail=True)
781 b5f33afa Michael Hanselmann
  AssertCommand(["gnt-instance", "activate-disks", instance.name])
782 32da72f3 Iustin Pop
  AssertCommand(["gnt-instance", "activate-disks", "--wait-for-sync",
783 b5f33afa Michael Hanselmann
                 instance.name])
784 9026e935 René Nussbaumer
  AssertCommand(buildcmd(["-a"]))
785 b5f33afa Michael Hanselmann
  AssertCommand(["gnt-instance", "start", instance.name])
786 9026e935 René Nussbaumer
787 7910e7a5 Michael Hanselmann
788 83180411 Bernardo Dal Seno
def _AssertRecreateDisks(cmdargs, instance, fail=False, check=True,
789 83180411 Bernardo Dal Seno
                         destroy=True):
790 83180411 Bernardo Dal Seno
  """Execute gnt-instance recreate-disks and check the result
791 83180411 Bernardo Dal Seno

792 83180411 Bernardo Dal Seno
  @param cmdargs: Arguments (instance name excluded)
793 83180411 Bernardo Dal Seno
  @param instance: Instance to operate on
794 83180411 Bernardo Dal Seno
  @param fail: True if the command is expected to fail
795 83180411 Bernardo Dal Seno
  @param check: If True and fail is False, check that the disks work
796 83180411 Bernardo Dal Seno
  @prama destroy: If True, destroy the old disks first
797 83180411 Bernardo Dal Seno

798 83180411 Bernardo Dal Seno
  """
799 83180411 Bernardo Dal Seno
  if destroy:
800 cc2a70b1 Guido Trotter
    _DestroyInstanceDisks(instance)
801 83180411 Bernardo Dal Seno
  AssertCommand((["gnt-instance", "recreate-disks"] + cmdargs +
802 b5f33afa Michael Hanselmann
                 [instance.name]), fail)
803 83180411 Bernardo Dal Seno
  if not fail and check:
804 83180411 Bernardo Dal Seno
    # Quick check that the disks are there
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 b5f33afa Michael Hanselmann
    AssertCommand(["gnt-instance", "deactivate-disks", instance.name])
809 83180411 Bernardo Dal Seno
810 a1cd2ecf Bernardo Dal Seno
811 83180411 Bernardo Dal Seno
@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
812 c99200a3 Bernardo Dal Seno
def TestRecreateDisks(instance, inodes, othernodes):
813 83180411 Bernardo Dal Seno
  """gnt-instance recreate-disks
814 83180411 Bernardo Dal Seno

815 83180411 Bernardo Dal Seno
  @param instance: Instance to work on
816 c99200a3 Bernardo Dal Seno
  @param inodes: List of the current nodes of the instance
817 83180411 Bernardo Dal Seno
  @param othernodes: list/tuple of nodes where to temporarily recreate disks
818 83180411 Bernardo Dal Seno

819 83180411 Bernardo Dal Seno
  """
820 e85be22a Bernardo Dal Seno
  options = qa_config.get("options", {})
821 e85be22a Bernardo Dal Seno
  use_ialloc = options.get("use-iallocators", True)
822 aecba21e Michael Hanselmann
  other_seq = ":".join([n.primary for n in othernodes])
823 aecba21e Michael Hanselmann
  orig_seq = ":".join([n.primary for n in inodes])
824 a085d96d Bernardo Dal Seno
  # These fail because the instance is running
825 83180411 Bernardo Dal Seno
  _AssertRecreateDisks(["-n", other_seq], instance, fail=True, destroy=False)
826 e85be22a Bernardo Dal Seno
  if use_ialloc:
827 e85be22a Bernardo Dal Seno
    _AssertRecreateDisks(["-I", "hail"], instance, fail=True, destroy=False)
828 e85be22a Bernardo Dal Seno
  else:
829 e85be22a Bernardo Dal Seno
    _AssertRecreateDisks(["-n", other_seq], instance, fail=True, destroy=False)
830 b5f33afa Michael Hanselmann
  AssertCommand(["gnt-instance", "stop", instance.name])
831 83180411 Bernardo Dal Seno
  # Disks exist: this should fail
832 83180411 Bernardo Dal Seno
  _AssertRecreateDisks([], instance, fail=True, destroy=False)
833 83180411 Bernardo Dal Seno
  # Recreate disks in place
834 83180411 Bernardo Dal Seno
  _AssertRecreateDisks([], instance)
835 83180411 Bernardo Dal Seno
  # Move disks away
836 e85be22a Bernardo Dal Seno
  if use_ialloc:
837 e85be22a Bernardo Dal Seno
    _AssertRecreateDisks(["-I", "hail"], instance)
838 e85be22a Bernardo Dal Seno
    # Move disks somewhere else
839 e85be22a Bernardo Dal Seno
    _AssertRecreateDisks(["-I", constants.DEFAULT_IALLOCATOR_SHORTCUT],
840 e85be22a Bernardo Dal Seno
                         instance)
841 e85be22a Bernardo Dal Seno
  else:
842 e85be22a Bernardo Dal Seno
    _AssertRecreateDisks(["-n", other_seq], instance)
843 83180411 Bernardo Dal Seno
  # Move disks back
844 83180411 Bernardo Dal Seno
  _AssertRecreateDisks(["-n", orig_seq], instance, check=False)
845 83180411 Bernardo Dal Seno
  # This and InstanceCheck decoration check that the disks are working
846 b5f33afa Michael Hanselmann
  AssertCommand(["gnt-instance", "reinstall", "-f", instance.name])
847 b5f33afa Michael Hanselmann
  AssertCommand(["gnt-instance", "start", instance.name])
848 83180411 Bernardo Dal Seno
849 83180411 Bernardo Dal Seno
850 5fa0375e Michael Hanselmann
@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
851 5d640672 Michael Hanselmann
def TestInstanceExport(instance, node):
852 bc696589 Michael Hanselmann
  """gnt-backup export -n ..."""
853 b5f33afa Michael Hanselmann
  name = instance.name
854 aecba21e Michael Hanselmann
  AssertCommand(["gnt-backup", "export", "-n", node.primary, name])
855 2f4b4f78 Iustin Pop
  return qa_utils.ResolveInstanceName(name)
856 5d640672 Michael Hanselmann
857 5d640672 Michael Hanselmann
858 51131cad Michael Hanselmann
@InstanceCheck(None, INST_DOWN, FIRST_ARG)
859 8d8d650c Michael Hanselmann
def TestInstanceExportWithRemove(instance, node):
860 8d8d650c Michael Hanselmann
  """gnt-backup export --remove-instance"""
861 aecba21e Michael Hanselmann
  AssertCommand(["gnt-backup", "export", "-n", node.primary,
862 b5f33afa Michael Hanselmann
                 "--remove-instance", instance.name])
863 8d8d650c Michael Hanselmann
864 8d8d650c Michael Hanselmann
865 5fa0375e Michael Hanselmann
@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
866 bc696589 Michael Hanselmann
def TestInstanceExportNoTarget(instance):
867 bc696589 Michael Hanselmann
  """gnt-backup export (without target node, should fail)"""
868 b5f33afa Michael Hanselmann
  AssertCommand(["gnt-backup", "export", instance.name], fail=True)
869 bc696589 Michael Hanselmann
870 bc696589 Michael Hanselmann
871 51131cad Michael Hanselmann
@InstanceCheck(None, INST_DOWN, FIRST_ARG)
872 5fa0375e Michael Hanselmann
def TestInstanceImport(newinst, node, expnode, name):
873 5d640672 Michael Hanselmann
  """gnt-backup import"""
874 906a0346 Bernardo Dal Seno
  templ = constants.DT_PLAIN
875 d0c8c01d Iustin Pop
  cmd = (["gnt-backup", "import",
876 906a0346 Bernardo Dal Seno
          "--disk-template=%s" % templ,
877 d0c8c01d Iustin Pop
          "--no-ip-check",
878 aecba21e Michael Hanselmann
          "--src-node=%s" % expnode.primary,
879 304d9f02 Michael Hanselmann
          "--src-dir=%s/%s" % (pathutils.EXPORT_DIR, name),
880 aecba21e Michael Hanselmann
          "--node=%s" % node.primary] +
881 59c75517 Michael Hanselmann
         _GetGenericAddParameters(newinst, templ,
882 59c75517 Michael Hanselmann
                                  force_mac=constants.VALUE_GENERATE))
883 b5f33afa Michael Hanselmann
  cmd.append(newinst.name)
884 2f4b4f78 Iustin Pop
  AssertCommand(cmd)
885 02a5fe0e Michael Hanselmann
  newinst.SetDiskTemplate(templ)
886 283f9d4c Michael Hanselmann
887 283f9d4c Michael Hanselmann
888 283f9d4c Michael Hanselmann
def TestBackupList(expnode):
889 283f9d4c Michael Hanselmann
  """gnt-backup list"""
890 aecba21e Michael Hanselmann
  AssertCommand(["gnt-backup", "list", "--node=%s" % expnode.primary])
891 e8ae0c20 Michael Hanselmann
892 0fdf247d Michael Hanselmann
  qa_utils.GenericQueryTest("gnt-backup", query.EXPORT_FIELDS.keys(),
893 0fdf247d Michael Hanselmann
                            namefield=None, test_unknown=False)
894 0fdf247d Michael Hanselmann
895 0fdf247d Michael Hanselmann
896 0fdf247d Michael Hanselmann
def TestBackupListFields():
897 0fdf247d Michael Hanselmann
  """gnt-backup list-fields"""
898 0fdf247d Michael Hanselmann
  qa_utils.GenericQueryFieldsTest("gnt-backup", query.EXPORT_FIELDS.keys())
899 f006f110 Bernardo Dal Seno
900 f006f110 Bernardo Dal Seno
901 f006f110 Bernardo Dal Seno
def TestRemoveInstanceOfflineNode(instance, snode, set_offline, set_online):
902 318bbaa9 Guido Trotter
  """gnt-instance remove with an off-line node
903 f006f110 Bernardo Dal Seno

904 f006f110 Bernardo Dal Seno
  @param instance: instance
905 f006f110 Bernardo Dal Seno
  @param snode: secondary node, to be set offline
906 f006f110 Bernardo Dal Seno
  @param set_offline: function to call to set the node off-line
907 f006f110 Bernardo Dal Seno
  @param set_online: function to call to set the node on-line
908 f006f110 Bernardo Dal Seno

909 f006f110 Bernardo Dal Seno
  """
910 b5f33afa Michael Hanselmann
  info = _GetInstanceInfo(instance.name)
911 f006f110 Bernardo Dal Seno
  set_offline(snode)
912 f006f110 Bernardo Dal Seno
  try:
913 f006f110 Bernardo Dal Seno
    TestInstanceRemove(instance)
914 f006f110 Bernardo Dal Seno
  finally:
915 f006f110 Bernardo Dal Seno
    set_online(snode)
916 318bbaa9 Guido Trotter
917 318bbaa9 Guido Trotter
  # Clean up the disks on the offline node, if necessary
918 318bbaa9 Guido Trotter
  if instance.disk_template not in constants.DTS_EXT_MIRROR:
919 318bbaa9 Guido Trotter
    # FIXME: abstract the cleanup inside the disks
920 318bbaa9 Guido Trotter
    if info["storage-type"] == constants.ST_LVM_VG:
921 318bbaa9 Guido Trotter
      for minor in info["drbd-minors"][snode.primary]:
922 318bbaa9 Guido Trotter
        AssertCommand(["drbdsetup", str(minor), "down"], node=snode)
923 318bbaa9 Guido Trotter
      AssertCommand(["lvremove", "-f"] + info["volumes"], node=snode)
924 318bbaa9 Guido Trotter
    elif info["storage-type"] == constants.ST_FILE:
925 318bbaa9 Guido Trotter
      filestorage = pathutils.DEFAULT_FILE_STORAGE_DIR
926 318bbaa9 Guido Trotter
      disk = os.path.join(filestorage, instance.name)
927 318bbaa9 Guido Trotter
      AssertCommand(["rm", "-rf", disk], node=snode)