Commit 3eaa6e1d authored by Klaus Aehlig's avatar Klaus Aehlig

Merge branch 'stable-2.8' into stable-2.9

* stable-2.8
  Add support for blktap2 file-driver
  Update opcodes test to include network tags
  Make network tags searchable
  Add network tag tests to QA
  Fix RAPI network tag handling
  Fix gnt-network list-tags

Conflicts:
	lib/cmdlib/tags.py
	test/py/ganeti.hypervisor.hv_xen_unittest.py
Resolution: manually apply the changes from stable-2.8 to
            the stable-2.9 code.
Signed-off-by: default avatarKlaus Aehlig <aehlig@google.com>
Reviewed-by: default avatarGuido Trotter <ultrotter@google.com>
parents 89c63fbe 7bc2c097
......@@ -130,17 +130,26 @@ class LUTagsSearch(NoHooksLU):
raise errors.OpPrereqError("Invalid search pattern '%s': %s" %
(self.op.pattern, err), errors.ECODE_INVAL)
@staticmethod
def _ExtendTagTargets(targets, object_type_name, object_info_dict):
return targets.extend(("/%s/%s" % (object_type_name, o.name), o)
for o in object_info_dict.values())
def Exec(self, feedback_fn):
"""Returns the tag list.
"""
tgts = [("/cluster", self.cfg.GetClusterInfo())]
ilist = self.cfg.GetAllInstancesInfo().values()
tgts.extend([("/instances/%s" % i.name, i) for i in ilist])
nlist = self.cfg.GetAllNodesInfo().values()
tgts.extend([("/nodes/%s" % n.name, n) for n in nlist])
tgts.extend(("/nodegroup/%s" % n.name, n)
for n in self.cfg.GetAllNodeGroupsInfo().values())
LUTagsSearch._ExtendTagTargets(tgts, "instances",
self.cfg.GetAllInstancesInfo())
LUTagsSearch._ExtendTagTargets(tgts, "nodes",
self.cfg.GetAllNodesInfo())
LUTagsSearch._ExtendTagTargets(tgts, "nodegroup",
self.cfg.GetAllNodeGroupsInfo())
LUTagsSearch._ExtendTagTargets(tgts, "network",
self.cfg.GetAllNetworksInfo())
results = []
for path, target in tgts:
for tag in target.GetTags():
......
......@@ -609,6 +609,7 @@ RBD_CMD = "rbd"
# file backend driver
FD_LOOP = "loop"
FD_BLKTAP = "blktap"
FD_BLKTAP2 = "blktap2"
FD_DEFAULT = FD_LOOP
# disk access mode
......@@ -665,7 +666,7 @@ RIE_CONNECT_RETRIES = 10
#: Give child process up to 5 seconds to exit after sending a signal
CHILD_LINGER_TIMEOUT = 5.0
FILE_DRIVER = compat.UniqueFrozenset([FD_LOOP, FD_BLKTAP])
FILE_DRIVER = compat.UniqueFrozenset([FD_LOOP, FD_BLKTAP, FD_BLKTAP2])
# import/export config options
INISECT_EXP = "export"
......
......@@ -48,6 +48,7 @@ _DISK_LETTERS = string.ascii_lowercase
_FILE_DRIVER_MAP = {
constants.FD_LOOP: "file",
constants.FD_BLKTAP: "tap:aio",
constants.FD_BLKTAP2: "tap2:tapdisk:aio",
}
......
......@@ -1501,7 +1501,8 @@ class _R_Tags(baserlib.OpcodeResource):
if kind in (constants.TAG_INSTANCE,
constants.TAG_NODEGROUP,
constants.TAG_NODE):
constants.TAG_NODE,
constants.TAG_NETWORK):
if not self.name:
raise http.HttpBadRequest("Missing name on tag request")
......@@ -1514,6 +1515,9 @@ class _R_Tags(baserlib.OpcodeResource):
ssc = ssconf.SimpleStore()
tags = ssc.GetClusterTags()
else:
raise http.HttpBadRequest("Unhandled tag type!")
return list(tags)
def GetPutOpInput(self):
......
......@@ -91,9 +91,9 @@ DISK_%N_FRONTEND_TYPE
DISK_%N_BACKEND_TYPE
How files are visible on the node side. This can be either
``block`` (when using block devices) or ``file:type``, where
``type`` is either ``loop`` or ``blktap`` depending on how the
hypervisor will be configured. Note that not all backend types
apply to all hypervisors.
``type`` is either ``loop``, ``blktap`` or ``blktap2``, depending on how the
hypervisor will be configured. Note that not all backend types apply to all
hypervisors.
NIC_COUNT
Similar to the ``DISK_COUNT``, this represents the number of NICs
......
......@@ -37,7 +37,7 @@ ADD
| [{-B|\--backend-parameters} *BEPARAMS*]
| [{-H|\--hypervisor-parameters} *HYPERVISOR* [: option=*value*... ]]
| [{-O|\--os-parameters} *param*=*value*... ]
| [\--file-storage-dir *dir\_path*] [\--file-driver {loop \| blktap}]
| [\--file-storage-dir *dir\_path*] [\--file-driver {loop \| blktap \| blktap2}]
| {{-n|\--node} *node[:secondary-node]* \| {-I|\--iallocator} *name*}
| {{-o|\--os-type} *os-type*}
| [\--submit] [\--print-job-id]
......@@ -849,6 +849,9 @@ blktap
better performance. Especially if you use a network file system
(e.g. NFS) to store your instances this is the recommended choice.
blktap2
Analogous to the blktap driver, but used by newer versions of Xen.
If ``--ignore-ipolicy`` is given any instance policy violations occuring
during this operation are ignored.
......
......@@ -385,6 +385,7 @@ def RunNetworkTests():
"""
RunTestIf("network", qa_network.TestNetworkAddRemove)
RunTestIf("network", qa_network.TestNetworkConnect)
RunTestIf(["network", "tags"], qa_network.TestNetworkTags)
def RunGroupRwTests():
......
......@@ -24,6 +24,7 @@
"""
import qa_config
import qa_tags
import qa_utils
from qa_utils import AssertCommand
......@@ -56,6 +57,14 @@ def TestNetworkAddRemove():
AssertCommand(["gnt-network", "remove", network2])
def TestNetworkTags():
"""gnt-network tags"""
(network, ) = GetNonexistentNetworks(1)
AssertCommand(["gnt-network", "add", "--network", "192.0.2.0/30", network])
qa_tags.TestNetworkTags(network)
AssertCommand(["gnt-network", "remove", network])
def TestNetworkConnect():
"""gnt-network connect/disconnect"""
(group1, ) = qa_utils.GetNonexistentGroups(1)
......
......@@ -464,6 +464,8 @@ def TestTags(kind, name, tags):
uri = "/2/instances/%s/tags" % name
elif kind == constants.TAG_NODEGROUP:
uri = "/2/groups/%s/tags" % name
elif kind == constants.TAG_NETWORK:
uri = "/2/networks/%s/tags" % name
else:
raise errors.ProgrammerError("Unknown tag kind")
......
......@@ -38,6 +38,7 @@ _KIND_TO_COMMAND = {
constants.TAG_NODE: "gnt-node",
constants.TAG_INSTANCE: "gnt-instance",
constants.TAG_NODEGROUP: "gnt-group",
constants.TAG_NETWORK: "gnt-network",
}
......@@ -83,3 +84,8 @@ def TestGroupTags(group):
def TestInstanceTags(instance):
"""gnt-instance tags"""
_TestTags(constants.TAG_INSTANCE, instance.name)
def TestNetworkTags(network):
"""gnt-network tags"""
_TestTags(constants.TAG_NETWORK, network)
......@@ -325,6 +325,7 @@ $(declareSADT "TagType"
, ("TagTypeNode", 'C.tagNode)
, ("TagTypeGroup", 'C.tagNodegroup)
, ("TagTypeCluster", 'C.tagCluster)
, ("TagTypeNetwork", 'C.tagNetwork)
])
$(makeJSONInstance ''TagType)
......@@ -332,6 +333,7 @@ $(makeJSONInstance ''TagType)
data TagObject = TagInstance String
| TagNode String
| TagGroup String
| TagNetwork String
| TagCluster
deriving (Show, Eq)
......@@ -341,12 +343,14 @@ tagTypeOf (TagInstance {}) = TagTypeInstance
tagTypeOf (TagNode {}) = TagTypeNode
tagTypeOf (TagGroup {}) = TagTypeGroup
tagTypeOf (TagCluster {}) = TagTypeCluster
tagTypeOf (TagNetwork {}) = TagTypeNetwork
-- | Gets the potential tag object name.
tagNameOf :: TagObject -> Maybe String
tagNameOf (TagInstance s) = Just s
tagNameOf (TagNode s) = Just s
tagNameOf (TagGroup s) = Just s
tagNameOf (TagNetwork s) = Just s
tagNameOf TagCluster = Nothing
-- | Builds a 'TagObject' from a tag type and name.
......@@ -355,6 +359,8 @@ tagObjectFrom TagTypeInstance (JSString s) =
return . TagInstance $ fromJSString s
tagObjectFrom TagTypeNode (JSString s) = return . TagNode $ fromJSString s
tagObjectFrom TagTypeGroup (JSString s) = return . TagGroup $ fromJSString s
tagObjectFrom TagTypeNetwork (JSString s) =
return . TagNetwork $ fromJSString s
tagObjectFrom TagTypeCluster JSNull = return TagCluster
tagObjectFrom t v =
fail $ "Invalid tag type/name combination: " ++ show t ++ "/" ++
......
......@@ -156,6 +156,7 @@ handleCall cfg (QueryTags kind) =
TagGroup name -> groupTags <$> Config.getGroup cfg name
TagNode name -> nodeTags <$> Config.getNode cfg name
TagInstance name -> instTags <$> Config.getInstance cfg name
TagNetwork name -> networkTags <$> Config.getNetwork cfg name
in return (J.showJSON <$> tags)
handleCall cfg (Query qkind qfields qfilter) = do
......
......@@ -62,6 +62,7 @@ instance Arbitrary OpCodes.TagObject where
arbitrary = oneof [ OpCodes.TagInstance <$> genFQDN
, OpCodes.TagNode <$> genFQDN
, OpCodes.TagGroup <$> genFQDN
, OpCodes.TagNetwork <$> genFQDN
, pure OpCodes.TagCluster
]
......@@ -554,6 +555,7 @@ case_TagObject_fail =
, (TagTypeInstance, J.JSNull)
, (TagTypeNode, J.JSNull)
, (TagTypeGroup, J.JSNull)
, (TagTypeNetwork, J.JSNull)
]
-- | Tests wrong (negative) disk index.
......
......@@ -311,6 +311,9 @@ class TestGetConfigFileDiskData(unittest.TestCase):
(objects.Disk(dev_type=constants.DT_FILE, mode=constants.DISK_RDWR,
physical_id=[constants.FD_LOOP]),
"/tmp/diskThree"),
(objects.Disk(dev_type=constants.DT_FILE, mode=constants.DISK_RDONLY,
physical_id=[constants.FD_BLKTAP2]),
"/tmp/diskFour"),
(objects.Disk(dev_type=constants.DT_FILE, mode=constants.DISK_RDWR,
physical_id=[constants.FD_BLKTAP]),
"/tmp/diskLast"),
......@@ -321,7 +324,8 @@ class TestGetConfigFileDiskData(unittest.TestCase):
"'file:/tmp/diskFirst,sda,w'",
"'tap:aio:/tmp/diskTwo,sdb,r'",
"'file:/tmp/diskThree,sdc,w'",
"'tap:aio:/tmp/diskLast,sdd,w'",
"'tap2:tapdisk:aio:/tmp/diskFour,sdd,r'",
"'tap:aio:/tmp/diskLast,sde,w'",
])
def testInvalidFileDisk(self):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment