merged trunk
This commit is contained in:
commit
6de809d887
@ -44,18 +44,20 @@ flags.DECLARE('auth_driver', 'nova.auth.manager')
|
||||
flags.DECLARE('redis_db', 'nova.datastore')
|
||||
flags.DECLARE('network_size', 'nova.network.manager')
|
||||
flags.DECLARE('num_networks', 'nova.network.manager')
|
||||
flags.DECLARE('update_dhcp_on_disassociate', 'nova.network.manager')
|
||||
|
||||
|
||||
def add_lease(_mac, ip_address, _hostname, _interface):
|
||||
def add_lease(mac, ip_address, _hostname, _interface):
|
||||
"""Set the IP that was assigned by the DHCP server."""
|
||||
if FLAGS.fake_rabbit:
|
||||
logging.debug("leasing ip")
|
||||
network_manager = utils.import_object(FLAGS.network_manager)
|
||||
network_manager.lease_fixed_ip(None, ip_address)
|
||||
network_manager.lease_fixed_ip(None, mac, ip_address)
|
||||
else:
|
||||
rpc.cast("%s.%s" % (FLAGS.network_topic, FLAGS.host),
|
||||
{"method": "lease_fixed_ip",
|
||||
"args": {"context": None,
|
||||
"mac": mac,
|
||||
"address": ip_address}})
|
||||
|
||||
|
||||
@ -64,16 +66,17 @@ def old_lease(_mac, _ip_address, _hostname, _interface):
|
||||
logging.debug("Adopted old lease or got a change of mac/hostname")
|
||||
|
||||
|
||||
def del_lease(_mac, ip_address, _hostname, _interface):
|
||||
def del_lease(mac, ip_address, _hostname, _interface):
|
||||
"""Called when a lease expires."""
|
||||
if FLAGS.fake_rabbit:
|
||||
logging.debug("releasing ip")
|
||||
network_manager = utils.import_object(FLAGS.network_manager)
|
||||
network_manager.release_fixed_ip(None, ip_address)
|
||||
network_manager.release_fixed_ip(None, mac, ip_address)
|
||||
else:
|
||||
rpc.cast("%s.%s" % (FLAGS.network_topic, FLAGS.host),
|
||||
{"method": "release_fixed_ip",
|
||||
"args": {"context": None,
|
||||
"mac": mac,
|
||||
"address": ip_address}})
|
||||
|
||||
|
||||
|
@ -17,6 +17,37 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
# Interactive shell based on Django:
|
||||
#
|
||||
# Copyright (c) 2005, the Lawrence Journal-World
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
#
|
||||
# 3. Neither the name of Django nor the names of its contributors may be used
|
||||
# to endorse or promote products derived from this software without
|
||||
# specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
"""
|
||||
CLI interface for nova management.
|
||||
Connects to the running ADMIN api in the api daemon.
|
||||
@ -103,6 +134,29 @@ class VpnCommands(object):
|
||||
self.pipe.launch_vpn_instance(project_id)
|
||||
|
||||
|
||||
class ShellCommands(object):
|
||||
def run(self):
|
||||
"Runs a Python interactive interpreter. Tries to use IPython, if it's available."
|
||||
try:
|
||||
import IPython
|
||||
# Explicitly pass an empty list as arguments, because otherwise IPython
|
||||
# would use sys.argv from this script.
|
||||
shell = IPython.Shell.IPShell(argv=[])
|
||||
shell.mainloop()
|
||||
except ImportError:
|
||||
import code
|
||||
try: # Try activating rlcompleter, because it's handy.
|
||||
import readline
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
# We don't have to wrap the following import in a 'try', because
|
||||
# we already know 'readline' was imported successfully.
|
||||
import rlcompleter
|
||||
readline.parse_and_bind("tab:complete")
|
||||
code.interact()
|
||||
|
||||
|
||||
class RoleCommands(object):
|
||||
"""Class for managing roles."""
|
||||
|
||||
@ -256,6 +310,7 @@ CATEGORIES = [
|
||||
('user', UserCommands),
|
||||
('project', ProjectCommands),
|
||||
('role', RoleCommands),
|
||||
('shell', ShellCommands),
|
||||
('vpn', VpnCommands),
|
||||
('floating', FloatingIpCommands)
|
||||
]
|
||||
|
@ -173,12 +173,20 @@ def floating_ip_get_instance(context, address):
|
||||
####################
|
||||
|
||||
|
||||
def fixed_ip_allocate(context, network_id):
|
||||
"""Allocate free fixed ip and return the address.
|
||||
def fixed_ip_associate(context, address, instance_id):
|
||||
"""Associate fixed ip to instance.
|
||||
|
||||
Raises if fixed ip is not available.
|
||||
"""
|
||||
return IMPL.fixed_ip_associate(context, address, instance_id)
|
||||
|
||||
|
||||
def fixed_ip_associate_pool(context, network_id, instance_id):
|
||||
"""Find free ip in network and associate it to instance.
|
||||
|
||||
Raises if one is not available.
|
||||
"""
|
||||
return IMPL.fixed_ip_allocate(context, network_id)
|
||||
return IMPL.fixed_ip_associate_pool(context, network_id, instance_id)
|
||||
|
||||
|
||||
def fixed_ip_create(context, values):
|
||||
@ -186,9 +194,9 @@ def fixed_ip_create(context, values):
|
||||
return IMPL.fixed_ip_create(context, values)
|
||||
|
||||
|
||||
def fixed_ip_deallocate(context, address):
|
||||
"""Deallocate a fixed ip by address."""
|
||||
return IMPL.fixed_ip_deallocate(context, address)
|
||||
def fixed_ip_disassociate(context, address):
|
||||
"""Disassociate a fixed ip from an instance by address."""
|
||||
return IMPL.fixed_ip_disassociate(context, address)
|
||||
|
||||
|
||||
def fixed_ip_get_by_address(context, address):
|
||||
@ -206,16 +214,6 @@ def fixed_ip_get_network(context, address):
|
||||
return IMPL.fixed_ip_get_network(context, address)
|
||||
|
||||
|
||||
def fixed_ip_instance_associate(context, address, instance_id):
|
||||
"""Associate a fixed ip to an instance by address."""
|
||||
return IMPL.fixed_ip_instance_associate(context, address, instance_id)
|
||||
|
||||
|
||||
def fixed_ip_instance_disassociate(context, address):
|
||||
"""Disassociate a fixed ip from an instance by address."""
|
||||
return IMPL.fixed_ip_instance_disassociate(context, address)
|
||||
|
||||
|
||||
def fixed_ip_update(context, address, values):
|
||||
"""Create a fixed ip from the values dictionary."""
|
||||
return IMPL.fixed_ip_update(context, address, values)
|
||||
|
@ -256,7 +256,25 @@ def floating_ip_get_instance(_context, address):
|
||||
###################
|
||||
|
||||
|
||||
def fixed_ip_allocate(_context, network_id):
|
||||
def fixed_ip_associate(_context, address, instance_id):
|
||||
session = get_session()
|
||||
with session.begin():
|
||||
fixed_ip_ref = session.query(models.FixedIp
|
||||
).filter_by(address=address
|
||||
).filter_by(deleted=False
|
||||
).filter_by(instance=None
|
||||
).with_lockmode('update'
|
||||
).first()
|
||||
# NOTE(vish): if with_lockmode isn't supported, as in sqlite,
|
||||
# then this has concurrency issues
|
||||
if not fixed_ip_ref:
|
||||
raise db.NoMoreAddresses()
|
||||
fixed_ip_ref.instance = models.Instance.find(instance_id,
|
||||
session=session)
|
||||
session.add(fixed_ip_ref)
|
||||
|
||||
|
||||
def fixed_ip_associate_pool(_context, network_id, instance_id):
|
||||
session = get_session()
|
||||
with session.begin():
|
||||
network_or_none = or_(models.FixedIp.network_id == network_id,
|
||||
@ -264,9 +282,8 @@ def fixed_ip_allocate(_context, network_id):
|
||||
fixed_ip_ref = session.query(models.FixedIp
|
||||
).filter(network_or_none
|
||||
).filter_by(reserved=False
|
||||
).filter_by(allocated=False
|
||||
).filter_by(leased=False
|
||||
).filter_by(deleted=False
|
||||
).filter_by(instance=None
|
||||
).with_lockmode('update'
|
||||
).first()
|
||||
# NOTE(vish): if with_lockmode isn't supported, as in sqlite,
|
||||
@ -276,7 +293,8 @@ def fixed_ip_allocate(_context, network_id):
|
||||
if not fixed_ip_ref.network:
|
||||
fixed_ip_ref.network = models.Network.find(network_id,
|
||||
session=session)
|
||||
fixed_ip_ref['allocated'] = True
|
||||
fixed_ip_ref.instance = models.Instance.find(instance_id,
|
||||
session=session)
|
||||
session.add(fixed_ip_ref)
|
||||
return fixed_ip_ref['address']
|
||||
|
||||
@ -289,6 +307,14 @@ def fixed_ip_create(_context, values):
|
||||
return fixed_ip_ref['address']
|
||||
|
||||
|
||||
def fixed_ip_disassociate(_context, address):
|
||||
session = get_session()
|
||||
with session.begin():
|
||||
fixed_ip_ref = models.FixedIp.find_by_str(address, session=session)
|
||||
fixed_ip_ref.instance = None
|
||||
fixed_ip_ref.save(session=session)
|
||||
|
||||
|
||||
def fixed_ip_get_by_address(_context, address):
|
||||
return models.FixedIp.find_by_str(address)
|
||||
|
||||
@ -305,27 +331,6 @@ def fixed_ip_get_network(_context, address):
|
||||
return models.FixedIp.find_by_str(address, session=session).network
|
||||
|
||||
|
||||
def fixed_ip_deallocate(context, address):
|
||||
db.fixed_ip_update(context, address, {'allocated': False})
|
||||
|
||||
|
||||
def fixed_ip_instance_associate(_context, address, instance_id):
|
||||
session = get_session()
|
||||
with session.begin():
|
||||
fixed_ip_ref = models.FixedIp.find_by_str(address, session=session)
|
||||
instance_ref = models.Instance.find(instance_id, session=session)
|
||||
fixed_ip_ref.instance = instance_ref
|
||||
fixed_ip_ref.save(session=session)
|
||||
|
||||
|
||||
def fixed_ip_instance_disassociate(_context, address):
|
||||
session = get_session()
|
||||
with session.begin():
|
||||
fixed_ip_ref = models.FixedIp.find_by_str(address, session=session)
|
||||
fixed_ip_ref.instance = None
|
||||
fixed_ip_ref.save(session=session)
|
||||
|
||||
|
||||
def fixed_ip_update(_context, address, values):
|
||||
session = get_session()
|
||||
with session.begin():
|
||||
|
@ -391,9 +391,7 @@ class CloudController(object):
|
||||
floating_addr = fixed['floating_ips'][0]['str_id']
|
||||
i['privateDnsName'] = fixed_addr
|
||||
i['publicDnsName'] = floating_addr
|
||||
if not i['publicDnsName']:
|
||||
i['publicDnsName'] = i['privateDnsName']
|
||||
i['dnsName'] = None
|
||||
i['dnsName'] = i['publicDnsName'] or i['privateDnsName']
|
||||
i['keyName'] = instance['key_name']
|
||||
if context.user.is_admin():
|
||||
i['keyName'] = '%s (%s, %s)' % (i['keyName'],
|
||||
@ -617,7 +615,7 @@ class CloudController(object):
|
||||
# NOTE(vish): Currently, nothing needs to be done on the
|
||||
# network node until release. If this changes,
|
||||
# we will need to cast here.
|
||||
db.fixed_ip_deallocate(context, address)
|
||||
self.network.deallocate_fixed_ip(context, address)
|
||||
|
||||
host = instance_ref['host']
|
||||
if host:
|
||||
|
@ -61,6 +61,8 @@ flags.DEFINE_integer('cnt_vpn_clients', 5,
|
||||
'Number of addresses reserved for vpn clients')
|
||||
flags.DEFINE_string('network_driver', 'nova.network.linux_net',
|
||||
'Driver to use for network creation')
|
||||
flags.DEFINE_bool('update_dhcp_on_disassociate', False,
|
||||
'Whether to update dhcp when fixed_ip is disassocated')
|
||||
|
||||
|
||||
class AddressAlreadyAllocated(exception.Error):
|
||||
@ -96,6 +98,10 @@ class NetworkManager(manager.Manager):
|
||||
"""Gets a fixed ip from the pool"""
|
||||
raise NotImplementedError()
|
||||
|
||||
def deallocate_fixed_ip(self, context, instance_id, *args, **kwargs):
|
||||
"""Returns a fixed ip to the pool"""
|
||||
raise NotImplementedError()
|
||||
|
||||
def setup_fixed_ip(self, context, address):
|
||||
"""Sets up rules for fixed ip"""
|
||||
raise NotImplementedError()
|
||||
@ -170,10 +176,17 @@ class FlatManager(NetworkManager):
|
||||
def allocate_fixed_ip(self, context, instance_id, *args, **kwargs):
|
||||
"""Gets a fixed ip from the pool"""
|
||||
network_ref = self.db.project_get_network(context, context.project.id)
|
||||
address = self.db.fixed_ip_allocate(context, network_ref['id'])
|
||||
self.db.fixed_ip_instance_associate(context, address, instance_id)
|
||||
address = self.db.fixed_ip_associate_pool(context,
|
||||
network_ref['id'],
|
||||
instance_id)
|
||||
self.db.fixed_ip_update(context, address, {'allocated': True})
|
||||
return address
|
||||
|
||||
def deallocate_fixed_ip(self, context, address, *args, **kwargs):
|
||||
"""Returns a fixed ip to the pool"""
|
||||
self.db.fixed_ip_update(context, address, {'allocated': False})
|
||||
self.db.fixed_ip_disassociate(context, address)
|
||||
|
||||
def setup_compute_network(self, context, project_id):
|
||||
"""Network is created manually"""
|
||||
pass
|
||||
@ -209,13 +222,29 @@ class VlanManager(NetworkManager):
|
||||
"""Gets a fixed ip from the pool"""
|
||||
network_ref = self.db.project_get_network(context, context.project.id)
|
||||
if kwargs.get('vpn', None):
|
||||
address = self._allocate_vpn_ip(context, network_ref['id'])
|
||||
address = network_ref['vpn_private_address']
|
||||
self.db.fixed_ip_associate(context, address, instance_id)
|
||||
else:
|
||||
address = self.db.fixed_ip_allocate(context,
|
||||
network_ref['id'])
|
||||
self.db.fixed_ip_instance_associate(context, address, instance_id)
|
||||
address = self.db.fixed_ip_associate_pool(context,
|
||||
network_ref['id'],
|
||||
instance_id)
|
||||
self.db.fixed_ip_update(context, address, {'allocated': True})
|
||||
return address
|
||||
|
||||
def deallocate_fixed_ip(self, context, address, *args, **kwargs):
|
||||
"""Returns a fixed ip to the pool"""
|
||||
self.db.fixed_ip_update(context, address, {'allocated': False})
|
||||
fixed_ip_ref = self.db.fixed_ip_get_by_address(context, address)
|
||||
if not fixed_ip_ref['leased']:
|
||||
self.db.fixed_ip_disassociate(context, address)
|
||||
# NOTE(vish): dhcp server isn't updated until next setup, this
|
||||
# means there will stale entries in the conf file
|
||||
# the code below will update the file if necessary
|
||||
if FLAGS.update_dhcp_on_disassociate:
|
||||
network_ref = self.db.fixed_ip_get_network(context, address)
|
||||
self.driver.update_dhcp(context, network_ref['id'])
|
||||
|
||||
|
||||
def setup_fixed_ip(self, context, address):
|
||||
"""Sets forwarding rules and dhcp for fixed ip"""
|
||||
fixed_ip_ref = self.db.fixed_ip_get_by_address(context, address)
|
||||
@ -226,22 +255,47 @@ class VlanManager(NetworkManager):
|
||||
network_ref['vpn_private_address'])
|
||||
self.driver.update_dhcp(context, network_ref['id'])
|
||||
|
||||
def lease_fixed_ip(self, context, address):
|
||||
def lease_fixed_ip(self, context, mac, address):
|
||||
"""Called by dhcp-bridge when ip is leased"""
|
||||
logging.debug("Leasing IP %s", address)
|
||||
fixed_ip_ref = self.db.fixed_ip_get_by_address(context, address)
|
||||
if not fixed_ip_ref['allocated']:
|
||||
logging.warn("IP %s leased that was already deallocated", address)
|
||||
return
|
||||
instance_ref = self.db.fixed_ip_get_instance(context, address)
|
||||
if not instance_ref:
|
||||
raise exception.Error("IP %s leased that isn't associated" %
|
||||
address)
|
||||
if instance_ref['mac_address'] != mac:
|
||||
raise exception.Error("IP %s leased to bad mac %s vs %s" %
|
||||
(address, instance_ref['mac_address'], mac))
|
||||
self.db.fixed_ip_update(context,
|
||||
fixed_ip_ref['str_id'],
|
||||
{'leased': True})
|
||||
|
||||
def release_fixed_ip(self, context, address):
|
||||
def release_fixed_ip(self, context, mac, address):
|
||||
"""Called by dhcp-bridge when ip is released"""
|
||||
logging.debug("Releasing IP %s", address)
|
||||
self.db.fixed_ip_update(context, address, {'allocated': False,
|
||||
'leased': False})
|
||||
self.db.fixed_ip_instance_disassociate(context, address)
|
||||
fixed_ip_ref = self.db.fixed_ip_get_by_address(context, address)
|
||||
if not fixed_ip_ref['leased']:
|
||||
logging.warn("IP %s released that was not leased", address)
|
||||
return
|
||||
instance_ref = self.db.fixed_ip_get_instance(context, address)
|
||||
if not instance_ref:
|
||||
raise exception.Error("IP %s released that isn't associated" %
|
||||
address)
|
||||
if instance_ref['mac_address'] != mac:
|
||||
raise exception.Error("IP %s released from bad mac %s vs %s" %
|
||||
(address, instance_ref['mac_address'], mac))
|
||||
self.db.fixed_ip_update(context, address, {'leased': False})
|
||||
if not fixed_ip_ref['allocated']:
|
||||
self.db.fixed_ip_disassociate(context, address)
|
||||
# NOTE(vish): dhcp server isn't updated until next setup, this
|
||||
# means there will stale entries in the conf file
|
||||
# the code below will update the file if necessary
|
||||
if FLAGS.update_dhcp_on_disassociate:
|
||||
network_ref = self.db.fixed_ip_get_network(context, address)
|
||||
self.driver.update_dhcp(context, network_ref['id'])
|
||||
|
||||
def allocate_network(self, context, project_id):
|
||||
"""Set up the network"""
|
||||
@ -283,19 +337,6 @@ class VlanManager(NetworkManager):
|
||||
# TODO(vish): Implement this
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def _allocate_vpn_ip(context, network_id):
|
||||
"""Allocate vpn ip for network"""
|
||||
# TODO(vish): There is a possible concurrency issue here.
|
||||
network_ref = db.network_get(context, network_id)
|
||||
address = network_ref['vpn_private_address']
|
||||
fixed_ip_ref = db.fixed_ip_get_by_address(context, address)
|
||||
# TODO(vish): Should this be fixed_ip_is_allocated?
|
||||
if fixed_ip_ref['allocated']:
|
||||
raise AddressAlreadyAllocated()
|
||||
db.fixed_ip_update(context, fixed_ip_ref['id'], {'allocated': True})
|
||||
return fixed_ip_ref['str_id']
|
||||
|
||||
def _ensure_indexes(self, context):
|
||||
"""Ensure the indexes for the network exist
|
||||
|
||||
|
@ -29,6 +29,7 @@ from nova import rpc
|
||||
from nova import test
|
||||
from nova import utils
|
||||
from nova.auth import manager
|
||||
from nova.compute import power_state
|
||||
from nova.endpoint import api
|
||||
from nova.endpoint import cloud
|
||||
|
||||
@ -94,7 +95,7 @@ class CloudTestCase(test.BaseTestCase):
|
||||
rv = yield defer.succeed(time.sleep(1))
|
||||
info = self.cloud._get_instance(instance['instance_id'])
|
||||
logging.debug(info['state'])
|
||||
if info['state'] == node.Instance.RUNNING:
|
||||
if info['state'] == power_state.RUNNING:
|
||||
break
|
||||
self.assert_(rv)
|
||||
|
||||
|
@ -28,6 +28,7 @@ from nova import flags
|
||||
from nova import test
|
||||
from nova import utils
|
||||
from nova.auth import manager
|
||||
from nova.endpoint import api
|
||||
|
||||
FLAGS = flags.FLAGS
|
||||
|
||||
@ -48,7 +49,7 @@ class NetworkTestCase(test.TrialTestCase):
|
||||
self.user = self.manager.create_user('netuser', 'netuser', 'netuser')
|
||||
self.projects = []
|
||||
self.network = utils.import_object(FLAGS.network_manager)
|
||||
self.context = None
|
||||
self.context = api.APIRequestContext(None, project=None, user=self.user)
|
||||
for i in range(5):
|
||||
name = 'project%s' % i
|
||||
self.projects.append(self.manager.create_project(name,
|
||||
@ -75,12 +76,10 @@ class NetworkTestCase(test.TrialTestCase):
|
||||
|
||||
def _create_address(self, project_num, instance_id=None):
|
||||
"""Create an address in given project num"""
|
||||
net = db.project_get_network(None, self.projects[project_num].id)
|
||||
address = db.fixed_ip_allocate(None, net['id'])
|
||||
if instance_id is None:
|
||||
instance_id = self.instance_id
|
||||
db.fixed_ip_instance_associate(None, address, instance_id)
|
||||
return address
|
||||
self.context.project = self.projects[project_num]
|
||||
return self.network.allocate_fixed_ip(self.context, instance_id)
|
||||
|
||||
def test_public_network_association(self):
|
||||
"""Makes sure that we can allocaate a public ip"""
|
||||
@ -103,14 +102,14 @@ class NetworkTestCase(test.TrialTestCase):
|
||||
address = db.instance_get_floating_address(None, self.instance_id)
|
||||
self.assertEqual(address, None)
|
||||
self.network.deallocate_floating_ip(self.context, float_addr)
|
||||
db.fixed_ip_deallocate(None, fix_addr)
|
||||
self.network.deallocate_fixed_ip(self.context, fix_addr)
|
||||
|
||||
def test_allocate_deallocate_fixed_ip(self):
|
||||
"""Makes sure that we can allocate and deallocate a fixed ip"""
|
||||
address = self._create_address(0)
|
||||
self.assertTrue(is_allocated_in_project(address, self.projects[0].id))
|
||||
lease_ip(address)
|
||||
db.fixed_ip_deallocate(None, address)
|
||||
self.network.deallocate_fixed_ip(self.context, address)
|
||||
|
||||
# Doesn't go away until it's dhcp released
|
||||
self.assertTrue(is_allocated_in_project(address, self.projects[0].id))
|
||||
@ -131,14 +130,14 @@ class NetworkTestCase(test.TrialTestCase):
|
||||
lease_ip(address)
|
||||
lease_ip(address2)
|
||||
|
||||
db.fixed_ip_deallocate(None, address)
|
||||
self.network.deallocate_fixed_ip(self.context, address)
|
||||
release_ip(address)
|
||||
self.assertFalse(is_allocated_in_project(address, self.projects[0].id))
|
||||
|
||||
# First address release shouldn't affect the second
|
||||
self.assertTrue(is_allocated_in_project(address2, self.projects[1].id))
|
||||
|
||||
db.fixed_ip_deallocate(None, address2)
|
||||
self.network.deallocate_fixed_ip(self.context, address2)
|
||||
release_ip(address2)
|
||||
self.assertFalse(is_allocated_in_project(address2,
|
||||
self.projects[1].id))
|
||||
@ -147,10 +146,23 @@ class NetworkTestCase(test.TrialTestCase):
|
||||
"""Makes sure that private ips don't overlap"""
|
||||
first = self._create_address(0)
|
||||
lease_ip(first)
|
||||
instance_ids = []
|
||||
for i in range(1, 5):
|
||||
address = self._create_address(i)
|
||||
address2 = self._create_address(i)
|
||||
address3 = self._create_address(i)
|
||||
mac = utils.generate_mac()
|
||||
instance_ref = db.instance_create(None,
|
||||
{'mac_address': mac})
|
||||
instance_ids.append(instance_ref['id'])
|
||||
address = self._create_address(i, instance_ref['id'])
|
||||
mac = utils.generate_mac()
|
||||
instance_ref = db.instance_create(None,
|
||||
{'mac_address': mac})
|
||||
instance_ids.append(instance_ref['id'])
|
||||
address2 = self._create_address(i, instance_ref['id'])
|
||||
mac = utils.generate_mac()
|
||||
instance_ref = db.instance_create(None,
|
||||
{'mac_address': mac})
|
||||
instance_ids.append(instance_ref['id'])
|
||||
address3 = self._create_address(i, instance_ref['id'])
|
||||
lease_ip(address)
|
||||
lease_ip(address2)
|
||||
lease_ip(address3)
|
||||
@ -160,14 +172,16 @@ class NetworkTestCase(test.TrialTestCase):
|
||||
self.projects[0].id))
|
||||
self.assertFalse(is_allocated_in_project(address3,
|
||||
self.projects[0].id))
|
||||
db.fixed_ip_deallocate(None, address)
|
||||
db.fixed_ip_deallocate(None, address2)
|
||||
db.fixed_ip_deallocate(None, address3)
|
||||
self.network.deallocate_fixed_ip(self.context, address)
|
||||
self.network.deallocate_fixed_ip(self.context, address2)
|
||||
self.network.deallocate_fixed_ip(self.context, address3)
|
||||
release_ip(address)
|
||||
release_ip(address2)
|
||||
release_ip(address3)
|
||||
for instance_id in instance_ids:
|
||||
db.instance_destroy(None, instance_id)
|
||||
release_ip(first)
|
||||
db.fixed_ip_deallocate(None, first)
|
||||
self.network.deallocate_fixed_ip(self.context, first)
|
||||
|
||||
def test_vpn_ip_and_port_looks_valid(self):
|
||||
"""Ensure the vpn ip and port are reasonable"""
|
||||
@ -194,12 +208,12 @@ class NetworkTestCase(test.TrialTestCase):
|
||||
"""Makes sure that ip addresses that are deallocated get reused"""
|
||||
address = self._create_address(0)
|
||||
lease_ip(address)
|
||||
db.fixed_ip_deallocate(None, address)
|
||||
self.network.deallocate_fixed_ip(self.context, address)
|
||||
release_ip(address)
|
||||
|
||||
address2 = self._create_address(0)
|
||||
self.assertEqual(address, address2)
|
||||
db.fixed_ip_deallocate(None, address2)
|
||||
self.network.deallocate_fixed_ip(self.context, address2)
|
||||
|
||||
def test_available_ips(self):
|
||||
"""Make sure the number of available ips for the network is correct
|
||||
@ -226,21 +240,27 @@ class NetworkTestCase(test.TrialTestCase):
|
||||
num_available_ips = db.network_count_available_ips(None,
|
||||
network['id'])
|
||||
addresses = []
|
||||
instance_ids = []
|
||||
for i in range(num_available_ips):
|
||||
address = self._create_address(0)
|
||||
mac = utils.generate_mac()
|
||||
instance_ref = db.instance_create(None,
|
||||
{'mac_address': mac})
|
||||
instance_ids.append(instance_ref['id'])
|
||||
address = self._create_address(0, instance_ref['id'])
|
||||
addresses.append(address)
|
||||
lease_ip(address)
|
||||
|
||||
self.assertEqual(db.network_count_available_ips(None,
|
||||
network['id']), 0)
|
||||
self.assertRaises(db.NoMoreAddresses,
|
||||
db.fixed_ip_allocate,
|
||||
None,
|
||||
network['id'])
|
||||
self.network.allocate_fixed_ip,
|
||||
self.context,
|
||||
'foo')
|
||||
|
||||
for i in range(len(addresses)):
|
||||
db.fixed_ip_deallocate(None, addresses[i])
|
||||
for i in range(num_available_ips):
|
||||
self.network.deallocate_fixed_ip(self.context, addresses[i])
|
||||
release_ip(addresses[i])
|
||||
db.instance_destroy(None, instance_ids[i])
|
||||
self.assertEqual(db.network_count_available_ips(None,
|
||||
network['id']),
|
||||
num_available_ips)
|
||||
@ -263,7 +283,10 @@ def binpath(script):
|
||||
def lease_ip(private_ip):
|
||||
"""Run add command on dhcpbridge"""
|
||||
network_ref = db.fixed_ip_get_network(None, private_ip)
|
||||
cmd = "%s add fake %s fake" % (binpath('nova-dhcpbridge'), private_ip)
|
||||
instance_ref = db.fixed_ip_get_instance(None, private_ip)
|
||||
cmd = "%s add %s %s fake" % (binpath('nova-dhcpbridge'),
|
||||
instance_ref['mac_address'],
|
||||
private_ip)
|
||||
env = {'DNSMASQ_INTERFACE': network_ref['bridge'],
|
||||
'TESTING': '1',
|
||||
'FLAGFILE': FLAGS.dhcpbridge_flagfile}
|
||||
@ -274,7 +297,10 @@ def lease_ip(private_ip):
|
||||
def release_ip(private_ip):
|
||||
"""Run del command on dhcpbridge"""
|
||||
network_ref = db.fixed_ip_get_network(None, private_ip)
|
||||
cmd = "%s del fake %s fake" % (binpath('nova-dhcpbridge'), private_ip)
|
||||
instance_ref = db.fixed_ip_get_instance(None, private_ip)
|
||||
cmd = "%s del %s %s fake" % (binpath('nova-dhcpbridge'),
|
||||
instance_ref['mac_address'],
|
||||
private_ip)
|
||||
env = {'DNSMASQ_INTERFACE': network_ref['bridge'],
|
||||
'TESTING': '1',
|
||||
'FLAGFILE': FLAGS.dhcpbridge_flagfile}
|
||||
|
@ -274,9 +274,19 @@ class XenAPIConnection(object):
|
||||
def destroy(self, instance):
|
||||
vm = yield self._lookup(instance.name)
|
||||
if vm is None:
|
||||
raise Exception('instance not present %s' % instance.name)
|
||||
task = yield self._call_xenapi('Async.VM.destroy', vm)
|
||||
yield self._wait_for_task(task)
|
||||
# Don't complain, just return. This lets us clean up instances
|
||||
# that have already disappeared from the underlying platform.
|
||||
defer.returnValue(None)
|
||||
try:
|
||||
task = yield self._call_xenapi('Async.VM.hard_shutdown', vm)
|
||||
yield self._wait_for_task(task)
|
||||
except Exception, exc:
|
||||
logging.warn(exc)
|
||||
try:
|
||||
task = yield self._call_xenapi('Async.VM.destroy', vm)
|
||||
yield self._wait_for_task(task)
|
||||
except Exception, exc:
|
||||
logging.warn(exc)
|
||||
|
||||
def get_info(self, instance_id):
|
||||
vm = self._lookup_blocking(instance_id)
|
||||
@ -330,9 +340,9 @@ class XenAPIConnection(object):
|
||||
error_info)
|
||||
deferred.errback(XenAPI.Failure(error_info))
|
||||
#logging.debug('Polling task %s done.', task)
|
||||
except Exception, exn:
|
||||
logging.warn(exn)
|
||||
deferred.errback(exn)
|
||||
except Exception, exc:
|
||||
logging.warn(exc)
|
||||
deferred.errback(exc)
|
||||
|
||||
@utils.deferredToThread
|
||||
def _call_xenapi(self, method, *args):
|
||||
@ -358,21 +368,21 @@ class XenAPIConnection(object):
|
||||
def _unwrap_plugin_exceptions(func, *args, **kwargs):
|
||||
try:
|
||||
return func(*args, **kwargs)
|
||||
except XenAPI.Failure, exn:
|
||||
logging.debug("Got exception: %s", exn)
|
||||
if (len(exn.details) == 4 and
|
||||
exn.details[0] == 'XENAPI_PLUGIN_EXCEPTION' and
|
||||
exn.details[2] == 'Failure'):
|
||||
except XenAPI.Failure, exc:
|
||||
logging.debug("Got exception: %s", exc)
|
||||
if (len(exc.details) == 4 and
|
||||
exc.details[0] == 'XENAPI_PLUGIN_EXCEPTION' and
|
||||
exc.details[2] == 'Failure'):
|
||||
params = None
|
||||
try:
|
||||
params = eval(exn.details[3])
|
||||
params = eval(exc.details[3])
|
||||
except:
|
||||
raise exn
|
||||
raise exc
|
||||
raise XenAPI.Failure(params)
|
||||
else:
|
||||
raise
|
||||
except xmlrpclib.ProtocolError, exn:
|
||||
logging.debug("Got exception: %s", exn)
|
||||
except xmlrpclib.ProtocolError, exc:
|
||||
logging.debug("Got exception: %s", exc)
|
||||
raise
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user