Statistics
| Branch: | Tag: | Revision:

root / qa / qa_cluster.py @ 2ef21e6e

History | View | Annotate | Download (30.5 kB)

1 c68d1f43 Michael Hanselmann
#
2 c68d1f43 Michael Hanselmann
#
3 c68d1f43 Michael Hanselmann
4 587f8ff6 Bernardo Dal Seno
# Copyright (C) 2007, 2010, 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
"""Cluster related QA tests.
23 cec9845c Michael Hanselmann

24 cec9845c Michael Hanselmann
"""
25 cec9845c Michael Hanselmann
26 587f8ff6 Bernardo Dal Seno
import re
27 cec9845c Michael Hanselmann
import tempfile
28 49ceab21 Michael Hanselmann
import os.path
29 cec9845c Michael Hanselmann
30 6d4a1656 Michael Hanselmann
from ganeti import constants
31 66d1f035 René Nussbaumer
from ganeti import compat
32 cec9845c Michael Hanselmann
from ganeti import utils
33 304d9f02 Michael Hanselmann
from ganeti import pathutils
34 cec9845c Michael Hanselmann
35 cec9845c Michael Hanselmann
import qa_config
36 cec9845c Michael Hanselmann
import qa_utils
37 cec9845c Michael Hanselmann
import qa_error
38 462f0faa Helga Velroyen
import qa_instance
39 cec9845c Michael Hanselmann
40 66d1f035 René Nussbaumer
from qa_utils import AssertEqual, AssertCommand, GetCommandOutput
41 cec9845c Michael Hanselmann
42 cec9845c Michael Hanselmann
43 23610ff8 Bernardo Dal Seno
# Prefix for LVM volumes created by QA code during tests
44 23610ff8 Bernardo Dal Seno
_QA_LV_PREFIX = "qa-"
45 23610ff8 Bernardo Dal Seno
46 c2a0947d Iustin Pop
#: cluster verify command
47 c2a0947d Iustin Pop
_CLUSTER_VERIFY = ["gnt-cluster", "verify"]
48 c2a0947d Iustin Pop
49 21bf2e2e Andrea Spadaccini
50 830da270 Michael Hanselmann
def _RemoveFileFromAllNodes(filename):
51 830da270 Michael Hanselmann
  """Removes a file from all nodes.
52 830da270 Michael Hanselmann

53 830da270 Michael Hanselmann
  """
54 2f4b4f78 Iustin Pop
  for node in qa_config.get("nodes"):
55 2f4b4f78 Iustin Pop
    AssertCommand(["rm", "-f", filename], node=node)
56 830da270 Michael Hanselmann
57 830da270 Michael Hanselmann
58 830da270 Michael Hanselmann
def _CheckFileOnAllNodes(filename, content):
59 830da270 Michael Hanselmann
  """Verifies the content of the given file on all nodes.
60 830da270 Michael Hanselmann

61 830da270 Michael Hanselmann
  """
62 830da270 Michael Hanselmann
  cmd = utils.ShellQuoteArgs(["cat", filename])
63 2f4b4f78 Iustin Pop
  for node in qa_config.get("nodes"):
64 aecba21e Michael Hanselmann
    AssertEqual(qa_utils.GetCommandOutput(node.primary, cmd), content)
65 830da270 Michael Hanselmann
66 830da270 Michael Hanselmann
67 0e79564a Bernardo Dal Seno
def _GetClusterField(field_path):
68 0e79564a Bernardo Dal Seno
  """Get the value of a cluster field.
69 17cfeee9 Bernardo Dal Seno

70 0e79564a Bernardo Dal Seno
  @type field_path: list of strings
71 0e79564a Bernardo Dal Seno
  @param field_path: Names of the groups/fields to navigate to get the desired
72 0e79564a Bernardo Dal Seno
      value, e.g. C{["Default node parameters", "oob_program"]}
73 0e79564a Bernardo Dal Seno
  @return: The effective value of the field (the actual type depends on the
74 0e79564a Bernardo Dal Seno
      chosen field)
75 17cfeee9 Bernardo Dal Seno

76 17cfeee9 Bernardo Dal Seno
  """
77 0e79564a Bernardo Dal Seno
  assert isinstance(field_path, list)
78 0e79564a Bernardo Dal Seno
  assert field_path
79 0e79564a Bernardo Dal Seno
  ret = qa_utils.GetObjectInfo(["gnt-cluster", "info"])
80 0e79564a Bernardo Dal Seno
  for key in field_path:
81 0e79564a Bernardo Dal Seno
    ret = ret[key]
82 0e79564a Bernardo Dal Seno
  return ret
83 17cfeee9 Bernardo Dal Seno
84 17cfeee9 Bernardo Dal Seno
85 587f8ff6 Bernardo Dal Seno
# Cluster-verify errors (date, "ERROR", then error code)
86 ab4832d1 Bernardo Dal Seno
_CVERROR_RE = re.compile(r"^[\w\s:]+\s+- (ERROR|WARNING):([A-Z0-9_-]+):")
87 587f8ff6 Bernardo Dal Seno
88 587f8ff6 Bernardo Dal Seno
89 587f8ff6 Bernardo Dal Seno
def _GetCVErrorCodes(cvout):
90 ab4832d1 Bernardo Dal Seno
  errs = set()
91 ab4832d1 Bernardo Dal Seno
  warns = set()
92 587f8ff6 Bernardo Dal Seno
  for l in cvout.splitlines():
93 587f8ff6 Bernardo Dal Seno
    m = _CVERROR_RE.match(l)
94 587f8ff6 Bernardo Dal Seno
    if m:
95 ab4832d1 Bernardo Dal Seno
      etype = m.group(1)
96 ab4832d1 Bernardo Dal Seno
      ecode = m.group(2)
97 ab4832d1 Bernardo Dal Seno
      if etype == "ERROR":
98 ab4832d1 Bernardo Dal Seno
        errs.add(ecode)
99 ab4832d1 Bernardo Dal Seno
      elif etype == "WARNING":
100 ab4832d1 Bernardo Dal Seno
        warns.add(ecode)
101 ab4832d1 Bernardo Dal Seno
  return (errs, warns)
102 587f8ff6 Bernardo Dal Seno
103 587f8ff6 Bernardo Dal Seno
104 ab4832d1 Bernardo Dal Seno
def _CheckVerifyErrors(actual, expected, etype):
105 ab4832d1 Bernardo Dal Seno
  exp_codes = compat.UniqueFrozenset(e for (_, e, _) in expected)
106 ab4832d1 Bernardo Dal Seno
  if not actual.issuperset(exp_codes):
107 ab4832d1 Bernardo Dal Seno
    missing = exp_codes.difference(actual)
108 ab4832d1 Bernardo Dal Seno
    raise qa_error.Error("Cluster-verify didn't return these expected"
109 ab4832d1 Bernardo Dal Seno
                         " %ss: %s" % (etype, utils.CommaJoin(missing)))
110 ab4832d1 Bernardo Dal Seno
111 ab4832d1 Bernardo Dal Seno
112 ab4832d1 Bernardo Dal Seno
def AssertClusterVerify(fail=False, errors=None, warnings=None):
113 587f8ff6 Bernardo Dal Seno
  """Run cluster-verify and check the result
114 587f8ff6 Bernardo Dal Seno

115 587f8ff6 Bernardo Dal Seno
  @type fail: bool
116 587f8ff6 Bernardo Dal Seno
  @param fail: if cluster-verify is expected to fail instead of succeeding
117 587f8ff6 Bernardo Dal Seno
  @type errors: list of tuples
118 587f8ff6 Bernardo Dal Seno
  @param errors: List of CV_XXX errors that are expected; if specified, all the
119 587f8ff6 Bernardo Dal Seno
      errors listed must appear in cluster-verify output. A non-empty value
120 587f8ff6 Bernardo Dal Seno
      implies C{fail=True}.
121 ab4832d1 Bernardo Dal Seno
  @type warnings: list of tuples
122 ab4832d1 Bernardo Dal Seno
  @param warnings: Same as C{errors} but for warnings.
123 587f8ff6 Bernardo Dal Seno

124 587f8ff6 Bernardo Dal Seno
  """
125 587f8ff6 Bernardo Dal Seno
  cvcmd = "gnt-cluster verify"
126 587f8ff6 Bernardo Dal Seno
  mnode = qa_config.GetMasterNode()
127 ab4832d1 Bernardo Dal Seno
  if errors or warnings:
128 aecba21e Michael Hanselmann
    cvout = GetCommandOutput(mnode.primary, cvcmd + " --error-codes",
129 ab4832d1 Bernardo Dal Seno
                             fail=(fail or errors))
130 ab4832d1 Bernardo Dal Seno
    (act_errs, act_warns) = _GetCVErrorCodes(cvout)
131 ab4832d1 Bernardo Dal Seno
    if errors:
132 ab4832d1 Bernardo Dal Seno
      _CheckVerifyErrors(act_errs, errors, "error")
133 ab4832d1 Bernardo Dal Seno
    if warnings:
134 ab4832d1 Bernardo Dal Seno
      _CheckVerifyErrors(act_warns, warnings, "warning")
135 587f8ff6 Bernardo Dal Seno
  else:
136 587f8ff6 Bernardo Dal Seno
    AssertCommand(cvcmd, fail=fail, node=mnode)
137 587f8ff6 Bernardo Dal Seno
138 587f8ff6 Bernardo Dal Seno
139 92cb4940 Andrea Spadaccini
# data for testing failures due to bad keys/values for disk parameters
140 92cb4940 Andrea Spadaccini
_FAIL_PARAMS = ["nonexistent:resync-rate=1",
141 92cb4940 Andrea Spadaccini
                "drbd:nonexistent=1",
142 92cb4940 Andrea Spadaccini
                "drbd:resync-rate=invalid",
143 92cb4940 Andrea Spadaccini
                ]
