summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVishvananda Ishaya <vishvananda@yahoo.com>2010-08-25 13:14:49 -0700
committerVishvananda Ishaya <vishvananda@yahoo.com>2010-08-25 13:14:49 -0700
commit674a5dae7c0630aef346e22950706db0caeb244b (patch)
tree596b34fdc90ca7675e7751679e2a6eef37aa1057
parent199b9b828d75ec6fa08481585aa5df462497c50f (diff)
downloadnova-674a5dae7c0630aef346e22950706db0caeb244b.tar.gz
nova-674a5dae7c0630aef346e22950706db0caeb244b.tar.xz
nova-674a5dae7c0630aef346e22950706db0caeb244b.zip
more data layer breakouts, lots of fixes to cloud.py
-rw-r--r--nova/compute/service.py10
-rw-r--r--nova/db/api.py39
-rw-r--r--nova/db/sqlalchemy/api.py54
-rw-r--r--nova/endpoint/cloud.py221
-rw-r--r--nova/models.py37
-rw-r--r--nova/tests/network_unittest.py2
6 files changed, 197 insertions, 166 deletions
diff --git a/nova/compute/service.py b/nova/compute/service.py
index a44f17a69..877246ef6 100644
--- a/nova/compute/service.py
+++ b/nova/compute/service.py
@@ -73,7 +73,7 @@ class ComputeService(service.Service):
def run_instance(self, instance_id, context=None, **_kwargs):
"""Launch a new instance with specified options."""
instance_ref = db.instance_get(context, instance_id)
- if instance_ref['name'] in self._conn.list_instances():
+ if instance_ref['str_id'] in self._conn.list_instances():
raise exception.Error("Instance has already been created")
logging.debug("Starting instance %s..." % (instance_id))
@@ -87,7 +87,7 @@ class ComputeService(service.Service):
yield self._conn.spawn(instance_ref)
except:
logging.exception("Failed to spawn instance %s" %
- instance_ref['name'])
+ instance_ref['str_id'])
db.instance_state(context, instance_id, power_state.SHUTDOWN)
self.update_state(instance_id, context)
@@ -127,11 +127,11 @@ class ComputeService(service.Service):
raise exception.Error(
'trying to reboot a non-running'
'instance: %s (state: %s excepted: %s)' %
- (instance_ref['name'],
+ (instance_ref['str_id'],
instance_ref['state'],
power_state.RUNNING))
- logging.debug('rebooting instance %s' % instance_ref['name'])
+ logging.debug('rebooting instance %s' % instance_ref['str_id'])
db.instance_state(
context, instance_id, power_state.NOSTATE, 'rebooting')
yield self._conn.reboot(instance_ref)
@@ -147,7 +147,7 @@ class ComputeService(service.Service):
if FLAGS.connection_type == 'libvirt':
fname = os.path.abspath(os.path.join(FLAGS.instances_path,
- instance_ref['name'],
+ instance_ref['str_id'],
'console.log'))
with open(fname, 'r') as f:
output = f.read()
diff --git a/nova/db/api.py b/nova/db/api.py
index edc3b7bdc..9efbcf76b 100644
--- a/nova/db/api.py
+++ b/nova/db/api.py
@@ -47,6 +47,7 @@ _impl = utils.LazyPluggable(FLAGS['db_backend'],
class AddressNotAllocated(exception.Error):
pass
+
class NoMoreAddresses(exception.Error):
pass
@@ -185,14 +186,9 @@ def instance_get_all(context):
return _impl.instance_get_all(context)
-def instance_get_by_ip(context, ip):
- """Gets an instance by fixed ipaddress or raise if it does not exist."""
- return _impl.instance_get_by_ip(context, ip)
-
-
-def instance_get_by_name(context, name):
- """Get an instance by name."""
- return _impl.instance_get_by_project(context, name)
+def instance_get_by_address(context, address):
+ """Gets an instance by fixed ip address or raise if it does not exist."""
+ return _impl.instance_get_by_address(context, address)
def instance_get_by_project(context, project_id):
@@ -205,9 +201,24 @@ def instance_get_by_reservation(context, reservation_id):
return _impl.instance_get_by_reservation(context, reservation_id)
+def instance_get_fixed_address(context, instance_id):
+ """Get the fixed ip address of an instance."""
+ return _impl.instance_get_fixed_address(context, instance_id)
+
+
+def instance_get_floating_address(context, instance_id):
+ """Get the first floating ip address of an instance."""
+ return _impl.instance_get_floating_address(context, instance_id)
+
+
+def instance_get_by_str(context, str_id):
+ """Get an instance by string id."""
+ return _impl.instance_get_by_str(context, str_id)
+
+
def instance_get_host(context, instance_id):
"""Get the host that the instance is running on."""
- return _impl.instance_get_all(context, instance_id)
+ return _impl.instance_get_host(context, instance_id)
def instance_is_vpn(context, instance_id):
@@ -365,6 +376,16 @@ def volume_get_by_project(context, project_id):
return _impl.volume_get_by_project(context, project_id)
+def volume_get_by_str(context, str_id):
+ """Get a volume by string id."""
+ return _impl.volume_get_by_str(context, str_id)
+
+
+def volume_get_host(context, volume_id):
+ """Get the host that the volume is running on."""
+ return _impl.volume_get_host(context, volume_id)
+
+
def volume_get_shelf_and_blade(context, volume_id):
"""Get the shelf and blade allocated to the volume."""
return _impl.volume_get_shelf_and_blade(context, volume_id)
diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py
index 2ce54a1d7..047a6c108 100644
--- a/nova/db/sqlalchemy/api.py
+++ b/nova/db/sqlalchemy/api.py
@@ -70,21 +70,21 @@ def floating_ip_allocate_address(context, node_name, project_id):
def floating_ip_fixed_ip_associate(context, floating_address, fixed_address):
- floating_ip_ref = models.FloatingIp.find_by_ip_str(floating_address)
- fixed_ip_ref = models.FixedIp.find_by_ip_str(fixed_address)
+ floating_ip_ref = models.FloatingIp.find_by_str(floating_address)
+ fixed_ip_ref = models.FixedIp.find_by_str(fixed_address)
floating_ip_ref.fixed_ip = fixed_ip_ref
floating_ip_ref.save()
def floating_ip_disassociate(context, address):
- floating_ip_ref = models.FloatingIp.find_by_ip_str(address)
+ floating_ip_ref = models.FloatingIp.find_by_str(address)
fixed_ip_address = floating_ip_ref.fixed_ip['ip_str']
floating_ip_ref['fixed_ip'] = None
floating_ip_ref.save()
return fixed_ip_address
def floating_ip_deallocate(context, address):
- floating_ip_ref = models.FloatingIp.find_by_ip_str(address)
+ floating_ip_ref = models.FloatingIp.find_by_str(address)
floating_ip_ref['project_id'] = None
floating_ip_ref.save()
@@ -108,11 +108,11 @@ def fixed_ip_allocate(context, network_id):
def fixed_ip_get_by_address(context, address):
- return models.FixedIp.find_by_ip_str(address)
+ return models.FixedIp.find_by_str(address)
def fixed_ip_get_network(context, address):
- return models.FixedIp.find_by_ip_str(address).network
+ return models.FixedIp.find_by_str(address).network
def fixed_ip_lease(context, address):
@@ -172,13 +172,11 @@ def instance_get_all(context):
return models.Instance.all()
-def instance_get_by_ip(context, ip):
- raise Exception("fixme(vish): add logic here!")
-
-
-def instance_get_by_name(context, name):
- # NOTE(vish): remove the 'i-'
- return models.Instance.find(name[2:])
+def instance_get_by_address(context, address):
+ fixed_ip_ref = db.fixed_ip_get_by_address(address)
+ if not fixed_ip_ref.instance:
+ raise exception.NotFound("No instance found for address %s" % address)
+ return fixed_ip_ref.instance
def instance_get_by_project(context, project_id):
@@ -197,6 +195,27 @@ def instance_get_by_reservation(context, reservation_id):
return results
+def instance_get_by_str(context, str_id):
+ return models.Instance.find_by_str(str_id)
+
+
+def instance_get_fixed_address(context, instance_id):
+ instance_ref = instance_get(context, instance_id)
+ if not instance_ref.fixed_ip:
+ return None
+ return instance_ref.fixed_ip['str_id']
+
+
+def instance_get_floating_address(context, instance_id):
+ instance_ref = instance_get(context, instance_id)
+ if not instance_ref.fixed_ip:
+ return None
+ if not instance_ref.fixed_ip.floating_ips:
+ return None
+ # NOTE(vish): this just returns the first floating ip
+ return instance_ref.fixed_ip.floating_ips[0]['str_id']
+
+
def instance_get_host(context, instance_id):
instance_ref = instance_get(context, instance_id)
return instance_ref['node_name']
@@ -453,6 +472,15 @@ def volume_get_by_project(context, project_id):
return results
+def volume_get_by_str(context, str_id):
+ return models.Volume.find_by_str(str_id)
+
+
+def volume_get_host(context, volume_id):
+ volume_ref = volume_get(context, volume_id)
+ return volume_ref['node_name']
+
+
def volume_get_shelf_and_blade(context, volume_id):
volume_ref = volume_get(context, volume_id)
export_device = volume_ref.export_device
diff --git a/nova/endpoint/cloud.py b/nova/endpoint/cloud.py
index 64a705e6d..ffe3d3cc7 100644
--- a/nova/endpoint/cloud.py
+++ b/nova/endpoint/cloud.py
@@ -32,16 +32,12 @@ from twisted.internet import defer
from nova import db
from nova import exception
from nova import flags
-from nova import models
from nova import rpc
from nova import utils
from nova.auth import rbac
from nova.auth import manager
-from nova.compute import model
from nova.compute.instance_types import INSTANCE_TYPES
from nova.endpoint import images
-from nova.network import service as network_service
-from nova.volume import service
FLAGS = flags.FLAGS
@@ -66,18 +62,6 @@ class CloudController(object):
def __init__(self):
self.setup()
- @property
- def instances(self):
- """ All instances in the system, as dicts """
- return db.instance_get_all(None)
-
- @property
- def volumes(self):
- """ returns a list of all volumes """
- for volume_id in datastore.Redis.instance().smembers("volumes"):
- volume = service.get_volume(volume_id)
- yield volume
-
def __str__(self):
return 'CloudController'
@@ -100,7 +84,7 @@ class CloudController(object):
def _get_mpi_data(self, project_id):
result = {}
for instance in db.instance_get_by_project(project_id):
- line = '%s slots=%d' % (instance['private_dns_name'],
+ line = '%s slots=%d' % (instance.fixed_ip['str_id'],
INSTANCE_TYPES[instance['instance_type']]['vcpus'])
if instance['key_name'] in result:
result[instance['key_name']].append(line)
@@ -109,7 +93,7 @@ class CloudController(object):
return result
def get_metadata(self, ipaddress):
- i = db.instance_get_by_ip(ipaddress)
+ i = db.instance_get_by_address(ipaddress)
if i is None:
return None
mpi = self._get_mpi_data(i['project_id'])
@@ -122,12 +106,7 @@ class CloudController(object):
}
else:
keys = ''
-
- address_record = network_model.FixedIp(i['private_dns_name'])
- if address_record:
- hostname = address_record['hostname']
- else:
- hostname = 'ip-%s' % i['private_dns_name'].replace('.', '-')
+ hostname = i['hostname']
data = {
'user-data': base64.b64decode(i['user_data']),
'meta-data': {
@@ -249,10 +228,11 @@ class CloudController(object):
@rbac.allow('projectmanager', 'sysadmin')
def get_console_output(self, context, instance_id, **kwargs):
# instance_id is passed in as a list of instances
- instance = db.instance_get(context, instance_id[0])
- return rpc.call('%s.%s' % (FLAGS.compute_topic, instance['node_name']),
- {"method": "get_console_output",
- "args": {"instance_id": instance_id[0]}})
+ instance_ref = db.instance_get_by_str(context, instance_id[0])
+ return rpc.call('%s.%s' % (FLAGS.compute_topic,
+ instance_ref['node_name']),
+ {"method": "get_console_output",
+ "args": {"instance_id": instance_ref['id']}})
@rbac.allow('projectmanager', 'sysadmin')
def describe_volumes(self, context, **kwargs):
@@ -267,7 +247,7 @@ class CloudController(object):
def _format_volume(self, context, volume):
v = {}
- v['volumeId'] = volume['id']
+ v['volumeId'] = volume['str_id']
v['status'] = volume['status']
v['size'] = volume['size']
v['availabilityZone'] = volume['availability_zone']
@@ -298,7 +278,7 @@ class CloudController(object):
vol['user_id'] = context.user.id
vol['project_id'] = context.project.id
vol['availability_zone'] = FLAGS.storage_availability_zone
- vol['status'] = "creating"
+ vol['status'] = "creating"
vol['attach_status'] = "detached"
volume_id = db.volume_create(context, vol)
@@ -308,61 +288,54 @@ class CloudController(object):
volume = db.volume_get(context, volume_id)
defer.returnValue({'volumeSet': [self._format_volume(context, volume)]})
- def _get_address(self, context, public_ip):
- # FIXME(vish) this should move into network.py
- address = network_model.FloatingIp.lookup(public_ip)
- if address and (context.user.is_admin() or address['project_id'] == context.project.id):
- return address
- raise exception.NotFound("Address at ip %s not found" % public_ip)
@rbac.allow('projectmanager', 'sysadmin')
def attach_volume(self, context, volume_id, instance_id, device, **kwargs):
- volume = db.volume_get(context, volume_id)
- if volume['status'] == "attached":
+ volume_ref = db.volume_get_by_str(context, volume_id)
+ # TODO(vish): abstract status checking?
+ if volume_ref['status'] == "attached":
raise exception.ApiError("Volume is already attached")
- # TODO(vish): looping through all volumes is slow. We should probably maintain an index
- for vol in self.volumes:
- if vol['instance_id'] == instance_id and vol['mountpoint'] == device:
- raise exception.ApiError("Volume %s is already attached to %s" % (vol['volume_id'], vol['mountpoint']))
- volume.start_attach(instance_id, device)
- instance = db.instance_get(context, instance_id)
- compute_node = instance['node_name']
- rpc.cast('%s.%s' % (FLAGS.compute_topic, compute_node),
+ #volume.start_attach(instance_id, device)
+ instance_ref = db.instance_get_by_str(context, instance_id)
+ host = db.instance_get_host(context, instance_ref['id'])
+ rpc.cast(db.queue_get_for(context, FLAGS.compute_topic, host),
{"method": "attach_volume",
- "args": {"volume_id": volume_id,
- "instance_id": instance_id,
+ "args": {"volume_id": volume_ref['id'],
+ "instance_id": instance_ref['id'],
"mountpoint": device}})
- return defer.succeed({'attachTime': volume['attach_time'],
- 'device': volume['mountpoint'],
- 'instanceId': instance_id,
+ return defer.succeed({'attachTime': volume_ref['attach_time'],
+ 'device': volume_ref['mountpoint'],
+ 'instanceId': instance_ref['id_str'],
'requestId': context.request_id,
- 'status': volume['attach_status'],
- 'volumeId': volume_id})
+ 'status': volume_ref['attach_status'],
+ 'volumeId': volume_ref['id']})
@rbac.allow('projectmanager', 'sysadmin')
def detach_volume(self, context, volume_id, **kwargs):
- volume = db.volume_get(context, volume_id)
- if volume['instance_id'] is None:
+ volume_ref = db.volume_get_by_str(context, volume_id)
+ instance_ref = db.volume_get_instance(context, volume_ref['id'])
+ if not instance_ref:
raise exception.Error("Volume isn't attached to anything!")
- if volume['status'] == "available":
+ # TODO(vish): abstract status checking?
+ if volume_ref['status'] == "available":
raise exception.Error("Volume is already detached")
try:
- volume.start_detach()
- instance = db.instance_get(context, instance_id)
- rpc.cast('%s.%s' % (FLAGS.compute_topic, instance['node_name']),
+ #volume.start_detach()
+ host = db.instance_get_host(context, instance_ref['id'])
+ rpc.cast(db.queue_get_for(context, FLAGS.compute_topic, host),
{"method": "detach_volume",
- "args": {"instance_id": instance_id,
- "volume_id": volume_id}})
+ "args": {"instance_id": instance_ref['id'],
+ "volume_id": volume_ref['id']}})
except exception.NotFound:
# If the instance doesn't exist anymore,
# then we need to call detach blind
- volume.finish_detach()
- return defer.succeed({'attachTime': volume['attach_time'],
- 'device': volume['mountpoint'],
- 'instanceId': instance_id,
+ db.volume_detached(context)
+ return defer.succeed({'attachTime': volume_ref['attach_time'],
+ 'device': volume_ref['mountpoint'],
+ 'instanceId': instance_ref['id_str'],
'requestId': context.request_id,
- 'status': volume['attach_status'],
- 'volumeId': volume_id})
+ 'status': volume_ref['attach_status'],
+ 'volumeId': volume_ref['id']})
def _convert_to_set(self, lst, label):
if lst == None or lst == []:
@@ -397,15 +370,18 @@ class CloudController(object):
if instance['image_id'] == FLAGS.vpn_image_id:
continue
i = {}
- i['instanceId'] = instance['name']
+ i['instanceId'] = instance['str_id']
i['imageId'] = instance['image_id']
i['instanceState'] = {
- 'code': instance.state,
- 'name': instance.state_description
+ 'code': instance['state'],
+ 'name': instance['state_description']
}
- i['public_dns_name'] = None #network_model.get_public_ip_for_instance(
- # i['instance_id'])
- i['private_dns_name'] = instance.fixed_ip['ip_str']
+ floating_addr = db.instance_get_floating_address(context,
+ instance['id'])
+ i['public_dns_name'] = floating_addr
+ fixed_addr = db.instance_get_fixed_address(context,
+ instance['id'])
+ i['private_dns_name'] = fixed_addr
if not i['public_dns_name']:
i['public_dns_name'] = i['private_dns_name']
i['dns_name'] = None
@@ -435,20 +411,23 @@ class CloudController(object):
def format_addresses(self, context):
addresses = []
- for address in network_model.FloatingIp.all():
- # TODO(vish): implement a by_project iterator for addresses
- if (context.user.is_admin() or
- address['project_id'] == context.project.id):
- address_rv = {
- 'public_ip': address['address'],
- 'instance_id': address.get('instance_id', 'free')
- }
- if context.user.is_admin():
- address_rv['instance_id'] = "%s (%s, %s)" % (
- address['instance_id'],
- address['user_id'],
- address['project_id'],
- )
+ if context.user.is_admin():
+ iterator = db.floating_ip_get_all(context)
+ else:
+ iterator = db.floating_ip_get_by_project(context,
+ context.project.id)
+ for floating_ip_ref in iterator:
+ address = floating_ip_ref['id_str']
+ instance_ref = db.instance_get_by_address(address)
+ address_rv = {
+ 'public_ip': address,
+ 'instance_id': instance_ref['id_str']
+ }
+ if context.user.is_admin():
+ address_rv['instance_id'] = "%s (%s)" % (
+ address_rv['instance_id'],
+ floating_ip_ref['project_id'],
+ )
addresses.append(address_rv)
return {'addressesSet': addresses}
@@ -458,41 +437,42 @@ class CloudController(object):
network_topic = yield self._get_network_topic(context)
public_ip = yield rpc.call(network_topic,
{"method": "allocate_floating_ip",
- "args": {"user_id": context.user.id,
- "project_id": context.project.id}})
+ "args": {"project_id": context.project.id}})
defer.returnValue({'addressSet': [{'publicIp': public_ip}]})
@rbac.allow('netadmin')
@defer.inlineCallbacks
def release_address(self, context, public_ip, **kwargs):
# NOTE(vish): Should we make sure this works?
+ floating_ip_ref = db.floating_ip_get_by_address(context, public_ip)
network_topic = yield self._get_network_topic(context)
rpc.cast(network_topic,
{"method": "deallocate_floating_ip",
- "args": {"floating_ip": public_ip}})
+ "args": {"floating_ip": floating_ip_ref['str_id']}})
defer.returnValue({'releaseResponse': ["Address released."]})
@rbac.allow('netadmin')
@defer.inlineCallbacks
def associate_address(self, context, instance_id, public_ip, **kwargs):
- instance = db.instance_get(context, instance_id)
- address = self._get_address(context, public_ip)
+ instance_ref = db.instance_get_by_str(context, instance_id)
+ fixed_ip_ref = db.fixed_ip_get_by_instance(context, instance_ref['id'])
+ floating_ip_ref = db.floating_ip_get_by_address(context, public_ip)
network_topic = yield self._get_network_topic(context)
rpc.cast(network_topic,
{"method": "associate_floating_ip",
- "args": {"floating_ip": address['address'],
- "fixed_ip": instance['private_dns_name'],
- "instance_id": instance['instance_id']}})
+ "args": {"floating_ip": floating_ip_ref['str_id'],
+ "fixed_ip": fixed_ip_ref['str_id'],
+ "instance_id": instance_ref['id']}})
defer.returnValue({'associateResponse': ["Address associated."]})
@rbac.allow('netadmin')
@defer.inlineCallbacks
def disassociate_address(self, context, public_ip, **kwargs):
- address = self._get_address(context, public_ip)
+ floating_ip_ref = db.floating_ip_get_by_address(context, public_ip)
network_topic = yield self._get_network_topic(context)
rpc.cast(network_topic,
{"method": "disassociate_floating_ip",
- "args": {"floating_ip": address['address']}})
+ "args": {"floating_ip": floating_ip_ref['str_id']}})
defer.returnValue({'disassociateResponse': ["Address disassociated."]})
@defer.inlineCallbacks
@@ -596,13 +576,13 @@ class CloudController(object):
def terminate_instances(self, context, instance_id, **kwargs):
logging.debug("Going to start terminating instances")
# network_topic = yield self._get_network_topic(context)
- for name in instance_id:
- logging.debug("Going to try and terminate %s" % name)
+ for id_str in instance_id:
+ logging.debug("Going to try and terminate %s" % id_str)
try:
- instance_ref = db.instance_get_by_name(context, name)
+ instance_ref = db.instance_get_by_str(context, id_str)
except exception.NotFound:
logging.warning("Instance %s was not found during terminate"
- % name)
+ % id_str)
continue
# FIXME(ja): where should network deallocate occur?
@@ -631,7 +611,7 @@ class CloudController(object):
# NOTE(joshua?): It's also internal default
rpc.cast(db.queue_get_for(context, FLAGS.compute_topic, host),
{"method": "terminate_instance",
- "args": {"instance_id": name}})
+ "args": {"instance_id": instance_ref['id']}})
else:
db.instance_destroy(context, instance_ref['id'])
# defer.returnValue(True)
@@ -640,19 +620,20 @@ class CloudController(object):
@rbac.allow('projectmanager', 'sysadmin')
def reboot_instances(self, context, instance_id, **kwargs):
"""instance_id is a list of instance ids"""
- for i in instance_id:
- instance = db.instance_get(context, i)
- rpc.cast('%s.%s' % (FLAGS.compute_topic, instance['node_name']),
- {"method": "reboot_instance",
- "args": {"instance_id": i}})
+ for id_str in instance_id:
+ instance_ref = db.instance_get_by_str(context, id_str)
+ host = db.instance_get_host(context, instance_ref['id'])
+ rpc.cast(db.queue_get_for(context, FLAGS.compute_topic, host),
+ {"method": "reboot_instance",
+ "args": {"instance_id": instance_ref['id']}})
return defer.succeed(True)
@rbac.allow('projectmanager', 'sysadmin')
def delete_volume(self, context, volume_id, **kwargs):
# TODO: return error if not authorized
- volume = db.volume_get(context, volume_id)
- volume_node = volume['node_name']
- rpc.cast('%s.%s' % (FLAGS.volume_topic, volume_node),
+ volume_ref = db.volume_get_by_str(context, volume_id)
+ host = db.volume_get_host(context, volume_ref['id'])
+ rpc.cast(db.queue_get_for(context, FLAGS.compute_topic, host),
{"method": "delete_volume",
"args": {"volume_id": volume_id}})
return defer.succeed(True)
@@ -705,23 +686,3 @@ class CloudController(object):
raise exception.ApiError('operation_type must be add or remove')
result = images.modify(context, image_id, operation_type)
return defer.succeed(result)
-
- def update_state(self, topic, value):
- """ accepts status reports from the queue and consolidates them """
- # TODO(jmc): if an instance has disappeared from
- # the node, call instance_death
- if topic == "instances":
- return defer.succeed(True)
- aggregate_state = getattr(self, topic)
- node_name = value.keys()[0]
- items = value[node_name]
-
- logging.debug("Updating %s state for %s" % (topic, node_name))
-
- for item_id in items.keys():
- if (aggregate_state.has_key('pending') and
- aggregate_state['pending'].has_key(item_id)):
- del aggregate_state['pending'][item_id]
- aggregate_state[node_name] = items
-
- return defer.succeed(True)
diff --git a/nova/models.py b/nova/models.py
index c7ca9bb74..7ad379814 100644
--- a/nova/models.py
+++ b/nova/models.py
@@ -40,6 +40,7 @@ flags.DEFINE_string('sql_connection',
class NovaBase(object):
__table_args__ = {'mysql_engine':'InnoDB'}
+ __prefix__ = 'none'
created_at = Column(DateTime)
updated_at = Column(DateTime)
@@ -86,6 +87,15 @@ class NovaBase(object):
except exc.NoResultFound:
raise exception.NotFound("No model for id %s" % obj_id)
+ @classmethod
+ def find_by_str(cls, str_id):
+ id = int(str_id.rpartition('-')[2])
+ return cls.find(id)
+
+ @property
+ def str_id(self):
+ return "%s-%s" % (self.__prefix__, self.id)
+
def save(self):
session = NovaBase.get_session()
session.add(self)
@@ -109,6 +119,7 @@ class NovaBase(object):
class Image(Base, NovaBase):
__tablename__ = 'images'
+ __prefix__ = 'ami'
id = Column(Integer, primary_key=True)
user_id = Column(String(255))#, ForeignKey('users.id'), nullable=False)
project_id = Column(String(255))#, ForeignKey('projects.id'), nullable=False)
@@ -166,6 +177,7 @@ class Daemon(Base, NovaBase):
class Instance(Base, NovaBase):
__tablename__ = 'instances'
+ __prefix__ = 'i'
id = Column(Integer, primary_key=True)
user_id = Column(String(255)) #, ForeignKey('users.id'), nullable=False)
@@ -182,7 +194,7 @@ class Instance(Base, NovaBase):
# TODO(vish): make this opaque somehow
@property
def name(self):
- return "i-%s" % self.id
+ return self.str_id
image_id = Column(Integer, ForeignKey('images.id'), nullable=True)
@@ -198,7 +210,7 @@ class Instance(Base, NovaBase):
state_description = Column(String(255))
hostname = Column(String(255))
- physical_node_id = Column(Integer)
+ node_name = Column(String(255)) #, ForeignKey('physical_node.id'))
instance_type = Column(Integer)
@@ -230,6 +242,7 @@ class Instance(Base, NovaBase):
class Volume(Base, NovaBase):
__tablename__ = 'volumes'
+ __prefix__ = 'vol'
id = Column(Integer, primary_key=True)
user_id = Column(String(255)) #, ForeignKey('users.id'), nullable=False)
@@ -267,15 +280,19 @@ class FixedIp(Base, NovaBase):
leased = Column(Boolean, default=False)
reserved = Column(Boolean, default=False)
+ @property
+ def str_id(self):
+ return self.ip_str
+
@classmethod
- def find_by_ip_str(cls, ip_str):
+ def find_by_str(cls, str_id):
session = NovaBase.get_session()
try:
- result = session.query(cls).filter_by(ip_str=ip_str).one()
+ result = session.query(cls).filter_by(ip_str=str_id).one()
session.commit()
return result
except exc.NoResultFound:
- raise exception.NotFound("No model for ip str %s" % ip_str)
+ raise exception.NotFound("No model for ip str %s" % str_id)
class FloatingIp(Base, NovaBase):
@@ -288,15 +305,19 @@ class FloatingIp(Base, NovaBase):
project_id = Column(String(255)) #, ForeignKey('projects.id'), nullable=False)
node_name = Column(String(255)) #, ForeignKey('physical_node.id'))
+ @property
+ def str_id(self):
+ return self.ip_str
+
@classmethod
- def find_by_ip_str(cls, ip_str):
+ def find_by_str(cls, str_id):
session = NovaBase.get_session()
try:
- result = session.query(cls).filter_by(ip_str=ip_str).one()
+ result = session.query(cls).filter_by(ip_str=str_id).one()
session.commit()
return result
except exc.NoResultFound:
- raise exception.NotFound("No model for ip str %s" % ip_str)
+ raise exception.NotFound("No model for ip str %s" % str_id)
class Network(Base, NovaBase):
diff --git a/nova/tests/network_unittest.py b/nova/tests/network_unittest.py
index afa217673..d8a398aa4 100644
--- a/nova/tests/network_unittest.py
+++ b/nova/tests/network_unittest.py
@@ -81,7 +81,7 @@ class NetworkTestCase(test.TrialTestCase):
pubnet = IPy.IP(flags.FLAGS.public_range)
ip_str = str(pubnet[0])
try:
- floating_ip = models.FloatingIp.find_by_ip_str(ip_str)
+ floating_ip = models.FloatingIp.find_by_str(ip_str)
except exception.NotFound:
floating_ip = models.FloatingIp()
floating_ip.ip_str = ip_str