Merge "Pool manager now creates Nova nodes"
This commit is contained in:
@@ -22,6 +22,7 @@ import sys
|
|||||||
import threading
|
import threading
|
||||||
|
|
||||||
from libra.mgm.rest import APIClient
|
from libra.mgm.rest import APIClient
|
||||||
|
from libra.mgm.nova import Node
|
||||||
from libra.common.options import Options, setup_logging
|
from libra.common.options import Options, setup_logging
|
||||||
|
|
||||||
|
|
||||||
@@ -63,14 +64,14 @@ class Server(object):
|
|||||||
return
|
return
|
||||||
if usage['free'] < self.args.nodes:
|
if usage['free'] < self.args.nodes:
|
||||||
# we need to build new nodes
|
# we need to build new nodes
|
||||||
|
nodes_required = self.args.nodes - usage['free']
|
||||||
self.logger.info(
|
self.logger.info(
|
||||||
'Building {nodes} nodes'
|
'Building {nodes} nodes'
|
||||||
.format(nodes=self.args.nodes - usage['free'])
|
.format(nodes=nodes_required)
|
||||||
)
|
)
|
||||||
# TODO:
|
# TODO:
|
||||||
# build nodes
|
|
||||||
# send to API server
|
|
||||||
# deal with case where node is created but not sent to API
|
# deal with case where node is created but not sent to API
|
||||||
|
self.build_nodes(nodes_required, api)
|
||||||
else:
|
else:
|
||||||
self.logger.info('No new nodes required')
|
self.logger.info('No new nodes required')
|
||||||
else:
|
else:
|
||||||
@@ -84,6 +85,36 @@ class Server(object):
|
|||||||
self.check_nodes, ())
|
self.check_nodes, ())
|
||||||
self.ct.start()
|
self.ct.start()
|
||||||
|
|
||||||
|
def build_nodes(self, count, api):
|
||||||
|
nova = Node(
|
||||||
|
self.args.nova_user,
|
||||||
|
self.args.nova_pass,
|
||||||
|
self.args.nova_tenant,
|
||||||
|
self.args.nova_auth_url,
|
||||||
|
self.args.nova_region,
|
||||||
|
self.args.nova_keyname,
|
||||||
|
self.args.nova_secgroup,
|
||||||
|
self.args.haproxy_image,
|
||||||
|
102
|
||||||
|
)
|
||||||
|
while count > 0:
|
||||||
|
# Do stuff
|
||||||
|
status, data = nova.build()
|
||||||
|
if not status:
|
||||||
|
self.logger.error(data)
|
||||||
|
return
|
||||||
|
body = {}
|
||||||
|
body['name'] = data['name']
|
||||||
|
addresses = data['addresses']['private']
|
||||||
|
for address in addresses:
|
||||||
|
if not address['addr'].startswith('10.'):
|
||||||
|
break
|
||||||
|
body['ip'] = address['addr']
|
||||||
|
self.logger.info('Adding server {name} on {ip}'
|
||||||
|
.format(name=body['name'], ip=body['ip']))
|
||||||
|
# TODO: upload to API server
|
||||||
|
count = count - 1
|
||||||
|
|
||||||
def exit_handler(self, signum, frame):
|
def exit_handler(self, signum, frame):
|
||||||
signal.signal(signal.SIGINT, signal.SIG_IGN)
|
signal.signal(signal.SIGINT, signal.SIG_IGN)
|
||||||
signal.signal(signal.SIGTERM, signal.SIG_IGN)
|
signal.signal(signal.SIGTERM, signal.SIG_IGN)
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
import uuid
|
import uuid
|
||||||
import time
|
import time
|
||||||
|
import sys
|
||||||
|
|
||||||
from novaclient import client
|
from novaclient import client
|
||||||
|
|
||||||
@@ -42,7 +43,9 @@ class Node(object):
|
|||||||
try:
|
try:
|
||||||
body = self._create(node_id)
|
body = self._create(node_id)
|
||||||
except:
|
except:
|
||||||
return False, 'Error creating node {nid}'.format(nid=node_id)
|
return False, 'Error creating node {nid} exception {exc}'.format(
|
||||||
|
nid=node_id, exc=sys.exc_info()[0]
|
||||||
|
)
|
||||||
|
|
||||||
server_id = body['server']['id']
|
server_id = body['server']['id']
|
||||||
# try for 40 * 3 seconds
|
# try for 40 * 3 seconds
|
||||||
@@ -50,8 +53,9 @@ class Node(object):
|
|||||||
while waits > 0:
|
while waits > 0:
|
||||||
time.sleep(3)
|
time.sleep(3)
|
||||||
status = self._status(server_id)
|
status = self._status(server_id)
|
||||||
if status == 'ACTIVE':
|
# Should also check if it is not spawning, so errors are detected
|
||||||
return True, body
|
if status['status'] == 'ACTIVE':
|
||||||
|
return True, status
|
||||||
waits = waits - 1
|
waits = waits - 1
|
||||||
|
|
||||||
return (False,
|
return (False,
|
||||||
@@ -91,7 +95,7 @@ class Node(object):
|
|||||||
""" used to keep scanning to see if node is up """
|
""" used to keep scanning to see if node is up """
|
||||||
url = "/servers/{0}".format(node_id)
|
url = "/servers/{0}".format(node_id)
|
||||||
resp, body = self.nova.get(url)
|
resp, body = self.nova.get(url)
|
||||||
return body['server']['status']
|
return body['server']
|
||||||
|
|
||||||
def _delete(self, node_id):
|
def _delete(self, node_id):
|
||||||
""" delete a nova node, return 204 succeed """
|
""" delete a nova node, return 204 succeed """
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ class TestLBaaSMgmNova(unittest.TestCase):
|
|||||||
with mock.patch('time.time', mock.Mock(return_value=1234)):
|
with mock.patch('time.time', mock.Mock(return_value=1234)):
|
||||||
resp, data = self.api.build()
|
resp, data = self.api.build()
|
||||||
self.assertTrue(resp)
|
self.assertTrue(resp)
|
||||||
self.assertEqual(data['server']['id'], 417773)
|
self.assertEqual(data['id'], 417773)
|
||||||
|
|
||||||
def testCreateNodeFail(self):
|
def testCreateNodeFail(self):
|
||||||
with mock.patch.object(httplib2.Http, "request", mock_bad_request):
|
with mock.patch.object(httplib2.Http, "request", mock_bad_request):
|
||||||
|
|||||||
Reference in New Issue
Block a user