144 92cb4940 Andrea Spadaccini
145 92cb4940 Andrea Spadaccini
146 92cb4940 Andrea Spadaccini
def TestClusterInitDisk():
147 92cb4940 Andrea Spadaccini
  """gnt-cluster init -D"""
148 92cb4940 Andrea Spadaccini
  name = qa_config.get("name")
149 92cb4940 Andrea Spadaccini
  for param in _FAIL_PARAMS:
150 92cb4940 Andrea Spadaccini
    AssertCommand(["gnt-cluster", "init", "-D", param, name], fail=True)
151 92cb4940 Andrea Spadaccini
152 92cb4940 Andrea Spadaccini
153 725ec2f1 René Nussbaumer
def TestClusterInit(rapi_user, rapi_secret):
154 cec9845c Michael Hanselmann
  """gnt-cluster init"""
155 cec9845c Michael Hanselmann
  master = qa_config.GetMasterNode()
156 cec9845c Michael Hanselmann
157 734fd6b4 Michael Hanselmann
  rapi_users_path = qa_utils.MakeNodePath(master, pathutils.RAPI_USERS_FILE)
158 734fd6b4 Michael Hanselmann
  rapi_dir = os.path.dirname(rapi_users_path)
159 49ceab21 Michael Hanselmann
160 725ec2f1 René Nussbaumer
  # First create the RAPI credentials
161 a62d1901 Michael Hanselmann
  fh = tempfile.NamedTemporaryFile()
162 a62d1901 Michael Hanselmann
  try:
163 a62d1901 Michael Hanselmann
    fh.write("%s %s write\n" % (rapi_user, rapi_secret))
164 a62d1901 Michael Hanselmann
    fh.flush()
165 a62d1901 Michael Hanselmann
166 aecba21e Michael Hanselmann
    tmpru = qa_utils.UploadFile(master.primary, fh.name)
167 a62d1901 Michael Hanselmann
    try:
168 49ceab21 Michael Hanselmann
      AssertCommand(["mkdir", "-p", rapi_dir])
169 734fd6b4 Michael Hanselmann
      AssertCommand(["mv", tmpru, rapi_users_path])
170 a62d1901 Michael Hanselmann
    finally:
171 2f4b4f78 Iustin Pop
      AssertCommand(["rm", "-f", tmpru])
172 a62d1901 Michael Hanselmann
  finally:
173 a62d1901 Michael Hanselmann
    fh.close()
174 a62d1901 Michael Hanselmann
175 a62d1901 Michael Hanselmann
  # Initialize cluster
176 e7b6183b Michael Hanselmann
  cmd = [
177 e7b6183b Michael Hanselmann
    "gnt-cluster", "init",
178 e7b6183b Michael Hanselmann
    "--primary-ip-version=%d" % qa_config.get("primary_ip_version", 4),
179 59c1d41e Michael Hanselmann
    "--enabled-hypervisors=%s" % ",".join(qa_config.GetEnabledHypervisors()),
180 2dae8d64 Helga Velroyen
    "--enabled-disk-templates=%s" %
181 2dae8d64 Helga Velroyen
      ",".join(qa_config.GetEnabledDiskTemplates())
182 e7b6183b Michael Hanselmann
    ]
183 20286f7c René Nussbaumer
184 20286f7c René Nussbaumer
  for spec_type in ("mem-size", "disk-size", "disk-count", "cpu-count",
185 20286f7c René Nussbaumer
                    "nic-count"):
186 20286f7c René Nussbaumer
    for spec_val in ("min", "max", "std"):
187 20286f7c René Nussbaumer
      spec = qa_config.get("ispec_%s_%s" %
188 3601d488 Michael Hanselmann
                           (spec_type.replace("-", "_"), spec_val), None)
189 00650761 Michael Hanselmann
      if spec is not None:
190 20286f7c René Nussbaumer
        cmd.append("--specs-%s=%s=%d" % (spec_type, spec_val, spec))
191 9486f6ae Manuel Franceschini
192 aecba21e Michael Hanselmann
  if master.secondary:
193 aecba21e Michael Hanselmann
    cmd.append("--secondary-ip=%s" % master.secondary)
194 cec9845c Michael Hanselmann
195 23610ff8 Bernardo Dal Seno
  vgname = qa_config.get("vg-name", None)
196 23610ff8 Bernardo Dal Seno
  if vgname:
197 23610ff8 Bernardo Dal Seno
    cmd.append("--vg-name=%s" % vgname)
198 23610ff8 Bernardo Dal Seno
199 3601d488 Michael Hanselmann
  master_netdev = qa_config.get("master-netdev", None)
200 3601d488 Michael Hanselmann
  if master_netdev:
201 3601d488 Michael Hanselmann
    cmd.append("--master-netdev=%s" % master_netdev)
202 3601d488 Michael Hanselmann
203 3601d488 Michael Hanselmann
  nicparams = qa_config.get("default-nicparams", None)
204 3601d488 Michael Hanselmann
  if nicparams:
205 3601d488 Michael Hanselmann
    cmd.append("--nic-parameters=%s" %
206 3601d488 Michael Hanselmann
               ",".join(utils.FormatKeyValue(nicparams)))
207 cec9845c Michael Hanselmann
208 6a0f22e1 Bernardo Dal Seno
  # Cluster value of the exclusive-storage node parameter
209 6a0f22e1 Bernardo Dal Seno
  e_s = qa_config.get("exclusive-storage")
210 6a0f22e1 Bernardo Dal Seno
  if e_s is not None:
211 6a0f22e1 Bernardo Dal Seno
    cmd.extend(["--node-parameters", "exclusive_storage=%s" % e_s])
212 6a0f22e1 Bernardo Dal Seno
  else:
213 6a0f22e1 Bernardo Dal Seno
    e_s = False
214 6a0f22e1 Bernardo Dal Seno
  qa_config.SetExclusiveStorage(e_s)
215 6a0f22e1 Bernardo Dal Seno
216 becf9d5c Michael Hanselmann
  extra_args = qa_config.get("cluster-init-args")
217 becf9d5c Michael Hanselmann
  if extra_args:
218 becf9d5c Michael Hanselmann
    cmd.extend(extra_args)
219 becf9d5c Michael Hanselmann
220 13d2e231 Andrea Spadaccini
  cmd.append(qa_config.get("name"))
221 becf9d5c Michael Hanselmann
222 2f4b4f78 Iustin Pop
  AssertCommand(cmd)
223 cec9845c Michael Hanselmann
224 5abecc1c Iustin Pop
  cmd = ["gnt-cluster", "modify"]
225 13d2e231 Andrea Spadaccini
226 5abecc1c Iustin Pop
  # hypervisor parameter modifications
227 5abecc1c Iustin Pop
  hvp = qa_config.get("hypervisor-parameters", {})
228 5abecc1c Iustin Pop
  for k, v in hvp.items():
229 5abecc1c Iustin Pop
    cmd.extend(["-H", "%s:%s" % (k, v)])
230 5abecc1c Iustin Pop
  # backend parameter modifications
231 5abecc1c Iustin Pop
  bep = qa_config.get("backend-parameters", "")
232 5abecc1c Iustin Pop
  if bep:
233 5abecc1c Iustin Pop
    cmd.extend(["-B", bep])
234 5abecc1c Iustin Pop
235 5abecc1c Iustin Pop
  if len(cmd) > 2:
236 5abecc1c Iustin Pop
    AssertCommand(cmd)
237 5abecc1c Iustin Pop
238 5abecc1c Iustin Pop
  # OS parameters
239 5abecc1c Iustin Pop
  osp = qa_config.get("os-parameters", {})
240 5abecc1c Iustin Pop
  for k, v in osp.items():
241 5abecc1c Iustin Pop
    AssertCommand(["gnt-os", "modify", "-O", v, k])
242 5abecc1c Iustin Pop
243 5abecc1c Iustin Pop
  # OS hypervisor parameters
244 5abecc1c Iustin Pop
  os_hvp = qa_config.get("os-hvp", {})
245 5abecc1c Iustin Pop
  for os_name in os_hvp:
246 5abecc1c Iustin Pop
    for hv, hvp in os_hvp[os_name].items():
247 5abecc1c Iustin Pop
      AssertCommand(["gnt-os", "modify", "-H", "%s:%s" % (hv, hvp), os_name])
248 5abecc1c Iustin Pop
249 cec9845c Michael Hanselmann
250 caea3b32 Iustin Pop
def TestClusterRename():
251 caea3b32 Iustin Pop
  """gnt-cluster rename"""
252 d0c8c01d Iustin Pop
  cmd = ["gnt-cluster", "rename", "-f"]
253 caea3b32 Iustin Pop
254 d0c8c01d Iustin Pop
  original_name = qa_config.get("name")
255 d0c8c01d Iustin Pop
  rename_target = qa_config.get("rename", None)
256 caea3b32 Iustin Pop
  if rename_target is None:
257 caea3b32 Iustin Pop
    print qa_utils.FormatError('"rename" entry is missing')
258 caea3b32 Iustin Pop
    return
259 caea3b32 Iustin Pop
260 2f4b4f78 Iustin Pop
  for data in [
261 2f4b4f78 Iustin Pop
    cmd + [rename_target],
262 c2a0947d Iustin Pop
    _CLUSTER_VERIFY,
263 2f4b4f78 Iustin Pop
    cmd + [original_name],
264 c2a0947d Iustin Pop
    _CLUSTER_VERIFY,
265 2f4b4f78 Iustin Pop
    ]:
266 2f4b4f78 Iustin Pop
    AssertCommand(data)
267 caea3b32 Iustin Pop
268 caea3b32 Iustin Pop
269 69df9d2b Iustin Pop
def TestClusterOob():
270 69df9d2b Iustin Pop
  """out-of-band framework"""
