+#
+#
+
# Copyright (C) 2007 Google Inc.
#
# This program is free software; you can redistribute it and/or modify
from ganeti import utils
+from ganeti import constants
import qa_config
import qa_error
import qa_utils
-from qa_utils import AssertEqual, StartSSH
+from qa_utils import AssertCommand
-def _NodeAdd(node):
- master = qa_config.GetMasterNode()
-
- if node.get('_added', False):
+def _NodeAdd(node, readd=False):
+ if not readd and node.get('_added', False):
raise qa_error.Error("Node %s already in cluster" % node['primary'])
+ elif readd and not node.get('_added', False):
+ raise qa_error.Error("Node %s not yet in cluster" % node['primary'])
- cmd = ['gnt-node', 'add']
+ cmd = ['gnt-node', 'add', "--no-ssh-key-check"]
if node.get('secondary', None):
cmd.append('--secondary-ip=%s' % node['secondary'])
+ if readd:
+ cmd.append('--readd')
cmd.append(node['primary'])
- AssertEqual(StartSSH(master['primary'],
- utils.ShellQuoteArgs(cmd)).wait(), 0)
+
+ AssertCommand(cmd)
node['_added'] = True
def _NodeRemove(node):
- master = qa_config.GetMasterNode()
-
- cmd = ['gnt-node', 'remove', node['primary']]
- AssertEqual(StartSSH(master['primary'],
- utils.ShellQuoteArgs(cmd)).wait(), 0)
+ AssertCommand(["gnt-node", "remove", node["primary"]])
node['_added'] = False
master = qa_config.GetMasterNode()
for node in qa_config.get('nodes'):
if node != master:
- _NodeAdd(node)
+ _NodeAdd(node, readd=False)
+
+
+def MarkNodeAddedAll():
+ """Mark all nodes as added.
+
+ This is useful if we don't create the cluster ourselves (in qa).
+
+ """
+ master = qa_config.GetMasterNode()
+ for node in qa_config.get('nodes'):
+ if node != master:
+ node['_added'] = True
def TestNodeRemoveAll():
_NodeRemove(node)
+def TestNodeReadd(node):
+ """gnt-node add --readd"""
+ _NodeAdd(node, readd=True)
+
+
def TestNodeInfo():
"""gnt-node info"""
- master = qa_config.GetMasterNode()
-
- cmd = ['gnt-node', 'info']
- AssertEqual(StartSSH(master['primary'],
- utils.ShellQuoteArgs(cmd)).wait(), 0)
+ AssertCommand(["gnt-node", "info"])
def TestNodeVolumes():
"""gnt-node volumes"""
+ AssertCommand(["gnt-node", "volumes"])
+
+
+def TestNodeStorage():
+ """gnt-node storage"""
master = qa_config.GetMasterNode()
- cmd = ['gnt-node', 'volumes']
- AssertEqual(StartSSH(master['primary'],
- utils.ShellQuoteArgs(cmd)).wait(), 0)
+ for storage_type in constants.VALID_STORAGE_TYPES:
+ # Test simple list
+ AssertCommand(["gnt-node", "list-storage", "--storage-type", storage_type])
+
+ # Test all storage fields
+ cmd = ["gnt-node", "list-storage", "--storage-type", storage_type,
+ "--output=%s" % ",".join(list(constants.VALID_STORAGE_FIELDS) +
+ [constants.SF_NODE, constants.SF_TYPE])]
+ AssertCommand(cmd)
+
+ # Get list of valid storage devices
+ cmd = ["gnt-node", "list-storage", "--storage-type", storage_type,
+ "--output=node,name,allocatable", "--separator=|",
+ "--no-headers"]
+ output = qa_utils.GetCommandOutput(master["primary"],
+ utils.ShellQuoteArgs(cmd))
+
+ # Test with up to two devices
+ testdevcount = 2
+
+ for line in output.splitlines()[:testdevcount]:
+ (node_name, st_name, st_allocatable) = line.split("|")
+
+ # Dummy modification without any changes
+ cmd = ["gnt-node", "modify-storage", node_name, storage_type, st_name]
+ AssertCommand(cmd)
+
+ # Make sure we end up with the same value as before
+ if st_allocatable.lower() == "y":
+ test_allocatable = ["no", "yes"]
+ else:
+ test_allocatable = ["yes", "no"]
+
+ fail = (constants.SF_ALLOCATABLE not in
+ constants.MODIFIABLE_STORAGE_FIELDS.get(storage_type, []))
+
+ for i in test_allocatable:
+ AssertCommand(["gnt-node", "modify-storage", "--allocatable", i,
+ node_name, storage_type, st_name], fail=fail)
+
+ # Test repair functionality
+ fail = (constants.SO_FIX_CONSISTENCY not in
+ constants.VALID_STORAGE_OPERATIONS.get(storage_type, []))
+ AssertCommand(["gnt-node", "repair-storage", node_name,
+ storage_type, st_name], fail=fail)
def TestNodeFailover(node, node2):
"""gnt-node failover"""
- master = qa_config.GetMasterNode()
-
- if qa_utils.GetNodeInstances(node2):
- raise qa_errors.UnusableNodeError("Secondary node has at least one "
- "primary instance. This test requires "
- "it to have no primary instances.")
+ if qa_utils.GetNodeInstances(node2, secondaries=False):
+ raise qa_error.UnusableNodeError("Secondary node has at least one"
+ " primary instance. This test requires"
+ " it to have no primary instances.")
# Fail over to secondary node
- cmd = ['gnt-node', 'failover', '-f', node['primary']]
- AssertEqual(StartSSH(master['primary'],
- utils.ShellQuoteArgs(cmd)).wait(), 0)
+ AssertCommand(["gnt-node", "failover", "-f", node["primary"]])
# ... and back again.
- cmd = ['gnt-node', 'failover', '-f', node2['primary']]
- AssertEqual(StartSSH(master['primary'],
- utils.ShellQuoteArgs(cmd)).wait(), 0)
+ AssertCommand(["gnt-node", "failover", "-f", node2["primary"]])
def TestNodeEvacuate(node, node2):
"""gnt-node evacuate"""
- master = qa_config.GetMasterNode()
-
node3 = qa_config.AcquireNode(exclude=[node, node2])
try:
- if qa_utils.GetNodeInstances(node3):
- raise qa_errors.UnusableNodeError("Evacuation node has at least one "
- "secondary instance. This test requires "
- "it to have no secondary instances.")
+ if qa_utils.GetNodeInstances(node3, secondaries=True):
+ raise qa_error.UnusableNodeError("Evacuation node has at least one"
+ " secondary instance. This test requires"
+ " it to have no secondary instances.")
# Evacuate all secondary instances
- cmd = ['gnt-node', 'evacuate', '-f', node2['primary'], node3['primary']]
- AssertEqual(StartSSH(master['primary'],
- utils.ShellQuoteArgs(cmd)).wait(), 0)
+ AssertCommand(["gnt-node", "evacuate", "-f",
+ "--new-secondary=%s" % node3["primary"], node2["primary"]])
# ... and back again.
- cmd = ['gnt-node', 'evacuate', '-f', node3['primary'], node2['primary']]
- AssertEqual(StartSSH(master['primary'],
- utils.ShellQuoteArgs(cmd)).wait(), 0)
+ AssertCommand(["gnt-node", "evacuate", "-f",
+ "--new-secondary=%s" % node2["primary"], node3["primary"]])
finally:
qa_config.ReleaseNode(node3)
+
+
+def TestNodeModify(node):
+ """gnt-node modify"""
+ for flag in ["master-candidate", "drained", "offline"]:
+ for value in ["yes", "no"]:
+ AssertCommand(["gnt-node", "modify", "--force",
+ "--%s=%s" % (flag, value), node["primary"]])
+
+ AssertCommand(["gnt-node", "modify", "--master-candidate=yes",
+ "--auto-promote", node["primary"]])