Statistics
| Branch: | Tag: | Revision:

root / qa / qa_instance.py @ 33c730a2

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

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

108 82d2f3df Bernardo Dal Seno
  """
109 82d2f3df Bernardo Dal Seno
  master = qa_config.GetMasterNode()
110 b07afbb3 Iustin Pop
  infocmd = utils.ShellQuoteArgs(["gnt-instance", "info", instance])
111 aecba21e Michael Hanselmann
  info_out = qa_utils.GetCommandOutput(master.primary, infocmd)
112 82d2f3df Bernardo Dal Seno
  re_node = re.compile(r"^\s+-\s+(?:primary|secondaries):\s+(\S.+)$")
113 82d2f3df Bernardo Dal Seno
  node_elem = r"([^,()]+)(?:\s+\([^)]+\))?"
114 82d2f3df Bernardo Dal Seno
  # re_nodelist matches a list of nodes returned by gnt-instance info, e.g.:
115 82d2f3df Bernardo Dal Seno
  #  node1.fqdn
116 82d2f3df Bernardo Dal Seno
  #  node2.fqdn,node3.fqdn
117 82d2f3df Bernardo Dal Seno
  #  node4.fqdn (group mygroup, group UUID 01234567-abcd-0123-4567-0123456789ab)
118 82d2f3df Bernardo Dal Seno
  # FIXME This works with no more than 2 secondaries
119 82d2f3df Bernardo Dal Seno
  re_nodelist = re.compile(node_elem + "(?:," + node_elem + ")?$")
120 82d2f3df Bernardo Dal Seno
  re_vol = re.compile(r"^\s+logical_id:\s+(\S+)$")
121 f006f110 Bernardo Dal Seno
  re_drbdnode = re.compile(r"^\s+node[AB]:\s+([^\s,]+),\s+minor=([0-9]+)$")
122 82d2f3df Bernardo Dal Seno
  nodes = []
123 82d2f3df Bernardo Dal Seno
  vols = []
124 f006f110 Bernardo Dal Seno
  drbd_min = {}
125 82d2f3df Bernardo Dal Seno
  for line in info_out.splitlines():
126 82d2f3df Bernardo Dal Seno
    m = re_node.match(line)
127 82d2f3df Bernardo Dal Seno
    if m:
128 82d2f3df Bernardo Dal Seno
      nodestr = m.group(1)
129 82d2f3df Bernardo Dal Seno
      m2 = re_nodelist.match(nodestr)
130 82d2f3df Bernardo Dal Seno
      if m2:
131 82d2f3df Bernardo Dal Seno
        nodes.extend(filter(None, m2.groups()))
132 82d2f3df Bernardo Dal Seno
      else:
133 82d2f3df Bernardo Dal Seno
        nodes.append(nodestr)
134 82d2f3df Bernardo Dal Seno
    m = re_vol.match(line)
135 82d2f3df Bernardo Dal Seno
    if m:
136 82d2f3df Bernardo Dal Seno
      vols.append(m.group(1))
137 f006f110 Bernardo Dal Seno
    m = re_drbdnode.match(line)
138 f006f110 Bernardo Dal Seno
    if m:
139 f006f110 Bernardo Dal Seno
      node = m.group(1)
140 f006f110 Bernardo Dal Seno
      minor = int(m.group(2))
141 f006f110 Bernardo Dal Seno
      if drbd_min.get(node) is not None:
142 f006f110 Bernardo Dal Seno
        drbd_min[node].append(minor)
143 f006f110 Bernardo Dal Seno
      else:
144 f006f110 Bernardo Dal Seno
        drbd_min[node] = [minor]
145 b296c810 Michael Hanselmann
146 82d2f3df Bernardo Dal Seno
  assert nodes
147 b296c810 Michael Hanselmann
  assert len(nodes) < 2 or vols
148 b296c810 Michael Hanselmann
149 1a6db3df Michael Hanselmann
  return {
150 1a6db3df Michael Hanselmann
    "nodes": nodes,
151 1a6db3df Michael Hanselmann
    "volumes": vols,
152 1a6db3df Michael Hanselmann
    "drbd-minors": drbd_min,
153 1a6db3df Michael Hanselmann
    }
154 cc4b14f0 Bernardo Dal Seno
155 cc4b14f0 Bernardo Dal Seno
156 cc4b14f0 Bernardo Dal Seno
def _DestroyInstanceVolumes(instance):
157 cc4b14f0 Bernardo Dal Seno
  """Remove all the LVM volumes of an instance.
158 cc4b14f0 Bernardo Dal Seno

159 cc4b14f0 Bernardo Dal Seno
  This is used to simulate HW errors (dead nodes, broken disks...); the
160 cc4b14f0 Bernardo Dal Seno
  configuration of the instance is not affected.
161 cc4b14f0 Bernardo Dal Seno
  @type instance: dictionary
162 cc4b14f0 Bernardo Dal Seno
  @param instance: the instance
163 cc4b14f0 Bernardo Dal Seno

164 cc4b14f0 Bernardo Dal Seno
  """
165 b5f33afa Michael Hanselmann
  info = _GetInstanceInfo(instance.name)
166 cc4b14f0 Bernardo Dal Seno
  vols = info["volumes"]
167 cc4b14f0 Bernardo Dal Seno
  for node in info["nodes"]:
168 82d2f3df Bernardo Dal Seno
    AssertCommand(["lvremove", "-f"] + vols, node=node)
169 82d2f3df Bernardo Dal Seno
170 82d2f3df Bernardo Dal Seno
171 ab4832d1 Bernardo Dal Seno
def _GetInstanceField(instance, field):
172 ab4832d1 Bernardo Dal Seno
  """Get the value of a field of an instance.
173 d55408b0 Bernardo Dal Seno

174 d55408b0 Bernardo Dal Seno
  @type instance: string
175 d55408b0 Bernardo Dal Seno
  @param instance: Instance name
176 d55408b0 Bernardo Dal Seno
  @type field: string
177 d55408b0 Bernardo Dal Seno
  @param field: Name of the field
178 ab4832d1 Bernardo Dal Seno
  @rtype: string
179 d55408b0 Bernardo Dal Seno

180 d55408b0 Bernardo Dal Seno
  """
181 d55408b0 Bernardo Dal Seno
  master = qa_config.GetMasterNode()
182 d55408b0 Bernardo Dal Seno
  infocmd = utils.ShellQuoteArgs(["gnt-instance", "list", "--no-headers",
183 ab4832d1 Bernardo Dal Seno
                                  "--units", "m", "-o", field, instance])
184 46d21495 Bernardo Dal Seno
  return qa_utils.GetCommandOutput(master.primary, infocmd).strip()
185 ab4832d1 Bernardo Dal Seno
186 ab4832d1 Bernardo Dal Seno
187 ab4832d1 Bernardo Dal Seno
def _GetBoolInstanceField(instance, field):
188 ab4832d1 Bernardo Dal Seno
  """Get the Boolean value of a field of an instance.
189 ab4832d1 Bernardo Dal Seno

190 ab4832d1 Bernardo Dal Seno
  @type instance: string
191 ab4832d1 Bernardo Dal Seno
  @param instance: Instance name
192 ab4832d1 Bernardo Dal Seno
  @type field: string
193 ab4832d1 Bernardo Dal Seno
  @param field: Name of the field
194 ab4832d1 Bernardo Dal Seno
  @rtype: bool
195 ab4832d1 Bernardo Dal Seno

196 ab4832d1 Bernardo Dal Seno
  """
197 ab4832d1 Bernardo Dal Seno
  info_out = _GetInstanceField(instance, field)
198 d55408b0 Bernardo Dal Seno
  if info_out == "Y":
199 d55408b0 Bernardo Dal Seno
    return True
200 d55408b0 Bernardo Dal Seno
  elif info_out == "N":
201 d55408b0 Bernardo Dal Seno
    return False
202 d55408b0 Bernardo Dal Seno
  else:
203 d55408b0 Bernardo Dal Seno
    raise qa_error.Error("Field %s of instance %s has a non-Boolean value:"
204 d55408b0 Bernardo Dal Seno
                         " %s" % (field, instance, info_out))
205 d55408b0 Bernardo Dal Seno
206 d55408b0 Bernardo Dal Seno
207 ab4832d1 Bernardo Dal Seno
def _GetNumInstanceField(instance, field):
208 ab4832d1 Bernardo Dal Seno
  """Get a numeric value of a field of an instance.
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 field: string
213 ab4832d1 Bernardo Dal Seno
  @param field: Name of the field
214 ab4832d1 Bernardo Dal Seno
  @rtype: int or float
215 ab4832d1 Bernardo Dal Seno

216 ab4832d1 Bernardo Dal Seno
  """
217 ab4832d1 Bernardo Dal Seno
  info_out = _GetInstanceField(instance, field)
218 ab4832d1 Bernardo Dal Seno
  try:
219 ab4832d1 Bernardo Dal Seno
    ret = int(info_out)
220 ab4832d1 Bernardo Dal Seno
  except ValueError:
221 ab4832d1 Bernardo Dal Seno
    try:
222 ab4832d1 Bernardo Dal Seno
      ret = float(info_out)
223 ab4832d1 Bernardo Dal Seno
    except ValueError:
224 ab4832d1 Bernardo Dal Seno
      raise qa_error.Error("Field %s of instance %s has a non-numeric value:"
225 ab4832d1 Bernardo Dal Seno
                           " %s" % (field, instance, info_out))
226 ab4832d1 Bernardo Dal Seno
  return ret
227 ab4832d1 Bernardo Dal Seno
228 ab4832d1 Bernardo Dal Seno
229 ab4832d1 Bernardo Dal Seno
def GetInstanceSpec(instance, spec):
230 ab4832d1 Bernardo Dal Seno
  """Return the current spec for the given parameter.
231 ab4832d1 Bernardo Dal Seno

232 ab4832d1 Bernardo Dal Seno
  @type instance: string
233 ab4832d1 Bernardo Dal Seno
  @param instance: Instance name
234 ab4832d1 Bernardo Dal Seno
  @type spec: string
235 ab4832d1 Bernardo Dal Seno
  @param spec: one of the supported parameters: "mem-size", "cpu-count",
236 ab4832d1 Bernardo Dal Seno
      "disk-count", "disk-size", "nic-count"
237 ab4832d1 Bernardo Dal Seno
  @rtype: tuple
238 ab4832d1 Bernardo Dal Seno
  @return: (minspec, maxspec); minspec and maxspec can be different only for
239 ab4832d1 Bernardo Dal Seno
      memory and disk size
240 ab4832d1 Bernardo Dal Seno

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

353 6a343475 Michael Hanselmann
  """
354 6a343475 Michael Hanselmann
  master = qa_config.GetMasterNode()
355 6a343475 Michael Hanselmann
356 e35c341e Michael Hanselmann
  ssconf_path = utils.PathJoin(pathutils.DATA_DIR,
357 e35c341e Michael Hanselmann
                               "ssconf_%s" % constants.SS_INSTANCE_LIST)
358 e35c341e Michael Hanselmann
359 e35c341e Michael Hanselmann
  cmd = ["cat", qa_utils.MakeNodePath(master, ssconf_path)]
360 6a343475 Michael Hanselmann
361 aecba21e Michael Hanselmann
  return qa_utils.GetCommandOutput(master.primary,
362 6a343475 Michael Hanselmann
                                   utils.ShellQuoteArgs(cmd)).splitlines()
363 6a343475 Michael Hanselmann
364 6a343475 Michael Hanselmann
365 6a343475 Michael Hanselmann
def _CheckSsconfInstanceList(instance):
366 6a343475 Michael Hanselmann
  """Checks if a certain instance is in the ssconf instance list.
367 6a343475 Michael Hanselmann

368 6a343475 Michael Hanselmann
  @type instance: string
369 6a343475 Michael Hanselmann
  @param instance: Instance name
370 6a343475 Michael Hanselmann

371 6a343475 Michael Hanselmann
  """
372 6a343475 Michael Hanselmann
  AssertIn(qa_utils.ResolveInstanceName(instance),
373 6a343475 Michael Hanselmann
           _ReadSsconfInstanceList())
374 6a343475 Michael Hanselmann
375 6a343475 Michael Hanselmann
376 51131cad Michael Hanselmann
@InstanceCheck(INST_DOWN, INST_DOWN, FIRST_ARG)
377 4c1a464b Iustin Pop
def TestInstanceRenameAndBack(rename_source, rename_target):
378 4c1a464b Iustin Pop
  """gnt-instance rename
379 4c1a464b Iustin Pop