271 f55312bd René Nussbaumer
  oob_path_exists = "/tmp/ganeti-qa-oob-does-exist-%s" % utils.NewUUID()
272 f55312bd René Nussbaumer
273 c2a0947d Iustin Pop
  AssertCommand(_CLUSTER_VERIFY)
274 f55312bd René Nussbaumer
  AssertCommand(["gnt-cluster", "modify", "--node-parameters",
275 f55312bd René Nussbaumer
                 "oob_program=/tmp/ganeti-qa-oob-does-not-exist-%s" %
276 f55312bd René Nussbaumer
                 utils.NewUUID()])
277 f55312bd René Nussbaumer
278 c2a0947d Iustin Pop
  AssertCommand(_CLUSTER_VERIFY, fail=True)
279 f55312bd René Nussbaumer
280 69df9d2b Iustin Pop
  AssertCommand(["touch", oob_path_exists])
281 69df9d2b Iustin Pop
  AssertCommand(["chmod", "0400", oob_path_exists])
282 69df9d2b Iustin Pop
  AssertCommand(["gnt-cluster", "copyfile", oob_path_exists])
283 f55312bd René Nussbaumer
284 f55312bd René Nussbaumer
  try:
285 f55312bd René Nussbaumer
    AssertCommand(["gnt-cluster", "modify", "--node-parameters",
286 f55312bd René Nussbaumer
                   "oob_program=%s" % oob_path_exists])
287 f55312bd René Nussbaumer
288 c2a0947d Iustin Pop
    AssertCommand(_CLUSTER_VERIFY, fail=True)
289 f55312bd René Nussbaumer
290 69df9d2b Iustin Pop
    AssertCommand(["chmod", "0500", oob_path_exists])
291 69df9d2b Iustin Pop
    AssertCommand(["gnt-cluster", "copyfile", oob_path_exists])
292 f55312bd René Nussbaumer
293 c2a0947d Iustin Pop
    AssertCommand(_CLUSTER_VERIFY)
294 f55312bd René Nussbaumer
  finally:
295 69df9d2b Iustin Pop
    AssertCommand(["gnt-cluster", "command", "rm", oob_path_exists])
296 f55312bd René Nussbaumer
297 f55312bd René Nussbaumer
  AssertCommand(["gnt-cluster", "modify", "--node-parameters",
298 f55312bd René Nussbaumer
                 "oob_program="])
299 69df9d2b Iustin Pop
300 69df9d2b Iustin Pop
301 66d1f035 René Nussbaumer
def TestClusterEpo():
302 66d1f035 René Nussbaumer
  """gnt-cluster epo"""
303 66d1f035 René Nussbaumer
  master = qa_config.GetMasterNode()
304 66d1f035 René Nussbaumer
305 66d1f035 René Nussbaumer
  # Assert that OOB is unavailable for all nodes
306 aecba21e Michael Hanselmann
  result_output = GetCommandOutput(master.primary,
307 58ea8d17 Michael Hanselmann
                                   "gnt-node list --verbose --no-headers -o"
308 66d1f035 René Nussbaumer
                                   " powered")
309 66d1f035 René Nussbaumer
  AssertEqual(compat.all(powered == "(unavail)"
310 66d1f035 René Nussbaumer
                         for powered in result_output.splitlines()), True)
311 66d1f035 René Nussbaumer
312 66d1f035 René Nussbaumer
  # Conflicting
313 66d1f035 René Nussbaumer
  AssertCommand(["gnt-cluster", "epo", "--groups", "--all"], fail=True)
314 66d1f035 René Nussbaumer
  # --all doesn't expect arguments
315 66d1f035 René Nussbaumer
  AssertCommand(["gnt-cluster", "epo", "--all", "some_arg"], fail=True)
316 66d1f035 René Nussbaumer
317 66d1f035 René Nussbaumer
  # Unless --all is given master is not allowed to be in the list
318 aecba21e Michael Hanselmann
  AssertCommand(["gnt-cluster", "epo", "-f", master.primary], fail=True)
319 66d1f035 René Nussbaumer
320 66d1f035 René Nussbaumer
  # This shouldn't fail
321 66d1f035 René Nussbaumer
  AssertCommand(["gnt-cluster", "epo", "-f", "--all"])
322 66d1f035 René Nussbaumer
323 66d1f035 René Nussbaumer
  # All instances should have been stopped now
324 aecba21e Michael Hanselmann
  result_output = GetCommandOutput(master.primary,
325 58ea8d17 Michael Hanselmann
                                   "gnt-instance list --no-headers -o status")
326 3e0ed18c René Nussbaumer
  # ERROR_down because the instance is stopped but not recorded as such
327 3e0ed18c René Nussbaumer
  AssertEqual(compat.all(status == "ERROR_down"
328 66d1f035 René Nussbaumer
                         for status in result_output.splitlines()), True)
329 66d1f035 René Nussbaumer
330 66d1f035 René Nussbaumer
  # Now start everything again
331 66d1f035 René Nussbaumer
  AssertCommand(["gnt-cluster", "epo", "--on", "-f", "--all"])
332 66d1f035 René Nussbaumer
333 66d1f035 René Nussbaumer
  # All instances should have been started now
334 aecba21e Michael Hanselmann
  result_output = GetCommandOutput(master.primary,
335 58ea8d17 Michael Hanselmann
                                   "gnt-instance list --no-headers -o status")
336 66d1f035 René Nussbaumer
  AssertEqual(compat.all(status == "running"
337 66d1f035 René Nussbaumer
                         for status in result_output.splitlines()), True)
338 66d1f035 René Nussbaumer
339 66d1f035 René Nussbaumer
340 69df9d2b Iustin Pop
def TestClusterVerify():
341 69df9d2b Iustin Pop
  """gnt-cluster verify"""
342 c2a0947d Iustin Pop
  AssertCommand(_CLUSTER_VERIFY)
343 c6953b6e Iustin Pop
  AssertCommand(["gnt-cluster", "verify-disks"])
344 cec9845c Michael Hanselmann
345 1377433b Michael Hanselmann
346 1377433b Michael Hanselmann
def TestJobqueue():
347 1377433b Michael Hanselmann
  """gnt-debug test-jobqueue"""
348 2f4b4f78 Iustin Pop
  AssertCommand(["gnt-debug", "test-jobqueue"])
349 1377433b Michael Hanselmann
350 1377433b Michael Hanselmann
351 5a85b99e Michael Hanselmann
def TestDelay(node):
352 5a85b99e Michael Hanselmann
  """gnt-debug delay"""
353 5a85b99e Michael Hanselmann
  AssertCommand(["gnt-debug", "delay", "1"])
354 5a85b99e Michael Hanselmann
  AssertCommand(["gnt-debug", "delay", "--no-master", "1"])
355 5a85b99e Michael Hanselmann
  AssertCommand(["gnt-debug", "delay", "--no-master",
356 aecba21e Michael Hanselmann
                 "-n", node.primary, "1"])
357 5a85b99e Michael Hanselmann
358 5a85b99e Michael Hanselmann
359 452913ed Iustin Pop
def TestClusterReservedLvs():
360 452913ed Iustin Pop
  """gnt-cluster reserved lvs"""
361 23610ff8 Bernardo Dal Seno
  vgname = qa_config.get("vg-name", constants.DEFAULT_VG)
362 23610ff8 Bernardo Dal Seno
  lvname = _QA_LV_PREFIX + "test"
363 23610ff8 Bernardo Dal Seno
  lvfullname = "/".join([vgname, lvname])
364 2f4b4f78 Iustin Pop
  for fail, cmd in [
365 c2a0947d Iustin Pop
    (False, _CLUSTER_VERIFY),
366 2f4b4f78 Iustin Pop
    (False, ["gnt-cluster", "modify", "--reserved-lvs", ""]),
367 23610ff8 Bernardo Dal Seno
    (False, ["lvcreate", "-L1G", "-n", lvname, vgname]),
368 21bf2e2e Andrea Spadaccini
    (True, _CLUSTER_VERIFY),
369 84d7e26b Dmitry Chernyak
    (False, ["gnt-cluster", "modify", "--reserved-lvs",
370 23610ff8 Bernardo Dal Seno
             "%s,.*/other-test" % lvfullname]),
371 c2a0947d Iustin Pop
    (False, _CLUSTER_VERIFY),
372 23610ff8 Bernardo Dal Seno
    (False, ["gnt-cluster", "modify", "--reserved-lvs",
373 23610ff8 Bernardo Dal Seno
             ".*/%s.*" % _QA_LV_PREFIX]),
374 c2a0947d Iustin Pop
    (False, _CLUSTER_VERIFY),
375 2f4b4f78 Iustin Pop
    (False, ["gnt-cluster", "modify", "--reserved-lvs", ""]),
376 21bf2e2e Andrea Spadaccini
    (True, _CLUSTER_VERIFY),
377 23610ff8 Bernardo Dal Seno
    (False, ["lvremove", "-f", lvfullname]),
378 c2a0947d Iustin Pop
    (False, _CLUSTER_VERIFY),
379 452913ed Iustin Pop
    ]:
380 2f4b4f78 Iustin Pop
    AssertCommand(cmd, fail=fail)
381 452913ed Iustin Pop
382 cec9845c Michael Hanselmann
383 1e7acc3b Iustin Pop
def TestClusterModifyEmpty():
384 1e7acc3b Iustin Pop
  """gnt-cluster modify"""
385 1e7acc3b Iustin Pop
  AssertCommand(["gnt-cluster", "modify"], fail=True)
386 1e7acc3b Iustin Pop
387 1e7acc3b Iustin Pop
388 92cb4940 Andrea Spadaccini
def TestClusterModifyDisk():
389 92cb4940 Andrea Spadaccini
  """gnt-cluster modify -D"""
