From 890ea4cef63a0a397f4be759c380647737d736d0 Mon Sep 17 00:00:00 2001 From: Michael Hanselmann <hansmi@google.com> Date: Thu, 5 Jan 2012 14:03:47 +0100 Subject: [PATCH] rpc._NodeConfigResolver: Support resolving offline nodes This is needed to powercycle a node marked offline. Signed-off-by: Michael Hanselmann <hansmi@google.com> Reviewed-by: Iustin Pop <iustin@google.com> --- lib/rpc.py | 15 ++++++++++----- lib/rpc_defs.py | 2 ++ test/ganeti.rpc_unittest.py | 12 ++++++++++++ 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/lib/rpc.py b/lib/rpc.py index cb0ca7847..126984516 100644 --- a/lib/rpc.py +++ b/lib/rpc.py @@ -285,7 +285,7 @@ class _StaticResolver: return zip(hosts, self._addresses) -def _CheckConfigNode(name, node): +def _CheckConfigNode(name, node, accept_offline_node): """Checks if a node is online. @type name: string @@ -297,24 +297,29 @@ def _CheckConfigNode(name, node): if node is None: # Depend on DNS for name resolution ip = name - elif node.offline: + elif node.offline and not accept_offline_node: ip = _OFFLINE else: ip = node.primary_ip return (name, ip) -def _NodeConfigResolver(single_node_fn, all_nodes_fn, hosts, _): +def _NodeConfigResolver(single_node_fn, all_nodes_fn, hosts, opts): """Calculate node addresses using configuration. """ + accept_offline_node = (opts is rpc_defs.ACCEPT_OFFLINE_NODE) + + assert accept_offline_node or opts is None, "Unknown option" + # Special case for single-host lookups if len(hosts) == 1: (name, ) = hosts - return [_CheckConfigNode(name, single_node_fn(name))] + return [_CheckConfigNode(name, single_node_fn(name), accept_offline_node)] else: all_nodes = all_nodes_fn() - return [_CheckConfigNode(name, all_nodes.get(name, None)) + return [_CheckConfigNode(name, all_nodes.get(name, None), + accept_offline_node) for name in hosts] diff --git a/lib/rpc_defs.py b/lib/rpc_defs.py index 2e32c82e9..657776ff4 100644 --- a/lib/rpc_defs.py +++ b/lib/rpc_defs.py @@ -58,6 +58,8 @@ TMO_1DAY = 86400 SINGLE = "single-node" MULTI = "multi-node" +ACCEPT_OFFLINE_NODE = object() + # Constants for encoding/decoding (ED_OBJECT_DICT, ED_OBJECT_DICT_LIST, diff --git a/test/ganeti.rpc_unittest.py b/test/ganeti.rpc_unittest.py index 633d89a54..da94a7089 100755 --- a/test/ganeti.rpc_unittest.py +++ b/test/ganeti.rpc_unittest.py @@ -28,6 +28,7 @@ import unittest from ganeti import constants from ganeti import compat from ganeti import rpc +from ganeti import rpc_defs from ganeti import http from ganeti import errors from ganeti import serializer @@ -397,6 +398,17 @@ class TestNodeConfigResolver(unittest.TestCase): ["node100.example.com"], None), [("node100.example.com", rpc._OFFLINE)]) + def testSingleOfflineWithAcceptOffline(self): + fn = self._GetSingleOfflineNode + assert fn("node100.example.com").offline + self.assertEqual(rpc._NodeConfigResolver(fn, NotImplemented, + ["node100.example.com"], + rpc_defs.ACCEPT_OFFLINE_NODE), + [("node100.example.com", "192.0.2.100")]) + for i in [False, True, "", "Hello", 0, 1]: + self.assertRaises(AssertionError, rpc._NodeConfigResolver, + fn, NotImplemented, ["node100.example.com"], i) + def testUnknownSingleNode(self): self.assertEqual(rpc._NodeConfigResolver(lambda _: None, NotImplemented, ["node110.example.com"], None), -- GitLab