380 4c1a464b Iustin Pop
  This must leave the instance with the original name, not the target
381 4c1a464b Iustin Pop
  name.
382 4c1a464b Iustin Pop

383 4c1a464b Iustin Pop
  """
384 31fe5102 René Nussbaumer
  _CheckSsconfInstanceList(rename_source)
385 5fa0375e Michael Hanselmann
386 4c1a464b Iustin Pop
  # first do a rename to a different actual name, expecting it to fail
387 31fe5102 René Nussbaumer
  qa_utils.AddToEtcHosts(["meeeeh-not-exists", rename_target])
388 31fe5102 René Nussbaumer
  try:
389 31fe5102 René Nussbaumer
    AssertCommand(["gnt-instance", "rename", rename_source, rename_target],
390 31fe5102 René Nussbaumer
                  fail=True)
391 31fe5102 René Nussbaumer
    _CheckSsconfInstanceList(rename_source)
392 31fe5102 René Nussbaumer
  finally:
393 31fe5102 René Nussbaumer
    qa_utils.RemoveFromEtcHosts(["meeeeh-not-exists", rename_target])
394 5fa0375e Michael Hanselmann
395 b07afbb3 Iustin Pop
  # Check instance volume tags correctly updated
396 b07afbb3 Iustin Pop
  # FIXME: this is LVM specific!
397 b07afbb3 Iustin Pop
  info = _GetInstanceInfo(rename_source)
398 b07afbb3 Iustin Pop
  tags_cmd = ("lvs -o tags --noheadings %s | grep " %
399 b07afbb3 Iustin Pop
              (" ".join(info["volumes"]), ))
400 b07afbb3 Iustin Pop
401 4c1a464b Iustin Pop
  # and now rename instance to rename_target...
402 31fe5102 René Nussbaumer
  AssertCommand(["gnt-instance", "rename", rename_source, rename_target])
403 31fe5102 René Nussbaumer
  _CheckSsconfInstanceList(rename_target)
404 5fa0375e Michael Hanselmann
  qa_utils.RunInstanceCheck(rename_source, False)
405 51131cad Michael Hanselmann
  qa_utils.RunInstanceCheck(rename_target, False)
406 5fa0375e Michael Hanselmann
407 b07afbb3 Iustin Pop
  # NOTE: tags might not be the exactly as the instance name, due to
408 b07afbb3 Iustin Pop
  # charset restrictions; hence the test might be flaky
409 b07afbb3 Iustin Pop
  if rename_source != rename_target:
410 b07afbb3 Iustin Pop
    for node in info["nodes"]:
411 b07afbb3 Iustin Pop
      AssertCommand(tags_cmd + rename_source, node=node, fail=True)
412 b07afbb3 Iustin Pop
      AssertCommand(tags_cmd + rename_target, node=node, fail=False)
413 b07afbb3 Iustin Pop
414 4c1a464b Iustin Pop
  # and back
415 4c1a464b Iustin Pop
  AssertCommand(["gnt-instance", "rename", rename_target, rename_source])
416 4c1a464b Iustin Pop
  _CheckSsconfInstanceList(rename_source)
417 5fa0375e Michael Hanselmann
  qa_utils.RunInstanceCheck(rename_target, False)
418 18337ca9 Iustin Pop
419 b07afbb3 Iustin Pop
  if rename_source != rename_target:
420 b07afbb3 Iustin Pop
    for node in info["nodes"]:
421 b07afbb3 Iustin Pop
      AssertCommand(tags_cmd + rename_source, node=node, fail=False)
422 b07afbb3 Iustin Pop
      AssertCommand(tags_cmd + rename_target, node=node, fail=True)
423 b07afbb3 Iustin Pop
424 18337ca9 Iustin Pop
425 5fa0375e Michael Hanselmann
@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
426 cec9845c Michael Hanselmann
def TestInstanceFailover(instance):
427 cec9845c Michael Hanselmann
  """gnt-instance failover"""
428 5de31440 Bernardo Dal Seno
  if not IsFailoverSupported(instance):
429 5de31440 Bernardo Dal Seno
    print qa_utils.FormatInfo("Instance doesn't support failover, skipping"
430 5de31440 Bernardo Dal Seno
                              " test")
431 5de31440 Bernardo Dal Seno
    return
432 5de31440 Bernardo Dal Seno
433 b5f33afa Michael Hanselmann
  cmd = ["gnt-instance", "failover", "--force", instance.name]
434 5fa0375e Michael Hanselmann
435 2f4b4f78 Iustin Pop
  # failover ...
436 2f4b4f78 Iustin Pop
  AssertCommand(cmd)
437 5fa0375e Michael Hanselmann
  qa_utils.RunInstanceCheck(instance, True)
438 5fa0375e Michael Hanselmann
439 76f59a32 Michael Hanselmann
  # ... and back
440 2f4b4f78 Iustin Pop
  AssertCommand(cmd)
441 76f59a32 Michael Hanselmann
442 cec9845c Michael Hanselmann
443 5fa0375e Michael Hanselmann
@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
444 d55408b0 Bernardo Dal Seno
def TestInstanceMigrate(instance, toggle_always_failover=True):
445 938bde86 Michael Hanselmann
  """gnt-instance migrate"""
446 5de31440 Bernardo Dal Seno
  if not IsMigrationSupported(instance):
447 5de31440 Bernardo Dal Seno
    print qa_utils.FormatInfo("Instance doesn't support migration, skipping"
448 5de31440 Bernardo Dal Seno
                              " test")
449 5de31440 Bernardo Dal Seno
    return
450 5de31440 Bernardo Dal Seno
451 b5f33afa Michael Hanselmann
  cmd = ["gnt-instance", "migrate", "--force", instance.name]
452 d55408b0 Bernardo Dal Seno
  af_par = constants.BE_ALWAYS_FAILOVER
453 d55408b0 Bernardo Dal Seno
  af_field = "be/" + constants.BE_ALWAYS_FAILOVER
454 b5f33afa Michael Hanselmann
  af_init_val = _GetBoolInstanceField(instance.name, af_field)
455 5fa0375e Michael Hanselmann
456 2f4b4f78 Iustin Pop
  # migrate ...
457 2f4b4f78 Iustin Pop
  AssertCommand(cmd)
458 d55408b0 Bernardo Dal Seno
  # TODO: Verify the choice between failover and migration
459 5fa0375e Michael Hanselmann
  qa_utils.RunInstanceCheck(instance, True)
460 5fa0375e Michael Hanselmann
461 d55408b0 Bernardo Dal Seno
  # ... and back (possibly with always_failover toggled)
462 d55408b0 Bernardo Dal Seno
  if toggle_always_failover:
463 d55408b0 Bernardo Dal Seno
    AssertCommand(["gnt-instance", "modify", "-B",
464 d55408b0 Bernardo Dal Seno
                   ("%s=%s" % (af_par, not af_init_val)),
465 b5f33afa Michael Hanselmann
                   instance.name])
466 2f4b4f78 Iustin Pop
  AssertCommand(cmd)
467 d55408b0 Bernardo Dal Seno
  # TODO: Verify the choice between failover and migration
468 d55408b0 Bernardo Dal Seno
  qa_utils.RunInstanceCheck(instance, True)
469 d55408b0 Bernardo Dal Seno
  if toggle_always_failover:
470 d55408b0 Bernardo Dal Seno
    AssertCommand(["gnt-instance", "modify", "-B",
471 b5f33afa Michael Hanselmann
                   ("%s=%s" % (af_par, af_init_val)), instance.name])
472 5fa0375e Michael Hanselmann
473 5fa0375e Michael Hanselmann
  # TODO: Split into multiple tests
474 b5f33afa Michael Hanselmann
  AssertCommand(["gnt-instance", "shutdown", instance.name])
475 5fa0375e Michael Hanselmann
  qa_utils.RunInstanceCheck(instance, False)
476 e9c487be René Nussbaumer
  AssertCommand(cmd, fail=True)
477 e9c487be René Nussbaumer
  AssertCommand(["gnt-instance", "migrate", "--force", "--allow-failover",
478 b5f33afa Michael Hanselmann
                 instance.name])
479 b5f33afa Michael Hanselmann
  AssertCommand(["gnt-instance", "start", instance.name])
480 e9c487be René Nussbaumer
  AssertCommand(cmd)
481 d55408b0 Bernardo Dal Seno
  # @InstanceCheck enforces the check that the instance is running
482 5fa0375e Michael Hanselmann
  qa_utils.RunInstanceCheck(instance, True)
483 5fa0375e Michael Hanselmann
484 42a769f9 Bernardo Dal Seno
  AssertCommand(["gnt-instance", "modify", "-B",
485 42a769f9 Bernardo Dal Seno
                 ("%s=%s" %
486 42a769f9 Bernardo Dal Seno
                  (constants.BE_ALWAYS_FAILOVER, constants.VALUE_TRUE)),
487 b5f33afa Michael Hanselmann
                 instance.name])
488 5fa0375e Michael Hanselmann
489 320a5dae Bernardo Dal Seno
  AssertCommand(cmd)
490 5fa0375e Michael Hanselmann
  qa_utils.RunInstanceCheck(instance, True)
491 320a5dae Bernardo Dal Seno
  # TODO: Verify that a failover has been done instead of a migration
492 5fa0375e Michael Hanselmann
493 5fa0375e Michael Hanselmann
  # TODO: Verify whether the default value is restored here (not hardcoded)
494 42a769f9 Bernardo Dal Seno
  AssertCommand(["gnt-instance", "modify", "-B",
495 42a769f9 Bernardo Dal Seno
                 ("%s=%s" %
496 42a769f9 Bernardo Dal Seno
                  (constants.BE_ALWAYS_FAILOVER, constants.VALUE_FALSE)),
497 b5f33afa Michael Hanselmann
                 instance.name])
498 5fa0375e Michael Hanselmann
499 42a769f9 Bernardo Dal Seno
  AssertCommand(cmd)
500 5fa0375e Michael Hanselmann
  qa_utils.RunInstanceCheck(instance, True)
501 938bde86 Michael Hanselmann
502 938bde86 Michael Hanselmann
503 cec9845c Michael Hanselmann
def TestInstanceInfo(instance):
504 cec9845c Michael Hanselmann
  """gnt-instance info"""
505 b5f33afa Michael Hanselmann
  AssertCommand(["gnt-instance", "info", instance.name])
506 5d640672 Michael Hanselmann
507 5d640672 Michael Hanselmann
508 5fa0375e Michael Hanselmann
@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
509 c0f74c55 Iustin Pop
def TestInstanceModify(instance):
510 c0f74c55 Iustin Pop
  """gnt-instance modify"""
511 d488adb6 Michael Hanselmann
  default_hv = qa_config.GetDefaultHypervisor()
512 d488adb6 Michael Hanselmann
513 1d693311 Michael Hanselmann
  # Assume /sbin/init exists on all systems
514 1d693311 Michael Hanselmann
  test_kernel = "/sbin/init"
515 1d693311 Michael Hanselmann
  test_initrd = test_kernel
516 1d693311 Michael Hanselmann
517 8ccbbe4b Guido Trotter
  orig_maxmem = qa_config.get(constants.BE_MAXMEM)
518 8ccbbe4b Guido Trotter
  orig_minmem = qa_config.get(constants.BE_MINMEM)
519 2f4b4f78 Iustin Pop
  #orig_bridge = qa_config.get("bridge", "xen-br0")
520 d488adb6 Michael Hanselmann
521 c0f74c55 Iustin Pop
  args = [
522 8ccbbe4b Guido Trotter
    ["-B", "%s=128" % constants.BE_MINMEM],
523 8ccbbe4b Guido Trotter
    ["-B", "%s=128" % constants.BE_MAXMEM],
524 8ccbbe4b Guido Trotter
    ["-B", "%s=%s,%s=%s" % (constants.BE_MINMEM, orig_minmem,
525 8ccbbe4b Guido Trotter
                            constants.BE_MAXMEM, orig_maxmem)],
526 1d693311 Michael Hanselmann
    ["-B", "%s=2" % constants.BE_VCPUS],
527 1d693311 Michael Hanselmann
    ["-B", "%s=1" % constants.BE_VCPUS],
528 1d693311 Michael Hanselmann
    ["-B", "%s=%s" % (constants.BE_VCPUS, constants.VALUE_DEFAULT)],
529 42a769f9 Bernardo Dal Seno
    ["-B", "%s=%s" % (constants.BE_ALWAYS_FAILOVER, constants.VALUE_TRUE)],
530 42a769f9 Bernardo Dal Seno
    ["-B", "%s=%s" % (constants.BE_ALWAYS_FAILOVER, constants.VALUE_DEFAULT)],
531 1d693311 Michael Hanselmann
532 1d693311 Michael Hanselmann
    ["-H", "%s=%s" % (constants.HV_KERNEL_PATH, test_kernel)],
533 1d693311 Michael Hanselmann
    ["-H", "%s=%s" % (constants.HV_KERNEL_PATH, constants.VALUE_DEFAULT)],
534 1d693311 Michael Hanselmann
535 1d693311 Michael Hanselmann
    # TODO: bridge tests
536 1d693311 Michael Hanselmann
    #["--bridge", "xen-br1"],
537 1d693311 Michael Hanselmann
    #["--bridge", orig_bridge],
538 c0f74c55 Iustin Pop
    ]
539 d488adb6 Michael Hanselmann
540 d488adb6 Michael Hanselmann
  if default_hv == constants.HT_XEN_PVM:
541 d488adb6 Michael Hanselmann
    args.extend([
542 d488adb6 Michael Hanselmann
      ["-H", "%s=%s" % (constants.HV_INITRD_PATH, test_initrd)],
543 d488adb6 Michael Hanselmann
      ["-H", "no_%s" % (constants.HV_INITRD_PATH, )],
544 d488adb6 Michael Hanselmann
      ["-H", "%s=%s" % (constants.HV_INITRD_PATH, constants.VALUE_DEFAULT)],
545 d488adb6 Michael Hanselmann
      ])
546 d488adb6 Michael Hanselmann
  elif default_hv == constants.HT_XEN_HVM:
547 d488adb6 Michael Hanselmann
    args.extend([
548 d488adb6 Michael Hanselmann
      ["-H", "%s=acn" % constants.HV_BOOT_ORDER],
549 d488adb6 Michael Hanselmann
      ["-H", "%s=%s" % (constants.HV_BOOT_ORDER, constants.VALUE_DEFAULT)],
550 d488adb6 Michael Hanselmann
      ])
551 d488adb6 Michael Hanselmann
552 c0f74c55 Iustin Pop
  for alist in args:
553 b5f33afa Michael Hanselmann
    AssertCommand(["gnt-instance", "modify"] + alist + [instance.name])
554 c0f74c55 Iustin Pop
555 c0f74c55 Iustin Pop
  # check no-modify
556 b5f33afa Michael Hanselmann
  AssertCommand(["gnt-instance", "modify", instance.name], fail=True)
557 c0f74c55 Iustin Pop
558 1ba25bad Guido Trotter
  # Marking offline while instance is running must fail...
559 b5f33afa Michael Hanselmann
  AssertCommand(["gnt-instance", "modify", "--offline", instance.name],
560 1ba25bad Guido Trotter
                 fail=True)
561 1ba25bad Guido Trotter
562 1ba25bad Guido Trotter
  # ...while making it online is ok, and should work
563 b5f33afa Michael Hanselmann
  AssertCommand(["gnt-instance", "modify", "--online", instance.name])
564 3016bc1f Michael Hanselmann
565 3016bc1f Michael Hanselmann
566 5fa0375e Michael Hanselmann
@InstanceCheck(INST_DOWN, INST_DOWN, FIRST_ARG)
567 3016bc1f Michael Hanselmann
def TestInstanceStoppedModify(instance):
568 3016bc1f Michael Hanselmann
  """gnt-instance modify (stopped instance)"""
569 b5f33afa Michael Hanselmann
  name = instance.name
570 3016bc1f Michael Hanselmann
571 58f0ce16 Michael Hanselmann
  # Instance was not marked offline; try marking it online once more
572 58f0ce16 Michael Hanselmann
  AssertCommand(["gnt-instance", "modify", "--online", name])
573 3016bc1f Michael Hanselmann
574 3016bc1f Michael Hanselmann
  # Mark instance as offline
575 3016bc1f Michael Hanselmann
  AssertCommand(["gnt-instance", "modify", "--offline", name])
576 3016bc1f Michael Hanselmann
577 1ba25bad Guido Trotter
  # When the instance is offline shutdown should only work with --force,
578 1ba25bad Guido Trotter
  # while start should never work
579 1ba25bad Guido Trotter
  AssertCommand(["gnt-instance", "shutdown", name], fail=True)
580 1ba25bad Guido Trotter
  AssertCommand(["gnt-instance", "shutdown", "--force", name])
581 1ba25bad Guido Trotter
  AssertCommand(["gnt-instance", "start", name], fail=True)
582 1ba25bad Guido Trotter
  AssertCommand(["gnt-instance", "start", "--force", name], fail=True)
583 1ba25bad Guido Trotter
584 1ba25bad Guido Trotter
  # Also do offline to offline
585 1ba25bad Guido Trotter
  AssertCommand(["gnt-instance", "modify", "--offline", name])
586 1ba25bad Guido Trotter
587 3016bc1f Michael Hanselmann
  # And online again
588 3016bc1f Michael Hanselmann
  AssertCommand(["gnt-instance", "modify", "--online", name])
589 3016bc1f Michael Hanselmann
590 c0f74c55 Iustin Pop
591 5fa0375e Michael Hanselmann
@InstanceCheck(INST_DOWN, INST_DOWN, FIRST_ARG)
592 c99200a3 Bernardo Dal Seno
def TestInstanceConvertDiskToPlain(instance, inodes):
593 7f69aabb Iustin Pop
  """gnt-instance modify -t"""
594 b5f33afa Michael Hanselmann
  name = instance.name
595 68c8c3df Michael Hanselmann
596 02a5fe0e Michael Hanselmann
  template = instance.disk_template
597 68c8c3df Michael Hanselmann
  if template != constants.DT_DRBD8:
598 5de31440 Bernardo Dal Seno
    print qa_utils.FormatInfo("Unsupported template %s, skipping conversion"
599 5de31440 Bernardo Dal Seno
                              " test" % template)
600 5de31440 Bernardo Dal Seno
    return
601 68c8c3df Michael Hanselmann
602 c99200a3 Bernardo Dal Seno
  assert len(inodes) == 2
603 68c8c3df Michael Hanselmann
  AssertCommand(["gnt-instance", "modify", "-t", constants.DT_PLAIN, name])
604 68c8c3df Michael Hanselmann
  AssertCommand(["gnt-instance", "modify", "-t", constants.DT_DRBD8,
605 aecba21e Michael Hanselmann
                 "-n", inodes[1].primary, name])
606 7f69aabb Iustin Pop
607 7f69aabb Iustin Pop
608 5fa0375e Michael Hanselmann
@InstanceCheck(INST_DOWN, INST_DOWN, FIRST_ARG)
609 26a5056d Iustin Pop
def TestInstanceGrowDisk(instance):
610 26a5056d Iustin Pop
  """gnt-instance grow-disk"""
611 5de31440 Bernardo Dal Seno
  if qa_config.GetExclusiveStorage():
612 5de31440 Bernardo Dal Seno
    print qa_utils.FormatInfo("Test not supported with exclusive_storage")
613 5de31440 Bernardo Dal Seno
    return
614 59c75517 Michael Hanselmann
615 59c75517 Michael Hanselmann
  if instance.disk_template == constants.DT_DISKLESS:
616 59c75517 Michael Hanselmann
    print qa_utils.FormatInfo("Test not supported for diskless instances")
617 59c75517 Michael Hanselmann
    return
618 59c75517 Michael Hanselmann
619 b5f33afa Michael Hanselmann
  name = instance.name
620 26a5056d Iustin Pop
  all_size = qa_config.get("disk")
621 26a5056d Iustin Pop
  all_grow = qa_config.get("disk-growth")
622 59c75517 Michael Hanselmann
623 26a5056d Iustin Pop
  if not all_grow:
624 26a5056d Iustin Pop
    # missing disk sizes but instance grow disk has been enabled,
625 26a5056d Iustin Pop
    # let's set fixed/nomimal growth
626 26a5056d Iustin Pop
    all_grow = ["128M" for _ in all_size]
627 59c75517 Michael Hanselmann
628 26a5056d Iustin Pop
  for idx, (size, grow) in enumerate(zip(all_size, all_grow)):
629 26a5056d Iustin Pop
    # succeed in grow by amount
630 26a5056d Iustin Pop
    AssertCommand(["gnt-instance", "grow-disk", name, str(idx), grow])
631 26a5056d Iustin Pop
    # fail in grow to the old size
632 26a5056d Iustin Pop
    AssertCommand(["gnt-instance", "grow-disk", "--absolute", name, str(idx),
633 26a5056d Iustin Pop
                   size], fail=True)
634 26a5056d Iustin Pop
    # succeed to grow to old size + 2 * growth
635 26a5056d Iustin Pop
    int_size = utils.ParseUnit(size)
636 26a5056d Iustin Pop
    int_grow = utils.ParseUnit(grow)
637 26a5056d Iustin Pop
    AssertCommand(["gnt-instance", "grow-disk", "--absolute", name, str(idx),
638 26a5056d Iustin Pop
                   str(int_size + 2 * int_grow)])
639 26a5056d Iustin Pop
640 26a5056d Iustin Pop
641 283f9d4c Michael Hanselmann
def TestInstanceList():
642 283f9d4c Michael Hanselmann
  """gnt-instance list"""
643 288d6440 Michael Hanselmann
  qa_utils.GenericQueryTest("gnt-instance", query.INSTANCE_FIELDS.keys())
644 283f9d4c Michael Hanselmann
645 283f9d4c Michael Hanselmann
646 2214cf14 Michael Hanselmann
def TestInstanceListFields():
647 2214cf14 Michael Hanselmann
  """gnt-instance list-fields"""
648 2214cf14 Michael Hanselmann
  qa_utils.GenericQueryFieldsTest("gnt-instance", query.INSTANCE_FIELDS.keys())
649 2214cf14 Michael Hanselmann
650 2214cf14 Michael Hanselmann
651 5fa0375e Michael Hanselmann
@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
652 4379b1fa Michael Hanselmann
def TestInstanceConsole(instance):
653 4379b1fa Michael Hanselmann
  """gnt-instance console"""
654 b5f33afa Michael Hanselmann
  AssertCommand(["gnt-instance", "console", "--show-cmd", instance.name])
655 4379b1fa Michael Hanselmann
656 4379b1fa Michael Hanselmann
657 5fa0375e Michael Hanselmann
@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
658 c99200a3 Bernardo Dal Seno
def TestReplaceDisks(instance, curr_nodes, other_nodes):
659 7910e7a5 Michael Hanselmann
  """gnt-instance replace-disks"""
660 7910e7a5 Michael Hanselmann
  def buildcmd(args):
661 d0c8c01d Iustin Pop
    cmd = ["gnt-instance", "replace-disks"]
662 7910e7a5 Michael Hanselmann
    cmd.extend(args)
663 b5f33afa Michael Hanselmann
    cmd.append(instance.name)
664 7910e7a5 Michael Hanselmann
    return cmd
665 7910e7a5 Michael Hanselmann
666 5de31440 Bernardo Dal Seno
  if not IsDiskReplacingSupported(instance):
667 5de31440 Bernardo Dal Seno
    print qa_utils.FormatInfo("Instance doesn't support disk replacing,"
668 5de31440 Bernardo Dal Seno
                              " skipping test")
669 5de31440 Bernardo Dal Seno
    return
670 5de31440 Bernardo Dal Seno
671 c99200a3 Bernardo Dal Seno
  # Currently all supported templates have one primary and one secondary node
672 c99200a3 Bernardo Dal Seno
  assert len(curr_nodes) == 2
673 c99200a3 Bernardo Dal Seno
  snode = curr_nodes[1]
674 c99200a3 Bernardo Dal Seno
  assert len(other_nodes) == 1
675 c99200a3 Bernardo Dal Seno
  othernode = other_nodes[0]
676 c99200a3 Bernardo Dal Seno
677 e85be22a Bernardo Dal Seno
  options = qa_config.get("options", {})
678 e85be22a Bernardo Dal Seno
  use_ialloc = options.get("use-iallocators", True)
679 2f4b4f78 Iustin Pop
  for data in [
680 2f4b4f78 Iustin Pop
    ["-p"],
681 2f4b4f78 Iustin Pop
    ["-s"],
682 e85be22a Bernardo Dal Seno
    # A placeholder; the actual command choice depends on use_ialloc
683 e85be22a Bernardo Dal Seno
    None,
684 e85be22a Bernardo Dal Seno
    # Restore the original secondary
685 aecba21e Michael Hanselmann
    ["--new-secondary=%s" % snode.primary],
686 2f4b4f78 Iustin Pop
    ]:
687 e85be22a Bernardo Dal Seno
    if data is None:
688 e85be22a Bernardo Dal Seno
      if use_ialloc:
689 e85be22a Bernardo Dal Seno
        data = ["-I", constants.DEFAULT_IALLOCATOR_SHORTCUT]
690 e85be22a Bernardo Dal Seno
      else:
691 aecba21e Michael Hanselmann
        data = ["--new-secondary=%s" % othernode.primary]
692 2f4b4f78 Iustin Pop
    AssertCommand(buildcmd(data))
693 7910e7a5 Michael Hanselmann
694 9026e935 René Nussbaumer
  AssertCommand(buildcmd(["-a"]))
695 b5f33afa Michael Hanselmann
  AssertCommand(["gnt-instance", "stop", instance.name])
696 9026e935 René Nussbaumer
  AssertCommand(buildcmd(["-a"]), fail=True)
697 b5f33afa Michael Hanselmann
  AssertCommand(["gnt-instance", "activate-disks", instance.name])
698 32da72f3 Iustin Pop
  AssertCommand(["gnt-instance", "activate-disks", "--wait-for-sync",
699 b5f33afa Michael Hanselmann
                 instance.name])
700 9026e935 René Nussbaumer
  AssertCommand(buildcmd(["-a"]))
701 b5f33afa Michael Hanselmann
  AssertCommand(["gnt-instance", "start", instance.name])
702 9026e935 René Nussbaumer
703 7910e7a5 Michael Hanselmann
704 83180411 Bernardo Dal Seno
def _AssertRecreateDisks(cmdargs, instance, fail=False, check=True,
705 83180411 Bernardo Dal Seno
                         destroy=True):
706 83180411 Bernardo Dal Seno
  """Execute gnt-instance recreate-disks and check the result
