diff --git a/lib/bootstrap.py b/lib/bootstrap.py index 8c4663f8253ae4e2ec9110ca1eed6af01f006688..0ae435c6d5ac28612a07e58556a8c0da985b0131 100644 --- a/lib/bootstrap.py +++ b/lib/bootstrap.py @@ -222,6 +222,8 @@ def _WaitForNodeDaemon(node_name): """ def _CheckNodeDaemon(): + # Pylint bug <http://www.logilab.org/ticket/35642> + # pylint: disable=E1101 result = rpc.BootstrapRunner().call_version([node_name])[node_name] if result.fail_msg: raise utils.RetryAgain() diff --git a/lib/cmdlib.py b/lib/cmdlib.py index 3b5ff61e05b7c34cdaf6379373a581c39228938e..7e8e3b5992494ff426b0a6be0e1d2dd45a335377 100644 --- a/lib/cmdlib.py +++ b/lib/cmdlib.py @@ -5909,9 +5909,7 @@ class LUNodeSetParams(LogicalUnit): if old_role == self._ROLE_OFFLINE and new_role != old_role: # Trying to transition out of offline status - # TODO: Use standard RPC runner, but make sure it works when the node is - # still marked offline - result = rpc.BootstrapRunner().call_version([node.name])[node.name] + result = self.rpc.call_version([node.name])[node.name] if result.fail_msg: raise errors.OpPrereqError("Node %s is being de-offlined but fails" " to report its version: %s" % diff --git a/lib/rpc.py b/lib/rpc.py index 5a9b167ca4d5a24d4c3f3704210169453279e1ec..3584ffc49eb89774e0296b901427a34dd2d3f4d0 100644 --- a/lib/rpc.py +++ b/lib/rpc.py @@ -239,11 +239,13 @@ class RpcResult(object): raise ec(*args) # pylint: disable=W0142 -def _SsconfResolver(node_list, _, +def _SsconfResolver(ssconf_ips, node_list, _, ssc=ssconf.SimpleStore, nslookup_fn=netutils.Hostname.GetIP): """Return addresses for given node names. + @type ssconf_ips: bool + @param ssconf_ips: Use the ssconf IPs @type node_list: list @param node_list: List of node names @type ssc: class @@ -255,9 +257,13 @@ def _SsconfResolver(node_list, _, """ ss = ssc() - iplist = ss.GetNodePrimaryIPList() family = ss.GetPrimaryIPFamily() - ipmap = dict(entry.split() for entry in iplist) + + if ssconf_ips: + iplist = ss.GetNodePrimaryIPList() + ipmap = dict(entry.split() for entry in iplist) + else: + ipmap = {} result = [] for node in node_list: @@ -584,6 +590,7 @@ _ENCODERS = { class RpcRunner(_RpcClientBase, _generated_rpc.RpcClientDefault, _generated_rpc.RpcClientBootstrap, + _generated_rpc.RpcClientDnsOnly, _generated_rpc.RpcClientConfig): """RPC runner class. @@ -624,6 +631,7 @@ class RpcRunner(_RpcClientBase, _req_process_fn=_req_process_fn) _generated_rpc.RpcClientConfig.__init__(self) _generated_rpc.RpcClientBootstrap.__init__(self) + _generated_rpc.RpcClientDnsOnly.__init__(self) _generated_rpc.RpcClientDefault.__init__(self) def _InstDict(self, instance, hvp=None, bep=None, osp=None): @@ -684,7 +692,7 @@ class JobQueueRunner(_RpcClientBase, _generated_rpc.RpcClientJobQueue): """ if address_list is None: - resolver = _SsconfResolver + resolver = compat.partial(_SsconfResolver, True) else: # Caller provided an address list resolver = _StaticResolver(address_list) @@ -694,7 +702,9 @@ class JobQueueRunner(_RpcClientBase, _generated_rpc.RpcClientJobQueue): _generated_rpc.RpcClientJobQueue.__init__(self) -class BootstrapRunner(_RpcClientBase, _generated_rpc.RpcClientBootstrap): +class BootstrapRunner(_RpcClientBase, + _generated_rpc.RpcClientBootstrap, + _generated_rpc.RpcClientDnsOnly): """RPC wrappers for bootstrapping. """ @@ -702,8 +712,27 @@ class BootstrapRunner(_RpcClientBase, _generated_rpc.RpcClientBootstrap): """Initializes this class. """ - _RpcClientBase.__init__(self, _SsconfResolver, _ENCODERS.get) + # Pylint doesn't recognize multiple inheritance properly, see + # <http://www.logilab.org/ticket/36586> and + # <http://www.logilab.org/ticket/35642> + # pylint: disable=W0233 + _RpcClientBase.__init__(self, compat.partial(_SsconfResolver, True), + _ENCODERS.get) _generated_rpc.RpcClientBootstrap.__init__(self) + _generated_rpc.RpcClientDnsOnly.__init__(self) + + +class DnsOnlyRunner(_RpcClientBase, _generated_rpc.RpcClientDnsOnly): + """RPC wrappers for calls using only DNS. + + """ + def __init__(self): + """Initialize this class. + + """ + _RpcClientBase.__init__(self, compat.partial(_SsconfResolver, False), + _ENCODERS.get) + _generated_rpc.RpcClientDnsOnly.__init__(self) class ConfigRunner(_RpcClientBase, _generated_rpc.RpcClientConfig): @@ -721,7 +750,7 @@ class ConfigRunner(_RpcClientBase, _generated_rpc.RpcClientConfig): lock_monitor_cb = None if address_list is None: - resolver = _SsconfResolver + resolver = compat.partial(_SsconfResolver, True) else: # Caller provided an address list resolver = _StaticResolver(address_list) diff --git a/lib/rpc_defs.py b/lib/rpc_defs.py index 44bdc4c06999ff549c0aaf45e360f8ac00bf36b4..669f79129dd53b63d2d6a9ebda5a809759dec7e5 100644 --- a/lib/rpc_defs.py +++ b/lib/rpc_defs.py @@ -543,7 +543,10 @@ CALLS = { "Requests a node to clean the cluster information it has"), ("master_info", MULTI, None, TMO_URGENT, [], None, None, "Query master info"), - ("version", MULTI, None, TMO_URGENT, [], None, None, "Query node version"), + ]), + "RpcClientDnsOnly": _Prepare([ + ("version", MULTI, ACCEPT_OFFLINE_NODE, TMO_URGENT, [], None, None, + "Query node version"), ]), "RpcClientConfig": _Prepare([ ("upload_file", MULTI, None, TMO_NORMAL, [ diff --git a/test/ganeti.rpc_unittest.py b/test/ganeti.rpc_unittest.py index 1eb03e85d44525c13eed281e41688fe0de231aee..0fe47a371db4ec42127f3fe7b37204b566c35553 100755 --- a/test/ganeti.rpc_unittest.py +++ b/test/ganeti.rpc_unittest.py @@ -1,7 +1,7 @@ #!/usr/bin/python # -# Copyright (C) 2010, 2011 Google Inc. +# Copyright (C) 2010, 2011, 2012 Google Inc. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -61,6 +61,13 @@ def GetFakeSimpleStoreClass(fn): return FakeSimpleStore +def _RaiseNotImplemented(): + """Simple wrapper to raise NotImplementedError. + + """ + raise NotImplementedError + + class TestRpcProcessor(unittest.TestCase): def _FakeAddressLookup(self, map): return lambda node_list: [map.get(node) for node in node_list] @@ -331,7 +338,7 @@ class TestSsconfResolver(unittest.TestCase): node_list = ["node%d.example.com" % n for n in range(0, 255, 13)] node_addr_list = [" ".join(t) for t in zip(node_list, addr_list)] ssc = GetFakeSimpleStoreClass(lambda _: node_addr_list) - result = rpc._SsconfResolver(node_list, NotImplemented, + result = rpc._SsconfResolver(True, node_list, NotImplemented, ssc=ssc, nslookup_fn=NotImplemented) self.assertEqual(result, zip(node_list, addr_list)) @@ -341,7 +348,17 @@ class TestSsconfResolver(unittest.TestCase): ssc = GetFakeSimpleStoreClass(lambda _: []) node_addr_map = dict(zip(node_list, addr_list)) nslookup_fn = lambda name, family=None: node_addr_map.get(name) - result = rpc._SsconfResolver(node_list, NotImplemented, + result = rpc._SsconfResolver(True, node_list, NotImplemented, + ssc=ssc, nslookup_fn=nslookup_fn) + self.assertEqual(result, zip(node_list, addr_list)) + + def testDisabledSsconfIp(self): + addr_list = ["192.0.2.%d" % n for n in range(0, 255, 13)] + node_list = ["node%d.example.com" % n for n in range(0, 255, 13)] + ssc = GetFakeSimpleStoreClass(_RaiseNotImplemented) + node_addr_map = dict(zip(node_list, addr_list)) + nslookup_fn = lambda name, family=None: node_addr_map.get(name) + result = rpc._SsconfResolver(False, node_list, NotImplemented, ssc=ssc, nslookup_fn=nslookup_fn) self.assertEqual(result, zip(node_list, addr_list)) @@ -353,7 +370,7 @@ class TestSsconfResolver(unittest.TestCase): ssc = GetFakeSimpleStoreClass(lambda _: node_addr_list) node_addr_map = dict(zip(node_list[:n], addr_list[:n])) nslookup_fn = lambda name, family=None: node_addr_map.get(name) - result = rpc._SsconfResolver(node_list, NotImplemented, + result = rpc._SsconfResolver(True, node_list, NotImplemented, ssc=ssc, nslookup_fn=nslookup_fn) self.assertEqual(result, zip(node_list, addr_list)) @@ -362,7 +379,7 @@ class TestSsconfResolver(unittest.TestCase): node_list = ["node%d.example.com" % n for n in range(0, 255, 11)] node_addr_list = [" ".join(t) for t in zip(node_list, addr_list)] ssc = GetFakeSimpleStoreClass(lambda _: node_addr_list) - result = rpc._SsconfResolver(node_list, NotImplemented, + result = rpc._SsconfResolver(True, node_list, NotImplemented, ssc=ssc, nslookup_fn=NotImplemented) self.assertEqual(result, zip(node_list, addr_list))