Add private ip to /etc/nodepool

The private IPs are more useful for having nodes to
 communicate with each other in multi-node jobs.

This change extends the /etc/nodepool with two new files.
* primary_node_private The private ip of the primary node
* sub_nodes_private The private ip of the sub nodes,
  in the same order as the floating ones.

This change helps in simplify the devstack-gate multi-node change.
This change causes DB schema change, both node and subnode table
extended with an ip_private field.

Change-Id: Ib7b29afbfae877e6edeea6568732c54c3d9e12f1
This commit is contained in:
Attila Fazekas 2014-08-17 21:20:41 +02:00
parent ca2ac5c741
commit 9cac605d8f
5 changed files with 59 additions and 5 deletions

View File

@ -45,10 +45,17 @@ Those files include:
the job), or a sub-node.
**/etc/nodepool/node**
The IP address of this node.
**/etc/nodepool/node_private**
The private IP address of this node.
**/etc/nodepool/primary_node**
The IP address of the primary node.
The IP address of the primary node, usable for external access.
**/etc/nodepool/primary_node_private**
The Private IP address of the primary node, for internal communication.
**/etc/nodepool/sub_nodes**
The IP addresses of the sub nodes, one on each line.
The IP addresses of the sub nodes, one on each line,
usable for external access.
**/etc/nodepool/sub_nodes_private**
The Private IP addresses of the sub nodes, one on each line.
**/etc/nodepool/id_rsa**
An OpenSSH private key generated specifically for this node group.
**/etc/nodepool/id_rsa.pub**

View File

@ -71,7 +71,10 @@ class FakeList(object):
name=kw['name'],
status='BUILD',
adminPass='fake',
addresses=dict(public=[dict(version=4, addr='fake')]),
addresses=dict(
public=[dict(version=4, addr='fake')],
private=[dict(version=4, addr='fake')]
),
metadata={},
manager=self)
self._list.append(s)

View File

@ -95,6 +95,8 @@ node_table = Table(
Column('az', String(255)),
# Primary IP address
Column('ip', String(255)),
# Internal/fixed IP address
Column('ip_private', String(255)),
# One of the above values
Column('state', Integer),
# Time of last state change
@ -110,6 +112,8 @@ subnode_table = Table(
Column('external_id', String(255)),
# Primary IP address
Column('ip', String(255)),
# Internal/fixed IP address
Column('ip_private', String(255)),
# One of the above values
Column('state', Integer),
# Time of last state change
@ -174,7 +178,7 @@ class SnapshotImage(object):
class Node(object):
def __init__(self, provider_name, label_name, target_name, az,
hostname=None, external_id=None, ip=None,
hostname=None, external_id=None, ip=None, ip_private=None,
state=BUILDING):
self.provider_name = provider_name
self.label_name = label_name
@ -182,6 +186,7 @@ class Node(object):
self.external_id = external_id
self.az = az
self.ip = ip
self.ip_private = ip_private
self.hostname = hostname
self.state = state
@ -205,7 +210,7 @@ class Node(object):
class SubNode(object):
def __init__(self, node,
hostname=None, external_id=None, ip=None,
hostname=None, external_id=None, ip=None, ip_private=None,
state=BUILDING):
self.node_id = node.id
self.provider_name = node.provider_name
@ -213,6 +218,7 @@ class SubNode(object):
self.target_name = node.target_name
self.external_id = external_id
self.ip = ip
self.ip_private = ip_private
self.hostname = hostname
self.state = state

View File

@ -405,6 +405,7 @@ class NodeLauncher(threading.Thread):
if not ip:
raise LaunchNetworkException("Unable to find public IP of server")
self.node.ip_private = server.get('private_v4')
self.node.ip = ip
self.log.debug("Node id: %s is running, ip: %s, testing ssh" %
(self.node.id, ip))
@ -502,15 +503,28 @@ class NodeLauncher(threading.Thread):
f = ftp.open('/etc/nodepool/node', 'w')
f.write(n.ip + '\n')
f.close()
# The private IP of this node
f = ftp.open('/etc/nodepool/node_private', 'w')
f.write(n.ip_private + '\n')
f.close()
# The IP of the primary node of this node set
f = ftp.open('/etc/nodepool/primary_node', 'w')
f.write(self.node.ip + '\n')
f.close()
# The private IP of the primary node of this node set
f = ftp.open('/etc/nodepool/primary_node_private', 'w')
f.write(self.node.ip_private + '\n')
f.close()
# The IPs of all sub nodes in this node set
f = ftp.open('/etc/nodepool/sub_nodes', 'w')
for subnode in self.node.subnodes:
f.write(subnode.ip + '\n')
f.close()
# The private IPs of all sub nodes in this node set
f = ftp.open('/etc/nodepool/sub_nodes_private', 'w')
for subnode in self.node.subnodes:
f.write(subnode.ip_private + '\n')
f.close()
# The SSH key for this node set
f = ftp.open('/etc/nodepool/id_rsa', 'w')
key.write_private_key(f)
@ -665,6 +679,7 @@ class SubNodeLauncher(threading.Thread):
if not ip:
raise LaunchNetworkException("Unable to find public IP of server")
self.subnode.ip_private = server.get('private_v4')
self.subnode.ip = ip
self.log.debug("Subnode id: %s for node id: %s is running, "
"ip: %s, testing ssh" %

View File

@ -67,6 +67,28 @@ def get_public_ip(server, version=4):
return None
def get_private_ip(server):
ret = []
for (name, network) in server.addresses.iteritems():
if name == 'private':
ret.extend([addrs['addr']
for addrs in network if addrs['version'] == 4])
else:
for interface_spec in network:
if interface_spec['version'] != 4:
continue
if ('OS-EXT-IPS:type' in interface_spec
and interface_spec['OS-EXT-IPS:type'] == 'fixed'):
ret.append(interface_spec['addr'])
if not ret:
if server.status == 'ACTIVE':
# Server expected to have at least one address in ACTIVE status
raise KeyError('No private ip found for server')
else:
return None
return ret[0]
def make_server_dict(server):
d = dict(id=str(server.id),
name=server.name,
@ -79,6 +101,7 @@ def make_server_dict(server):
if hasattr(server, 'progress'):
d['progress'] = server.progress
d['public_v4'] = get_public_ip(server)
d['private_v4'] = get_private_ip(server)
return d