Statistics
| Branch: | Tag: | Revision:

root / qa / qa_cluster.py @ da5f09ef

History | View | Annotate | Download (28 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 cec9845c Michael Hanselmann
39 66d1f035 René Nussbaumer
from qa_utils import AssertEqual, AssertCommand, GetCommandOutput
40 cec9845c Michael Hanselmann
41 cec9845c Michael Hanselmann
42 23610ff8 Bernardo Dal Seno
# Prefix for LVM volumes created by QA code during tests
43 23610ff8 Bernardo Dal Seno
_QA_LV_PREFIX = "qa-"
44 23610ff8 Bernardo Dal Seno
45 c2a0947d Iustin Pop
#: cluster verify command
46 c2a0947d Iustin Pop
_CLUSTER_VERIFY = ["gnt-cluster", "verify"]
47 c2a0947d Iustin Pop
48 21bf2e2e Andrea Spadaccini
49 830da270 Michael Hanselmann
def _RemoveFileFromAllNodes(filename):
50 830da270 Michael Hanselmann
  """Removes a file from all nodes.
51 830da270 Michael Hanselmann

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

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

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

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

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

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

459 b3f3aa3d Bernardo Dal Seno
  @rtype: tuple
460 b3f3aa3d Bernardo Dal Seno
  @return: (policy, specs), where:
461 b3f3aa3d Bernardo Dal Seno
      - policy is a dictionary of the policy values, instance specs excluded
462 b3f3aa3d Bernardo Dal Seno
      - specs is dict of dict, specs[par][key] is a spec value, where key is
463 b3f3aa3d Bernardo Dal Seno
        "min", "max", or "std"
464 b3f3aa3d Bernardo Dal Seno

465 b3f3aa3d Bernardo Dal Seno
  """
466 0e79564a Bernardo Dal Seno
  info = qa_utils.GetObjectInfo(["gnt-cluster", "info"])
467 0e79564a Bernardo Dal Seno
  policy = info["Instance policy - limits for instances"]
468 0e79564a Bernardo Dal Seno
  ret_specs = {}
469 0e79564a Bernardo Dal Seno
  ret_policy = {}
470 da5f09ef Bernardo Dal Seno
  ispec_keys = constants.ISPECS_MINMAX_KEYS | frozenset([constants.ISPECS_STD])
471 0e79564a Bernardo Dal Seno
  for (key, val) in policy.items():
472 da5f09ef Bernardo Dal Seno
    if key in ispec_keys:
473 0e79564a Bernardo Dal Seno
      for (par, pval) in val.items():
474 b3f3aa3d Bernardo Dal Seno
        if par == "memory-size":
475 b3f3aa3d Bernardo Dal Seno
          par = "mem-size"
476 0e79564a Bernardo Dal Seno
        d = ret_specs.setdefault(par, {})
477 0e79564a Bernardo Dal Seno
        d[key] = pval
478 b3f3aa3d Bernardo Dal Seno
    else:
479 0e79564a Bernardo Dal Seno
      ret_policy[key] = val
480 0e79564a Bernardo Dal Seno
481 b3f3aa3d Bernardo Dal Seno
  # Sanity checks
482 0e79564a Bernardo Dal Seno
  assert len(ret_specs) > 0
483 e118deb1 Bernardo Dal Seno
  good = all("min" in d and "std" in d and "max" in d
484 e118deb1 Bernardo Dal Seno
             for d in ret_specs.values())
485 0e79564a Bernardo Dal Seno
  assert good, "Missing item in specs: %s" % ret_specs
486 0e79564a Bernardo Dal Seno
  assert len(ret_policy) > 0
487 0e79564a Bernardo Dal Seno
  return (ret_policy, ret_specs)
488 b3f3aa3d Bernardo Dal Seno
489 b3f3aa3d Bernardo Dal Seno
490 b3f3aa3d Bernardo Dal Seno
def TestClusterModifyIPolicy():
491 b3f3aa3d Bernardo Dal Seno
  """gnt-cluster modify --ipolicy-*"""
492 b3f3aa3d Bernardo Dal Seno
  basecmd = ["gnt-cluster", "modify"]
493 b3f3aa3d Bernardo Dal Seno
  (old_policy, old_specs) = _GetClusterIPolicy()
494 b3f3aa3d Bernardo Dal Seno
  for par in ["vcpu-ratio", "spindle-ratio"]:
495 b3f3aa3d Bernardo Dal Seno
    curr_val = float(old_policy[par])
496 b3f3aa3d Bernardo Dal Seno
    test_values = [
497 b3f3aa3d Bernardo Dal Seno
      (True, 1.0),
498 b3f3aa3d Bernardo Dal Seno
      (True, 1.5),
499 b3f3aa3d Bernardo Dal Seno
      (True, 2),
500 b3f3aa3d Bernardo Dal Seno
      (False, "a"),
501 b3f3aa3d Bernardo Dal Seno
      # Restore the old value
502 b3f3aa3d Bernardo Dal Seno
      (True, curr_val),
503 b3f3aa3d Bernardo Dal Seno
      ]
504 b3f3aa3d Bernardo Dal Seno
    for (good, val) in test_values:
505 b3f3aa3d Bernardo Dal Seno
      cmd = basecmd + ["--ipolicy-%s=%s" % (par, val)]
506 b3f3aa3d Bernardo Dal Seno
      AssertCommand(cmd, fail=not good)
507 b3f3aa3d Bernardo Dal Seno
      if good:
508 b3f3aa3d Bernardo Dal Seno
        curr_val = val
509 b3f3aa3d Bernardo Dal Seno
      # Check the affected parameter
510 b3f3aa3d Bernardo Dal Seno
      (eff_policy, eff_specs) = _GetClusterIPolicy()
511 b3f3aa3d Bernardo Dal Seno
      AssertEqual(float(eff_policy[par]), curr_val)
512 b3f3aa3d Bernardo Dal Seno
      # Check everything else
513 b3f3aa3d Bernardo Dal Seno
      AssertEqual(eff_specs, old_specs)
514 b3f3aa3d Bernardo Dal Seno
      for p in eff_policy.keys():
515 b3f3aa3d Bernardo Dal Seno
        if p == par:
516 b3f3aa3d Bernardo Dal Seno
          continue
517 b3f3aa3d Bernardo Dal Seno
        AssertEqual(eff_policy[p], old_policy[p])
518 b3f3aa3d Bernardo Dal Seno
519 b3f3aa3d Bernardo Dal Seno
  # Disk templates are treated slightly differently
520 b3f3aa3d Bernardo Dal Seno
  par = "disk-templates"
521 b3f3aa3d Bernardo Dal Seno
  disp_str = "enabled disk templates"
522 b3f3aa3d Bernardo Dal Seno
  curr_val = old_policy[disp_str]
523 b3f3aa3d Bernardo Dal Seno
  test_values = [
524 b3f3aa3d Bernardo Dal Seno
    (True, constants.DT_PLAIN),
525 b3f3aa3d Bernardo Dal Seno
    (True, "%s,%s" % (constants.DT_PLAIN, constants.DT_DRBD8)),
526 b3f3aa3d Bernardo Dal Seno
    (False, "thisisnotadisktemplate"),
527 b3f3aa3d Bernardo Dal Seno
    (False, ""),
528 b3f3aa3d Bernardo Dal Seno
    # Restore the old value
529 b3f3aa3d Bernardo Dal Seno
    (True, curr_val.replace(" ", "")),
530 b3f3aa3d Bernardo Dal Seno
    ]
531 b3f3aa3d Bernardo Dal Seno
  for (good, val) in test_values:
532 b3f3aa3d Bernardo Dal Seno
    cmd = basecmd + ["--ipolicy-%s=%s" % (par, val)]
533 b3f3aa3d Bernardo Dal Seno
    AssertCommand(cmd, fail=not good)
534 b3f3aa3d Bernardo Dal Seno
    if good:
535 b3f3aa3d Bernardo Dal Seno
      curr_val = val
536 b3f3aa3d Bernardo Dal Seno
    # Check the affected parameter
537 b3f3aa3d Bernardo Dal Seno
    (eff_policy, eff_specs) = _GetClusterIPolicy()
538 b3f3aa3d Bernardo Dal Seno
    AssertEqual(eff_policy[disp_str].replace(" ", ""), curr_val)
539 b3f3aa3d Bernardo Dal Seno
    # Check everything else
540 b3f3aa3d Bernardo Dal Seno
    AssertEqual(eff_specs, old_specs)
541 b3f3aa3d Bernardo Dal Seno
    for p in eff_policy.keys():
542 b3f3aa3d Bernardo Dal Seno
      if p == disp_str:
543 b3f3aa3d Bernardo Dal Seno
        continue
544 b3f3aa3d Bernardo Dal Seno
      AssertEqual(eff_policy[p], old_policy[p])
545 b3f3aa3d Bernardo Dal Seno
546 b3f3aa3d Bernardo Dal Seno
547 b3f3aa3d Bernardo Dal Seno
def TestClusterSetISpecs(new_specs, fail=False, old_values=None):
548 b3f3aa3d Bernardo Dal Seno
  """Change instance specs.
549 b3f3aa3d Bernardo Dal Seno

550 b3f3aa3d Bernardo Dal Seno
  @type new_specs: dict of dict
551 b3f3aa3d Bernardo Dal Seno
  @param new_specs: new_specs[par][key], where key is "min", "max", "std". It
552 b3f3aa3d Bernardo Dal Seno
      can be an empty dictionary.
553 b3f3aa3d Bernardo Dal Seno
  @type fail: bool
554 b3f3aa3d Bernardo Dal Seno
  @param fail: if the change is expected to fail
555 b3f3aa3d Bernardo Dal Seno
  @type old_values: tuple
556 b3f3aa3d Bernardo Dal Seno
  @param old_values: (old_policy, old_specs), as returned by
557 b3f3aa3d Bernardo Dal Seno
     L{_GetClusterIPolicy}
558 b3f3aa3d Bernardo Dal Seno
  @return: same as L{_GetClusterIPolicy}
559 b3f3aa3d Bernardo Dal Seno

560 b3f3aa3d Bernardo Dal Seno
  """
561 b3f3aa3d Bernardo Dal Seno
  if old_values:
562 b3f3aa3d Bernardo Dal Seno
    (old_policy, old_specs) = old_values
563 b3f3aa3d Bernardo Dal Seno
  else:
564 b3f3aa3d Bernardo Dal Seno
    (old_policy, old_specs) = _GetClusterIPolicy()
565 b3f3aa3d Bernardo Dal Seno
  if new_specs:
566 b3f3aa3d Bernardo Dal Seno
    cmd = ["gnt-cluster", "modify"]
567 b3f3aa3d Bernardo Dal Seno
    for (par, keyvals) in new_specs.items():
568 b3f3aa3d Bernardo Dal Seno
      if par == "spindle-use":
569 b3f3aa3d Bernardo Dal Seno
        # ignore spindle-use, which is not settable
570 b3f3aa3d Bernardo Dal Seno
        continue
571 b3f3aa3d Bernardo Dal Seno
      cmd += [
572 b3f3aa3d Bernardo Dal Seno
        "--specs-%s" % par,
573 b3f3aa3d Bernardo Dal Seno
        ",".join(["%s=%s" % (k, v) for (k, v) in keyvals.items()]),
574 b3f3aa3d Bernardo Dal Seno
        ]
575 b3f3aa3d Bernardo Dal Seno
    AssertCommand(cmd, fail=fail)
576 b3f3aa3d Bernardo Dal Seno
  # Check the new state
577 b3f3aa3d Bernardo Dal Seno
  (eff_policy, eff_specs) = _GetClusterIPolicy()
578 b3f3aa3d Bernardo Dal Seno
  AssertEqual(eff_policy, old_policy)
579 b3f3aa3d Bernardo Dal Seno
  if fail:
580 b3f3aa3d Bernardo Dal Seno
    AssertEqual(eff_specs, old_specs)
581 b3f3aa3d Bernardo Dal Seno
  else:
582 b3f3aa3d Bernardo Dal Seno
    for par in eff_specs:
583 b3f3aa3d Bernardo Dal Seno
      for key in eff_specs[par]:
584 b3f3aa3d Bernardo Dal Seno
        if par in new_specs and key in new_specs[par]:
585 b3f3aa3d Bernardo Dal Seno
          AssertEqual(int(eff_specs[par][key]), int(new_specs[par][key]))
586 b3f3aa3d Bernardo Dal Seno
        else:
587 b3f3aa3d Bernardo Dal Seno
          AssertEqual(int(eff_specs[par][key]), int(old_specs[par][key]))
588 b3f3aa3d Bernardo Dal Seno
  return (eff_policy, eff_specs)
589 b3f3aa3d Bernardo Dal Seno
590 b3f3aa3d Bernardo Dal Seno
591 b3f3aa3d Bernardo Dal Seno
def TestClusterModifyISpecs():
592 b3f3aa3d Bernardo Dal Seno
  """gnt-cluster modify --specs-*"""
593 b3f3aa3d Bernardo Dal Seno
  params = ["mem-size", "disk-size", "disk-count", "cpu-count", "nic-count"]
594 b3f3aa3d Bernardo Dal Seno
  (cur_policy, cur_specs) = _GetClusterIPolicy()
595 b3f3aa3d Bernardo Dal Seno
  for par in params:
596 b3f3aa3d Bernardo Dal Seno
    test_values = [
597 b3f3aa3d Bernardo Dal Seno
      (True, 0, 4, 12),
598 b3f3aa3d Bernardo Dal Seno
      (True, 4, 4, 12),
599 b3f3aa3d Bernardo Dal Seno
      (True, 4, 12, 12),
600 b3f3aa3d Bernardo Dal Seno
      (True, 4, 4, 4),
601 b3f3aa3d Bernardo Dal Seno
      (False, 4, 0, 12),
602 b3f3aa3d Bernardo Dal Seno
      (False, 4, 16, 12),
603 b3f3aa3d Bernardo Dal Seno
      (False, 4, 4, 0),
604 b3f3aa3d Bernardo Dal Seno
      (False, 12, 4, 4),
605 b3f3aa3d Bernardo Dal Seno
      (False, 12, 4, 0),
606 b3f3aa3d Bernardo Dal Seno
      (False, "a", 4, 12),
607 b3f3aa3d Bernardo Dal Seno
      (False, 0, "a", 12),
608 b3f3aa3d Bernardo Dal Seno
      (False, 0, 4, "a"),
609 b3f3aa3d Bernardo Dal Seno
      # This is to restore the old values
610 b3f3aa3d Bernardo Dal Seno
      (True,
611 b3f3aa3d Bernardo Dal Seno
       cur_specs[par]["min"], cur_specs[par]["std"], cur_specs[par]["max"])
612 b3f3aa3d Bernardo Dal Seno
      ]
613 b3f3aa3d Bernardo Dal Seno
    for (good, mn, st, mx) in test_values:
614 b3f3aa3d Bernardo Dal Seno
      new_vals = {par: {"min": str(mn), "std": str(st), "max": str(mx)}}
615 b3f3aa3d Bernardo Dal Seno
      cur_state = (cur_policy, cur_specs)
616 b3f3aa3d Bernardo Dal Seno
      # We update cur_specs, as we've copied the values to restore already
617 b3f3aa3d Bernardo Dal Seno
      (cur_policy, cur_specs) = TestClusterSetISpecs(new_vals, fail=not good,
618 b3f3aa3d Bernardo Dal Seno
                                                     old_values=cur_state)
619 b3f3aa3d Bernardo Dal Seno
620 b3f3aa3d Bernardo Dal Seno
621 cec9845c Michael Hanselmann
def TestClusterInfo():
622 cec9845c Michael Hanselmann
  """gnt-cluster info"""
623 2f4b4f78 Iustin Pop
  AssertCommand(["gnt-cluster", "info"])
624 283f9d4c Michael Hanselmann
625 283f9d4c Michael Hanselmann
626 3e8b5a9c Iustin Pop
def TestClusterRedistConf():
627 3e8b5a9c Iustin Pop
  """gnt-cluster redist-conf"""
628 3e8b5a9c Iustin Pop
  AssertCommand(["gnt-cluster", "redist-conf"])
629 3e8b5a9c Iustin Pop
630 3e8b5a9c Iustin Pop
631 283f9d4c Michael Hanselmann
def TestClusterGetmaster():
632 283f9d4c Michael Hanselmann
  """gnt-cluster getmaster"""
633 2f4b4f78 Iustin Pop
  AssertCommand(["gnt-cluster", "getmaster"])
634 283f9d4c Michael Hanselmann
635 283f9d4c Michael Hanselmann
636 283f9d4c Michael Hanselmann
def TestClusterVersion():
637 283f9d4c Michael Hanselmann
  """gnt-cluster version"""
638 2f4b4f78 Iustin Pop
  AssertCommand(["gnt-cluster", "version"])
639 cec9845c Michael Hanselmann
640 cec9845c Michael Hanselmann
641 6d4a1656 Michael Hanselmann
def TestClusterRenewCrypto():
642 6d4a1656 Michael Hanselmann
  """gnt-cluster renew-crypto"""
643 6d4a1656 Michael Hanselmann
  master = qa_config.GetMasterNode()
644 6d4a1656 Michael Hanselmann
645 6d4a1656 Michael Hanselmann
  # Conflicting options
646 6d4a1656 Michael Hanselmann
  cmd = ["gnt-cluster", "renew-crypto", "--force",
647 3db3eb2a Michael Hanselmann
         "--new-cluster-certificate", "--new-confd-hmac-key"]
648 3db3eb2a Michael Hanselmann
  conflicting = [
649 3db3eb2a Michael Hanselmann
    ["--new-rapi-certificate", "--rapi-certificate=/dev/null"],
650 3db3eb2a Michael Hanselmann
    ["--new-cluster-domain-secret", "--cluster-domain-secret=/dev/null"],
651 3db3eb2a Michael Hanselmann
    ]
652 3db3eb2a Michael Hanselmann
  for i in conflicting:
653 21bf2e2e Andrea Spadaccini
    AssertCommand(cmd + i, fail=True)
654 6d4a1656 Michael Hanselmann
655 6d4a1656 Michael Hanselmann
  # Invalid RAPI certificate
656 6d4a1656 Michael Hanselmann
  cmd = ["gnt-cluster", "renew-crypto", "--force",
657 6d4a1656 Michael Hanselmann
         "--rapi-certificate=/dev/null"]
658 2f4b4f78 Iustin Pop
  AssertCommand(cmd, fail=True)
659 6d4a1656 Michael Hanselmann
660 aecba21e Michael Hanselmann
  rapi_cert_backup = qa_utils.BackupFile(master.primary,
661 304d9f02 Michael Hanselmann
                                         pathutils.RAPI_CERT_FILE)
662 502f5236 Michael Hanselmann
  try:
663 502f5236 Michael Hanselmann
    # Custom RAPI certificate
664 502f5236 Michael Hanselmann
    fh = tempfile.NamedTemporaryFile()
665 6d4a1656 Michael Hanselmann
666 502f5236 Michael Hanselmann
    # Ensure certificate doesn't cause "gnt-cluster verify" to complain
667 502f5236 Michael Hanselmann
    validity = constants.SSL_CERT_EXPIRATION_WARN * 3
668 6d4a1656 Michael Hanselmann
669 5e26633b Michael Hanselmann
    utils.GenerateSelfSignedSslCert(fh.name, validity=validity)
670 6d4a1656 Michael Hanselmann
671 aecba21e Michael Hanselmann
    tmpcert = qa_utils.UploadFile(master.primary, fh.name)
672 502f5236 Michael Hanselmann
    try:
673 2f4b4f78 Iustin Pop
      AssertCommand(["gnt-cluster", "renew-crypto", "--force",
674 2f4b4f78 Iustin Pop
                     "--rapi-certificate=%s" % tmpcert])
675 502f5236 Michael Hanselmann
    finally:
676 2f4b4f78 Iustin Pop
      AssertCommand(["rm", "-f", tmpcert])
677 502f5236 Michael Hanselmann
678 5e26633b Michael Hanselmann
    # Custom cluster domain secret
679 5e26633b Michael Hanselmann
    cds_fh = tempfile.NamedTemporaryFile()
680 5e26633b Michael Hanselmann
    cds_fh.write(utils.GenerateSecret())
681 5e26633b Michael Hanselmann
    cds_fh.write("\n")
682 5e26633b Michael Hanselmann
    cds_fh.flush()
683 5e26633b Michael Hanselmann
684 aecba21e Michael Hanselmann
    tmpcds = qa_utils.UploadFile(master.primary, cds_fh.name)
685 5e26633b Michael Hanselmann
    try:
686 2f4b4f78 Iustin Pop
      AssertCommand(["gnt-cluster", "renew-crypto", "--force",
687 2f4b4f78 Iustin Pop
                     "--cluster-domain-secret=%s" % tmpcds])
688 5e26633b Michael Hanselmann
    finally:
689 2f4b4f78 Iustin Pop
      AssertCommand(["rm", "-f", tmpcds])
690 5e26633b Michael Hanselmann
691 502f5236 Michael Hanselmann
    # Normal case
692 2f4b4f78 Iustin Pop
    AssertCommand(["gnt-cluster", "renew-crypto", "--force",
693 2f4b4f78 Iustin Pop
                   "--new-cluster-certificate", "--new-confd-hmac-key",
694 2f4b4f78 Iustin Pop
                   "--new-rapi-certificate", "--new-cluster-domain-secret"])
695 3db3eb2a Michael Hanselmann
696 502f5236 Michael Hanselmann
    # Restore RAPI certificate
697 2f4b4f78 Iustin Pop
    AssertCommand(["gnt-cluster", "renew-crypto", "--force",
698 2f4b4f78 Iustin Pop
                   "--rapi-certificate=%s" % rapi_cert_backup])
699 3db3eb2a Michael Hanselmann
  finally:
700 2f4b4f78 Iustin Pop
    AssertCommand(["rm", "-f", rapi_cert_backup])
701 3db3eb2a Michael Hanselmann
702 6d4a1656 Michael Hanselmann
703 cec9845c Michael Hanselmann
def TestClusterBurnin():
704 cec9845c Michael Hanselmann
  """Burnin"""
705 cec9845c Michael Hanselmann
  master = qa_config.GetMasterNode()
706 cec9845c Michael Hanselmann
707 d0c8c01d Iustin Pop
  options = qa_config.get("options", {})
708 68c8c3df Michael Hanselmann
  disk_template = options.get("burnin-disk-template", constants.DT_DRBD8)
709 d0c8c01d Iustin Pop
  parallel = options.get("burnin-in-parallel", False)
710 d0c8c01d Iustin Pop
  check_inst = options.get("burnin-check-instances", False)
711 d0c8c01d Iustin Pop
  do_rename = options.get("burnin-rename", "")
712 d0c8c01d Iustin Pop
  do_reboot = options.get("burnin-reboot", True)
713 1d103c02 Iustin Pop
  reboot_types = options.get("reboot-types", constants.REBOOT_TYPES)
714 23103544 Michael Hanselmann
715 cec9845c Michael Hanselmann
  # Get as many instances as we need
716 cec9845c Michael Hanselmann
  instances = []
717 cec9845c Michael Hanselmann
  try:
718 23103544 Michael Hanselmann
    try:
719 d0c8c01d Iustin Pop
      num = qa_config.get("options", {}).get("burnin-instances", 1)
720 f1501b3f Michael Hanselmann
      for _ in range(0, num):
721 23103544 Michael Hanselmann
        instances.append(qa_config.AcquireInstance())
722 23103544 Michael Hanselmann
    except qa_error.OutOfInstancesError:
723 23103544 Michael Hanselmann
      print "Not enough instances, continuing anyway."
724 cec9845c Michael Hanselmann
725 23103544 Michael Hanselmann
    if len(instances) < 1:
726 23103544 Michael Hanselmann
      raise qa_error.Error("Burnin needs at least one instance")
727 cec9845c Michael Hanselmann
728 aecba21e Michael Hanselmann
    script = qa_utils.UploadFile(master.primary, "../tools/burnin")
729 cec9845c Michael Hanselmann
    try:
730 23103544 Michael Hanselmann
      # Run burnin
731 cec9845c Michael Hanselmann
      cmd = [script,
732 d0c8c01d Iustin Pop
             "--os=%s" % qa_config.get("os"),
733 f356202a Guido Trotter
             "--minmem-size=%s" % qa_config.get(constants.BE_MINMEM),
734 f356202a Guido Trotter
             "--maxmem-size=%s" % qa_config.get(constants.BE_MAXMEM),
735 d0c8c01d Iustin Pop
             "--disk-size=%s" % ",".join(qa_config.get("disk")),
736 d0c8c01d Iustin Pop
             "--disk-growth=%s" % ",".join(qa_config.get("disk-growth")),
737 d0c8c01d Iustin Pop
             "--disk-template=%s" % disk_template]
738 0b0a150a Iustin Pop
      if parallel:
739 d0c8c01d Iustin Pop
        cmd.append("--parallel")
740 d0c8c01d Iustin Pop
        cmd.append("--early-release")
741 0b0a150a Iustin Pop
      if check_inst:
742 d0c8c01d Iustin Pop
        cmd.append("--http-check")
743 4dc76b24 Iustin Pop
      if do_rename:
744 d0c8c01d Iustin Pop
        cmd.append("--rename=%s" % do_rename)
745 58598264 Iustin Pop
      if not do_reboot:
746 d0c8c01d Iustin Pop
        cmd.append("--no-reboot")
747 1d103c02 Iustin Pop
      else:
748 d0c8c01d Iustin Pop
        cmd.append("--reboot-types=%s" % ",".join(reboot_types))
749 b5f33afa Michael Hanselmann
      cmd += [inst.name for inst in instances]
750 2f4b4f78 Iustin Pop
      AssertCommand(cmd)
751 cec9845c Michael Hanselmann
    finally:
752 2f4b4f78 Iustin Pop
      AssertCommand(["rm", "-f", script])
753 2f4b4f78 Iustin Pop
754 cec9845c Michael Hanselmann
  finally:
755 cec9845c Michael Hanselmann
    for inst in instances:
756 6f88e076 Michael Hanselmann
      inst.Release()
757 cec9845c Michael Hanselmann
758 cec9845c Michael Hanselmann
759 cec9845c Michael Hanselmann
def TestClusterMasterFailover():
760 c28502b1 Iustin Pop
  """gnt-cluster master-failover"""
761 cec9845c Michael Hanselmann
  master = qa_config.GetMasterNode()
762 cec9845c Michael Hanselmann
  failovermaster = qa_config.AcquireNode(exclude=master)
763 cec9845c Michael Hanselmann
764 2f4b4f78 Iustin Pop
  cmd = ["gnt-cluster", "master-failover"]
765 2f4b4f78 Iustin Pop
  try:
766 2f4b4f78 Iustin Pop
    AssertCommand(cmd, node=failovermaster)
767 ff699aa9 Michael Hanselmann
    # Back to original master node
768 2f4b4f78 Iustin Pop
    AssertCommand(cmd, node=master)
769 cec9845c Michael Hanselmann
  finally:
770 565cb4bf Michael Hanselmann
    failovermaster.Release()
771 cec9845c Michael Hanselmann
772 cec9845c Michael Hanselmann
773 2df92990 Michael Hanselmann
def _NodeQueueDrainFile(node):
774 2df92990 Michael Hanselmann
  """Returns path to queue drain file for a node.
775 2df92990 Michael Hanselmann

776 2df92990 Michael Hanselmann
  """
777 2df92990 Michael Hanselmann
  return qa_utils.MakeNodePath(node, pathutils.JOB_QUEUE_DRAIN_FILE)
778 2df92990 Michael Hanselmann
779 2df92990 Michael Hanselmann
780 2df92990 Michael Hanselmann
def _AssertDrainFile(node, **kwargs):
781 2df92990 Michael Hanselmann
  """Checks for the queue drain file.
782 2df92990 Michael Hanselmann

783 2df92990 Michael Hanselmann
  """
784 2df92990 Michael Hanselmann
  AssertCommand(["test", "-f", _NodeQueueDrainFile(node)], node=node, **kwargs)
785 2df92990 Michael Hanselmann
786 2df92990 Michael Hanselmann
787 ff699aa9 Michael Hanselmann
def TestClusterMasterFailoverWithDrainedQueue():
788 ff699aa9 Michael Hanselmann
  """gnt-cluster master-failover with drained queue"""
789 ff699aa9 Michael Hanselmann
  master = qa_config.GetMasterNode()
790 ff699aa9 Michael Hanselmann
  failovermaster = qa_config.AcquireNode(exclude=master)
791 ff699aa9 Michael Hanselmann
792 ff699aa9 Michael Hanselmann
  # Ensure queue is not drained
793 ff699aa9 Michael Hanselmann
  for node in [master, failovermaster]:
794 2df92990 Michael Hanselmann
    _AssertDrainFile(node, fail=True)
795 ff699aa9 Michael Hanselmann
796 ff699aa9 Michael Hanselmann
  # Drain queue on failover master
797 2df92990 Michael Hanselmann
  AssertCommand(["touch", _NodeQueueDrainFile(failovermaster)],
798 2df92990 Michael Hanselmann
                node=failovermaster)
799 ff699aa9 Michael Hanselmann
800 ff699aa9 Michael Hanselmann
  cmd = ["gnt-cluster", "master-failover"]
801 ff699aa9 Michael Hanselmann
  try:
802 2df92990 Michael Hanselmann
    _AssertDrainFile(failovermaster)
803 ff699aa9 Michael Hanselmann
    AssertCommand(cmd, node=failovermaster)
804 2df92990 Michael Hanselmann
    _AssertDrainFile(master, fail=True)
805 2df92990 Michael Hanselmann
    _AssertDrainFile(failovermaster, fail=True)
806 ff699aa9 Michael Hanselmann
807 ff699aa9 Michael Hanselmann
    # Back to original master node
808 ff699aa9 Michael Hanselmann
    AssertCommand(cmd, node=master)
809 ff699aa9 Michael Hanselmann
  finally:
810 565cb4bf Michael Hanselmann
    failovermaster.Release()
811 ff699aa9 Michael Hanselmann
812 2df92990 Michael Hanselmann
  # Ensure queue is not drained
813 2df92990 Michael Hanselmann
  for node in [master, failovermaster]:
814 2df92990 Michael Hanselmann
    _AssertDrainFile(node, fail=True)
815 ff699aa9 Michael Hanselmann
816 ff699aa9 Michael Hanselmann
817 cec9845c Michael Hanselmann
def TestClusterCopyfile():
818 cec9845c Michael Hanselmann
  """gnt-cluster copyfile"""
819 cec9845c Michael Hanselmann
  master = qa_config.GetMasterNode()
820 cec9845c Michael Hanselmann
821 24818e8f Michael Hanselmann
  uniqueid = utils.NewUUID()
822 830da270 Michael Hanselmann
823 cec9845c Michael Hanselmann
  # Create temporary file
824 cec9845c Michael Hanselmann
  f = tempfile.NamedTemporaryFile()
825 830da270 Michael Hanselmann
  f.write(uniqueid)
826 cec9845c Michael Hanselmann
  f.flush()
827 cec9845c Michael Hanselmann
  f.seek(0)
828 cec9845c Michael Hanselmann
829 cec9845c Michael Hanselmann
  # Upload file to master node
830 aecba21e Michael Hanselmann
  testname = qa_utils.UploadFile(master.primary, f.name)
831 cec9845c Michael Hanselmann
  try:
832 cec9845c Michael Hanselmann
    # Copy file to all nodes
833 2f4b4f78 Iustin Pop
    AssertCommand(["gnt-cluster", "copyfile", testname])
834 830da270 Michael Hanselmann
    _CheckFileOnAllNodes(testname, uniqueid)
835 cec9845c Michael Hanselmann
  finally:
836 830da270 Michael Hanselmann
    _RemoveFileFromAllNodes(testname)
837 830da270 Michael Hanselmann
838 830da270 Michael Hanselmann
839 830da270 Michael Hanselmann
def TestClusterCommand():
840 830da270 Michael Hanselmann
  """gnt-cluster command"""
841 24818e8f Michael Hanselmann
  uniqueid = utils.NewUUID()
842 24818e8f Michael Hanselmann
  rfile = "/tmp/gnt%s" % utils.NewUUID()
843 d0c8c01d Iustin Pop
  rcmd = utils.ShellQuoteArgs(["echo", "-n", uniqueid])
844 d0c8c01d Iustin Pop
  cmd = utils.ShellQuoteArgs(["gnt-cluster", "command",
845 830da270 Michael Hanselmann
                              "%s >%s" % (rcmd, rfile)])
846 830da270 Michael Hanselmann
847 830da270 Michael Hanselmann
  try:
848 2f4b4f78 Iustin Pop
    AssertCommand(cmd)
849 830da270 Michael Hanselmann
    _CheckFileOnAllNodes(rfile, uniqueid)
850 830da270 Michael Hanselmann
  finally:
851 830da270 Michael Hanselmann
    _RemoveFileFromAllNodes(rfile)
852 cec9845c Michael Hanselmann
853 cec9845c Michael Hanselmann
854 cec9845c Michael Hanselmann
def TestClusterDestroy():
855 cec9845c Michael Hanselmann
  """gnt-cluster destroy"""
856 2f4b4f78 Iustin Pop
  AssertCommand(["gnt-cluster", "destroy", "--yes-do-it"])
857 65a884ef Iustin Pop
858 65a884ef Iustin Pop
859 65a884ef Iustin Pop
def TestClusterRepairDiskSizes():
860 65a884ef Iustin Pop
  """gnt-cluster repair-disk-sizes"""
861 65a884ef Iustin Pop
  AssertCommand(["gnt-cluster", "repair-disk-sizes"])
862 50ef6a41 Bernardo Dal Seno
863 50ef6a41 Bernardo Dal Seno
864 50ef6a41 Bernardo Dal Seno
def TestSetExclStorCluster(newvalue):
865 50ef6a41 Bernardo Dal Seno
  """Set the exclusive_storage node parameter at the cluster level.
866 50ef6a41 Bernardo Dal Seno

867 50ef6a41 Bernardo Dal Seno
  @type newvalue: bool
868 50ef6a41 Bernardo Dal Seno
  @param newvalue: New value of exclusive_storage
869 50ef6a41 Bernardo Dal Seno
  @rtype: bool
870 50ef6a41 Bernardo Dal Seno
  @return: The old value of exclusive_storage
871 50ef6a41 Bernardo Dal Seno

872 50ef6a41 Bernardo Dal Seno
  """
873 0e79564a Bernardo Dal Seno
  es_path = ["Default node parameters", "exclusive_storage"]
874 0e79564a Bernardo Dal Seno
  oldvalue = _GetClusterField(es_path)
875 50ef6a41 Bernardo Dal Seno
  AssertCommand(["gnt-cluster", "modify", "--node-parameters",
876 50ef6a41 Bernardo Dal Seno
                 "exclusive_storage=%s" % newvalue])
877 0e79564a Bernardo Dal Seno
  effvalue = _GetClusterField(es_path)
878 50ef6a41 Bernardo Dal Seno
  if effvalue != newvalue:
879 50ef6a41 Bernardo Dal Seno
    raise qa_error.Error("exclusive_storage has the wrong value: %s instead"
880 50ef6a41 Bernardo Dal Seno
                         " of %s" % (effvalue, newvalue))
881 6a0f22e1 Bernardo Dal Seno
  qa_config.SetExclusiveStorage(newvalue)
882 50ef6a41 Bernardo Dal Seno
  return oldvalue
883 e8b919a1 Bernardo Dal Seno
884 e8b919a1 Bernardo Dal Seno
885 21e2734f Bernardo Dal Seno
def TestExclStorSharedPv(node):
886 21e2734f Bernardo Dal Seno
  """cluster-verify reports LVs that share the same PV with exclusive_storage.
887 21e2734f Bernardo Dal Seno

888 21e2734f Bernardo Dal Seno
  """
889 21e2734f Bernardo Dal Seno
  vgname = qa_config.get("vg-name", constants.DEFAULT_VG)
890 21e2734f Bernardo Dal Seno
  lvname1 = _QA_LV_PREFIX + "vol1"
891 21e2734f Bernardo Dal Seno
  lvname2 = _QA_LV_PREFIX + "vol2"
892 aecba21e Michael Hanselmann
  node_name = node.primary
893 21e2734f Bernardo Dal Seno
  AssertCommand(["lvcreate", "-L1G", "-n", lvname1, vgname], node=node_name)
894 21e2734f Bernardo Dal Seno
  AssertClusterVerify(fail=True, errors=[constants.CV_ENODEORPHANLV])
895 21e2734f Bernardo Dal Seno
  AssertCommand(["lvcreate", "-L1G", "-n", lvname2, vgname], node=node_name)
896 21e2734f Bernardo Dal Seno
  AssertClusterVerify(fail=True, errors=[constants.CV_ENODELVM,
897 21e2734f Bernardo Dal Seno
                                         constants.CV_ENODEORPHANLV])
898 21e2734f Bernardo Dal Seno
  AssertCommand(["lvremove", "-f", "/".join([vgname, lvname1])], node=node_name)
899 21e2734f Bernardo Dal Seno
  AssertCommand(["lvremove", "-f", "/".join([vgname, lvname2])], node=node_name)
900 21e2734f Bernardo Dal Seno
  AssertClusterVerify()