390 92cb4940 Andrea Spadaccini
  for param in _FAIL_PARAMS:
391 92cb4940 Andrea Spadaccini
    AssertCommand(["gnt-cluster", "modify", "-D", param], fail=True)
392 92cb4940 Andrea Spadaccini
393 92cb4940 Andrea Spadaccini
394 2dae8d64 Helga Velroyen
def TestClusterModifyDiskTemplates():
395 2dae8d64 Helga Velroyen
  """gnt-cluster modify --enabled-disk-templates=..."""
396 462f0faa Helga Velroyen
  enabled_disk_templates = qa_config.GetEnabledDiskTemplates()
397 2dae8d64 Helga Velroyen
  default_disk_template = qa_config.GetDefaultDiskTemplate()
398 462f0faa Helga Velroyen
399 462f0faa Helga Velroyen
  _TestClusterModifyDiskTemplatesArguments(default_disk_template,
400 462f0faa Helga Velroyen
                                           enabled_disk_templates)
401 462f0faa Helga Velroyen
402 462f0faa Helga Velroyen
  _RestoreEnabledDiskTemplates()
403 462f0faa Helga Velroyen
  nodes = qa_config.AcquireManyNodes(2)
404 462f0faa Helga Velroyen
405 462f0faa Helga Velroyen
  instance_template = enabled_disk_templates[0]
406 462f0faa Helga Velroyen
  instance = qa_instance.CreateInstanceByDiskTemplate(nodes, instance_template)
407 462f0faa Helga Velroyen
408 462f0faa Helga Velroyen
  _TestClusterModifyUnusedDiskTemplate(instance_template)
409 462f0faa Helga Velroyen
  _TestClusterModifyUsedDiskTemplate(instance_template,
410 462f0faa Helga Velroyen
                                     enabled_disk_templates)
411 462f0faa Helga Velroyen
412 462f0faa Helga Velroyen
  qa_instance.TestInstanceRemove(instance)
413 462f0faa Helga Velroyen
  _RestoreEnabledDiskTemplates()
414 462f0faa Helga Velroyen
415 462f0faa Helga Velroyen
416 462f0faa Helga Velroyen
def _RestoreEnabledDiskTemplates():
417 462f0faa Helga Velroyen
  """Sets the list of enabled disk templates back to the list of enabled disk
418 462f0faa Helga Velroyen
     templates from the QA configuration. This can be used to make sure that
419 462f0faa Helga Velroyen
     the tests that modify the list of disk templates do not interfere with
420 462f0faa Helga Velroyen
     other tests.
421 462f0faa Helga Velroyen

422 462f0faa Helga Velroyen
  """
423 dacd8ba4 Helga Velroyen
  AssertCommand(
424 dacd8ba4 Helga Velroyen
    ["gnt-cluster", "modify",
425 462f0faa Helga Velroyen
     "--enabled-disk-template=%s" %
426 462f0faa Helga Velroyen
       ",".join(qa_config.GetEnabledDiskTemplates())],
427 dacd8ba4 Helga Velroyen
    fail=False)
428 462f0faa Helga Velroyen
429 462f0faa Helga Velroyen
430 462f0faa Helga Velroyen
def _TestClusterModifyDiskTemplatesArguments(default_disk_template,
431 462f0faa Helga Velroyen
                                             enabled_disk_templates):
432 462f0faa Helga Velroyen
  """Tests argument handling of 'gnt-cluster modify' with respect to
433 462f0faa Helga Velroyen
     the parameter '--enabled-disk-templates'. This test is independent
434 462f0faa Helga Velroyen
     of instances.
435 462f0faa Helga Velroyen

436 462f0faa Helga Velroyen
  """
437 dacd8ba4 Helga Velroyen
  AssertCommand(
438 dacd8ba4 Helga Velroyen
    ["gnt-cluster", "modify",
439 2dae8d64 Helga Velroyen
     "--enabled-disk-template=%s" %
440 462f0faa Helga Velroyen
       ",".join(enabled_disk_templates)],
441 dacd8ba4 Helga Velroyen
    fail=False)
442 462f0faa Helga Velroyen
443 2dae8d64 Helga Velroyen
  # bogus templates
444 dacd8ba4 Helga Velroyen
  AssertCommand(["gnt-cluster", "modify",
445 2dae8d64 Helga Velroyen
                 "--enabled-disk-templates=pinkbunny"],
446 dacd8ba4 Helga Velroyen
                fail=True)
447 462f0faa Helga Velroyen
448 dacd8ba4 Helga Velroyen
  # duplicate entries do no harm
449 dacd8ba4 Helga Velroyen
  AssertCommand(
450 dacd8ba4 Helga Velroyen
    ["gnt-cluster", "modify",
451 2dae8d64 Helga Velroyen
     "--enabled-disk-templates=%s,%s" %
452 2dae8d64 Helga Velroyen
      (default_disk_template, default_disk_template)],
453 dacd8ba4 Helga Velroyen
    fail=False)
454 462f0faa Helga Velroyen
455 462f0faa Helga Velroyen
456 462f0faa Helga Velroyen
def _TestClusterModifyUsedDiskTemplate(instance_template,
457 462f0faa Helga Velroyen
                                       enabled_disk_templates):
458 462f0faa Helga Velroyen
  """Tests that disk templates that are currently in use by instances cannot
459 462f0faa Helga Velroyen
     be disabled on the cluster.
460 462f0faa Helga Velroyen

461 462f0faa Helga Velroyen
  """
462 462f0faa Helga Velroyen
  # If the list of enabled disk templates contains only one template
463 462f0faa Helga Velroyen
  # we need to add some other templates, because the list of enabled disk
464 462f0faa Helga Velroyen
  # templates can only be set to a non-empty list.
465 462f0faa Helga Velroyen
  new_disk_templates = list(set(enabled_disk_templates)
466 462f0faa Helga Velroyen
                              - set([instance_template]))
467 462f0faa Helga Velroyen
  if not new_disk_templates:
468 462f0faa Helga Velroyen
    new_disk_templates = list(set(constants.DISK_TEMPLATES)
469 462f0faa Helga Velroyen
                                - set([instance_template]))
470 462f0faa Helga Velroyen
  AssertCommand(
471 462f0faa Helga Velroyen
    ["gnt-cluster", "modify",
472 462f0faa Helga Velroyen
     "--enabled-disk-templates=%s" %
473 462f0faa Helga Velroyen
       ",".join(new_disk_templates)],
474 462f0faa Helga Velroyen
    fail=True)
475 462f0faa Helga Velroyen
476 462f0faa Helga Velroyen
477 462f0faa Helga Velroyen
def _TestClusterModifyUnusedDiskTemplate(instance_template):
478 462f0faa Helga Velroyen
  """Tests that unused disk templates can be disabled safely."""
479 462f0faa Helga Velroyen
  all_disk_templates = constants.DISK_TEMPLATES
480 462f0faa Helga Velroyen
  AssertCommand(
481 462f0faa Helga Velroyen
    ["gnt-cluster", "modify",
482 462f0faa Helga Velroyen
     "--enabled-disk-templates=%s" %
483 462f0faa Helga Velroyen
       ",".join(all_disk_templates)],
484 462f0faa Helga Velroyen
    fail=False)
485 462f0faa Helga Velroyen
  new_disk_templates = [instance_template]
486 462f0faa Helga Velroyen
  AssertCommand(
487 462f0faa Helga Velroyen
    ["gnt-cluster", "modify",
488 462f0faa Helga Velroyen
     "--enabled-disk-templates=%s" %
489 462f0faa Helga Velroyen
       ",".join(new_disk_templates)],
490 462f0faa Helga Velroyen
    fail=False)
491 dacd8ba4 Helga Velroyen
492 dacd8ba4 Helga Velroyen
493 9738ca94 Iustin Pop
def TestClusterModifyBe():
494 9738ca94 Iustin Pop
  """gnt-cluster modify -B"""
495 2f4b4f78 Iustin Pop
  for fail, cmd in [
496 8ccbbe4b Guido Trotter
    # max/min mem
497 8ccbbe4b Guido Trotter
    (False, ["gnt-cluster", "modify", "-B", "maxmem=256"]),
498 8ccbbe4b Guido Trotter
    (False, ["sh", "-c", "gnt-cluster info|grep '^ *maxmem: 256$'"]),
499 8ccbbe4b Guido Trotter
    (False, ["gnt-cluster", "modify", "-B", "minmem=256"]),
500 8ccbbe4b Guido Trotter
    (False, ["sh", "-c", "gnt-cluster info|grep '^ *minmem: 256$'"]),
501 8ccbbe4b Guido Trotter
    (True, ["gnt-cluster", "modify", "-B", "maxmem=a"]),
502 8ccbbe4b Guido Trotter
    (False, ["sh", "-c", "gnt-cluster info|grep '^ *maxmem: 256$'"]),
503 8ccbbe4b Guido Trotter
    (True, ["gnt-cluster", "modify", "-B", "minmem=a"]),
504 8ccbbe4b Guido Trotter
    (False, ["sh", "-c", "gnt-cluster info|grep '^ *minmem: 256$'"]),
505 8ccbbe4b Guido Trotter
    (False, ["gnt-cluster", "modify", "-B", "maxmem=128,minmem=128"]),
506 8ccbbe4b Guido Trotter
    (False, ["sh", "-c", "gnt-cluster info|grep '^ *maxmem: 128$'"]),
507 8ccbbe4b Guido Trotter
    (False, ["sh", "-c", "gnt-cluster info|grep '^ *minmem: 128$'"]),
508 9738ca94 Iustin Pop
    # vcpus
509 2f4b4f78 Iustin Pop
    (False, ["gnt-cluster", "modify", "-B", "vcpus=4"]),
510 2f4b4f78 Iustin Pop
    (False, ["sh", "-c", "gnt-cluster info|grep '^ *vcpus: 4$'"]),
511 21bf2e2e Andrea Spadaccini
    (True, ["gnt-cluster", "modify", "-B", "vcpus=a"]),
512 2f4b4f78 Iustin Pop
    (False, ["gnt-cluster", "modify", "-B", "vcpus=1"]),
513 2f4b4f78 Iustin Pop
    (False, ["sh", "-c", "gnt-cluster info|grep '^ *vcpus: 1$'"]),
514 9738ca94 Iustin Pop
    # auto_balance
515 2f4b4f78 Iustin Pop
    (False, ["gnt-cluster", "modify", "-B", "auto_balance=False"]),
516 2f4b4f78 Iustin Pop
    (False, ["sh", "-c", "gnt-cluster info|grep '^ *auto_balance: False$'"]),
517 21bf2e2e Andrea Spadaccini
    (True, ["gnt-cluster", "modify", "-B", "auto_balance=1"]),
518 2f4b4f78 Iustin Pop
    (False, ["gnt-cluster", "modify", "-B", "auto_balance=True"]),
519 2f4b4f78 Iustin Pop
    (False, ["sh", "-c", "gnt-cluster info|grep '^ *auto_balance: True$'"]),
520 9738ca94 Iustin Pop
    ]:
521 2f4b4f78 Iustin Pop
    AssertCommand(cmd, fail=fail)
522 9738ca94 Iustin Pop
523 5abecc1c Iustin Pop
  # redo the original-requested BE parameters, if any
524 5abecc1c Iustin Pop
  bep = qa_config.get("backend-parameters", "")
525 5abecc1c Iustin Pop
  if bep:
526 5abecc1c Iustin Pop
    AssertCommand(["gnt-cluster", "modify", "-B", bep])
527 9738ca94 Iustin Pop
528 21bf2e2e Andrea Spadaccini
529 b3f3aa3d Bernardo Dal Seno
def _GetClusterIPolicy():
530 b3f3aa3d Bernardo Dal Seno
  """Return the run-time values of the cluster-level instance policy.
531 b3f3aa3d Bernardo Dal Seno

532 b3f3aa3d Bernardo Dal Seno
  @rtype: tuple
533 b3f3aa3d Bernardo Dal Seno
  @return: (policy, specs), where:
534 b3f3aa3d Bernardo Dal Seno
      - policy is a dictionary of the policy values, instance specs excluded
535 b3f3aa3d Bernardo Dal Seno
      - specs is dict of dict, specs[par][key] is a spec value, where key is
536 b3f3aa3d Bernardo Dal Seno
        "min", "max", or "std"
537 b3f3aa3d Bernardo Dal Seno

538 b3f3aa3d Bernardo Dal Seno
  """
539 0e79564a Bernardo Dal Seno
  info = qa_utils.GetObjectInfo(["gnt-cluster", "info"])
540 0e79564a Bernardo Dal Seno
  policy = info["Instance policy - limits for instances"]
541 0e79564a Bernardo Dal Seno
  ret_specs = {}
542 0e79564a Bernardo Dal Seno
  ret_policy = {}
543 da5f09ef Bernardo Dal Seno
  ispec_keys = constants.ISPECS_MINMAX_KEYS | frozenset([constants.ISPECS_STD])
544 0e79564a Bernardo Dal Seno
  for (key, val) in policy.items():
545 da5f09ef Bernardo Dal Seno
    if key in ispec_keys:
546 0e79564a Bernardo Dal Seno
      for (par, pval) in val.items():
547 b3f3aa3d Bernardo Dal Seno
        if par == "memory-size":
548 b3f3aa3d Bernardo Dal Seno
          par = "mem-size"
549 0e79564a Bernardo Dal Seno
        d = ret_specs.setdefault(par, {})
550 0e79564a Bernardo Dal Seno
        d[key] = pval
551 b3f3aa3d Bernardo Dal Seno
    else:
552 0e79564a Bernardo Dal Seno
      ret_policy[key] = val
553 0e79564a Bernardo Dal Seno
554 b3f3aa3d Bernardo Dal Seno
  # Sanity checks
555 0e79564a Bernardo Dal Seno
  assert len(ret_specs) > 0
556 e118deb1 Bernardo Dal Seno
  good = all("min" in d and "std" in d and "max" in d
557 e118deb1 Bernardo Dal Seno
             for d in ret_specs.values())
558 0e79564a Bernardo Dal Seno
  assert good, "Missing item in specs: %s" % ret_specs
559 0e79564a Bernardo Dal Seno
  assert len(ret_policy) > 0
560 0e79564a Bernardo Dal Seno
  return (ret_policy, ret_specs)
561 b3f3aa3d Bernardo Dal Seno
562 b3f3aa3d Bernardo Dal Seno
563 b3f3aa3d Bernardo Dal Seno
def TestClusterModifyIPolicy():
564 b3f3aa3d Bernardo Dal Seno
  """gnt-cluster modify --ipolicy-*"""
565 b3f3aa3d Bernardo Dal Seno
  basecmd = ["gnt-cluster", "modify"]
566 b3f3aa3d Bernardo Dal Seno
  (old_policy, old_specs) = _GetClusterIPolicy()
567 b3f3aa3d Bernardo Dal Seno
  for par in ["vcpu-ratio", "spindle-ratio"]:
568 b3f3aa3d Bernardo Dal Seno
    curr_val = float(old_policy[par])
569 b3f3aa3d Bernardo Dal Seno
    test_values = [
570 b3f3aa3d Bernardo Dal Seno
      (True, 1.0),
571 b3f3aa3d Bernardo Dal Seno
      (True, 1.5),
572 b3f3aa3d Bernardo Dal Seno
      (True, 2),
573 b3f3aa3d Bernardo Dal Seno
      (False, "a"),
574 b3f3aa3d Bernardo Dal Seno
      # Restore the old value
575 b3f3aa3d Bernardo Dal Seno
      (True, curr_val),
576 b3f3aa3d Bernardo Dal Seno
      ]
577 b3f3aa3d Bernardo Dal Seno
    for (good, val) in test_values:
578 b3f3aa3d Bernardo Dal Seno
      cmd = basecmd + ["--ipolicy-%s=%s" % (par, val)]
579 b3f3aa3d Bernardo Dal Seno
      AssertCommand(cmd, fail=not good)
580 b3f3aa3d Bernardo Dal Seno
      if good:
581 b3f3aa3d Bernardo Dal Seno
        curr_val = val
582 b3f3aa3d Bernardo Dal Seno
      # Check the affected parameter
583 b3f3aa3d Bernardo Dal Seno
      (eff_policy, eff_specs) = _GetClusterIPolicy()
584 b3f3aa3d Bernardo Dal Seno
      AssertEqual(float(eff_policy[par]), curr_val)
585 b3f3aa3d Bernardo Dal Seno
      # Check everything else
586 b3f3aa3d Bernardo Dal Seno
      AssertEqual(eff_specs, old_specs)
587 b3f3aa3d Bernardo Dal Seno
      for p in eff_policy.keys():
588 b3f3aa3d Bernardo Dal Seno
        if p == par:
589 b3f3aa3d Bernardo Dal Seno
          continue
590 b3f3aa3d Bernardo Dal Seno
        AssertEqual(eff_policy[p], old_policy[p])
591 b3f3aa3d Bernardo Dal Seno
592 b3f3aa3d Bernardo Dal Seno
  # Disk templates are treated slightly differently
593 b3f3aa3d Bernardo Dal Seno
  par = "disk-templates"
594 b3f3aa3d Bernardo Dal Seno
  disp_str = "enabled disk templates"
595 b3f3aa3d Bernardo Dal Seno
  curr_val = old_policy[disp_str]
596 b3f3aa3d Bernardo Dal Seno
  test_values = [
597 b3f3aa3d Bernardo Dal Seno
    (True, constants.DT_PLAIN),
598 b3f3aa3d Bernardo Dal Seno
    (True, "%s,%s" % (constants.DT_PLAIN, constants.DT_DRBD8)),
599 b3f3aa3d Bernardo Dal Seno
    (False, "thisisnotadisktemplate"),
600 b3f3aa3d Bernardo Dal Seno
    (False, ""),
601 b3f3aa3d Bernardo Dal Seno
    # Restore the old value
602 b3f3aa3d Bernardo Dal Seno
    (True, curr_val.replace(" ", "")),
603 b3f3aa3d Bernardo Dal Seno
    ]
604 b3f3aa3d Bernardo Dal Seno
  for (good, val) in test_values:
605 b3f3aa3d Bernardo Dal Seno
    cmd = basecmd + ["--ipolicy-%s=%s" % (par, val)]
606 b3f3aa3d Bernardo Dal Seno
    AssertCommand(cmd, fail=not good)
607 b3f3aa3d Bernardo Dal Seno
    if good:
608 b3f3aa3d Bernardo Dal Seno
      curr_val = val
609 b3f3aa3d Bernardo Dal Seno
    # Check the affected parameter
610 b3f3aa3d Bernardo Dal Seno
    (eff_policy, eff_specs) = _GetClusterIPolicy()
611 b3f3aa3d Bernardo Dal Seno
    AssertEqual(eff_policy[disp_str].replace(" ", ""), curr_val)
612 b3f3aa3d Bernardo Dal Seno
    # Check everything else
613 b3f3aa3d Bernardo Dal Seno
    AssertEqual(eff_specs, old_specs)
614 b3f3aa3d Bernardo Dal Seno
    for p in eff_policy.keys():
615 b3f3aa3d Bernardo Dal Seno
      if p == disp_str:
616 b3f3aa3d Bernardo Dal Seno
        continue