707 83180411 Bernardo Dal Seno

708 83180411 Bernardo Dal Seno
  @param cmdargs: Arguments (instance name excluded)
709 83180411 Bernardo Dal Seno
  @param instance: Instance to operate on
710 83180411 Bernardo Dal Seno
  @param fail: True if the command is expected to fail
711 83180411 Bernardo Dal Seno
  @param check: If True and fail is False, check that the disks work
712 83180411 Bernardo Dal Seno
  @prama destroy: If True, destroy the old disks first
713 83180411 Bernardo Dal Seno

714 83180411 Bernardo Dal Seno
  """
715 83180411 Bernardo Dal Seno
  if destroy:
716 83180411 Bernardo Dal Seno
    _DestroyInstanceVolumes(instance)
717 83180411 Bernardo Dal Seno
  AssertCommand((["gnt-instance", "recreate-disks"] + cmdargs +
718 b5f33afa Michael Hanselmann
                 [instance.name]), fail)
719 83180411 Bernardo Dal Seno
  if not fail and check:
720 83180411 Bernardo Dal Seno
    # Quick check that the disks are there
721 b5f33afa Michael Hanselmann
    AssertCommand(["gnt-instance", "activate-disks", instance.name])
722 32da72f3 Iustin Pop
    AssertCommand(["gnt-instance", "activate-disks", "--wait-for-sync",
723 b5f33afa Michael Hanselmann
                   instance.name])
724 b5f33afa Michael Hanselmann
    AssertCommand(["gnt-instance", "deactivate-disks", instance.name])
725 83180411 Bernardo Dal Seno
726 a1cd2ecf Bernardo Dal Seno
727 83180411 Bernardo Dal Seno
@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
728 c99200a3 Bernardo Dal Seno
def TestRecreateDisks(instance, inodes, othernodes):
729 83180411 Bernardo Dal Seno
  """gnt-instance recreate-disks
