Statistics
| Branch: | Tag: | Revision:

root / qa / qa_instance.py @ deaa347b

History | View | Annotate | Download (26.5 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 e8ae0c20 Michael Hanselmann
import re
27 e8ae0c20 Michael Hanselmann
import time
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 1c573fb4 Iustin Pop
def _GetGenericAddParameters(inst, 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 d0c8c01d Iustin Pop
  for idx, size in enumerate(qa_config.get("disk")):
53 1d693311 Michael Hanselmann
    params.extend(["--disk", "%s:size=%s" % (idx, size)])
54 f346a7d9 Michael Hanselmann
55 f346a7d9 Michael Hanselmann
  # Set static MAC address if configured
56 1c573fb4 Iustin Pop
  if force_mac:
57 1c573fb4 Iustin Pop
    nic0_mac = force_mac
58 1c573fb4 Iustin Pop
  else:
59 1c573fb4 Iustin Pop
    nic0_mac = qa_config.GetInstanceNicMac(inst)
60 f346a7d9 Michael Hanselmann
  if nic0_mac:
61 f346a7d9 Michael Hanselmann
    params.extend(["--net", "0:mac=%s" % nic0_mac])
62 f346a7d9 Michael Hanselmann
63 1d693311 Michael Hanselmann
  return params
64 5d640672 Michael Hanselmann
65 5d640672 Michael Hanselmann
66 113b8d89 Michael Hanselmann
def _DiskTest(node, disk_template):
67 cec9845c Michael Hanselmann
  instance = qa_config.AcquireInstance()
68 cec9845c Michael Hanselmann
  try:
69 d0c8c01d Iustin Pop
    cmd = (["gnt-instance", "add",
70 d0c8c01d Iustin Pop
            "--os-type=%s" % qa_config.get("os"),
71 d0c8c01d Iustin Pop
            "--disk-template=%s" % disk_template,
72 d0c8c01d Iustin Pop
            "--node=%s" % node] +
73 f346a7d9 Michael Hanselmann
           _GetGenericAddParameters(instance))
74 d0c8c01d Iustin Pop
    cmd.append(instance["name"])
75 cec9845c Michael Hanselmann
76 2f4b4f78 Iustin Pop
    AssertCommand(cmd)
77 6a343475 Michael Hanselmann
78 6a343475 Michael Hanselmann
    _CheckSsconfInstanceList(instance["name"])
79 6a343475 Michael Hanselmann
80 cec9845c Michael Hanselmann
    return instance
81 cec9845c Michael Hanselmann
  except:
82 cec9845c Michael Hanselmann
    qa_config.ReleaseInstance(instance)
83 cec9845c Michael Hanselmann
    raise
84 cec9845c Michael Hanselmann
85 cec9845c Michael Hanselmann
86 cc4b14f0 Bernardo Dal Seno
def _GetInstanceInfo(instance):
87 cc4b14f0 Bernardo Dal Seno
  """Return information about the actual state of an instance.
88 82d2f3df Bernardo Dal Seno

89 b07afbb3 Iustin Pop
  @type instance: string
90 b07afbb3 Iustin Pop
  @param instance: the instance name
91 b07afbb3 Iustin Pop
  @return: a dictionary with two keys:
92 b07afbb3 Iustin Pop
      - "nodes": instance nodes, a list of strings
93 b07afbb3 Iustin Pop
      - "volumes": instance volume IDs, a list of strings
94 82d2f3df Bernardo Dal Seno

95 82d2f3df Bernardo Dal Seno
  """
96 82d2f3df Bernardo Dal Seno
  master = qa_config.GetMasterNode()
97 b07afbb3 Iustin Pop
  infocmd = utils.ShellQuoteArgs(["gnt-instance", "info", instance])
98 82d2f3df Bernardo Dal Seno
  info_out = qa_utils.GetCommandOutput(master["primary"], infocmd)
99 82d2f3df Bernardo Dal Seno
  re_node = re.compile(r"^\s+-\s+(?:primary|secondaries):\s+(\S.+)$")
100 82d2f3df Bernardo Dal Seno
  node_elem = r"([^,()]+)(?:\s+\([^)]+\))?"
101 82d2f3df Bernardo Dal Seno
  # re_nodelist matches a list of nodes returned by gnt-instance info, e.g.:
102 82d2f3df Bernardo Dal Seno
  #  node1.fqdn
103 82d2f3df Bernardo Dal Seno
  #  node2.fqdn,node3.fqdn
104 82d2f3df Bernardo Dal Seno
  #  node4.fqdn (group mygroup, group UUID 01234567-abcd-0123-4567-0123456789ab)
105 82d2f3df Bernardo Dal Seno
  # FIXME This works with no more than 2 secondaries
106 82d2f3df Bernardo Dal Seno
  re_nodelist = re.compile(node_elem + "(?:," + node_elem + ")?$")
107 82d2f3df Bernardo Dal Seno
  re_vol = re.compile(r"^\s+logical_id:\s+(\S+)$")
108 82d2f3df Bernardo Dal Seno
  nodes = []
109 82d2f3df Bernardo Dal Seno
  vols = []
110 82d2f3df Bernardo Dal Seno
  for line in info_out.splitlines():
111 82d2f3df Bernardo Dal Seno
    m = re_node.match(line)
112 82d2f3df Bernardo Dal Seno
    if m:
113 82d2f3df Bernardo Dal Seno
      nodestr = m.group(1)
114 82d2f3df Bernardo Dal Seno
      m2 = re_nodelist.match(nodestr)
115 82d2f3df Bernardo Dal Seno
      if m2:
116 82d2f3df Bernardo Dal Seno
        nodes.extend(filter(None, m2.groups()))
117 82d2f3df Bernardo Dal Seno
      else:
118 82d2f3df Bernardo Dal Seno
        nodes.append(nodestr)
119 82d2f3df Bernardo Dal Seno
    m = re_vol.match(line)
120 82d2f3df Bernardo Dal Seno
    if m:
121 82d2f3df Bernardo Dal Seno
      vols.append(m.group(1))
122 82d2f3df Bernardo Dal Seno
  assert vols
123 82d2f3df Bernardo Dal Seno
  assert nodes
124 cc4b14f0 Bernardo Dal Seno
  return {"nodes": nodes, "volumes": vols}
125 cc4b14f0 Bernardo Dal Seno
126 cc4b14f0 Bernardo Dal Seno
127 cc4b14f0 Bernardo Dal Seno
def _DestroyInstanceVolumes(instance):
128 cc4b14f0 Bernardo Dal Seno
  """Remove all the LVM volumes of an instance.
129 cc4b14f0 Bernardo Dal Seno

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

135 cc4b14f0 Bernardo Dal Seno
  """
136 b07afbb3 Iustin Pop
  info = _GetInstanceInfo(instance["name"])
137 cc4b14f0 Bernardo Dal Seno
  vols = info["volumes"]
138 cc4b14f0 Bernardo Dal Seno
  for node in info["nodes"]:
139 82d2f3df Bernardo Dal Seno
    AssertCommand(["lvremove", "-f"] + vols, node=node)
140 82d2f3df Bernardo Dal Seno
141 82d2f3df Bernardo Dal Seno
142 d55408b0 Bernardo Dal Seno
def _GetBoolInstanceField(instance, field):
143 d55408b0 Bernardo Dal Seno
  """Get the Boolean value of a field of an instance.
144 d55408b0 Bernardo Dal Seno

145 d55408b0 Bernardo Dal Seno
  @type instance: string
146 d55408b0 Bernardo Dal Seno
  @param instance: Instance name
147 d55408b0 Bernardo Dal Seno
  @type field: string
148 d55408b0 Bernardo Dal Seno
  @param field: Name of the field
149 d55408b0 Bernardo Dal Seno

150 d55408b0 Bernardo Dal Seno
  """
151 d55408b0 Bernardo Dal Seno
  master = qa_config.GetMasterNode()
152 d55408b0 Bernardo Dal Seno
  infocmd = utils.ShellQuoteArgs(["gnt-instance", "list", "--no-headers",
153 d55408b0 Bernardo Dal Seno
                                  "-o", field, instance])
154 d55408b0 Bernardo Dal Seno
  info_out = qa_utils.GetCommandOutput(master["primary"], infocmd).strip()
155 d55408b0 Bernardo Dal Seno
  if info_out == "Y":
156 d55408b0 Bernardo Dal Seno
    return True
157 d55408b0 Bernardo Dal Seno
  elif info_out == "N":
158 d55408b0 Bernardo Dal Seno
    return False
159 d55408b0 Bernardo Dal Seno
  else:
160 d55408b0 Bernardo Dal Seno
    raise qa_error.Error("Field %s of instance %s has a non-Boolean value:"
161 d55408b0 Bernardo Dal Seno
                         " %s" % (field, instance, info_out))
162 d55408b0 Bernardo Dal Seno
163 d55408b0 Bernardo Dal Seno
164 5fa0375e Michael Hanselmann
@InstanceCheck(None, INST_UP, RETURN_VALUE)
165 cec9845c Michael Hanselmann
def TestInstanceAddWithPlainDisk(node):
166 cec9845c Michael Hanselmann
  """gnt-instance add -t plain"""
167 d0c8c01d Iustin Pop
  return _DiskTest(node["primary"], "plain")
168 cec9845c Michael Hanselmann
169 cec9845c Michael Hanselmann
170 5fa0375e Michael Hanselmann
@InstanceCheck(None, INST_UP, RETURN_VALUE)
171 7d7609a3 Michael Hanselmann
def TestInstanceAddWithDrbdDisk(node, node2):
172 7d7609a3 Michael Hanselmann
  """gnt-instance add -t drbd"""
173 d0c8c01d Iustin Pop
  return _DiskTest("%s:%s" % (node["primary"], node2["primary"]),
174 d0c8c01d Iustin Pop
                   "drbd")
175 7d7609a3 Michael Hanselmann
176 7d7609a3 Michael Hanselmann
177 5fa0375e Michael Hanselmann
@InstanceCheck(None, INST_DOWN, FIRST_ARG)
178 cec9845c Michael Hanselmann
def TestInstanceRemove(instance):
179 cec9845c Michael Hanselmann
  """gnt-instance remove"""
180 2f4b4f78 Iustin Pop
  AssertCommand(["gnt-instance", "remove", "-f", instance["name"]])
181 cec9845c Michael Hanselmann
182 cec9845c Michael Hanselmann
  qa_config.ReleaseInstance(instance)
183 cec9845c Michael Hanselmann
184 cec9845c Michael Hanselmann
185 5fa0375e Michael Hanselmann
@InstanceCheck(INST_DOWN, INST_UP, FIRST_ARG)
186 cec9845c Michael Hanselmann
def TestInstanceStartup(instance):
187 cec9845c Michael Hanselmann
  """gnt-instance startup"""
188 2f4b4f78 Iustin Pop
  AssertCommand(["gnt-instance", "startup", instance["name"]])
189 cec9845c Michael Hanselmann
190 cec9845c Michael Hanselmann
191 5fa0375e Michael Hanselmann
@InstanceCheck(INST_UP, INST_DOWN, FIRST_ARG)
192 cec9845c Michael Hanselmann
def TestInstanceShutdown(instance):
193 cec9845c Michael Hanselmann
  """gnt-instance shutdown"""
194 2f4b4f78 Iustin Pop
  AssertCommand(["gnt-instance", "shutdown", instance["name"]])
195 cec9845c Michael Hanselmann
196 cec9845c Michael Hanselmann
197 5fa0375e Michael Hanselmann
@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
198 8a4e8898 Michael Hanselmann
def TestInstanceReboot(instance):
199 8a4e8898 Michael Hanselmann
  """gnt-instance reboot"""
200 d0c8c01d Iustin Pop
  options = qa_config.get("options", {})
201 1d103c02 Iustin Pop
  reboot_types = options.get("reboot-types", constants.REBOOT_TYPES)
202 2f4b4f78 Iustin Pop
  name = instance["name"]
203 1d103c02 Iustin Pop
  for rtype in reboot_types:
204 2f4b4f78 Iustin Pop
    AssertCommand(["gnt-instance", "reboot", "--type=%s" % rtype, name])
205 8a4e8898 Michael Hanselmann
206 cc27265e René Nussbaumer
  AssertCommand(["gnt-instance", "shutdown", name])
207 5fa0375e Michael Hanselmann
  qa_utils.RunInstanceCheck(instance, False)
208 cc27265e René Nussbaumer
  AssertCommand(["gnt-instance", "reboot", name])
209 cc27265e René Nussbaumer
210 cc27265e René Nussbaumer
  master = qa_config.GetMasterNode()
211 58ea8d17 Michael Hanselmann
  cmd = ["gnt-instance", "list", "--no-headers", "-o", "status", name]
212 cc27265e René Nussbaumer
  result_output = qa_utils.GetCommandOutput(master["primary"],
213 cc27265e René Nussbaumer
                                            utils.ShellQuoteArgs(cmd))
214 cc27265e René Nussbaumer
  AssertEqual(result_output.strip(), constants.INSTST_RUNNING)
215 cc27265e René Nussbaumer
216 8a4e8898 Michael Hanselmann
217 5fa0375e Michael Hanselmann
@InstanceCheck(INST_DOWN, INST_DOWN, FIRST_ARG)
218 283f9d4c Michael Hanselmann
def TestInstanceReinstall(instance):
219 283f9d4c Michael Hanselmann
  """gnt-instance reinstall"""
220 2f4b4f78 Iustin Pop
  AssertCommand(["gnt-instance", "reinstall", "-f", instance["name"]])
221 283f9d4c Michael Hanselmann
222 64be07b1 Michael Hanselmann
  # Test with non-existant OS definition
223 64be07b1 Michael Hanselmann
  AssertCommand(["gnt-instance", "reinstall", "-f",
224 64be07b1 Michael Hanselmann
                 "--os-type=NonExistantOsForQa",
225 64be07b1 Michael Hanselmann
                 instance["name"]],
226 64be07b1 Michael Hanselmann
                fail=True)
227 64be07b1 Michael Hanselmann
228 283f9d4c Michael Hanselmann
229 6a343475 Michael Hanselmann
def _ReadSsconfInstanceList():
230 6a343475 Michael Hanselmann
  """Reads ssconf_instance_list from the master node.
231 6a343475 Michael Hanselmann

232 6a343475 Michael Hanselmann
  """
233 6a343475 Michael Hanselmann
  master = qa_config.GetMasterNode()
234 6a343475 Michael Hanselmann
235 304d9f02 Michael Hanselmann
  cmd = ["cat", utils.PathJoin(pathutils.DATA_DIR,
236 6a343475 Michael Hanselmann
                               "ssconf_%s" % constants.SS_INSTANCE_LIST)]
237 6a343475 Michael Hanselmann
238 6a343475 Michael Hanselmann
  return qa_utils.GetCommandOutput(master["primary"],
239 6a343475 Michael Hanselmann
                                   utils.ShellQuoteArgs(cmd)).splitlines()
240 6a343475 Michael Hanselmann
241 6a343475 Michael Hanselmann
242 6a343475 Michael Hanselmann
def _CheckSsconfInstanceList(instance):
243 6a343475 Michael Hanselmann
  """Checks if a certain instance is in the ssconf instance list.
244 6a343475 Michael Hanselmann

245 6a343475 Michael Hanselmann
  @type instance: string
246 6a343475 Michael Hanselmann
  @param instance: Instance name
247 6a343475 Michael Hanselmann

248 6a343475 Michael Hanselmann
  """
249 6a343475 Michael Hanselmann
  AssertIn(qa_utils.ResolveInstanceName(instance),
250 6a343475 Michael Hanselmann
           _ReadSsconfInstanceList())
251 6a343475 Michael Hanselmann
252 6a343475 Michael Hanselmann
253 51131cad Michael Hanselmann
@InstanceCheck(INST_DOWN, INST_DOWN, FIRST_ARG)
254 4c1a464b Iustin Pop
def TestInstanceRenameAndBack(rename_source, rename_target):
255 4c1a464b Iustin Pop
  """gnt-instance rename
256 4c1a464b Iustin Pop

257 4c1a464b Iustin Pop
  This must leave the instance with the original name, not the target
258 4c1a464b Iustin Pop
  name.
259 4c1a464b Iustin Pop

260 4c1a464b Iustin Pop
  """
261 31fe5102 René Nussbaumer
  _CheckSsconfInstanceList(rename_source)
262 5fa0375e Michael Hanselmann
263 4c1a464b Iustin Pop
  # first do a rename to a different actual name, expecting it to fail
264 31fe5102 René Nussbaumer
  qa_utils.AddToEtcHosts(["meeeeh-not-exists", rename_target])
265 31fe5102 René Nussbaumer
  try:
266 31fe5102 René Nussbaumer
    AssertCommand(["gnt-instance", "rename", rename_source, rename_target],
267 31fe5102 René Nussbaumer
                  fail=True)
268 31fe5102 René Nussbaumer
    _CheckSsconfInstanceList(rename_source)
269 31fe5102 René Nussbaumer
  finally:
270 31fe5102 René Nussbaumer
    qa_utils.RemoveFromEtcHosts(["meeeeh-not-exists", rename_target])
271 5fa0375e Michael Hanselmann
272 b07afbb3 Iustin Pop
  # Check instance volume tags correctly updated
273 b07afbb3 Iustin Pop
  # FIXME: this is LVM specific!
274 b07afbb3 Iustin Pop
  info = _GetInstanceInfo(rename_source)
275 b07afbb3 Iustin Pop
  tags_cmd = ("lvs -o tags --noheadings %s | grep " %
276 b07afbb3 Iustin Pop
              (" ".join(info["volumes"]), ))
277 b07afbb3 Iustin Pop
278 4c1a464b Iustin Pop
  # and now rename instance to rename_target...
279 31fe5102 René Nussbaumer
  AssertCommand(["gnt-instance", "rename", rename_source, rename_target])
280 31fe5102 René Nussbaumer
  _CheckSsconfInstanceList(rename_target)
281 5fa0375e Michael Hanselmann
  qa_utils.RunInstanceCheck(rename_source, False)
282 51131cad Michael Hanselmann
  qa_utils.RunInstanceCheck(rename_target, False)
283 5fa0375e Michael Hanselmann
284 b07afbb3 Iustin Pop
  # NOTE: tags might not be the exactly as the instance name, due to
285 b07afbb3 Iustin Pop
  # charset restrictions; hence the test might be flaky
286 b07afbb3 Iustin Pop
  if rename_source != rename_target:
287 b07afbb3 Iustin Pop
    for node in info["nodes"]:
288 b07afbb3 Iustin Pop
      AssertCommand(tags_cmd + rename_source, node=node, fail=True)
289 b07afbb3 Iustin Pop
      AssertCommand(tags_cmd + rename_target, node=node, fail=False)
290 b07afbb3 Iustin Pop
291 4c1a464b Iustin Pop
  # and back
292 4c1a464b Iustin Pop
  AssertCommand(["gnt-instance", "rename", rename_target, rename_source])
293 4c1a464b Iustin Pop
  _CheckSsconfInstanceList(rename_source)
294 5fa0375e Michael Hanselmann
  qa_utils.RunInstanceCheck(rename_target, False)
295 18337ca9 Iustin Pop
296 b07afbb3 Iustin Pop
  if rename_source != rename_target:
297 b07afbb3 Iustin Pop
    for node in info["nodes"]:
298 b07afbb3 Iustin Pop
      AssertCommand(tags_cmd + rename_source, node=node, fail=False)
299 b07afbb3 Iustin Pop
      AssertCommand(tags_cmd + rename_target, node=node, fail=True)
300 b07afbb3 Iustin Pop
301 18337ca9 Iustin Pop
302 5fa0375e Michael Hanselmann
@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
303 cec9845c Michael Hanselmann
def TestInstanceFailover(instance):
304 cec9845c Michael Hanselmann
  """gnt-instance failover"""
305 d0c8c01d Iustin Pop
  cmd = ["gnt-instance", "failover", "--force", instance["name"]]
306 5fa0375e Michael Hanselmann
307 2f4b4f78 Iustin Pop
  # failover ...
308 2f4b4f78 Iustin Pop
  AssertCommand(cmd)
309 5fa0375e Michael Hanselmann
  qa_utils.RunInstanceCheck(instance, True)
310 5fa0375e Michael Hanselmann
311 76f59a32 Michael Hanselmann
  # ... and back
312 2f4b4f78 Iustin Pop
  AssertCommand(cmd)
313 76f59a32 Michael Hanselmann
314 cec9845c Michael Hanselmann
315 5fa0375e Michael Hanselmann
@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
316 d55408b0 Bernardo Dal Seno
def TestInstanceMigrate(instance, toggle_always_failover=True):
317 938bde86 Michael Hanselmann
  """gnt-instance migrate"""
318 938bde86 Michael Hanselmann
  cmd = ["gnt-instance", "migrate", "--force", instance["name"]]
319 d55408b0 Bernardo Dal Seno
  af_par = constants.BE_ALWAYS_FAILOVER
320 d55408b0 Bernardo Dal Seno
  af_field = "be/" + constants.BE_ALWAYS_FAILOVER
321 d55408b0 Bernardo Dal Seno
  af_init_val = _GetBoolInstanceField(instance["name"], af_field)
322 5fa0375e Michael Hanselmann
323 2f4b4f78 Iustin Pop
  # migrate ...
324 2f4b4f78 Iustin Pop
  AssertCommand(cmd)
325 d55408b0 Bernardo Dal Seno
  # TODO: Verify the choice between failover and migration
326 5fa0375e Michael Hanselmann
  qa_utils.RunInstanceCheck(instance, True)
327 5fa0375e Michael Hanselmann
328 d55408b0 Bernardo Dal Seno
  # ... and back (possibly with always_failover toggled)
329 d55408b0 Bernardo Dal Seno
  if toggle_always_failover:
330 d55408b0 Bernardo Dal Seno
    AssertCommand(["gnt-instance", "modify", "-B",
331 d55408b0 Bernardo Dal Seno
                   ("%s=%s" % (af_par, not af_init_val)),
332 d55408b0 Bernardo Dal Seno
                   instance["name"]])
333 2f4b4f78 Iustin Pop
  AssertCommand(cmd)
334 d55408b0 Bernardo Dal Seno
  # TODO: Verify the choice between failover and migration
335 d55408b0 Bernardo Dal Seno
  qa_utils.RunInstanceCheck(instance, True)
336 d55408b0 Bernardo Dal Seno
  if toggle_always_failover:
337 d55408b0 Bernardo Dal Seno
    AssertCommand(["gnt-instance", "modify", "-B",
338 d55408b0 Bernardo Dal Seno
                   ("%s=%s" % (af_par, af_init_val)), instance["name"]])
339 5fa0375e Michael Hanselmann
340 5fa0375e Michael Hanselmann
  # TODO: Split into multiple tests
341 e9c487be René Nussbaumer
  AssertCommand(["gnt-instance", "shutdown", instance["name"]])
342 5fa0375e Michael Hanselmann
  qa_utils.RunInstanceCheck(instance, False)
343 e9c487be René Nussbaumer
  AssertCommand(cmd, fail=True)
344 e9c487be René Nussbaumer
  AssertCommand(["gnt-instance", "migrate", "--force", "--allow-failover",
345 e9c487be René Nussbaumer
                 instance["name"]])
346 e9c487be René Nussbaumer
  AssertCommand(["gnt-instance", "start", instance["name"]])
347 e9c487be René Nussbaumer
  AssertCommand(cmd)
348 d55408b0 Bernardo Dal Seno
  # @InstanceCheck enforces the check that the instance is running
349 5fa0375e Michael Hanselmann
  qa_utils.RunInstanceCheck(instance, True)
350 5fa0375e Michael Hanselmann
351 42a769f9 Bernardo Dal Seno
  AssertCommand(["gnt-instance", "modify", "-B",
352 42a769f9 Bernardo Dal Seno
                 ("%s=%s" %
353 42a769f9 Bernardo Dal Seno
                  (constants.BE_ALWAYS_FAILOVER, constants.VALUE_TRUE)),
354 42a769f9 Bernardo Dal Seno
                 instance["name"]])
355 5fa0375e Michael Hanselmann
356 320a5dae Bernardo Dal Seno
  AssertCommand(cmd)
357 5fa0375e Michael Hanselmann
  qa_utils.RunInstanceCheck(instance, True)
358 320a5dae Bernardo Dal Seno
  # TODO: Verify that a failover has been done instead of a migration
359 5fa0375e Michael Hanselmann
360 5fa0375e Michael Hanselmann
  # TODO: Verify whether the default value is restored here (not hardcoded)
361 42a769f9 Bernardo Dal Seno
  AssertCommand(["gnt-instance", "modify", "-B",
362 42a769f9 Bernardo Dal Seno
                 ("%s=%s" %
363 42a769f9 Bernardo Dal Seno
                  (constants.BE_ALWAYS_FAILOVER, constants.VALUE_FALSE)),
364 42a769f9 Bernardo Dal Seno
                 instance["name"]])
365 5fa0375e Michael Hanselmann
366 42a769f9 Bernardo Dal Seno
  AssertCommand(cmd)
367 5fa0375e Michael Hanselmann
  qa_utils.RunInstanceCheck(instance, True)
368 938bde86 Michael Hanselmann
369 938bde86 Michael Hanselmann
370 cec9845c Michael Hanselmann
def TestInstanceInfo(instance):
371 cec9845c Michael Hanselmann
  """gnt-instance info"""
372 2f4b4f78 Iustin Pop
  AssertCommand(["gnt-instance", "info", instance["name"]])
373 5d640672 Michael Hanselmann
374 5d640672 Michael Hanselmann
375 5fa0375e Michael Hanselmann
@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
376 c0f74c55 Iustin Pop
def TestInstanceModify(instance):
377 c0f74c55 Iustin Pop
  """gnt-instance modify"""
378 d488adb6 Michael Hanselmann
  default_hv = qa_config.GetDefaultHypervisor()
379 d488adb6 Michael Hanselmann
380 1d693311 Michael Hanselmann
  # Assume /sbin/init exists on all systems
381 1d693311 Michael Hanselmann
  test_kernel = "/sbin/init"
382 1d693311 Michael Hanselmann
  test_initrd = test_kernel
383 1d693311 Michael Hanselmann
384 8ccbbe4b Guido Trotter
  orig_maxmem = qa_config.get(constants.BE_MAXMEM)
385 8ccbbe4b Guido Trotter
  orig_minmem = qa_config.get(constants.BE_MINMEM)
386 2f4b4f78 Iustin Pop
  #orig_bridge = qa_config.get("bridge", "xen-br0")
387 d488adb6 Michael Hanselmann
388 c0f74c55 Iustin Pop
  args = [
389 8ccbbe4b Guido Trotter
    ["-B", "%s=128" % constants.BE_MINMEM],
390 8ccbbe4b Guido Trotter
    ["-B", "%s=128" % constants.BE_MAXMEM],
391 8ccbbe4b Guido Trotter
    ["-B", "%s=%s,%s=%s" % (constants.BE_MINMEM, orig_minmem,
392 8ccbbe4b Guido Trotter
                            constants.BE_MAXMEM, orig_maxmem)],
393 1d693311 Michael Hanselmann
    ["-B", "%s=2" % constants.BE_VCPUS],
394 1d693311 Michael Hanselmann
    ["-B", "%s=1" % constants.BE_VCPUS],
395 1d693311 Michael Hanselmann
    ["-B", "%s=%s" % (constants.BE_VCPUS, constants.VALUE_DEFAULT)],
396 42a769f9 Bernardo Dal Seno
    ["-B", "%s=%s" % (constants.BE_ALWAYS_FAILOVER, constants.VALUE_TRUE)],
397 42a769f9 Bernardo Dal Seno
    ["-B", "%s=%s" % (constants.BE_ALWAYS_FAILOVER, constants.VALUE_DEFAULT)],
398 1d693311 Michael Hanselmann
399 1d693311 Michael Hanselmann
    ["-H", "%s=%s" % (constants.HV_KERNEL_PATH, test_kernel)],
400 1d693311 Michael Hanselmann
    ["-H", "%s=%s" % (constants.HV_KERNEL_PATH, constants.VALUE_DEFAULT)],
401 1d693311 Michael Hanselmann
402 1d693311 Michael Hanselmann
    # TODO: bridge tests
403 1d693311 Michael Hanselmann
    #["--bridge", "xen-br1"],
404 1d693311 Michael Hanselmann
    #["--bridge", orig_bridge],
405 c0f74c55 Iustin Pop
    ]
406 d488adb6 Michael Hanselmann
407 d488adb6 Michael Hanselmann
  if default_hv == constants.HT_XEN_PVM:
408 d488adb6 Michael Hanselmann
    args.extend([
409 d488adb6 Michael Hanselmann
      ["-H", "%s=%s" % (constants.HV_INITRD_PATH, test_initrd)],
410 d488adb6 Michael Hanselmann
      ["-H", "no_%s" % (constants.HV_INITRD_PATH, )],
411 d488adb6 Michael Hanselmann
      ["-H", "%s=%s" % (constants.HV_INITRD_PATH, constants.VALUE_DEFAULT)],
412 d488adb6 Michael Hanselmann
      ])
413 d488adb6 Michael Hanselmann
  elif default_hv == constants.HT_XEN_HVM:
414 d488adb6 Michael Hanselmann
    args.extend([
415 d488adb6 Michael Hanselmann
      ["-H", "%s=acn" % constants.HV_BOOT_ORDER],
416 d488adb6 Michael Hanselmann
      ["-H", "%s=%s" % (constants.HV_BOOT_ORDER, constants.VALUE_DEFAULT)],
417 d488adb6 Michael Hanselmann
      ])
418 d488adb6 Michael Hanselmann
419 c0f74c55 Iustin Pop
  for alist in args:
420 2f4b4f78 Iustin Pop
    AssertCommand(["gnt-instance", "modify"] + alist + [instance["name"]])
421 c0f74c55 Iustin Pop
422 c0f74c55 Iustin Pop
  # check no-modify
423 2f4b4f78 Iustin Pop
  AssertCommand(["gnt-instance", "modify", instance["name"]], fail=True)
424 c0f74c55 Iustin Pop
425 1ba25bad Guido Trotter
  # Marking offline while instance is running must fail...
426 1ba25bad Guido Trotter
  AssertCommand(["gnt-instance", "modify", "--offline", instance["name"]],
427 1ba25bad Guido Trotter
                 fail=True)
428 1ba25bad Guido Trotter
429 1ba25bad Guido Trotter
  # ...while making it online is ok, and should work
430 1ba25bad Guido Trotter
  AssertCommand(["gnt-instance", "modify", "--online", instance["name"]])
431 3016bc1f Michael Hanselmann
432 3016bc1f Michael Hanselmann
433 5fa0375e Michael Hanselmann
@InstanceCheck(INST_DOWN, INST_DOWN, FIRST_ARG)
434 3016bc1f Michael Hanselmann
def TestInstanceStoppedModify(instance):
435 3016bc1f Michael Hanselmann
  """gnt-instance modify (stopped instance)"""
436 3016bc1f Michael Hanselmann
  name = instance["name"]
437 3016bc1f Michael Hanselmann
438 58f0ce16 Michael Hanselmann
  # Instance was not marked offline; try marking it online once more
439 58f0ce16 Michael Hanselmann
  AssertCommand(["gnt-instance", "modify", "--online", name])
440 3016bc1f Michael Hanselmann
441 3016bc1f Michael Hanselmann
  # Mark instance as offline
442 3016bc1f Michael Hanselmann
  AssertCommand(["gnt-instance", "modify", "--offline", name])
443 3016bc1f Michael Hanselmann
444 1ba25bad Guido Trotter
  # When the instance is offline shutdown should only work with --force,
445 1ba25bad Guido Trotter
  # while start should never work
446 1ba25bad Guido Trotter
  AssertCommand(["gnt-instance", "shutdown", name], fail=True)
447 1ba25bad Guido Trotter
  AssertCommand(["gnt-instance", "shutdown", "--force", name])
448 1ba25bad Guido Trotter
  AssertCommand(["gnt-instance", "start", name], fail=True)
449 1ba25bad Guido Trotter
  AssertCommand(["gnt-instance", "start", "--force", name], fail=True)
450 1ba25bad Guido Trotter
451 1ba25bad Guido Trotter
  # Also do offline to offline
452 1ba25bad Guido Trotter
  AssertCommand(["gnt-instance", "modify", "--offline", name])
453 1ba25bad Guido Trotter
454 3016bc1f Michael Hanselmann
  # And online again
455 3016bc1f Michael Hanselmann
  AssertCommand(["gnt-instance", "modify", "--online", name])
456 3016bc1f Michael Hanselmann
457 c0f74c55 Iustin Pop
458 5fa0375e Michael Hanselmann
@InstanceCheck(INST_DOWN, INST_DOWN, FIRST_ARG)
459 7f69aabb Iustin Pop
def TestInstanceConvertDisk(instance, snode):
460 7f69aabb Iustin Pop
  """gnt-instance modify -t"""
461 2f4b4f78 Iustin Pop
  name = instance["name"]
462 2f4b4f78 Iustin Pop
  AssertCommand(["gnt-instance", "modify", "-t", "plain", name])
463 2f4b4f78 Iustin Pop
  AssertCommand(["gnt-instance", "modify", "-t", "drbd",
464 2f4b4f78 Iustin Pop
                 "-n", snode["primary"], name])
465 7f69aabb Iustin Pop
466 7f69aabb Iustin Pop
467 5fa0375e Michael Hanselmann
@InstanceCheck(INST_DOWN, INST_DOWN, FIRST_ARG)
468 26a5056d Iustin Pop
def TestInstanceGrowDisk(instance):
469 26a5056d Iustin Pop
  """gnt-instance grow-disk"""
470 26a5056d Iustin Pop
  name = instance["name"]
471 26a5056d Iustin Pop
  all_size = qa_config.get("disk")
472 26a5056d Iustin Pop
  all_grow = qa_config.get("disk-growth")
473 26a5056d Iustin Pop
  if not all_grow:
474 26a5056d Iustin Pop
    # missing disk sizes but instance grow disk has been enabled,
475 26a5056d Iustin Pop
    # let's set fixed/nomimal growth
476 26a5056d Iustin Pop
    all_grow = ["128M" for _ in all_size]
477 26a5056d Iustin Pop
  for idx, (size, grow) in enumerate(zip(all_size, all_grow)):
478 26a5056d Iustin Pop
    # succeed in grow by amount
479 26a5056d Iustin Pop
    AssertCommand(["gnt-instance", "grow-disk", name, str(idx), grow])
480 26a5056d Iustin Pop
    # fail in grow to the old size
481 26a5056d Iustin Pop
    AssertCommand(["gnt-instance", "grow-disk", "--absolute", name, str(idx),
482 26a5056d Iustin Pop
                   size], fail=True)
483 26a5056d Iustin Pop
    # succeed to grow to old size + 2 * growth
484 26a5056d Iustin Pop
    int_size = utils.ParseUnit(size)
485 26a5056d Iustin Pop
    int_grow = utils.ParseUnit(grow)
486 26a5056d Iustin Pop
    AssertCommand(["gnt-instance", "grow-disk", "--absolute", name, str(idx),
487 26a5056d Iustin Pop
                   str(int_size + 2 * int_grow)])
488 26a5056d Iustin Pop
489 26a5056d Iustin Pop
490 283f9d4c Michael Hanselmann
def TestInstanceList():
491 283f9d4c Michael Hanselmann
  """gnt-instance list"""
492 288d6440 Michael Hanselmann
  qa_utils.GenericQueryTest("gnt-instance", query.INSTANCE_FIELDS.keys())
493 283f9d4c Michael Hanselmann
494 283f9d4c Michael Hanselmann
495 2214cf14 Michael Hanselmann
def TestInstanceListFields():
496 2214cf14 Michael Hanselmann
  """gnt-instance list-fields"""
497 2214cf14 Michael Hanselmann
  qa_utils.GenericQueryFieldsTest("gnt-instance", query.INSTANCE_FIELDS.keys())
498 2214cf14 Michael Hanselmann
499 2214cf14 Michael Hanselmann
500 5fa0375e Michael Hanselmann
@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
501 4379b1fa Michael Hanselmann
def TestInstanceConsole(instance):
502 4379b1fa Michael Hanselmann
  """gnt-instance console"""
503 2f4b4f78 Iustin Pop
  AssertCommand(["gnt-instance", "console", "--show-cmd", instance["name"]])
504 4379b1fa Michael Hanselmann
505 4379b1fa Michael Hanselmann
506 5fa0375e Michael Hanselmann
@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
507 7910e7a5 Michael Hanselmann
def TestReplaceDisks(instance, pnode, snode, othernode):
508 7910e7a5 Michael Hanselmann
  """gnt-instance replace-disks"""
509 b459a848 Andrea Spadaccini
  # pylint: disable=W0613
510 3582eef6 Iustin Pop
  # due to unused pnode arg
511 3582eef6 Iustin Pop
  # FIXME: should be removed from the function completely
512 7910e7a5 Michael Hanselmann
  def buildcmd(args):
513 d0c8c01d Iustin Pop
    cmd = ["gnt-instance", "replace-disks"]
514 7910e7a5 Michael Hanselmann
    cmd.extend(args)
515 7910e7a5 Michael Hanselmann
    cmd.append(instance["name"])
516 7910e7a5 Michael Hanselmann
    return cmd
517 7910e7a5 Michael Hanselmann
518 e85be22a Bernardo Dal Seno
  options = qa_config.get("options", {})
519 e85be22a Bernardo Dal Seno
  use_ialloc = options.get("use-iallocators", True)
520 2f4b4f78 Iustin Pop
  for data in [
521 2f4b4f78 Iustin Pop
    ["-p"],
522 2f4b4f78 Iustin Pop
    ["-s"],
523 e85be22a Bernardo Dal Seno
    # A placeholder; the actual command choice depends on use_ialloc
524 e85be22a Bernardo Dal Seno
    None,
525 e85be22a Bernardo Dal Seno
    # Restore the original secondary
526 e85be22a Bernardo Dal Seno
    ["--new-secondary=%s" % snode["primary"]],
527 2f4b4f78 Iustin Pop
    ]:
528 e85be22a Bernardo Dal Seno
    if data is None:
529 e85be22a Bernardo Dal Seno
      if use_ialloc:
530 e85be22a Bernardo Dal Seno
        data = ["-I", constants.DEFAULT_IALLOCATOR_SHORTCUT]
531 e85be22a Bernardo Dal Seno
      else:
532 e85be22a Bernardo Dal Seno
        data = ["--new-secondary=%s" % othernode["primary"]]
533 2f4b4f78 Iustin Pop
    AssertCommand(buildcmd(data))
534 7910e7a5 Michael Hanselmann
535 9026e935 René Nussbaumer
  AssertCommand(buildcmd(["-a"]))
536 9026e935 René Nussbaumer
  AssertCommand(["gnt-instance", "stop", instance["name"]])
537 9026e935 René Nussbaumer
  AssertCommand(buildcmd(["-a"]), fail=True)
538 9026e935 René Nussbaumer
  AssertCommand(["gnt-instance", "activate-disks", instance["name"]])
539 32da72f3 Iustin Pop
  AssertCommand(["gnt-instance", "activate-disks", "--wait-for-sync",
540 32da72f3 Iustin Pop
                 instance["name"]])
541 9026e935 René Nussbaumer
  AssertCommand(buildcmd(["-a"]))
542 9026e935 René Nussbaumer
  AssertCommand(["gnt-instance", "start", instance["name"]])
543 9026e935 René Nussbaumer
544 7910e7a5 Michael Hanselmann
545 83180411 Bernardo Dal Seno
def _AssertRecreateDisks(cmdargs, instance, fail=False, check=True,
546 83180411 Bernardo Dal Seno
                         destroy=True):
547 83180411 Bernardo Dal Seno
  """Execute gnt-instance recreate-disks and check the result
548 83180411 Bernardo Dal Seno

549 83180411 Bernardo Dal Seno
  @param cmdargs: Arguments (instance name excluded)
550 83180411 Bernardo Dal Seno
  @param instance: Instance to operate on
551 83180411 Bernardo Dal Seno
  @param fail: True if the command is expected to fail
552 83180411 Bernardo Dal Seno
  @param check: If True and fail is False, check that the disks work
553 83180411 Bernardo Dal Seno
  @prama destroy: If True, destroy the old disks first
554 83180411 Bernardo Dal Seno

555 83180411 Bernardo Dal Seno
  """
556 83180411 Bernardo Dal Seno
  if destroy:
557 83180411 Bernardo Dal Seno
    _DestroyInstanceVolumes(instance)
558 83180411 Bernardo Dal Seno
  AssertCommand((["gnt-instance", "recreate-disks"] + cmdargs +
559 83180411 Bernardo Dal Seno
                 [instance["name"]]), fail)
560 83180411 Bernardo Dal Seno
  if not fail and check:
561 83180411 Bernardo Dal Seno
    # Quick check that the disks are there
562 83180411 Bernardo Dal Seno
    AssertCommand(["gnt-instance", "activate-disks", instance["name"]])
563 32da72f3 Iustin Pop
    AssertCommand(["gnt-instance", "activate-disks", "--wait-for-sync",
564 32da72f3 Iustin Pop
                   instance["name"]])
565 83180411 Bernardo Dal Seno
    AssertCommand(["gnt-instance", "deactivate-disks", instance["name"]])
566 83180411 Bernardo Dal Seno
567 a1cd2ecf Bernardo Dal Seno
568 83180411 Bernardo Dal Seno
@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
569 83180411 Bernardo Dal Seno
def TestRecreateDisks(instance, pnode, snode, othernodes):
570 83180411 Bernardo Dal Seno
  """gnt-instance recreate-disks
571 83180411 Bernardo Dal Seno

572 83180411 Bernardo Dal Seno
  @param instance: Instance to work on
573 83180411 Bernardo Dal Seno
  @param pnode: Primary node
574 83180411 Bernardo Dal Seno
  @param snode: Secondary node, or None for sigle-homed instances
575 83180411 Bernardo Dal Seno
  @param othernodes: list/tuple of nodes where to temporarily recreate disks
576 83180411 Bernardo Dal Seno

577 83180411 Bernardo Dal Seno
  """
578 e85be22a Bernardo Dal Seno
  options = qa_config.get("options", {})
579 e85be22a Bernardo Dal Seno
  use_ialloc = options.get("use-iallocators", True)
580 83180411 Bernardo Dal Seno
  other_seq = ":".join([n["primary"] for n in othernodes])
581 83180411 Bernardo Dal Seno
  orig_seq = pnode["primary"]
582 83180411 Bernardo Dal Seno
  if snode:
583 83180411 Bernardo Dal Seno
    orig_seq = orig_seq + ":" + snode["primary"]
584 a085d96d Bernardo Dal Seno
  # These fail because the instance is running
585 83180411 Bernardo Dal Seno
  _AssertRecreateDisks(["-n", other_seq], instance, fail=True, destroy=False)
586 e85be22a Bernardo Dal Seno
  if use_ialloc:
587 e85be22a Bernardo Dal Seno
    _AssertRecreateDisks(["-I", "hail"], instance, fail=True, destroy=False)
588 e85be22a Bernardo Dal Seno
  else:
589 e85be22a Bernardo Dal Seno
    _AssertRecreateDisks(["-n", other_seq], instance, fail=True, destroy=False)
590 83180411 Bernardo Dal Seno
  AssertCommand(["gnt-instance", "stop", instance["name"]])
591 83180411 Bernardo Dal Seno
  # Disks exist: this should fail
592 83180411 Bernardo Dal Seno
  _AssertRecreateDisks([], instance, fail=True, destroy=False)
593 83180411 Bernardo Dal Seno
  # Recreate disks in place
594 83180411 Bernardo Dal Seno
  _AssertRecreateDisks([], instance)
595 83180411 Bernardo Dal Seno
  # Move disks away
596 e85be22a Bernardo Dal Seno
  if use_ialloc:
597 e85be22a Bernardo Dal Seno
    _AssertRecreateDisks(["-I", "hail"], instance)
598 e85be22a Bernardo Dal Seno
    # Move disks somewhere else
599 e85be22a Bernardo Dal Seno
    _AssertRecreateDisks(["-I", constants.DEFAULT_IALLOCATOR_SHORTCUT],
600 e85be22a Bernardo Dal Seno
                         instance)
601 e85be22a Bernardo Dal Seno
  else:
602 e85be22a Bernardo Dal Seno
    _AssertRecreateDisks(["-n", other_seq], instance)
603 83180411 Bernardo Dal Seno
  # Move disks back
604 83180411 Bernardo Dal Seno
  _AssertRecreateDisks(["-n", orig_seq], instance, check=False)
605 83180411 Bernardo Dal Seno
  # This and InstanceCheck decoration check that the disks are working
606 83180411 Bernardo Dal Seno
  AssertCommand(["gnt-instance", "reinstall", "-f", instance["name"]])
607 83180411 Bernardo Dal Seno
  AssertCommand(["gnt-instance", "start", instance["name"]])
608 83180411 Bernardo Dal Seno
609 83180411 Bernardo Dal Seno
610 5fa0375e Michael Hanselmann
@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
611 5d640672 Michael Hanselmann
def TestInstanceExport(instance, node):
612 bc696589 Michael Hanselmann
  """gnt-backup export -n ..."""
613 2f4b4f78 Iustin Pop
  name = instance["name"]
614 2f4b4f78 Iustin Pop
  AssertCommand(["gnt-backup", "export", "-n", node["primary"], name])
615 2f4b4f78 Iustin Pop
  return qa_utils.ResolveInstanceName(name)
616 5d640672 Michael Hanselmann
617 5d640672 Michael Hanselmann
618 51131cad Michael Hanselmann
@InstanceCheck(None, INST_DOWN, FIRST_ARG)
619 8d8d650c Michael Hanselmann
def TestInstanceExportWithRemove(instance, node):
620 8d8d650c Michael Hanselmann
  """gnt-backup export --remove-instance"""
621 2f4b4f78 Iustin Pop
  AssertCommand(["gnt-backup", "export", "-n", node["primary"],
622 2f4b4f78 Iustin Pop
                 "--remove-instance", instance["name"]])
623 deaa347b Bernardo Dal Seno
  qa_config.ReleaseInstance(instance)
624 8d8d650c Michael Hanselmann
625 8d8d650c Michael Hanselmann
626 5fa0375e Michael Hanselmann
@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
627 bc696589 Michael Hanselmann
def TestInstanceExportNoTarget(instance):
628 bc696589 Michael Hanselmann
  """gnt-backup export (without target node, should fail)"""
629 2f4b4f78 Iustin Pop
  AssertCommand(["gnt-backup", "export", instance["name"]], fail=True)
630 bc696589 Michael Hanselmann
631 bc696589 Michael Hanselmann
632 51131cad Michael Hanselmann
@InstanceCheck(None, INST_DOWN, FIRST_ARG)
633 5fa0375e Michael Hanselmann
def TestInstanceImport(newinst, node, expnode, name):
634 5d640672 Michael Hanselmann
  """gnt-backup import"""
635 d0c8c01d Iustin Pop
  cmd = (["gnt-backup", "import",
636 d0c8c01d Iustin Pop
          "--disk-template=plain",
637 d0c8c01d Iustin Pop
          "--no-ip-check",
638 d0c8c01d Iustin Pop
          "--src-node=%s" % expnode["primary"],
639 304d9f02 Michael Hanselmann
          "--src-dir=%s/%s" % (pathutils.EXPORT_DIR, name),
640 d0c8c01d Iustin Pop
          "--node=%s" % node["primary"]] +
641 1c573fb4 Iustin Pop
         _GetGenericAddParameters(newinst, force_mac=constants.VALUE_GENERATE))
642 d0c8c01d Iustin Pop
  cmd.append(newinst["name"])
643 2f4b4f78 Iustin Pop
  AssertCommand(cmd)
644 283f9d4c Michael Hanselmann
645 283f9d4c Michael Hanselmann
646 283f9d4c Michael Hanselmann
def TestBackupList(expnode):
647 283f9d4c Michael Hanselmann
  """gnt-backup list"""
648 2f4b4f78 Iustin Pop
  AssertCommand(["gnt-backup", "list", "--node=%s" % expnode["primary"]])
649 e8ae0c20 Michael Hanselmann
650 0fdf247d Michael Hanselmann
  qa_utils.GenericQueryTest("gnt-backup", query.EXPORT_FIELDS.keys(),
651 0fdf247d Michael Hanselmann
                            namefield=None, test_unknown=False)
652 0fdf247d Michael Hanselmann
653 0fdf247d Michael Hanselmann
654 0fdf247d Michael Hanselmann
def TestBackupListFields():
655 0fdf247d Michael Hanselmann
  """gnt-backup list-fields"""
656 0fdf247d Michael Hanselmann
  qa_utils.GenericQueryFieldsTest("gnt-backup", query.EXPORT_FIELDS.keys())
657 0fdf247d Michael Hanselmann
658 e8ae0c20 Michael Hanselmann
659 e8ae0c20 Michael Hanselmann
def _TestInstanceDiskFailure(instance, node, node2, onmaster):
660 e8ae0c20 Michael Hanselmann
  """Testing disk failure."""
661 e8ae0c20 Michael Hanselmann
  master = qa_config.GetMasterNode()
662 e8ae0c20 Michael Hanselmann
  sq = utils.ShellQuoteArgs
663 e8ae0c20 Michael Hanselmann
664 46f9a948 Michael Hanselmann
  instance_full = qa_utils.ResolveInstanceName(instance["name"])
665 e8ae0c20 Michael Hanselmann
  node_full = qa_utils.ResolveNodeName(node)
666 e8ae0c20 Michael Hanselmann
  node2_full = qa_utils.ResolveNodeName(node2)
667 e8ae0c20 Michael Hanselmann
668 29df1f02 Michael Hanselmann
  print qa_utils.FormatInfo("Getting physical disk names")
669 d0c8c01d Iustin Pop
  cmd = ["gnt-node", "volumes", "--separator=|", "--no-headers",
670 d0c8c01d Iustin Pop
         "--output=node,phys,instance",
671 d0c8c01d Iustin Pop
         node["primary"], node2["primary"]]
672 d0c8c01d Iustin Pop
  output = qa_utils.GetCommandOutput(master["primary"], sq(cmd))
673 e8ae0c20 Michael Hanselmann
674 e8ae0c20 Michael Hanselmann
  # Get physical disk names
675 d0c8c01d Iustin Pop
  re_disk = re.compile(r"^/dev/([a-z]+)\d+$")
676 e8ae0c20 Michael Hanselmann
  node2disk = {}
677 e8ae0c20 Michael Hanselmann
  for line in output.splitlines():
678 d0c8c01d Iustin Pop
    (node_name, phys, inst) = line.split("|")
679 e8ae0c20 Michael Hanselmann
    if inst == instance_full:
680 e8ae0c20 Michael Hanselmann
      if node_name not in node2disk:
681 e8ae0c20 Michael Hanselmann
        node2disk[node_name] = []
682 e8ae0c20 Michael Hanselmann
683 e8ae0c20 Michael Hanselmann
      m = re_disk.match(phys)
684 e8ae0c20 Michael Hanselmann
      if not m:
685 2f4b4f78 Iustin Pop
        raise qa_error.Error("Unknown disk name format: %s" % phys)
686 e8ae0c20 Michael Hanselmann
687 e8ae0c20 Michael Hanselmann
      name = m.group(1)
688 e8ae0c20 Michael Hanselmann
      if name not in node2disk[node_name]:
689 e8ae0c20 Michael Hanselmann
        node2disk[node_name].append(name)
690 e8ae0c20 Michael Hanselmann
691 e8ae0c20 Michael Hanselmann
  if [node2_full, node_full][int(onmaster)] not in node2disk:
692 f4bc1f2c Michael Hanselmann
    raise qa_error.Error("Couldn't find physical disks used on"
693 f4bc1f2c Michael Hanselmann
                         " %s node" % ["secondary", "master"][int(onmaster)])
694 e8ae0c20 Michael Hanselmann
695 29df1f02 Michael Hanselmann
  print qa_utils.FormatInfo("Checking whether nodes have ability to stop"
696 29df1f02 Michael Hanselmann
                            " disks")
697 e8ae0c20 Michael Hanselmann
  for node_name, disks in node2disk.iteritems():
698 e8ae0c20 Michael Hanselmann
    cmds = []
699 e8ae0c20 Michael Hanselmann
    for disk in disks:
700 e8ae0c20 Michael Hanselmann
      cmds.append(sq(["test", "-f", _GetDiskStatePath(disk)]))
701 2f4b4f78 Iustin Pop
    AssertCommand(" && ".join(cmds), node=node_name)
702 e8ae0c20 Michael Hanselmann
703 29df1f02 Michael Hanselmann
  print qa_utils.FormatInfo("Getting device paths")
704 d0c8c01d Iustin Pop
  cmd = ["gnt-instance", "activate-disks", instance["name"]]
705 d0c8c01d Iustin Pop
  output = qa_utils.GetCommandOutput(master["primary"], sq(cmd))
706 e8ae0c20 Michael Hanselmann
  devpath = []
707 e8ae0c20 Michael Hanselmann
  for line in output.splitlines():
708 d0c8c01d Iustin Pop
    (_, _, tmpdevpath) = line.split(":")
709 e8ae0c20 Michael Hanselmann
    devpath.append(tmpdevpath)
710 29df1f02 Michael Hanselmann
  print devpath
711 e8ae0c20 Michael Hanselmann
712 29df1f02 Michael Hanselmann
  print qa_utils.FormatInfo("Getting drbd device paths")
713 d0c8c01d Iustin Pop
  cmd = ["gnt-instance", "info", instance["name"]]
714 d0c8c01d Iustin Pop
  output = qa_utils.GetCommandOutput(master["primary"], sq(cmd))
715 d0c8c01d Iustin Pop
  pattern = (r"\s+-\s+sd[a-z]+,\s+type:\s+drbd8?,\s+.*$"
716 d0c8c01d Iustin Pop
             r"\s+primary:\s+(/dev/drbd\d+)\s+")
717 e8ae0c20 Michael Hanselmann
  drbddevs = re.findall(pattern, output, re.M)
718 29df1f02 Michael Hanselmann
  print drbddevs
719 e8ae0c20 Michael Hanselmann
720 e8ae0c20 Michael Hanselmann
  halted_disks = []
721 e8ae0c20 Michael Hanselmann
  try:
722 29df1f02 Michael Hanselmann
    print qa_utils.FormatInfo("Deactivating disks")
723 b1ffe1eb Michael Hanselmann
    cmds = []
724 b1ffe1eb Michael Hanselmann
    for name in node2disk[[node2_full, node_full][int(onmaster)]]:
725 b1ffe1eb Michael Hanselmann
      halted_disks.append(name)
726 b1ffe1eb Michael Hanselmann
      cmds.append(sq(["echo", "offline"]) + " >%s" % _GetDiskStatePath(name))
727 2f4b4f78 Iustin Pop
    AssertCommand(" && ".join(cmds), node=[node2, node][int(onmaster)])
728 b1ffe1eb Michael Hanselmann
729 29df1f02 Michael Hanselmann
    print qa_utils.FormatInfo("Write to disks and give some time to notice"
730 3bc145d8 Bernardo Dal Seno
                              " the problem")
731 e8ae0c20 Michael Hanselmann
    cmds = []
732 e8ae0c20 Michael Hanselmann
    for disk in devpath:
733 e8ae0c20 Michael Hanselmann
      cmds.append(sq(["dd", "count=1", "bs=512", "conv=notrunc",
734 e8ae0c20 Michael Hanselmann
                      "if=%s" % disk, "of=%s" % disk]))
735 e8ae0c20 Michael Hanselmann
    for _ in (0, 1, 2):
736 2f4b4f78 Iustin Pop
      AssertCommand(" && ".join(cmds), node=node)
737 e8ae0c20 Michael Hanselmann
      time.sleep(3)
738 e8ae0c20 Michael Hanselmann
739 29df1f02 Michael Hanselmann
    print qa_utils.FormatInfo("Debugging info")
740 b1ffe1eb Michael Hanselmann
    for name in drbddevs:
741 2f4b4f78 Iustin Pop
      AssertCommand(["drbdsetup", name, "show"], node=node)
742 b1ffe1eb Michael Hanselmann
743 2f4b4f78 Iustin Pop
    AssertCommand(["gnt-instance", "info", instance["name"]])
744 e8ae0c20 Michael Hanselmann
745 e8ae0c20 Michael Hanselmann
  finally:
746 29df1f02 Michael Hanselmann
    print qa_utils.FormatInfo("Activating disks again")
747 e8ae0c20 Michael Hanselmann
    cmds = []
748 e8ae0c20 Michael Hanselmann
    for name in halted_disks:
749 e8ae0c20 Michael Hanselmann
      cmds.append(sq(["echo", "running"]) + " >%s" % _GetDiskStatePath(name))
750 2f4b4f78 Iustin Pop
    AssertCommand("; ".join(cmds), node=[node2, node][int(onmaster)])
751 e8ae0c20 Michael Hanselmann
752 b1ffe1eb Michael Hanselmann
  if onmaster:
753 b1ffe1eb Michael Hanselmann
    for name in drbddevs:
754 2f4b4f78 Iustin Pop
      AssertCommand(["drbdsetup", name, "detach"], node=node)
755 b1ffe1eb Michael Hanselmann
  else:
756 b1ffe1eb Michael Hanselmann
    for name in drbddevs:
757 2f4b4f78 Iustin Pop
      AssertCommand(["drbdsetup", name, "disconnect"], node=node2)
758 b1ffe1eb Michael Hanselmann
759 29df1f02 Michael Hanselmann
  # TODO
760 2f4b4f78 Iustin Pop
  #AssertCommand(["vgs"], [node2, node][int(onmaster)])
761 b1ffe1eb Michael Hanselmann
762 29df1f02 Michael Hanselmann
  print qa_utils.FormatInfo("Making sure disks are up again")
763 2f4b4f78 Iustin Pop
  AssertCommand(["gnt-instance", "replace-disks", instance["name"]])
764 29df1f02 Michael Hanselmann
765 29df1f02 Michael Hanselmann
  print qa_utils.FormatInfo("Restarting instance")
766 2f4b4f78 Iustin Pop
  AssertCommand(["gnt-instance", "shutdown", instance["name"]])
767 2f4b4f78 Iustin Pop
  AssertCommand(["gnt-instance", "startup", instance["name"]])
768 e8ae0c20 Michael Hanselmann
769 2f4b4f78 Iustin Pop
  AssertCommand(["gnt-cluster", "verify"])
770 e8ae0c20 Michael Hanselmann
771 e8ae0c20 Michael Hanselmann
772 e8ae0c20 Michael Hanselmann
def TestInstanceMasterDiskFailure(instance, node, node2):
773 e8ae0c20 Michael Hanselmann
  """Testing disk failure on master node."""
774 b459a848 Andrea Spadaccini
  # pylint: disable=W0613
775 3582eef6 Iustin Pop
  # due to unused args
776 f4bc1f2c Michael Hanselmann
  print qa_utils.FormatError("Disk failure on primary node cannot be"
777 f4bc1f2c Michael Hanselmann
                             " tested due to potential crashes.")
778 e8ae0c20 Michael Hanselmann
  # The following can cause crashes, thus it's disabled until fixed
779 dfe11bad Michael Hanselmann
  #return _TestInstanceDiskFailure(instance, node, node2, True)
780 e8ae0c20 Michael Hanselmann
781 e8ae0c20 Michael Hanselmann
782 e8ae0c20 Michael Hanselmann
def TestInstanceSecondaryDiskFailure(instance, node, node2):
783 e8ae0c20 Michael Hanselmann
  """Testing disk failure on secondary node."""
784 e8ae0c20 Michael Hanselmann
  return _TestInstanceDiskFailure(instance, node, node2, False)