617 b3f3aa3d Bernardo Dal Seno
      AssertEqual(eff_policy[p], old_policy[p])
618 b3f3aa3d Bernardo Dal Seno
619 b3f3aa3d Bernardo Dal Seno
620 b3f3aa3d Bernardo Dal Seno
def TestClusterSetISpecs(new_specs, fail=False, old_values=None):
621 b3f3aa3d Bernardo Dal Seno
  """Change instance specs.
622 b3f3aa3d Bernardo Dal Seno

623 b3f3aa3d Bernardo Dal Seno
  @type new_specs: dict of dict
624 b3f3aa3d Bernardo Dal Seno
  @param new_specs: new_specs[par][key], where key is "min", "max", "std". It
625 b3f3aa3d Bernardo Dal Seno
      can be an empty dictionary.
626 b3f3aa3d Bernardo Dal Seno
  @type fail: bool
627 b3f3aa3d Bernardo Dal Seno
  @param fail: if the change is expected to fail
628 b3f3aa3d Bernardo Dal Seno
  @type old_values: tuple
629 b3f3aa3d Bernardo Dal Seno
  @param old_values: (old_policy, old_specs), as returned by
630 b3f3aa3d Bernardo Dal Seno
     L{_GetClusterIPolicy}
631 b3f3aa3d Bernardo Dal Seno
  @return: same as L{_GetClusterIPolicy}
632 b3f3aa3d Bernardo Dal Seno

633 b3f3aa3d Bernardo Dal Seno
  """
634 b3f3aa3d Bernardo Dal Seno
  if old_values:
635 b3f3aa3d Bernardo Dal Seno
    (old_policy, old_specs) = old_values
636 b3f3aa3d Bernardo Dal Seno
  else:
637 b3f3aa3d Bernardo Dal Seno
    (old_policy, old_specs) = _GetClusterIPolicy()
638 b3f3aa3d Bernardo Dal Seno
  if new_specs:
639 b3f3aa3d Bernardo Dal Seno
    cmd = ["gnt-cluster", "modify"]
640 b3f3aa3d Bernardo Dal Seno
    for (par, keyvals) in new_specs.items():
641 b3f3aa3d Bernardo Dal Seno
      if par == "spindle-use":
642 b3f3aa3d Bernardo Dal Seno
        # ignore spindle-use, which is not settable
643 b3f3aa3d Bernardo Dal Seno
        continue
644 b3f3aa3d Bernardo Dal Seno
      cmd += [
645 b3f3aa3d Bernardo Dal Seno
        "--specs-%s" % par,
646 b3f3aa3d Bernardo Dal Seno
        ",".join(["%s=%s" % (k, v) for (k, v) in keyvals.items()]),
647 b3f3aa3d Bernardo Dal Seno
        ]
648 b3f3aa3d Bernardo Dal Seno
    AssertCommand(cmd, fail=fail)
649 b3f3aa3d Bernardo Dal Seno
  # Check the new state
650 b3f3aa3d Bernardo Dal Seno
  (eff_policy, eff_specs) = _GetClusterIPolicy()
651 b3f3aa3d Bernardo Dal Seno
  AssertEqual(eff_policy, old_policy)
652 b3f3aa3d Bernardo Dal Seno
  if fail:
653 b3f3aa3d Bernardo Dal Seno
    AssertEqual(eff_specs, old_specs)
654 b3f3aa3d Bernardo Dal Seno
  else:
655 b3f3aa3d Bernardo Dal Seno
    for par in eff_specs:
656 b3f3aa3d Bernardo Dal Seno
      for key in eff_specs[par]:
657 b3f3aa3d Bernardo Dal Seno
        if par in new_specs and key in new_specs[par]:
658 b3f3aa3d Bernardo Dal Seno
          AssertEqual(int(eff_specs[par][key]), int(new_specs[par][key]))
659 b3f3aa3d Bernardo Dal Seno
        else:
660 b3f3aa3d Bernardo Dal Seno
          AssertEqual(int(eff_specs[par][key]), int(old_specs[par][key]))
661 b3f3aa3d Bernardo Dal Seno
  return (eff_policy, eff_specs)
662 b3f3aa3d Bernardo Dal Seno
663 b3f3aa3d Bernardo Dal Seno
664 b3f3aa3d Bernardo Dal Seno
def TestClusterModifyISpecs():
665 b3f3aa3d Bernardo Dal Seno
  """gnt-cluster modify --specs-*"""
666 b3f3aa3d Bernardo Dal Seno
  params = ["mem-size", "disk-size", "disk-count", "cpu-count", "nic-count"]
667 b3f3aa3d Bernardo Dal Seno
  (cur_policy, cur_specs) = _GetClusterIPolicy()
668 b3f3aa3d Bernardo Dal Seno
  for par in params:
669 b3f3aa3d Bernardo Dal Seno
    test_values = [
670 b3f3aa3d Bernardo Dal Seno
      (True, 0, 4, 12),
671 b3f3aa3d Bernardo Dal Seno
      (True, 4, 4, 12),
672 b3f3aa3d Bernardo Dal Seno
      (True, 4, 12, 12),
673 b3f3aa3d Bernardo Dal Seno
      (True, 4, 4, 4),
674 b3f3aa3d Bernardo Dal Seno
      (False, 4, 0, 12),
675 b3f3aa3d Bernardo Dal Seno
      (False, 4, 16, 12),
676 b3f3aa3d Bernardo Dal Seno
      (False, 4, 4, 0),
677 b3f3aa3d Bernardo Dal Seno
      (False, 12, 4, 4),
678 b3f3aa3d Bernardo Dal Seno
      (False, 12, 4, 0),
679 b3f3aa3d Bernardo Dal Seno
      (False, "a", 4, 12),
680 b3f3aa3d Bernardo Dal Seno
      (False, 0, "a", 12),
681 b3f3aa3d Bernardo Dal Seno
      (False, 0, 4, "a"),
682 b3f3aa3d Bernardo Dal Seno
      # This is to restore the old values
683 b3f3aa3d Bernardo Dal Seno
      (True,
684 b3f3aa3d Bernardo Dal Seno
       cur_specs[par]["min"], cur_specs[par]["std"], cur_specs[par]["max"])
685 b3f3aa3d Bernardo Dal Seno
      ]
686 b3f3aa3d Bernardo Dal Seno
    for (good, mn, st, mx) in test_values:
687 b3f3aa3d Bernardo Dal Seno
      new_vals = {par: {"min": str(mn), "std": str(st), "max": str(mx)}}
688 b3f3aa3d Bernardo Dal Seno
      cur_state = (cur_policy, cur_specs)
689 b3f3aa3d Bernardo Dal Seno
      # We update cur_specs, as we've copied the values to restore already
690 b3f3aa3d Bernardo Dal Seno
      (cur_policy, cur_specs) = TestClusterSetISpecs(new_vals, fail=not good,
691 b3f3aa3d Bernardo Dal Seno
                                                     old_values=cur_state)
692 b3f3aa3d Bernardo Dal Seno
693 b3f3aa3d Bernardo Dal Seno
694 cec9845c Michael Hanselmann
def TestClusterInfo():
695 cec9845c Michael Hanselmann
  """gnt-cluster info"""
696 2f4b4f78 Iustin Pop
  AssertCommand(["gnt-cluster", "info"])
697 283f9d4c Michael Hanselmann
698 283f9d4c Michael Hanselmann
699 3e8b5a9c Iustin Pop
def TestClusterRedistConf():
700 3e8b5a9c Iustin Pop
  """gnt-cluster redist-conf"""
701 3e8b5a9c Iustin Pop
  AssertCommand(["gnt-cluster", "redist-conf"])
702 3e8b5a9c Iustin Pop
703 3e8b5a9c Iustin Pop
704 283f9d4c Michael Hanselmann
def TestClusterGetmaster():
705 283f9d4c Michael Hanselmann
  """gnt-cluster getmaster"""
706 2f4b4f78 Iustin Pop
  AssertCommand(["gnt-cluster", "getmaster"])
707 283f9d4c Michael Hanselmann
708 283f9d4c Michael Hanselmann
709 283f9d4c Michael Hanselmann
def TestClusterVersion():
710 283f9d4c Michael Hanselmann
  """gnt-cluster version"""
711 2f4b4f78 Iustin Pop
  AssertCommand(["gnt-cluster", "version"])
712 cec9845c Michael Hanselmann
713 cec9845c Michael Hanselmann
714 6d4a1656 Michael Hanselmann
def TestClusterRenewCrypto():
715 6d4a1656 Michael Hanselmann
  """gnt-cluster renew-crypto"""
716 6d4a1656 Michael Hanselmann
  master = qa_config.GetMasterNode()
717 6d4a1656 Michael Hanselmann
718 6d4a1656 Michael Hanselmann
  # Conflicting options
719 6d4a1656 Michael Hanselmann
  cmd = ["gnt-cluster", "renew-crypto", "--force",
720 3db3eb2a Michael Hanselmann
         "--new-cluster-certificate", "--new-confd-hmac-key"]
721 3db3eb2a Michael Hanselmann
  conflicting = [
722 3db3eb2a Michael Hanselmann
    ["--new-rapi-certificate", "--rapi-certificate=/dev/null"],
723 3db3eb2a Michael Hanselmann
    ["--new-cluster-domain-secret", "--cluster-domain-secret=/dev/null"],
724 3db3eb2a Michael Hanselmann
    ]
725 3db3eb2a Michael Hanselmann
  for i in conflicting:
726 21bf2e2e Andrea Spadaccini
    AssertCommand(cmd + i, fail=True)
727 6d4a1656 Michael Hanselmann
728 6d4a1656 Michael Hanselmann
  # Invalid RAPI certificate
