Commit bd6d1202 authored by René Nussbaumer's avatar René Nussbaumer

RPC: Add a new client type for DNS only

This patch moves the “call_version” to a new RPC client definition and
then adds a new runner using the DNS resolver for getting the host
address.

The standard “BootstrapRunner”, where the call was before, tries to
resolve node names using ssconf first, which doesn't work properly when
re-adding a node with a new primary IP address.
Signed-off-by: default avatarRené Nussbaumer <rn@google.com>
Reviewed-by: default avatarIustin Pop <iustin@google.com>
parent f6d62af4
......@@ -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()
......
......@@ -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" %
......
......@@ -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)
......
......@@ -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, [
......
#!/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))
......
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