Commit caad16e2 authored by Iustin Pop's avatar Iustin Pop
Browse files

Abstract checking own address into a function

Currently, we check if we have a given ip address (i.e. it's alive on
one of our interfaces) but manually calling TcpPing(source=localhost).
This works, but having it spread all over the code makes it hard to
change the implementation.

The patch abstracts this into a separate utils.OwnIpAddress(addr)
function. We add a rpc call for it, which we use instead of the
(single-use of) call_node_tcp_ping. We leave node_tcp_ping in, as seems
useful and eventually it should be removed in a separate patch.

Reviewed-by: imsnah
parent 15396f60
......@@ -411,6 +411,13 @@ class NodeHttpServer(http.HttpServer):
return utils.TcpPing(params[1], params[2], timeout=params[3],
live_port_needed=params[4], source=params[0])
def perspective_node_has_ip_address(params):
"""Checks if a node has the given ip address.
return utils.OwnIpAddress(params[0])
def perspective_node_info(params):
"""Query node information.
......@@ -117,8 +117,7 @@ def StartMaster(start_daemons):
return False
if utils.TcpPing(master_ip, constants.DEFAULT_NODED_PORT):
if utils.TcpPing(master_ip, constants.DEFAULT_NODED_PORT,
if utils.OwnIpAddress(master_ip):
# we already have the ip:
logging.debug("Already started")
......@@ -128,8 +128,7 @@ def InitCluster(cluster_name, hypervisor_type, mac_prefix, def_bridge,
" range (%s). Please fix DNS or %s." %
(hostname.ip, constants.ETC_HOSTS))
if not utils.TcpPing(hostname.ip, constants.DEFAULT_NODED_PORT,
if not utils.OwnIpAddress(hostname.ip):
raise errors.OpPrereqError("Inconsistency: this host's name resolves"
" to %s,\nbut this ip address does not"
" belong to this host."
......@@ -145,8 +144,7 @@ def InitCluster(cluster_name, hypervisor_type, mac_prefix, def_bridge,
if not utils.IsValidIP(secondary_ip):
raise errors.OpPrereqError("Invalid secondary ip given")
if (secondary_ip != hostname.ip and
(not utils.TcpPing(secondary_ip, constants.DEFAULT_NODED_PORT,
not utils.OwnIpAddress(secondary_ip)):
raise errors.OpPrereqError("You gave %s as secondary IP,"
" but it does not belong to this host." %
......@@ -1774,11 +1774,8 @@ class LUAddNode(LogicalUnit):
if new_node.secondary_ip != new_node.primary_ip:
if not self.rpc.call_node_tcp_ping(,
10, False):
if not self.rpc.call_node_has_ip_address(,
raise errors.OpExecError("Node claims it doesn't have the secondary ip"
" you gave (%s). Please fix and re-run this"
" command." % new_node.secondary_ip)
......@@ -339,6 +339,7 @@ class RpcRunner(object):
"""Do a TcpPing on the remote node
This is a single-node call.
c = Client("node_tcp_ping", [source, target, port, timeout,
......@@ -346,6 +347,16 @@ class RpcRunner(object):
return c.getresult().get(node, False)
def call_node_has_ip_address(self, node, address):
"""Checks if a node has the given IP address.
This is a single-node call.
c = Client("node_has_ip_address", [address])
return c.getresult().get(node, False)
def call_node_info(self, node_list, vg_name, hypervisor_type):
"""Return node information.
......@@ -823,6 +823,21 @@ def TcpPing(target, port, timeout=10, live_port_needed=False, source=None):
return success
def OwnIpAddress(address):
"""Check if the current host has the the given IP address.
Currently this is done by tcp-pinging the address from the loopback
@type address: string
@param address: the addres to check
@rtype: bool
return TcpPing(address, constants.DEFAULT_NODED_PORT,
def ListVisibleFiles(path):
"""Returns a list of all visible files in a directory.
......@@ -41,7 +41,7 @@ from ganeti.utils import IsProcessAlive, RunCmd, \
RemoveFile, CheckDict, MatchNameComponent, FormatUnit, \
ParseUnit, AddAuthorizedKey, RemoveAuthorizedKey, \
ShellQuote, ShellQuoteArgs, TcpPing, ListVisibleFiles, \
SetEtcHostsEntry, RemoveEtcHostsEntry, FirstFree
SetEtcHostsEntry, RemoveEtcHostsEntry, FirstFree, OwnIpAddress
from ganeti.errors import LockError, UnitParseError, GenericError, \
......@@ -635,6 +635,24 @@ class TestTcpPingDeaf(unittest.TestCase):
"failed to ping alive host on deaf port (no source addr)")
class TestOwnIpAddress(unittest.TestCase):
"""Testcase for OwnIpAddress"""
def testOwnLoopback(self):
"""check having the loopback ip"""
"Should own the loopback address")
def testNowOwnAddress(self):
"""check that I don't own an address"""
# network is reserved for test/documentation as per
# rfc 3330, so we *should* not have an address of this range... if
# this fails, we should extend the test to multiple addresses
DST_IP = ""
self.failIf(OwnIpAddress(DST_IP), "Should not own IP address %s" % DST_IP)
class TestListVisibleFiles(unittest.TestCase):
"""Test case for ListVisibleFiles"""
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