729 6d4a1656 Michael Hanselmann
  cmd = ["gnt-cluster", "renew-crypto", "--force",
730 6d4a1656 Michael Hanselmann
         "--rapi-certificate=/dev/null"]
731 2f4b4f78 Iustin Pop
  AssertCommand(cmd, fail=True)
732 6d4a1656 Michael Hanselmann
733 aecba21e Michael Hanselmann
  rapi_cert_backup = qa_utils.BackupFile(master.primary,
734 304d9f02 Michael Hanselmann
                                         pathutils.RAPI_CERT_FILE)
735 502f5236 Michael Hanselmann
  try:
736 502f5236 Michael Hanselmann
    # Custom RAPI certificate
737 502f5236 Michael Hanselmann
    fh = tempfile.NamedTemporaryFile()
738 6d4a1656 Michael Hanselmann
739 502f5236 Michael Hanselmann
    # Ensure certificate doesn't cause "gnt-cluster verify" to complain
740 502f5236 Michael Hanselmann
    validity = constants.SSL_CERT_EXPIRATION_WARN * 3
741 6d4a1656 Michael Hanselmann
742 5e26633b Michael Hanselmann
    utils.GenerateSelfSignedSslCert(fh.name, validity=validity)
743 6d4a1656 Michael Hanselmann
744 aecba21e Michael Hanselmann
    tmpcert = qa_utils.UploadFile(master.primary, fh.name)
745 502f5236 Michael Hanselmann
    try:
746 2f4b4f78 Iustin Pop
      AssertCommand(["gnt-cluster", "renew-crypto", "--force",
747 2f4b4f78 Iustin Pop
                     "--rapi-certificate=%s" % tmpcert])
748 502f5236 Michael Hanselmann
    finally:
749 2f4b4f78 Iustin Pop
      AssertCommand(["rm", "-f", tmpcert])
750 502f5236 Michael Hanselmann
751 5e26633b Michael Hanselmann
    # Custom cluster domain secret
752 5e26633b Michael Hanselmann
    cds_fh = tempfile.NamedTemporaryFile()
753 5e26633b Michael Hanselmann
    cds_fh.write(utils.GenerateSecret())
754 5e26633b Michael Hanselmann
    cds_fh.write("\n")
755 5e26633b Michael Hanselmann
    cds_fh.flush()
756 5e26633b Michael Hanselmann
757 aecba21e Michael Hanselmann
    tmpcds = qa_utils.UploadFile(master.primary, cds_fh.name)
758 5e26633b Michael Hanselmann
    try:
759 2f4b4f78 Iustin Pop
      AssertCommand(["gnt-cluster", "renew-crypto", "--force",
760 2f4b4f78 Iustin Pop
                     "--cluster-domain-secret=%s" % tmpcds])
761 5e26633b Michael Hanselmann
    finally:
762 2f4b4f78 Iustin Pop
      AssertCommand(["rm", "-f", tmpcds])
763 5e26633b Michael Hanselmann
764 502f5236 Michael Hanselmann
    # Normal case
765 2f4b4f78 Iustin Pop
    AssertCommand(["gnt-cluster", "renew-crypto", "--force",
766 2f4b4f78 Iustin Pop
                   "--new-cluster-certificate", "--new-confd-hmac-key",
767 2f4b4f78 Iustin Pop
                   "--new-rapi-certificate", "--new-cluster-domain-secret"])
768 3db3eb2a Michael Hanselmann
769 502f5236 Michael Hanselmann
    # Restore RAPI certificate
770 2f4b4f78 Iustin Pop
    AssertCommand(["gnt-cluster", "renew-crypto", "--force",
771 2f4b4f78 Iustin Pop
                   "--rapi-certificate=%s" % rapi_cert_backup])
772 3db3eb2a Michael Hanselmann
  finally:
773 2f4b4f78 Iustin Pop
    AssertCommand(["rm", "-f", rapi_cert_backup])
774 3db3eb2a Michael Hanselmann
775 6d4a1656 Michael Hanselmann
776 cec9845c Michael Hanselmann
def TestClusterBurnin():
777 cec9845c Michael Hanselmann
  """Burnin"""
778 cec9845c Michael Hanselmann
  master = qa_config.GetMasterNode()
779 cec9845c Michael Hanselmann
780 d0c8c01d Iustin Pop
  options = qa_config.get("options", {})
781 68c8c3df Michael Hanselmann
  disk_template = options.get("burnin-disk-template", constants.DT_DRBD8)
782 d0c8c01d Iustin Pop
  parallel = options.get("burnin-in-parallel", False)
783 d0c8c01d Iustin Pop
  check_inst = options.get("burnin-check-instances", False)
784 d0c8c01d Iustin Pop
  do_rename = options.get("burnin-rename", "")
785 d0c8c01d Iustin Pop
  do_reboot = options.get("burnin-reboot", True)
786 1d103c02 Iustin Pop
  reboot_types = options.get("reboot-types", constants.REBOOT_TYPES)
787 23103544 Michael Hanselmann
788 cec9845c Michael Hanselmann
  # Get as many instances as we need
789 cec9845c Michael Hanselmann
  instances = []
790 cec9845c Michael Hanselmann
  try:
791 23103544 Michael Hanselmann
    try:
792 d0c8c01d Iustin Pop
      num = qa_config.get("options", {}).get("burnin-instances", 1)
793 f1501b3f Michael Hanselmann
      for _ in range(0, num):
794 23103544 Michael Hanselmann
        instances.append(qa_config.AcquireInstance())
795 23103544 Michael Hanselmann
    except qa_error.OutOfInstancesError:
796 23103544 Michael Hanselmann
      print "Not enough instances, continuing anyway."
797 cec9845c Michael Hanselmann
798 23103544 Michael Hanselmann
    if len(instances) < 1:
799 23103544 Michael Hanselmann
      raise qa_error.Error("Burnin needs at least one instance")
800 cec9845c Michael Hanselmann
801 aecba21e Michael Hanselmann
    script = qa_utils.UploadFile(master.primary, "../tools/burnin")
802 cec9845c Michael Hanselmann
    try:
803 23103544 Michael Hanselmann
      # Run burnin
804 cec9845c Michael Hanselmann
      cmd = [script,
805 d0c8c01d Iustin Pop
             "--os=%s" % qa_config.get("os"),
806 f356202a Guido Trotter
             "--minmem-size=%s" % qa_config.get(constants.BE_MINMEM),
807 f356202a Guido Trotter
             "--maxmem-size=%s" % qa_config.get(constants.BE_MAXMEM),
808 d0c8c01d Iustin Pop
             "--disk-size=%s" % ",".join(qa_config.get("disk")),
809 d0c8c01d Iustin Pop
             "--disk-growth=%s" % ",".join(qa_config.get("disk-growth")),
810 d0c8c01d Iustin Pop
             "--disk-template=%s" % disk_template]
811 0b0a150a Iustin Pop
      if parallel:
812 d0c8c01d Iustin Pop
        cmd.append("--parallel")
813 d0c8c01d Iustin Pop
        cmd.append("--early-release")
814 0b0a150a Iustin Pop
      if check_inst:
815 d0c8c01d Iustin Pop
        cmd.append("--http-check")
816 4dc76b24 Iustin Pop
      if do_rename:
817 d0c8c01d Iustin Pop
        cmd.append("--rename=%s" % do_rename)
818 58598264 Iustin Pop
      if not do_reboot:
819 d0c8c01d Iustin Pop
        cmd.append("--no-reboot")
820 1d103c02 Iustin Pop
      else:
821 d0c8c01d Iustin Pop
        cmd.append("--reboot-types=%s" % ",".join(reboot_types))
822 b5f33afa Michael Hanselmann
      cmd += [inst.name for inst in instances]
823 2f4b4f78 Iustin Pop
      AssertCommand(cmd)
824 cec9845c Michael Hanselmann
    finally:
825 2f4b4f78 Iustin Pop
      AssertCommand(["rm", "-f", script])
826 2f4b4f78 Iustin Pop
827 cec9845c Michael Hanselmann
  finally:
828 cec9845c Michael Hanselmann
    for inst in instances:
829 6f88e076 Michael Hanselmann
      inst.Release()
830 cec9845c Michael Hanselmann
831 cec9845c Michael Hanselmann
832 cec9845c Michael Hanselmann
def TestClusterMasterFailover():
833 c28502b1 Iustin Pop
  """gnt-cluster master-failover"""
834 cec9845c Michael Hanselmann
  master = qa_config.GetMasterNode()
835 cec9845c Michael Hanselmann
  failovermaster = qa_config.AcquireNode(exclude=master)
836 cec9845c Michael Hanselmann
837 2f4b4f78 Iustin Pop
  cmd = ["gnt-cluster", "master-failover"]
838 2f4b4f78 Iustin Pop
  try:
839 2f4b4f78 Iustin Pop
    AssertCommand(cmd, node=failovermaster)
840 ff699aa9 Michael Hanselmann
    # Back to original master node
841 2f4b4f78 Iustin Pop
    AssertCommand(cmd, node=master)
842 cec9845c Michael Hanselmann
  finally:
843 565cb4bf Michael Hanselmann
    failovermaster.Release()
844 cec9845c Michael Hanselmann
845 cec9845c Michael Hanselmann
846 2df92990 Michael Hanselmann
def _NodeQueueDrainFile(node):
847 2df92990 Michael Hanselmann
  """Returns path to queue drain file for a node.
848 2df92990 Michael Hanselmann

849 2df92990 Michael Hanselmann
  """
850 2df92990 Michael Hanselmann
  return qa_utils.MakeNodePath(node, pathutils.JOB_QUEUE_DRAIN_FILE)
851 2df92990 Michael Hanselmann
852 2df92990 Michael Hanselmann
853 2df92990 Michael Hanselmann
def _AssertDrainFile(node, **kwargs):
854 2df92990 Michael Hanselmann
  """Checks for the queue drain file.
855 2df92990 Michael Hanselmann

856 2df92990 Michael Hanselmann
  """
