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