730 83180411 Bernardo Dal Seno

731 83180411 Bernardo Dal Seno
  @param instance: Instance to work on
732 c99200a3 Bernardo Dal Seno
  @param inodes: List of the current nodes of the instance
733 83180411 Bernardo Dal Seno
  @param othernodes: list/tuple of nodes where to temporarily recreate disks
734 83180411 Bernardo Dal Seno

735 83180411 Bernardo Dal Seno
  """
736 e85be22a Bernardo Dal Seno
  options = qa_config.get("options", {})
737 e85be22a Bernardo Dal Seno
  use_ialloc = options.get("use-iallocators", True)
738 aecba21e Michael Hanselmann
  other_seq = ":".join([n.primary for n in othernodes])
739 aecba21e Michael Hanselmann
  orig_seq = ":".join([n.primary for n in inodes])
740 a085d96d Bernardo Dal Seno
  # These fail because the instance is running
741 83180411 Bernardo Dal Seno
  _AssertRecreateDisks(["-n", other_seq], instance, fail=True, destroy=False)
742 e85be22a Bernardo Dal Seno
  if use_ialloc:
743 e85be22a Bernardo Dal Seno
    _AssertRecreateDisks(["-I", "hail"], instance, fail=True, destroy=False)
744 e85be22a Bernardo Dal Seno
  else:
745 e85be22a Bernardo Dal Seno
    _AssertRecreateDisks(["-n", other_seq], instance, fail=True, destroy=False)
746 b5f33afa Michael Hanselmann
  AssertCommand(["gnt-instance", "stop", instance.name])
747 83180411 Bernardo Dal Seno
  # Disks exist: this should fail
748 83180411 Bernardo Dal Seno
  _AssertRecreateDisks([], instance, fail=True, destroy=False)
749 83180411 Bernardo Dal Seno
  # Recreate disks in place
750 83180411 Bernardo Dal Seno
  _AssertRecreateDisks([], instance)
751 83180411 Bernardo Dal Seno
  # Move disks away
752 e85be22a Bernardo Dal Seno
  if use_ialloc:
753 e85be22a Bernardo Dal Seno
    _AssertRecreateDisks(["-I", "hail"], instance)
754 e85be22a Bernardo Dal Seno
    # Move disks somewhere else
755 e85be22a Bernardo Dal Seno
    _AssertRecreateDisks(["-I", constants.DEFAULT_IALLOCATOR_SHORTCUT],
756 e85be22a Bernardo Dal Seno
                         instance)
757 e85be22a Bernardo Dal Seno
  else:
758 e85be22a Bernardo Dal Seno
    _AssertRecreateDisks(["-n", other_seq], instance)
759 83180411 Bernardo Dal Seno
  # Move disks back
760 83180411 Bernardo Dal Seno
  _AssertRecreateDisks(["-n", orig_seq], instance, check=False)
761 83180411 Bernardo Dal Seno
  # This and InstanceCheck decoration check that the disks are working
762 b5f33afa Michael Hanselmann
  AssertCommand(["gnt-instance", "reinstall", "-f", instance.name])
763 b5f33afa Michael Hanselmann
  AssertCommand(["gnt-instance", "start", instance.name])
764 83180411 Bernardo Dal Seno
765 83180411 Bernardo Dal Seno
766 5fa0375e Michael Hanselmann
@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
767 5d640672 Michael Hanselmann
def TestInstanceExport(instance, node):
768 bc696589 Michael Hanselmann
  """gnt-backup export -n ..."""
769 b5f33afa Michael Hanselmann
  name = instance.name
770 aecba21e Michael Hanselmann
  AssertCommand(["gnt-backup", "export", "-n", node.primary, name])
771 2f4b4f78 Iustin Pop
  return qa_utils.ResolveInstanceName(name)
772 5d640672 Michael Hanselmann
773 5d640672 Michael Hanselmann
774 51131cad Michael Hanselmann
@InstanceCheck(None, INST_DOWN, FIRST_ARG)
775 8d8d650c Michael Hanselmann
def TestInstanceExportWithRemove(instance, node):
776 8d8d650c Michael Hanselmann
  """gnt-backup export --remove-instance"""
777 aecba21e Michael Hanselmann
  AssertCommand(["gnt-backup", "export", "-n", node.primary,
778 b5f33afa Michael Hanselmann
                 "--remove-instance", instance.name])
779 8d8d650c Michael Hanselmann
780 8d8d650c Michael Hanselmann
781 5fa0375e Michael Hanselmann
@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
782 bc696589 Michael Hanselmann
def TestInstanceExportNoTarget(instance):
783 bc696589 Michael Hanselmann
  """gnt-backup export (without target node, should fail)"""
784 b5f33afa Michael Hanselmann
  AssertCommand(["gnt-backup", "export", instance.name], fail=True)
785 bc696589 Michael Hanselmann
786 bc696589 Michael Hanselmann
787 51131cad Michael Hanselmann
@InstanceCheck(None, INST_DOWN, FIRST_ARG)
788 5fa0375e Michael Hanselmann
def TestInstanceImport(newinst, node, expnode, name):
789 5d640672 Michael Hanselmann
  """gnt-backup import"""
790 906a0346 Bernardo Dal Seno
  templ = constants.DT_PLAIN
791 d0c8c01d Iustin Pop
  cmd = (["gnt-backup", "import",
792 906a0346 Bernardo Dal Seno
          "--disk-template=%s" % templ,
793 d0c8c01d Iustin Pop
          "--no-ip-check",
794 aecba21e Michael Hanselmann
          "--src-node=%s" % expnode.primary,
795 304d9f02 Michael Hanselmann
          "--src-dir=%s/%s" % (pathutils.EXPORT_DIR, name),
796 aecba21e Michael Hanselmann
          "--node=%s" % node.primary] +
797 59c75517 Michael Hanselmann
         _GetGenericAddParameters(newinst, templ,
798 59c75517 Michael Hanselmann
                                  force_mac=constants.VALUE_GENERATE))
799 b5f33afa Michael Hanselmann
  cmd.append(newinst.name)
800 2f4b4f78 Iustin Pop
  AssertCommand(cmd)
801 02a5fe0e Michael Hanselmann
  newinst.SetDiskTemplate(templ)
802 283f9d4c Michael Hanselmann
803 283f9d4c Michael Hanselmann
804 283f9d4c Michael Hanselmann
def TestBackupList(expnode):
805 283f9d4c Michael Hanselmann
  """gnt-backup list"""
806 aecba21e Michael Hanselmann
  AssertCommand(["gnt-backup", "list", "--node=%s" % expnode.primary])
807 e8ae0c20 Michael Hanselmann
808 0fdf247d Michael Hanselmann
  qa_utils.GenericQueryTest("gnt-backup", query.EXPORT_FIELDS.keys(),
809 0fdf247d Michael Hanselmann
                            namefield=None, test_unknown=False)
810 0fdf247d Michael Hanselmann
811 0fdf247d Michael Hanselmann
812 0fdf247d Michael Hanselmann
def TestBackupListFields():
813 0fdf247d Michael Hanselmann
  """gnt-backup list-fields"""
814 0fdf247d Michael Hanselmann
  qa_utils.GenericQueryFieldsTest("gnt-backup", query.EXPORT_FIELDS.keys())
815 f006f110 Bernardo Dal Seno
816 f006f110 Bernardo Dal Seno
817 f006f110 Bernardo Dal Seno
def TestRemoveInstanceOfflineNode(instance, snode, set_offline, set_online):
818 f006f110 Bernardo Dal Seno
  """gtn-instance remove with an off-line node