857 2df92990 Michael Hanselmann
  AssertCommand(["test", "-f", _NodeQueueDrainFile(node)], node=node, **kwargs)
858 2df92990 Michael Hanselmann
859 2df92990 Michael Hanselmann
860 ff699aa9 Michael Hanselmann
def TestClusterMasterFailoverWithDrainedQueue():
861 ff699aa9 Michael Hanselmann
  """gnt-cluster master-failover with drained queue"""
862 ff699aa9 Michael Hanselmann
  master = qa_config.GetMasterNode()
863 ff699aa9 Michael Hanselmann
  failovermaster = qa_config.AcquireNode(exclude=master)
864 ff699aa9 Michael Hanselmann
865 ff699aa9 Michael Hanselmann
  # Ensure queue is not drained
866 ff699aa9 Michael Hanselmann
  for node in [master, failovermaster]:
867 2df92990 Michael Hanselmann
    _AssertDrainFile(node, fail=True)
868 ff699aa9 Michael Hanselmann
869 ff699aa9 Michael Hanselmann
  # Drain queue on failover master
870 2df92990 Michael Hanselmann
  AssertCommand(["touch", _NodeQueueDrainFile(failovermaster)],
871 2df92990 Michael Hanselmann
                node=failovermaster)
872 ff699aa9 Michael Hanselmann
873 ff699aa9 Michael Hanselmann
  cmd = ["gnt-cluster", "master-failover"]
874 ff699aa9 Michael Hanselmann
  try:
875 2df92990 Michael Hanselmann
    _AssertDrainFile(failovermaster)
876 ff699aa9 Michael Hanselmann
    AssertCommand(cmd, node=failovermaster)
877 2df92990 Michael Hanselmann
    _AssertDrainFile(master, fail=True)
878 2df92990 Michael Hanselmann
    _AssertDrainFile(failovermaster, fail=True)
879 ff699aa9 Michael Hanselmann
880 ff699aa9 Michael Hanselmann
    # Back to original master node
881 ff699aa9 Michael Hanselmann
    AssertCommand(cmd, node=master)
882 ff699aa9 Michael Hanselmann
  finally:
883 565cb4bf Michael Hanselmann
    failovermaster.Release()
884 ff699aa9 Michael Hanselmann
885 2df92990 Michael Hanselmann
  # Ensure queue is not drained
886 2df92990 Michael Hanselmann
  for node in [master, failovermaster]:
887 2df92990 Michael Hanselmann
    _AssertDrainFile(node, fail=True)
888 ff699aa9 Michael Hanselmann
889 ff699aa9 Michael Hanselmann
890 cec9845c Michael Hanselmann
def TestClusterCopyfile():
891 cec9845c Michael Hanselmann
  """gnt-cluster copyfile"""
892 cec9845c Michael Hanselmann
  master = qa_config.GetMasterNode()
893 cec9845c Michael Hanselmann
894 24818e8f Michael Hanselmann
  uniqueid = utils.NewUUID()
895 830da270 Michael Hanselmann
896 cec9845c Michael Hanselmann
  # Create temporary file
897 cec9845c Michael Hanselmann
  f = tempfile.NamedTemporaryFile()
898 830da270 Michael Hanselmann
  f.write(uniqueid)
899 cec9845c Michael Hanselmann
  f.flush()
900 cec9845c Michael Hanselmann
  f.seek(0)
901 cec9845c Michael Hanselmann
902 cec9845c Michael Hanselmann
  # Upload file to master node
903 aecba21e Michael Hanselmann
  testname = qa_utils.UploadFile(master.primary, f.name)
904 cec9845c Michael Hanselmann
  try:
905 cec9845c Michael Hanselmann
    # Copy file to all nodes
906 2f4b4f78 Iustin Pop
    AssertCommand(["gnt-cluster", "copyfile", testname])
907 830da270 Michael Hanselmann
    _CheckFileOnAllNodes(testname, uniqueid)
908 cec9845c Michael Hanselmann
  finally:
909 830da270 Michael Hanselmann
    _RemoveFileFromAllNodes(testname)
910 830da270 Michael Hanselmann
911 830da270 Michael Hanselmann
912 830da270 Michael Hanselmann
def TestClusterCommand():
913 830da270 Michael Hanselmann
  """gnt-cluster command"""
914 24818e8f Michael Hanselmann
  uniqueid = utils.NewUUID()
915 24818e8f Michael Hanselmann
  rfile = "/tmp/gnt%s" % utils.NewUUID()
916 d0c8c01d Iustin Pop
  rcmd = utils.ShellQuoteArgs(["echo", "-n", uniqueid])
917 d0c8c01d Iustin Pop
  cmd = utils.ShellQuoteArgs(["gnt-cluster", "command",
918 830da270 Michael Hanselmann
                              "%s >%s" % (rcmd, rfile)])
919 830da270 Michael Hanselmann
920 830da270 Michael Hanselmann
  try:
921 2f4b4f78 Iustin Pop
    AssertCommand(cmd)
922 830da270 Michael Hanselmann
    _CheckFileOnAllNodes(rfile, uniqueid)
923 830da270 Michael Hanselmann
  finally:
924 830da270 Michael Hanselmann
    _RemoveFileFromAllNodes(rfile)
925 cec9845c Michael Hanselmann
926 cec9845c Michael Hanselmann
927 cec9845c Michael Hanselmann
def TestClusterDestroy():
928 cec9845c Michael Hanselmann
  """gnt-cluster destroy"""
929 2f4b4f78 Iustin Pop
  AssertCommand(["gnt-cluster", "destroy", "--yes-do-it"])
930 65a884ef Iustin Pop
931 65a884ef Iustin Pop
932 65a884ef Iustin Pop
def TestClusterRepairDiskSizes():
933 65a884ef Iustin Pop
  """gnt-cluster repair-disk-sizes"""
934 65a884ef Iustin Pop
  AssertCommand(["gnt-cluster", "repair-disk-sizes"])
935 50ef6a41 Bernardo Dal Seno
936 50ef6a41 Bernardo Dal Seno
937 50ef6a41 Bernardo Dal Seno
def TestSetExclStorCluster(newvalue):
938 50ef6a41 Bernardo Dal Seno
  """Set the exclusive_storage node parameter at the cluster level.
939 50ef6a41 Bernardo Dal Seno

940 50ef6a41 Bernardo Dal Seno
  @type newvalue: bool
941 50ef6a41 Bernardo Dal Seno
  @param newvalue: New value of exclusive_storage
942 50ef6a41 Bernardo Dal Seno
  @rtype: bool
943 50ef6a41 Bernardo Dal Seno
  @return: The old value of exclusive_storage
944 50ef6a41 Bernardo Dal Seno

945 50ef6a41 Bernardo Dal Seno
  """
946 0e79564a Bernardo Dal Seno
  es_path = ["Default node parameters", "exclusive_storage"]
947 0e79564a Bernardo Dal Seno
  oldvalue = _GetClusterField(es_path)
948 50ef6a41 Bernardo Dal Seno
  AssertCommand(["gnt-cluster", "modify", "--node-parameters",
949 50ef6a41 Bernardo Dal Seno
                 "exclusive_storage=%s" % newvalue])
950 0e79564a Bernardo Dal Seno
  effvalue = _GetClusterField(es_path)
951 50ef6a41 Bernardo Dal Seno
  if effvalue != newvalue:
952 50ef6a41 Bernardo Dal Seno
    raise qa_error.Error("exclusive_storage has the wrong value: %s instead"
953 50ef6a41 Bernardo Dal Seno
                         " of %s" % (effvalue, newvalue))
954 6a0f22e1 Bernardo Dal Seno
  qa_config.SetExclusiveStorage(newvalue)
955 50ef6a41 Bernardo Dal Seno
  return oldvalue
956 e8b919a1 Bernardo Dal Seno
957 e8b919a1 Bernardo Dal Seno
958 21e2734f Bernardo Dal Seno
def TestExclStorSharedPv(node):
959 21e2734f Bernardo Dal Seno
  """cluster-verify reports LVs that share the same PV with exclusive_storage.
960 21e2734f Bernardo Dal Seno

961 21e2734f Bernardo Dal Seno
  """
962 21e2734f Bernardo Dal Seno
  vgname = qa_config.get("vg-name", constants.DEFAULT_VG)
963 21e2734f Bernardo Dal Seno
  lvname1 = _QA_LV_PREFIX + "vol1"
964 21e2734f Bernardo Dal Seno
  lvname2 = _QA_LV_PREFIX + "vol2"
965 aecba21e Michael Hanselmann
  node_name = node.primary
966 21e2734f Bernardo Dal Seno
  AssertCommand(["lvcreate", "-L1G", "-n", lvname1, vgname], node=node_name)
967 21e2734f Bernardo Dal Seno
  AssertClusterVerify(fail=True, errors=[constants.CV_ENODEORPHANLV])
968 21e2734f Bernardo Dal Seno
  AssertCommand(["lvcreate", "-L1G", "-n", lvname2, vgname], node=node_name)
969 21e2734f Bernardo Dal Seno
  AssertClusterVerify(fail=True, errors=[constants.CV_ENODELVM,
970 21e2734f Bernardo Dal Seno
                                         constants.CV_ENODEORPHANLV])
971 21e2734f Bernardo Dal Seno
  AssertCommand(["lvremove", "-f", "/".join([vgname, lvname1])], node=node_name)
972 21e2734f Bernardo Dal Seno
  AssertCommand(["lvremove", "-f", "/".join([vgname, lvname2])], node=node_name)
973 21e2734f Bernardo Dal Seno
  AssertClusterVerify()