Statistics
| Branch: | Tag: | Revision:

root / qa / qa_cluster.py @ 587f8ff6

History | View | Annotate | Download (18.4 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 c2a0947d Iustin Pop
#: cluster verify command
43 c2a0947d Iustin Pop
_CLUSTER_VERIFY = ["gnt-cluster", "verify"]
44 c2a0947d Iustin Pop
45 21bf2e2e Andrea Spadaccini
46 830da270 Michael Hanselmann
def _RemoveFileFromAllNodes(filename):
47 830da270 Michael Hanselmann
  """Removes a file from all nodes.
48 830da270 Michael Hanselmann

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

57 830da270 Michael Hanselmann
  """
58 830da270 Michael Hanselmann
  cmd = utils.ShellQuoteArgs(["cat", filename])
59 2f4b4f78 Iustin Pop
  for node in qa_config.get("nodes"):
60 2f4b4f78 Iustin Pop
    AssertEqual(qa_utils.GetCommandOutput(node["primary"], cmd), content)
61 830da270 Michael Hanselmann
62 830da270 Michael Hanselmann
63 587f8ff6 Bernardo Dal Seno
# Cluster-verify errors (date, "ERROR", then error code)
64 587f8ff6 Bernardo Dal Seno
_CVERROR_RE = re.compile(r"^[\w\s:]+\s+- ERROR:([A-Z0-9_-]+):")
65 587f8ff6 Bernardo Dal Seno
66 587f8ff6 Bernardo Dal Seno
67 587f8ff6 Bernardo Dal Seno
def _GetCVErrorCodes(cvout):
68 587f8ff6 Bernardo Dal Seno
  ret = set()
69 587f8ff6 Bernardo Dal Seno
  for l in cvout.splitlines():
70 587f8ff6 Bernardo Dal Seno
    m = _CVERROR_RE.match(l)
71 587f8ff6 Bernardo Dal Seno
    if m:
72 587f8ff6 Bernardo Dal Seno
      ecode = m.group(1)
73 587f8ff6 Bernardo Dal Seno
      ret.add(ecode)
74 587f8ff6 Bernardo Dal Seno
  return ret
75 587f8ff6 Bernardo Dal Seno
76 587f8ff6 Bernardo Dal Seno
77 587f8ff6 Bernardo Dal Seno
def AssertClusterVerify(fail=False, errors=None):
78 587f8ff6 Bernardo Dal Seno
  """Run cluster-verify and check the result
79 587f8ff6 Bernardo Dal Seno

80 587f8ff6 Bernardo Dal Seno
  @type fail: bool
81 587f8ff6 Bernardo Dal Seno
  @param fail: if cluster-verify is expected to fail instead of succeeding
82 587f8ff6 Bernardo Dal Seno
  @type errors: list of tuples
83 587f8ff6 Bernardo Dal Seno
  @param errors: List of CV_XXX errors that are expected; if specified, all the
84 587f8ff6 Bernardo Dal Seno
      errors listed must appear in cluster-verify output. A non-empty value
85 587f8ff6 Bernardo Dal Seno
      implies C{fail=True}.
86 587f8ff6 Bernardo Dal Seno

87 587f8ff6 Bernardo Dal Seno
  """
88 587f8ff6 Bernardo Dal Seno
  cvcmd = "gnt-cluster verify"
89 587f8ff6 Bernardo Dal Seno
  mnode = qa_config.GetMasterNode()
90 587f8ff6 Bernardo Dal Seno
  if errors:
91 587f8ff6 Bernardo Dal Seno
    cvout = GetCommandOutput(mnode["primary"], cvcmd + " --error-codes",
92 587f8ff6 Bernardo Dal Seno
                             fail=True)
93 587f8ff6 Bernardo Dal Seno
    actual = _GetCVErrorCodes(cvout)
94 587f8ff6 Bernardo Dal Seno
    expected = compat.UniqueFrozenset(e for (_, e, _) in errors)
95 587f8ff6 Bernardo Dal Seno
    if not actual.issuperset(expected):
96 587f8ff6 Bernardo Dal Seno
      missing = expected.difference(actual)
97 587f8ff6 Bernardo Dal Seno
      raise qa_error.Error("Cluster-verify didn't return these expected"
98 587f8ff6 Bernardo Dal Seno
                           " errors: %s" % utils.CommaJoin(missing))
99 587f8ff6 Bernardo Dal Seno
  else:
100 587f8ff6 Bernardo Dal Seno
    AssertCommand(cvcmd, fail=fail, node=mnode)
101 587f8ff6 Bernardo Dal Seno
102 587f8ff6 Bernardo Dal Seno
103 92cb4940 Andrea Spadaccini
# data for testing failures due to bad keys/values for disk parameters
104 92cb4940 Andrea Spadaccini
_FAIL_PARAMS = ["nonexistent:resync-rate=1",
105 92cb4940 Andrea Spadaccini
                "drbd:nonexistent=1",
106 92cb4940 Andrea Spadaccini
                "drbd:resync-rate=invalid",
107 92cb4940 Andrea Spadaccini
                ]
108 92cb4940 Andrea Spadaccini
109 92cb4940 Andrea Spadaccini
110 92cb4940 Andrea Spadaccini
def TestClusterInitDisk():
111 92cb4940 Andrea Spadaccini
  """gnt-cluster init -D"""
112 92cb4940 Andrea Spadaccini
  name = qa_config.get("name")
113 92cb4940 Andrea Spadaccini
  for param in _FAIL_PARAMS:
114 92cb4940 Andrea Spadaccini
    AssertCommand(["gnt-cluster", "init", "-D", param, name], fail=True)
115 92cb4940 Andrea Spadaccini
116 92cb4940 Andrea Spadaccini
117 725ec2f1 René Nussbaumer
def TestClusterInit(rapi_user, rapi_secret):
118 cec9845c Michael Hanselmann
  """gnt-cluster init"""
119 cec9845c Michael Hanselmann
  master = qa_config.GetMasterNode()
120 cec9845c Michael Hanselmann
121 304d9f02 Michael Hanselmann
  rapi_dir = os.path.dirname(pathutils.RAPI_USERS_FILE)
122 49ceab21 Michael Hanselmann
123 725ec2f1 René Nussbaumer
  # First create the RAPI credentials
124 a62d1901 Michael Hanselmann
  fh = tempfile.NamedTemporaryFile()
125 a62d1901 Michael Hanselmann
  try:
126 a62d1901 Michael Hanselmann
    fh.write("%s %s write\n" % (rapi_user, rapi_secret))
127 a62d1901 Michael Hanselmann
    fh.flush()
128 a62d1901 Michael Hanselmann
129 a62d1901 Michael Hanselmann
    tmpru = qa_utils.UploadFile(master["primary"], fh.name)
130 a62d1901 Michael Hanselmann
    try:
131 49ceab21 Michael Hanselmann
      AssertCommand(["mkdir", "-p", rapi_dir])
132 304d9f02 Michael Hanselmann
      AssertCommand(["mv", tmpru, pathutils.RAPI_USERS_FILE])
133 a62d1901 Michael Hanselmann
    finally:
134 2f4b4f78 Iustin Pop
      AssertCommand(["rm", "-f", tmpru])
135 a62d1901 Michael Hanselmann
  finally:
136 a62d1901 Michael Hanselmann
    fh.close()
137 a62d1901 Michael Hanselmann
138 a62d1901 Michael Hanselmann
  # Initialize cluster
139 e7b6183b Michael Hanselmann
  cmd = [
140 e7b6183b Michael Hanselmann
    "gnt-cluster", "init",
141 e7b6183b Michael Hanselmann
    "--primary-ip-version=%d" % qa_config.get("primary_ip_version", 4),
142 59c1d41e Michael Hanselmann
    "--enabled-hypervisors=%s" % ",".join(qa_config.GetEnabledHypervisors()),
143 e7b6183b Michael Hanselmann
    ]
144 20286f7c René Nussbaumer
145 20286f7c René Nussbaumer
  for spec_type in ("mem-size", "disk-size", "disk-count", "cpu-count",
146 20286f7c René Nussbaumer
                    "nic-count"):
147 20286f7c René Nussbaumer
    for spec_val in ("min", "max", "std"):
148 20286f7c René Nussbaumer
      spec = qa_config.get("ispec_%s_%s" %
149 3601d488 Michael Hanselmann
                           (spec_type.replace("-", "_"), spec_val), None)
150 20286f7c René Nussbaumer
      if spec:
151 20286f7c René Nussbaumer
        cmd.append("--specs-%s=%s=%d" % (spec_type, spec_val, spec))
152 9486f6ae Manuel Franceschini
153 d0c8c01d Iustin Pop
  if master.get("secondary", None):
154 d0c8c01d Iustin Pop
    cmd.append("--secondary-ip=%s" % master["secondary"])
155 cec9845c Michael Hanselmann
156 3601d488 Michael Hanselmann
  master_netdev = qa_config.get("master-netdev", None)
157 3601d488 Michael Hanselmann
  if master_netdev:
158 3601d488 Michael Hanselmann
    cmd.append("--master-netdev=%s" % master_netdev)
159 3601d488 Michael Hanselmann
160 3601d488 Michael Hanselmann
  nicparams = qa_config.get("default-nicparams", None)
161 3601d488 Michael Hanselmann
  if nicparams:
162 3601d488 Michael Hanselmann
    cmd.append("--nic-parameters=%s" %
163 3601d488 Michael Hanselmann
               ",".join(utils.FormatKeyValue(nicparams)))
164 cec9845c Michael Hanselmann
165 13d2e231 Andrea Spadaccini
  cmd.append(qa_config.get("name"))
166 2f4b4f78 Iustin Pop
  AssertCommand(cmd)
167 cec9845c Michael Hanselmann
168 5abecc1c Iustin Pop
  cmd = ["gnt-cluster", "modify"]
169 13d2e231 Andrea Spadaccini
170 5abecc1c Iustin Pop
  # hypervisor parameter modifications
171 5abecc1c Iustin Pop
  hvp = qa_config.get("hypervisor-parameters", {})
172 5abecc1c Iustin Pop
  for k, v in hvp.items():
173 5abecc1c Iustin Pop
    cmd.extend(["-H", "%s:%s" % (k, v)])
174 5abecc1c Iustin Pop
  # backend parameter modifications
175 5abecc1c Iustin Pop
  bep = qa_config.get("backend-parameters", "")
176 5abecc1c Iustin Pop
  if bep:
177 5abecc1c Iustin Pop
    cmd.extend(["-B", bep])
178 5abecc1c Iustin Pop
179 5abecc1c Iustin Pop
  if len(cmd) > 2:
180 5abecc1c Iustin Pop
    AssertCommand(cmd)
181 5abecc1c Iustin Pop
182 5abecc1c Iustin Pop
  # OS parameters
183 5abecc1c Iustin Pop
  osp = qa_config.get("os-parameters", {})
184 5abecc1c Iustin Pop
  for k, v in osp.items():
185 5abecc1c Iustin Pop
    AssertCommand(["gnt-os", "modify", "-O", v, k])
186 5abecc1c Iustin Pop
187 5abecc1c Iustin Pop
  # OS hypervisor parameters
188 5abecc1c Iustin Pop
  os_hvp = qa_config.get("os-hvp", {})
189 5abecc1c Iustin Pop
  for os_name in os_hvp:
190 5abecc1c Iustin Pop
    for hv, hvp in os_hvp[os_name].items():
191 5abecc1c Iustin Pop
      AssertCommand(["gnt-os", "modify", "-H", "%s:%s" % (hv, hvp), os_name])
192 5abecc1c Iustin Pop
193 cec9845c Michael Hanselmann
194 caea3b32 Iustin Pop
def TestClusterRename():
195 caea3b32 Iustin Pop
  """gnt-cluster rename"""
196 d0c8c01d Iustin Pop
  cmd = ["gnt-cluster", "rename", "-f"]
197 caea3b32 Iustin Pop
198 d0c8c01d Iustin Pop
  original_name = qa_config.get("name")
199 d0c8c01d Iustin Pop
  rename_target = qa_config.get("rename", None)
200 caea3b32 Iustin Pop
  if rename_target is None:
201 caea3b32 Iustin Pop
    print qa_utils.FormatError('"rename" entry is missing')
202 caea3b32 Iustin Pop
    return
203 caea3b32 Iustin Pop
204 2f4b4f78 Iustin Pop
  for data in [
205 2f4b4f78 Iustin Pop
    cmd + [rename_target],
206 c2a0947d Iustin Pop
    _CLUSTER_VERIFY,
207 2f4b4f78 Iustin Pop
    cmd + [original_name],
208 c2a0947d Iustin Pop
    _CLUSTER_VERIFY,
209 2f4b4f78 Iustin Pop
    ]:
210 2f4b4f78 Iustin Pop
    AssertCommand(data)
211 caea3b32 Iustin Pop
212 caea3b32 Iustin Pop
213 69df9d2b Iustin Pop
def TestClusterOob():
214 69df9d2b Iustin Pop
  """out-of-band framework"""
215 f55312bd René Nussbaumer
  oob_path_exists = "/tmp/ganeti-qa-oob-does-exist-%s" % utils.NewUUID()
216 f55312bd René Nussbaumer
217 c2a0947d Iustin Pop
  AssertCommand(_CLUSTER_VERIFY)
218 f55312bd René Nussbaumer
  AssertCommand(["gnt-cluster", "modify", "--node-parameters",
219 f55312bd René Nussbaumer
                 "oob_program=/tmp/ganeti-qa-oob-does-not-exist-%s" %
220 f55312bd René Nussbaumer
                 utils.NewUUID()])
221 f55312bd René Nussbaumer
222 c2a0947d Iustin Pop
  AssertCommand(_CLUSTER_VERIFY, fail=True)
223 f55312bd René Nussbaumer
224 69df9d2b Iustin Pop
  AssertCommand(["touch", oob_path_exists])
225 69df9d2b Iustin Pop
  AssertCommand(["chmod", "0400", oob_path_exists])
226 69df9d2b Iustin Pop
  AssertCommand(["gnt-cluster", "copyfile", oob_path_exists])
227 f55312bd René Nussbaumer
228 f55312bd René Nussbaumer
  try:
229 f55312bd René Nussbaumer
    AssertCommand(["gnt-cluster", "modify", "--node-parameters",
230 f55312bd René Nussbaumer
                   "oob_program=%s" % oob_path_exists])
231 f55312bd René Nussbaumer
232 c2a0947d Iustin Pop
    AssertCommand(_CLUSTER_VERIFY, fail=True)
233 f55312bd René Nussbaumer
234 69df9d2b Iustin Pop
    AssertCommand(["chmod", "0500", oob_path_exists])
235 69df9d2b Iustin Pop
    AssertCommand(["gnt-cluster", "copyfile", oob_path_exists])
236 f55312bd René Nussbaumer
237 c2a0947d Iustin Pop
    AssertCommand(_CLUSTER_VERIFY)
238 f55312bd René Nussbaumer
  finally:
239 69df9d2b Iustin Pop
    AssertCommand(["gnt-cluster", "command", "rm", oob_path_exists])
240 f55312bd René Nussbaumer
241 f55312bd René Nussbaumer
  AssertCommand(["gnt-cluster", "modify", "--node-parameters",
242 f55312bd René Nussbaumer
                 "oob_program="])
243 69df9d2b Iustin Pop
244 69df9d2b Iustin Pop
245 66d1f035 René Nussbaumer
def TestClusterEpo():
246 66d1f035 René Nussbaumer
  """gnt-cluster epo"""
247 66d1f035 René Nussbaumer
  master = qa_config.GetMasterNode()
248 66d1f035 René Nussbaumer
249 66d1f035 René Nussbaumer
  # Assert that OOB is unavailable for all nodes
250 66d1f035 René Nussbaumer
  result_output = GetCommandOutput(master["primary"],
251 58ea8d17 Michael Hanselmann
                                   "gnt-node list --verbose --no-headers -o"
252 66d1f035 René Nussbaumer
                                   " powered")
253 66d1f035 René Nussbaumer
  AssertEqual(compat.all(powered == "(unavail)"
254 66d1f035 René Nussbaumer
                         for powered in result_output.splitlines()), True)
255 66d1f035 René Nussbaumer
256 66d1f035 René Nussbaumer
  # Conflicting
257 66d1f035 René Nussbaumer
  AssertCommand(["gnt-cluster", "epo", "--groups", "--all"], fail=True)
258 66d1f035 René Nussbaumer
  # --all doesn't expect arguments
259 66d1f035 René Nussbaumer
  AssertCommand(["gnt-cluster", "epo", "--all", "some_arg"], fail=True)
260 66d1f035 René Nussbaumer
261 66d1f035 René Nussbaumer
  # Unless --all is given master is not allowed to be in the list
262 66d1f035 René Nussbaumer
  AssertCommand(["gnt-cluster", "epo", "-f", master["primary"]], fail=True)
263 66d1f035 René Nussbaumer
264 66d1f035 René Nussbaumer
  # This shouldn't fail
265 66d1f035 René Nussbaumer
  AssertCommand(["gnt-cluster", "epo", "-f", "--all"])
266 66d1f035 René Nussbaumer
267 66d1f035 René Nussbaumer
  # All instances should have been stopped now
268 66d1f035 René Nussbaumer
  result_output = GetCommandOutput(master["primary"],
269 58ea8d17 Michael Hanselmann
                                   "gnt-instance list --no-headers -o status")
270 3e0ed18c René Nussbaumer
  # ERROR_down because the instance is stopped but not recorded as such
271 3e0ed18c René Nussbaumer
  AssertEqual(compat.all(status == "ERROR_down"
272 66d1f035 René Nussbaumer
                         for status in result_output.splitlines()), True)
273 66d1f035 René Nussbaumer
274 66d1f035 René Nussbaumer
  # Now start everything again
275 66d1f035 René Nussbaumer
  AssertCommand(["gnt-cluster", "epo", "--on", "-f", "--all"])
276 66d1f035 René Nussbaumer
277 66d1f035 René Nussbaumer
  # All instances should have been started now
278 66d1f035 René Nussbaumer
  result_output = GetCommandOutput(master["primary"],
279 58ea8d17 Michael Hanselmann
                                   "gnt-instance list --no-headers -o status")
280 66d1f035 René Nussbaumer
  AssertEqual(compat.all(status == "running"
281 66d1f035 René Nussbaumer
                         for status in result_output.splitlines()), True)
282 66d1f035 René Nussbaumer
283 66d1f035 René Nussbaumer
284 69df9d2b Iustin Pop
def TestClusterVerify():
285 69df9d2b Iustin Pop
  """gnt-cluster verify"""
286 c2a0947d Iustin Pop
  AssertCommand(_CLUSTER_VERIFY)
287 c6953b6e Iustin Pop
  AssertCommand(["gnt-cluster", "verify-disks"])
288 cec9845c Michael Hanselmann
289 1377433b Michael Hanselmann
290 1377433b Michael Hanselmann
def TestJobqueue():
291 1377433b Michael Hanselmann
  """gnt-debug test-jobqueue"""
292 2f4b4f78 Iustin Pop
  AssertCommand(["gnt-debug", "test-jobqueue"])
293 1377433b Michael Hanselmann
294 1377433b Michael Hanselmann
295 5a85b99e Michael Hanselmann
def TestDelay(node):
296 5a85b99e Michael Hanselmann
  """gnt-debug delay"""
297 5a85b99e Michael Hanselmann
  AssertCommand(["gnt-debug", "delay", "1"])
298 5a85b99e Michael Hanselmann
  AssertCommand(["gnt-debug", "delay", "--no-master", "1"])
299 5a85b99e Michael Hanselmann
  AssertCommand(["gnt-debug", "delay", "--no-master",
300 5a85b99e Michael Hanselmann
                 "-n", node["primary"], "1"])
301 5a85b99e Michael Hanselmann
302 5a85b99e Michael Hanselmann
303 452913ed Iustin Pop
def TestClusterReservedLvs():
304 452913ed Iustin Pop
  """gnt-cluster reserved lvs"""
305 2f4b4f78 Iustin Pop
  for fail, cmd in [
306 c2a0947d Iustin Pop
    (False, _CLUSTER_VERIFY),
307 2f4b4f78 Iustin Pop
    (False, ["gnt-cluster", "modify", "--reserved-lvs", ""]),
308 2f4b4f78 Iustin Pop
    (False, ["lvcreate", "-L1G", "-nqa-test", "xenvg"]),
309 21bf2e2e Andrea Spadaccini
    (True, _CLUSTER_VERIFY),
310 84d7e26b Dmitry Chernyak
    (False, ["gnt-cluster", "modify", "--reserved-lvs",
311 84d7e26b Dmitry Chernyak
             "xenvg/qa-test,.*/other-test"]),
312 c2a0947d Iustin Pop
    (False, _CLUSTER_VERIFY),
313 84d7e26b Dmitry Chernyak
    (False, ["gnt-cluster", "modify", "--reserved-lvs", ".*/qa-.*"]),
314 c2a0947d Iustin Pop
    (False, _CLUSTER_VERIFY),
315 2f4b4f78 Iustin Pop
    (False, ["gnt-cluster", "modify", "--reserved-lvs", ""]),
316 21bf2e2e Andrea Spadaccini
    (True, _CLUSTER_VERIFY),
317 2f4b4f78 Iustin Pop
    (False, ["lvremove", "-f", "xenvg/qa-test"]),
318 c2a0947d Iustin Pop
    (False, _CLUSTER_VERIFY),
319 452913ed Iustin Pop
    ]:
320 2f4b4f78 Iustin Pop
    AssertCommand(cmd, fail=fail)
321 452913ed Iustin Pop
322 cec9845c Michael Hanselmann
323 1e7acc3b Iustin Pop
def TestClusterModifyEmpty():
324 1e7acc3b Iustin Pop
  """gnt-cluster modify"""
325 1e7acc3b Iustin Pop
  AssertCommand(["gnt-cluster", "modify"], fail=True)
326 1e7acc3b Iustin Pop
327 1e7acc3b Iustin Pop
328 92cb4940 Andrea Spadaccini
def TestClusterModifyDisk():
329 92cb4940 Andrea Spadaccini
  """gnt-cluster modify -D"""
330 92cb4940 Andrea Spadaccini
  for param in _FAIL_PARAMS:
331 92cb4940 Andrea Spadaccini
    AssertCommand(["gnt-cluster", "modify", "-D", param], fail=True)
332 92cb4940 Andrea Spadaccini
333 92cb4940 Andrea Spadaccini
334 9738ca94 Iustin Pop
def TestClusterModifyBe():
335 9738ca94 Iustin Pop
  """gnt-cluster modify -B"""
336 2f4b4f78 Iustin Pop
  for fail, cmd in [
337 8ccbbe4b Guido Trotter
    # max/min mem
338 8ccbbe4b Guido Trotter
    (False, ["gnt-cluster", "modify", "-B", "maxmem=256"]),
339 8ccbbe4b Guido Trotter
    (False, ["sh", "-c", "gnt-cluster info|grep '^ *maxmem: 256$'"]),
340 8ccbbe4b Guido Trotter
    (False, ["gnt-cluster", "modify", "-B", "minmem=256"]),
341 8ccbbe4b Guido Trotter
    (False, ["sh", "-c", "gnt-cluster info|grep '^ *minmem: 256$'"]),
342 8ccbbe4b Guido Trotter
    (True, ["gnt-cluster", "modify", "-B", "maxmem=a"]),
343 8ccbbe4b Guido Trotter
    (False, ["sh", "-c", "gnt-cluster info|grep '^ *maxmem: 256$'"]),
344 8ccbbe4b Guido Trotter
    (True, ["gnt-cluster", "modify", "-B", "minmem=a"]),
345 8ccbbe4b Guido Trotter
    (False, ["sh", "-c", "gnt-cluster info|grep '^ *minmem: 256$'"]),
346 8ccbbe4b Guido Trotter
    (False, ["gnt-cluster", "modify", "-B", "maxmem=128,minmem=128"]),
347 8ccbbe4b Guido Trotter
    (False, ["sh", "-c", "gnt-cluster info|grep '^ *maxmem: 128$'"]),
348 8ccbbe4b Guido Trotter
    (False, ["sh", "-c", "gnt-cluster info|grep '^ *minmem: 128$'"]),
349 9738ca94 Iustin Pop
    # vcpus
350 2f4b4f78 Iustin Pop
    (False, ["gnt-cluster", "modify", "-B", "vcpus=4"]),
351 2f4b4f78 Iustin Pop
    (False, ["sh", "-c", "gnt-cluster info|grep '^ *vcpus: 4$'"]),
352 21bf2e2e Andrea Spadaccini
    (True, ["gnt-cluster", "modify", "-B", "vcpus=a"]),
353 2f4b4f78 Iustin Pop
    (False, ["gnt-cluster", "modify", "-B", "vcpus=1"]),
354 2f4b4f78 Iustin Pop
    (False, ["sh", "-c", "gnt-cluster info|grep '^ *vcpus: 1$'"]),
355 9738ca94 Iustin Pop
    # auto_balance
356 2f4b4f78 Iustin Pop
    (False, ["gnt-cluster", "modify", "-B", "auto_balance=False"]),
357 2f4b4f78 Iustin Pop
    (False, ["sh", "-c", "gnt-cluster info|grep '^ *auto_balance: False$'"]),
358 21bf2e2e Andrea Spadaccini
    (True, ["gnt-cluster", "modify", "-B", "auto_balance=1"]),
359 2f4b4f78 Iustin Pop
    (False, ["gnt-cluster", "modify", "-B", "auto_balance=True"]),
360 2f4b4f78 Iustin Pop
    (False, ["sh", "-c", "gnt-cluster info|grep '^ *auto_balance: True$'"]),
361 9738ca94 Iustin Pop
    ]:
362 2f4b4f78 Iustin Pop
    AssertCommand(cmd, fail=fail)
363 9738ca94 Iustin Pop
364 5abecc1c Iustin Pop
  # redo the original-requested BE parameters, if any
365 5abecc1c Iustin Pop
  bep = qa_config.get("backend-parameters", "")
366 5abecc1c Iustin Pop
  if bep:
367 5abecc1c Iustin Pop
    AssertCommand(["gnt-cluster", "modify", "-B", bep])
368 9738ca94 Iustin Pop
369 21bf2e2e Andrea Spadaccini
370 cec9845c Michael Hanselmann
def TestClusterInfo():
371 cec9845c Michael Hanselmann
  """gnt-cluster info"""
372 2f4b4f78 Iustin Pop
  AssertCommand(["gnt-cluster", "info"])
373 283f9d4c Michael Hanselmann
374 283f9d4c Michael Hanselmann
375 3e8b5a9c Iustin Pop
def TestClusterRedistConf():
376 3e8b5a9c Iustin Pop
  """gnt-cluster redist-conf"""
377 3e8b5a9c Iustin Pop
  AssertCommand(["gnt-cluster", "redist-conf"])
378 3e8b5a9c Iustin Pop
379 3e8b5a9c Iustin Pop
380 283f9d4c Michael Hanselmann
def TestClusterGetmaster():
381 283f9d4c Michael Hanselmann
  """gnt-cluster getmaster"""
382 2f4b4f78 Iustin Pop
  AssertCommand(["gnt-cluster", "getmaster"])
383 283f9d4c Michael Hanselmann
384 283f9d4c Michael Hanselmann
385 283f9d4c Michael Hanselmann
def TestClusterVersion():
386 283f9d4c Michael Hanselmann
  """gnt-cluster version"""
387 2f4b4f78 Iustin Pop
  AssertCommand(["gnt-cluster", "version"])
388 cec9845c Michael Hanselmann
389 cec9845c Michael Hanselmann
390 6d4a1656 Michael Hanselmann
def TestClusterRenewCrypto():
391 6d4a1656 Michael Hanselmann
  """gnt-cluster renew-crypto"""
392 6d4a1656 Michael Hanselmann
  master = qa_config.GetMasterNode()
393 6d4a1656 Michael Hanselmann
394 6d4a1656 Michael Hanselmann
  # Conflicting options
395 6d4a1656 Michael Hanselmann
  cmd = ["gnt-cluster", "renew-crypto", "--force",
396 3db3eb2a Michael Hanselmann
         "--new-cluster-certificate", "--new-confd-hmac-key"]
397 3db3eb2a Michael Hanselmann
  conflicting = [
398 3db3eb2a Michael Hanselmann
    ["--new-rapi-certificate", "--rapi-certificate=/dev/null"],
399 3db3eb2a Michael Hanselmann
    ["--new-cluster-domain-secret", "--cluster-domain-secret=/dev/null"],
400 3db3eb2a Michael Hanselmann
    ]
401 3db3eb2a Michael Hanselmann
  for i in conflicting:
402 21bf2e2e Andrea Spadaccini
    AssertCommand(cmd + i, fail=True)
403 6d4a1656 Michael Hanselmann
404 6d4a1656 Michael Hanselmann
  # Invalid RAPI certificate
405 6d4a1656 Michael Hanselmann
  cmd = ["gnt-cluster", "renew-crypto", "--force",
406 6d4a1656 Michael Hanselmann
         "--rapi-certificate=/dev/null"]
407 2f4b4f78 Iustin Pop
  AssertCommand(cmd, fail=True)
408 6d4a1656 Michael Hanselmann
409 502f5236 Michael Hanselmann
  rapi_cert_backup = qa_utils.BackupFile(master["primary"],
410 304d9f02 Michael Hanselmann
                                         pathutils.RAPI_CERT_FILE)
411 502f5236 Michael Hanselmann
  try:
412 502f5236 Michael Hanselmann
    # Custom RAPI certificate
413 502f5236 Michael Hanselmann
    fh = tempfile.NamedTemporaryFile()
414 6d4a1656 Michael Hanselmann
415 502f5236 Michael Hanselmann
    # Ensure certificate doesn't cause "gnt-cluster verify" to complain
416 502f5236 Michael Hanselmann
    validity = constants.SSL_CERT_EXPIRATION_WARN * 3
417 6d4a1656 Michael Hanselmann
418 5e26633b Michael Hanselmann
    utils.GenerateSelfSignedSslCert(fh.name, validity=validity)
419 6d4a1656 Michael Hanselmann
420 502f5236 Michael Hanselmann
    tmpcert = qa_utils.UploadFile(master["primary"], fh.name)
421 502f5236 Michael Hanselmann
    try:
422 2f4b4f78 Iustin Pop
      AssertCommand(["gnt-cluster", "renew-crypto", "--force",
423 2f4b4f78 Iustin Pop
                     "--rapi-certificate=%s" % tmpcert])
424 502f5236 Michael Hanselmann
    finally:
425 2f4b4f78 Iustin Pop
      AssertCommand(["rm", "-f", tmpcert])
426 502f5236 Michael Hanselmann
427 5e26633b Michael Hanselmann
    # Custom cluster domain secret
428 5e26633b Michael Hanselmann
    cds_fh = tempfile.NamedTemporaryFile()
429 5e26633b Michael Hanselmann
    cds_fh.write(utils.GenerateSecret())
430 5e26633b Michael Hanselmann
    cds_fh.write("\n")
431 5e26633b Michael Hanselmann
    cds_fh.flush()
432 5e26633b Michael Hanselmann
433 5e26633b Michael Hanselmann
    tmpcds = qa_utils.UploadFile(master["primary"], cds_fh.name)
434 5e26633b Michael Hanselmann
    try:
435 2f4b4f78 Iustin Pop
      AssertCommand(["gnt-cluster", "renew-crypto", "--force",
436 2f4b4f78 Iustin Pop
                     "--cluster-domain-secret=%s" % tmpcds])
437 5e26633b Michael Hanselmann
    finally:
438 2f4b4f78 Iustin Pop
      AssertCommand(["rm", "-f", tmpcds])
439 5e26633b Michael Hanselmann
440 502f5236 Michael Hanselmann
    # Normal case
441 2f4b4f78 Iustin Pop
    AssertCommand(["gnt-cluster", "renew-crypto", "--force",
442 2f4b4f78 Iustin Pop
                   "--new-cluster-certificate", "--new-confd-hmac-key",
443 2f4b4f78 Iustin Pop
                   "--new-rapi-certificate", "--new-cluster-domain-secret"])
444 3db3eb2a Michael Hanselmann
445 502f5236 Michael Hanselmann
    # Restore RAPI certificate
446 2f4b4f78 Iustin Pop
    AssertCommand(["gnt-cluster", "renew-crypto", "--force",
447 2f4b4f78 Iustin Pop
                   "--rapi-certificate=%s" % rapi_cert_backup])
448 3db3eb2a Michael Hanselmann
  finally:
449 2f4b4f78 Iustin Pop
    AssertCommand(["rm", "-f", rapi_cert_backup])
450 3db3eb2a Michael Hanselmann
451 6d4a1656 Michael Hanselmann
452 cec9845c Michael Hanselmann
def TestClusterBurnin():
453 cec9845c Michael Hanselmann
  """Burnin"""
454 cec9845c Michael Hanselmann
  master = qa_config.GetMasterNode()
455 cec9845c Michael Hanselmann
456 d0c8c01d Iustin Pop
  options = qa_config.get("options", {})
457 d0c8c01d Iustin Pop
  disk_template = options.get("burnin-disk-template", "drbd")
458 d0c8c01d Iustin Pop
  parallel = options.get("burnin-in-parallel", False)
459 d0c8c01d Iustin Pop
  check_inst = options.get("burnin-check-instances", False)
460 d0c8c01d Iustin Pop
  do_rename = options.get("burnin-rename", "")
461 d0c8c01d Iustin Pop
  do_reboot = options.get("burnin-reboot", True)
462 1d103c02 Iustin Pop
  reboot_types = options.get("reboot-types", constants.REBOOT_TYPES)
463 23103544 Michael Hanselmann
464 cec9845c Michael Hanselmann
  # Get as many instances as we need
465 cec9845c Michael Hanselmann
  instances = []
466 cec9845c Michael Hanselmann
  try:
467 23103544 Michael Hanselmann
    try:
468 d0c8c01d Iustin Pop
      num = qa_config.get("options", {}).get("burnin-instances", 1)
469 f1501b3f Michael Hanselmann
      for _ in range(0, num):
470 23103544 Michael Hanselmann
        instances.append(qa_config.AcquireInstance())
471 23103544 Michael Hanselmann
    except qa_error.OutOfInstancesError:
472 23103544 Michael Hanselmann
      print "Not enough instances, continuing anyway."
473 cec9845c Michael Hanselmann
474 23103544 Michael Hanselmann
    if len(instances) < 1:
475 23103544 Michael Hanselmann
      raise qa_error.Error("Burnin needs at least one instance")
476 cec9845c Michael Hanselmann
477 d0c8c01d Iustin Pop
    script = qa_utils.UploadFile(master["primary"], "../tools/burnin")
478 cec9845c Michael Hanselmann
    try:
479 23103544 Michael Hanselmann
      # Run burnin
480 cec9845c Michael Hanselmann
      cmd = [script,
481 d0c8c01d Iustin Pop
             "--os=%s" % qa_config.get("os"),
482 f356202a Guido Trotter
             "--minmem-size=%s" % qa_config.get(constants.BE_MINMEM),
483 f356202a Guido Trotter
             "--maxmem-size=%s" % qa_config.get(constants.BE_MAXMEM),
484 d0c8c01d Iustin Pop
             "--disk-size=%s" % ",".join(qa_config.get("disk")),
485 d0c8c01d Iustin Pop
             "--disk-growth=%s" % ",".join(qa_config.get("disk-growth")),
486 d0c8c01d Iustin Pop
             "--disk-template=%s" % disk_template]
487 0b0a150a Iustin Pop
      if parallel:
488 d0c8c01d Iustin Pop
        cmd.append("--parallel")
489 d0c8c01d Iustin Pop
        cmd.append("--early-release")
490 0b0a150a Iustin Pop
      if check_inst:
491 d0c8c01d Iustin Pop
        cmd.append("--http-check")
492 4dc76b24 Iustin Pop
      if do_rename:
493 d0c8c01d Iustin Pop
        cmd.append("--rename=%s" % do_rename)
494 58598264 Iustin Pop
      if not do_reboot:
495 d0c8c01d Iustin Pop
        cmd.append("--no-reboot")
496 1d103c02 Iustin Pop
      else:
497 d0c8c01d Iustin Pop
        cmd.append("--reboot-types=%s" % ",".join(reboot_types))
498 d0c8c01d Iustin Pop
      cmd += [inst["name"] for inst in instances]
499 2f4b4f78 Iustin Pop
      AssertCommand(cmd)
500 cec9845c Michael Hanselmann
    finally:
501 2f4b4f78 Iustin Pop
      AssertCommand(["rm", "-f", script])
502 2f4b4f78 Iustin Pop
503 cec9845c Michael Hanselmann
  finally:
504 cec9845c Michael Hanselmann
    for inst in instances:
505 cec9845c Michael Hanselmann
      qa_config.ReleaseInstance(inst)
506 cec9845c Michael Hanselmann
507 cec9845c Michael Hanselmann
508 cec9845c Michael Hanselmann
def TestClusterMasterFailover():
509 c28502b1 Iustin Pop
  """gnt-cluster master-failover"""
510 cec9845c Michael Hanselmann
  master = qa_config.GetMasterNode()
511 cec9845c Michael Hanselmann
  failovermaster = qa_config.AcquireNode(exclude=master)
512 cec9845c Michael Hanselmann
513 2f4b4f78 Iustin Pop
  cmd = ["gnt-cluster", "master-failover"]
514 2f4b4f78 Iustin Pop
  try:
515 2f4b4f78 Iustin Pop
    AssertCommand(cmd, node=failovermaster)
516 ff699aa9 Michael Hanselmann
    # Back to original master node
517 2f4b4f78 Iustin Pop
    AssertCommand(cmd, node=master)
518 cec9845c Michael Hanselmann
  finally:
519 cec9845c Michael Hanselmann
    qa_config.ReleaseNode(failovermaster)
520 cec9845c Michael Hanselmann
521 cec9845c Michael Hanselmann
522 ff699aa9 Michael Hanselmann
def TestClusterMasterFailoverWithDrainedQueue():
523 ff699aa9 Michael Hanselmann
  """gnt-cluster master-failover with drained queue"""
524 304d9f02 Michael Hanselmann
  drain_check = ["test", "-f", pathutils.JOB_QUEUE_DRAIN_FILE]
525 ff699aa9 Michael Hanselmann
526 ff699aa9 Michael Hanselmann
  master = qa_config.GetMasterNode()
527 ff699aa9 Michael Hanselmann
  failovermaster = qa_config.AcquireNode(exclude=master)
528 ff699aa9 Michael Hanselmann
529 ff699aa9 Michael Hanselmann
  # Ensure queue is not drained
530 ff699aa9 Michael Hanselmann
  for node in [master, failovermaster]:
531 ff699aa9 Michael Hanselmann
    AssertCommand(drain_check, node=node, fail=True)
532 ff699aa9 Michael Hanselmann
533 ff699aa9 Michael Hanselmann
  # Drain queue on failover master
534 304d9f02 Michael Hanselmann
  AssertCommand(["touch", pathutils.JOB_QUEUE_DRAIN_FILE], node=failovermaster)
535 ff699aa9 Michael Hanselmann
536 ff699aa9 Michael Hanselmann
  cmd = ["gnt-cluster", "master-failover"]
537 ff699aa9 Michael Hanselmann
  try:
538 ff699aa9 Michael Hanselmann
    AssertCommand(drain_check, node=failovermaster)
539 ff699aa9 Michael Hanselmann
    AssertCommand(cmd, node=failovermaster)
540 ff699aa9 Michael Hanselmann
    AssertCommand(drain_check, fail=True)
541 ff699aa9 Michael Hanselmann
    AssertCommand(drain_check, node=failovermaster, fail=True)
542 ff699aa9 Michael Hanselmann
543 ff699aa9 Michael Hanselmann
    # Back to original master node
544 ff699aa9 Michael Hanselmann
    AssertCommand(cmd, node=master)
545 ff699aa9 Michael Hanselmann
  finally:
546 ff699aa9 Michael Hanselmann
    qa_config.ReleaseNode(failovermaster)
547 ff699aa9 Michael Hanselmann
548 ff699aa9 Michael Hanselmann
  AssertCommand(drain_check, fail=True)
549 ff699aa9 Michael Hanselmann
  AssertCommand(drain_check, node=failovermaster, fail=True)
550 ff699aa9 Michael Hanselmann
551 ff699aa9 Michael Hanselmann
552 cec9845c Michael Hanselmann
def TestClusterCopyfile():
553 cec9845c Michael Hanselmann
  """gnt-cluster copyfile"""
554 cec9845c Michael Hanselmann
  master = qa_config.GetMasterNode()
555 cec9845c Michael Hanselmann
556 24818e8f Michael Hanselmann
  uniqueid = utils.NewUUID()
557 830da270 Michael Hanselmann
558 cec9845c Michael Hanselmann
  # Create temporary file
559 cec9845c Michael Hanselmann
  f = tempfile.NamedTemporaryFile()
560 830da270 Michael Hanselmann
  f.write(uniqueid)
561 cec9845c Michael Hanselmann
  f.flush()
562 cec9845c Michael Hanselmann
  f.seek(0)
563 cec9845c Michael Hanselmann
564 cec9845c Michael Hanselmann
  # Upload file to master node
565 d0c8c01d Iustin Pop
  testname = qa_utils.UploadFile(master["primary"], f.name)
566 cec9845c Michael Hanselmann
  try:
567 cec9845c Michael Hanselmann
    # Copy file to all nodes
568 2f4b4f78 Iustin Pop
    AssertCommand(["gnt-cluster", "copyfile", testname])
569 830da270 Michael Hanselmann
    _CheckFileOnAllNodes(testname, uniqueid)
570 cec9845c Michael Hanselmann
  finally:
571 830da270 Michael Hanselmann
    _RemoveFileFromAllNodes(testname)
572 830da270 Michael Hanselmann
573 830da270 Michael Hanselmann
574 830da270 Michael Hanselmann
def TestClusterCommand():
575 830da270 Michael Hanselmann
  """gnt-cluster command"""
576 24818e8f Michael Hanselmann
  uniqueid = utils.NewUUID()
577 24818e8f Michael Hanselmann
  rfile = "/tmp/gnt%s" % utils.NewUUID()
578 d0c8c01d Iustin Pop
  rcmd = utils.ShellQuoteArgs(["echo", "-n", uniqueid])
579 d0c8c01d Iustin Pop
  cmd = utils.ShellQuoteArgs(["gnt-cluster", "command",
580 830da270 Michael Hanselmann
                              "%s >%s" % (rcmd, rfile)])
581 830da270 Michael Hanselmann
582 830da270 Michael Hanselmann
  try:
583 2f4b4f78 Iustin Pop
    AssertCommand(cmd)
584 830da270 Michael Hanselmann
    _CheckFileOnAllNodes(rfile, uniqueid)
585 830da270 Michael Hanselmann
  finally:
586 830da270 Michael Hanselmann
    _RemoveFileFromAllNodes(rfile)
587 cec9845c Michael Hanselmann
588 cec9845c Michael Hanselmann
589 cec9845c Michael Hanselmann
def TestClusterDestroy():
590 cec9845c Michael Hanselmann
  """gnt-cluster destroy"""
591 2f4b4f78 Iustin Pop
  AssertCommand(["gnt-cluster", "destroy", "--yes-do-it"])
592 65a884ef Iustin Pop
593 65a884ef Iustin Pop
594 65a884ef Iustin Pop
def TestClusterRepairDiskSizes():
595 65a884ef Iustin Pop
  """gnt-cluster repair-disk-sizes"""
596 65a884ef Iustin Pop
  AssertCommand(["gnt-cluster", "repair-disk-sizes"])