819 f006f110 Bernardo Dal Seno

820 f006f110 Bernardo Dal Seno
  @param instance: instance
821 f006f110 Bernardo Dal Seno
  @param snode: secondary node, to be set offline
822 f006f110 Bernardo Dal Seno
  @param set_offline: function to call to set the node off-line
823 f006f110 Bernardo Dal Seno
  @param set_online: function to call to set the node on-line
824 f006f110 Bernardo Dal Seno

825 f006f110 Bernardo Dal Seno
  """
826 b5f33afa Michael Hanselmann
  info = _GetInstanceInfo(instance.name)
827 f006f110 Bernardo Dal Seno
  set_offline(snode)
828 f006f110 Bernardo Dal Seno
  try:
829 f006f110 Bernardo Dal Seno
    TestInstanceRemove(instance)
830 f006f110 Bernardo Dal Seno
  finally:
831 f006f110 Bernardo Dal Seno
    set_online(snode)
832 f006f110 Bernardo Dal Seno
  # Clean up the disks on the offline node
833 aecba21e Michael Hanselmann
  for minor in info["drbd-minors"][snode.primary]:
834 f006f110 Bernardo Dal Seno
    AssertCommand(["drbdsetup", str(minor), "down"], node=snode)
835 f006f110 Bernardo Dal Seno
  AssertCommand(["lvremove", "-f"] + info["volumes"], node=snode)