summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDevin Carlen <devin.carlen@gmail.com>2010-09-29 01:53:14 +0000
committerTarmac <>2010-09-29 01:53:14 +0000
commit27220e66e20e30304bae8491ebe90fcc968c43ca (patch)
tree7329256f146fdfc9357e17bb238749b9b6eb1dc0
parent0945a8869fa64d466527f865ba13b6275f1649c2 (diff)
parente3102b6b9be148597a2f502d2b2baf750ecc0a34 (diff)
downloadnova-27220e66e20e30304bae8491ebe90fcc968c43ca.tar.gz
nova-27220e66e20e30304bae8491ebe90fcc968c43ca.tar.xz
nova-27220e66e20e30304bae8491ebe90fcc968c43ca.zip
Added random ec2 style id's for volumes and instances.
-rwxr-xr-xbin/nova-manage2
-rw-r--r--nova/api/ec2/cloud.py46
-rw-r--r--nova/compute/manager.py10
-rw-r--r--nova/db/api.py12
-rw-r--r--nova/db/sqlalchemy/api.py60
-rw-r--r--nova/db/sqlalchemy/models.py13
-rw-r--r--nova/network/linux_net.py2
-rw-r--r--nova/network/manager.py2
-rw-r--r--nova/volume/manager.py10
9 files changed, 99 insertions, 58 deletions
diff --git a/bin/nova-manage b/bin/nova-manage
index baa1cb4db..a5087bfec 100755
--- a/bin/nova-manage
+++ b/bin/nova-manage
@@ -316,7 +316,7 @@ class FloatingIpCommands(object):
for floating_ip in floating_ips:
instance = None
if floating_ip['fixed_ip']:
- instance = floating_ip['fixed_ip']['instance']['str_id']
+ instance = floating_ip['fixed_ip']['instance']['ec2_id']
print "%s\t%s\t%s" % (floating_ip['host'],
floating_ip['address'],
instance)
diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py
index 367511e3b..05e8065f3 100644
--- a/nova/api/ec2/cloud.py
+++ b/nova/api/ec2/cloud.py
@@ -103,7 +103,7 @@ class CloudController(object):
result = {}
for instance in db.instance_get_by_project(None, project_id):
if instance['fixed_ip']:
- line = '%s slots=%d' % (instance['fixed_ip']['str_id'],
+ line = '%s slots=%d' % (instance['fixed_ip']['address'],
INSTANCE_TYPES[instance['instance_type']]['vcpus'])
key = str(instance['key_name'])
if key in result:
@@ -143,7 +143,7 @@ class CloudController(object):
},
'hostname': hostname,
'instance-action': 'none',
- 'instance-id': instance_ref['str_id'],
+ 'instance-id': instance_ref['ec2_id'],
'instance-type': instance_ref['instance_type'],
'local-hostname': hostname,
'local-ipv4': address,
@@ -245,7 +245,7 @@ class CloudController(object):
def get_console_output(self, context, instance_id, **kwargs):
# instance_id is passed in as a list of instances
- instance_ref = db.instance_get_by_str(context, instance_id[0])
+ instance_ref = db.instance_get_by_ec2_id(context, instance_id[0])
return rpc.call('%s.%s' % (FLAGS.compute_topic,
instance_ref['host']),
{"method": "get_console_output",
@@ -264,7 +264,7 @@ class CloudController(object):
def _format_volume(self, context, volume):
v = {}
- v['volumeId'] = volume['str_id']
+ v['volumeId'] = volume['ec2_id']
v['status'] = volume['status']
v['size'] = volume['size']
v['availabilityZone'] = volume['availability_zone']
@@ -282,7 +282,7 @@ class CloudController(object):
'device': volume['mountpoint'],
'instanceId': volume['instance_id'],
'status': 'attached',
- 'volume_id': volume['str_id']}]
+ 'volume_id': volume['ec2_id']}]
else:
v['attachmentSet'] = [{}]
return v
@@ -314,13 +314,13 @@ class CloudController(object):
def attach_volume(self, context, volume_id, instance_id, device, **kwargs):
- volume_ref = db.volume_get_by_str(context, volume_id)
+ volume_ref = db.volume_get_by_ec2_id(context, volume_id)
# TODO(vish): abstract status checking?
if volume_ref['status'] != "available":
raise exception.ApiError("Volume status must be available")
if volume_ref['attach_status'] == "attached":
raise exception.ApiError("Volume is already attached")
- instance_ref = db.instance_get_by_str(context, instance_id)
+ instance_ref = db.instance_get_by_ec2_id(context, instance_id)
host = instance_ref['host']
rpc.cast(db.queue_get_for(context, FLAGS.compute_topic, host),
{"method": "attach_volume",
@@ -336,7 +336,7 @@ class CloudController(object):
'volumeId': volume_ref['id']}
def detach_volume(self, context, volume_id, **kwargs):
- volume_ref = db.volume_get_by_str(context, volume_id)
+ volume_ref = db.volume_get_by_ec2_id(context, volume_id)
instance_ref = db.volume_get_instance(context, volume_ref['id'])
if not instance_ref:
raise exception.ApiError("Volume isn't attached to anything!")
@@ -356,7 +356,7 @@ class CloudController(object):
db.volume_detached(context)
return {'attachTime': volume_ref['attach_time'],
'device': volume_ref['mountpoint'],
- 'instanceId': instance_ref['str_id'],
+ 'instanceId': instance_ref['ec2_id'],
'requestId': context.request_id,
'status': volume_ref['attach_status'],
'volumeId': volume_ref['id']}
@@ -395,7 +395,7 @@ class CloudController(object):
if instance['image_id'] == FLAGS.vpn_image_id:
continue
i = {}
- i['instanceId'] = instance['str_id']
+ i['instanceId'] = instance['ec2_id']
i['imageId'] = instance['image_id']
i['instanceState'] = {
'code': instance['state'],
@@ -404,10 +404,10 @@ class CloudController(object):
fixed_addr = None
floating_addr = None
if instance['fixed_ip']:
- fixed_addr = instance['fixed_ip']['str_id']
+ fixed_addr = instance['fixed_ip']['address']
if instance['fixed_ip']['floating_ips']:
fixed = instance['fixed_ip']
- floating_addr = fixed['floating_ips'][0]['str_id']
+ floating_addr = fixed['floating_ips'][0]['address']
i['privateDnsName'] = fixed_addr
i['publicDnsName'] = floating_addr
i['dnsName'] = i['publicDnsName'] or i['privateDnsName']
@@ -442,11 +442,11 @@ class CloudController(object):
iterator = db.floating_ip_get_by_project(context,
context.project.id)
for floating_ip_ref in iterator:
- address = floating_ip_ref['str_id']
+ address = floating_ip_ref['address']
instance_id = None
if (floating_ip_ref['fixed_ip']
and floating_ip_ref['fixed_ip']['instance']):
- instance_id = floating_ip_ref['fixed_ip']['instance']['str_id']
+ instance_id = floating_ip_ref['fixed_ip']['instance']['ec2_id']
address_rv = {'public_ip': address,
'instance_id': instance_id}
if context.user.is_admin():
@@ -477,19 +477,19 @@ class CloudController(object):
rpc.cast(network_topic,
{"method": "deallocate_floating_ip",
"args": {"context": None,
- "floating_address": floating_ip_ref['str_id']}})
+ "floating_address": floating_ip_ref['address']}})
return {'releaseResponse': ["Address released."]}
def associate_address(self, context, instance_id, public_ip, **kwargs):
- instance_ref = db.instance_get_by_str(context, instance_id)
+ instance_ref = db.instance_get_by_ec2_id(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 = self._get_network_topic(context)
rpc.cast(network_topic,
{"method": "associate_floating_ip",
"args": {"context": None,
- "floating_address": floating_ip_ref['str_id'],
- "fixed_address": fixed_ip_ref['str_id']}})
+ "floating_address": floating_ip_ref['address'],
+ "fixed_address": fixed_ip_ref['address']}})
return {'associateResponse': ["Address associated."]}
def disassociate_address(self, context, public_ip, **kwargs):
@@ -498,7 +498,7 @@ class CloudController(object):
rpc.cast(network_topic,
{"method": "disassociate_floating_ip",
"args": {"context": None,
- "floating_address": floating_ip_ref['str_id']}})
+ "floating_address": floating_ip_ref['address']}})
return {'disassociateResponse': ["Address disassociated."]}
def _get_network_topic(self, context):
@@ -589,7 +589,7 @@ class CloudController(object):
inst = {}
inst['mac_address'] = utils.generate_mac()
inst['launch_index'] = num
- inst['hostname'] = instance_ref['str_id']
+ inst['hostname'] = instance_ref['ec2_id']
db.instance_update(context, inst_id, inst)
address = self.network_manager.allocate_fixed_ip(context,
inst_id,
@@ -618,7 +618,7 @@ class CloudController(object):
for id_str in instance_id:
logging.debug("Going to try and terminate %s" % id_str)
try:
- instance_ref = db.instance_get_by_str(context, id_str)
+ instance_ref = db.instance_get_by_ec2_id(context, id_str)
except exception.NotFound:
logging.warning("Instance %s was not found during terminate"
% id_str)
@@ -664,7 +664,7 @@ class CloudController(object):
def reboot_instances(self, context, instance_id, **kwargs):
"""instance_id is a list of instance ids"""
for id_str in instance_id:
- instance_ref = db.instance_get_by_str(context, id_str)
+ instance_ref = db.instance_get_by_ec2_id(context, id_str)
host = instance_ref['host']
rpc.cast(db.queue_get_for(context, FLAGS.compute_topic, host),
{"method": "reboot_instance",
@@ -674,7 +674,7 @@ class CloudController(object):
def delete_volume(self, context, volume_id, **kwargs):
# TODO: return error if not authorized
- volume_ref = db.volume_get_by_str(context, volume_id)
+ volume_ref = db.volume_get_by_ec2_id(context, volume_id)
if volume_ref['status'] != "available":
raise exception.ApiError("Volume status must be available")
now = datetime.datetime.utcnow()
diff --git a/nova/compute/manager.py b/nova/compute/manager.py
index 24538e4f1..f370ede8b 100644
--- a/nova/compute/manager.py
+++ b/nova/compute/manager.py
@@ -67,7 +67,7 @@ class ComputeManager(manager.Manager):
def run_instance(self, context, instance_id, **_kwargs):
"""Launch a new instance with specified options."""
instance_ref = self.db.instance_get(context, instance_id)
- if instance_ref['str_id'] in self.driver.list_instances():
+ if instance_ref['ec2_id'] in self.driver.list_instances():
raise exception.Error("Instance has already been created")
logging.debug("instance %s: starting...", instance_id)
project_id = instance_ref['project_id']
@@ -129,7 +129,7 @@ class ComputeManager(manager.Manager):
raise exception.Error(
'trying to reboot a non-running'
'instance: %s (state: %s excepted: %s)' %
- (instance_ref['str_id'],
+ (instance_ref['ec2_id'],
instance_ref['state'],
power_state.RUNNING))
@@ -151,7 +151,7 @@ class ComputeManager(manager.Manager):
if FLAGS.connection_type == 'libvirt':
fname = os.path.abspath(os.path.join(FLAGS.instances_path,
- instance_ref['str_id'],
+ instance_ref['ec2_id'],
'console.log'))
with open(fname, 'r') as f:
output = f.read()
@@ -174,7 +174,7 @@ class ComputeManager(manager.Manager):
instance_ref = self.db.instance_get(context, instance_id)
dev_path = yield self.volume_manager.setup_compute_volume(context,
volume_id)
- yield self.driver.attach_volume(instance_ref['str_id'],
+ yield self.driver.attach_volume(instance_ref['ec2_id'],
dev_path,
mountpoint)
self.db.volume_attached(context, volume_id, instance_id, mountpoint)
@@ -189,7 +189,7 @@ class ComputeManager(manager.Manager):
volume_id)
instance_ref = self.db.instance_get(context, instance_id)
volume_ref = self.db.volume_get(context, volume_id)
- yield self.driver.detach_volume(instance_ref['str_id'],
+ yield self.driver.detach_volume(instance_ref['ec2_id'],
volume_ref['mountpoint'])
self.db.volume_detached(context, volume_id)
defer.returnValue(True)
diff --git a/nova/db/api.py b/nova/db/api.py
index b0b8f234d..208720ff9 100644
--- a/nova/db/api.py
+++ b/nova/db/api.py
@@ -275,9 +275,9 @@ def instance_get_floating_address(context, instance_id):
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_by_ec2_id(context, ec2_id):
+ """Get an instance by ec2 id."""
+ return IMPL.instance_get_by_ec2_id(context, ec2_id)
def instance_is_vpn(context, instance_id):
@@ -540,9 +540,9 @@ 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_by_ec2_id(context, ec2_id):
+ """Get a volume by ec2 id."""
+ return IMPL.volume_get_by_ec2_id(context, ec2_id)
def volume_get_shelf_and_blade(context, volume_id):
diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py
index 5c1ceee92..8b9a3e1c6 100644
--- a/nova/db/sqlalchemy/api.py
+++ b/nova/db/sqlalchemy/api.py
@@ -22,11 +22,12 @@ Implementation of SQLAlchemy backend
from nova import db
from nova import exception
from nova import flags
+from nova import utils
from nova.db.sqlalchemy import models
from nova.db.sqlalchemy.session import get_session
from sqlalchemy import or_
from sqlalchemy.orm import joinedload_all
-from sqlalchemy.sql import func
+from sqlalchemy.sql import exists, func
FLAGS = flags.FLAGS
@@ -356,9 +357,15 @@ def instance_create(_context, values):
instance_ref = models.Instance()
for (key, value) in values.iteritems():
instance_ref[key] = value
- instance_ref.save()
- return instance_ref
+ session = get_session()
+ with session.begin():
+ while instance_ref.ec2_id == None:
+ ec2_id = utils.generate_uid(instance_ref.__prefix__)
+ if not instance_ec2_id_exists(_context, ec2_id, session=session):
+ instance_ref.ec2_id = ec2_id
+ instance_ref.save(session=session)
+ return instance_ref
def instance_data_get_for_project(_context, project_id):
session = get_session()
@@ -415,8 +422,22 @@ def instance_get_by_reservation(_context, reservation_id):
).all()
-def instance_get_by_str(context, str_id):
- return models.Instance.find_by_str(str_id, deleted=_deleted(context))
+def instance_get_by_ec2_id(context, ec2_id):
+ session = get_session()
+ instance_ref = session.query(models.Instance
+ ).filter_by(ec2_id=ec2_id
+ ).filter_by(deleted=_deleted(context)
+ ).first()
+ if not instance_ref:
+ raise exception.NotFound('Instance %s not found' % (ec2_id))
+
+ return instance_ref
+
+
+def instance_ec2_id_exists(context, ec2_id, session=None):
+ if not session:
+ session = get_session()
+ return session.query(exists().where(models.Instance.id==ec2_id)).one()[0]
def instance_get_fixed_address(_context, instance_id):
@@ -706,7 +727,7 @@ def auth_create_token(_context, token):
tk[k] = v
tk.save()
return tk
-
+
###################
@@ -775,7 +796,14 @@ def volume_create(_context, values):
volume_ref = models.Volume()
for (key, value) in values.iteritems():
volume_ref[key] = value
- volume_ref.save()
+
+ session = get_session()
+ with session.begin():
+ while volume_ref.ec2_id == None:
+ ec2_id = utils.generate_uid(volume_ref.__prefix__)
+ if not volume_ec2_id_exists(_context, ec2_id, session=session):
+ volume_ref.ec2_id = ec2_id
+ volume_ref.save(session=session)
return volume_ref
@@ -828,8 +856,22 @@ def volume_get_by_project(context, project_id):
).all()
-def volume_get_by_str(context, str_id):
- return models.Volume.find_by_str(str_id, deleted=_deleted(context))
+def volume_get_by_ec2_id(context, ec2_id):
+ session = get_session()
+ volume_ref = session.query(models.Volume
+ ).filter_by(ec2_id=ec2_id
+ ).filter_by(deleted=_deleted(context)
+ ).first()
+ if not volume_ref:
+ raise exception.NotFound('Volume %s not found' % (ec2_id))
+
+ return volume_ref
+
+
+def volume_ec2_id_exists(context, ec2_id, session=None):
+ if not session:
+ session = get_session()
+ return session.query(exists().where(models.Volume.id==ec2_id)).one()[0]
def volume_get_instance(_context, volume_id):
diff --git a/nova/db/sqlalchemy/models.py b/nova/db/sqlalchemy/models.py
index 63f8c6172..d4e04153a 100644
--- a/nova/db/sqlalchemy/models.py
+++ b/nova/db/sqlalchemy/models.py
@@ -126,6 +126,7 @@ class NovaBase(object):
# __tablename__ = 'images'
# __prefix__ = 'ami'
# id = Column(Integer, primary_key=True)
+# ec2_id = Column(String(12), unique=True)
# user_id = Column(String(255))
# project_id = Column(String(255))
# image_type = Column(String(255))
@@ -195,6 +196,7 @@ class Instance(BASE, NovaBase):
__tablename__ = 'instances'
__prefix__ = 'i'
id = Column(Integer, primary_key=True)
+ ec2_id = Column(String(10), unique=True)
user_id = Column(String(255))
project_id = Column(String(255))
@@ -209,7 +211,7 @@ class Instance(BASE, NovaBase):
@property
def name(self):
- return self.str_id
+ return self.ec2_id
image_id = Column(String(255))
kernel_id = Column(String(255))
@@ -267,6 +269,7 @@ class Volume(BASE, NovaBase):
__tablename__ = 'volumes'
__prefix__ = 'vol'
id = Column(Integer, primary_key=True)
+ ec2_id = Column(String(12), unique=True)
user_id = Column(String(255))
project_id = Column(String(255))
@@ -400,8 +403,8 @@ class NetworkIndex(BASE, NovaBase):
uselist=False))
class AuthToken(BASE, NovaBase):
- """Represents an authorization token for all API transactions. Fields
- are a string representing the actual token and a user id for mapping
+ """Represents an authorization token for all API transactions. Fields
+ are a string representing the actual token and a user id for mapping
to the actual user"""
__tablename__ = 'auth_tokens'
token_hash = Column(String(255), primary_key=True)
@@ -456,10 +459,6 @@ class FloatingIp(BASE, NovaBase):
project_id = Column(String(255))
host = Column(String(255)) # , ForeignKey('hosts.id'))
- @property
- def str_id(self):
- return self.address
-
@classmethod
def find_by_str(cls, str_id, session=None, deleted=False):
if not session:
diff --git a/nova/network/linux_net.py b/nova/network/linux_net.py
index 41aeb5da7..25a9456b9 100644
--- a/nova/network/linux_net.py
+++ b/nova/network/linux_net.py
@@ -133,7 +133,7 @@ def get_dhcp_hosts(context, network_id):
"""Get a string containing a network's hosts config in dnsmasq format"""
hosts = []
for fixed_ip in db.network_get_associated_fixed_ips(context, network_id):
- hosts.append(_host_dhcp(fixed_ip['str_id']))
+ hosts.append(_host_dhcp(fixed_ip['address']))
return '\n'.join(hosts)
diff --git a/nova/network/manager.py b/nova/network/manager.py
index 191c1d364..321dac914 100644
--- a/nova/network/manager.py
+++ b/nova/network/manager.py
@@ -270,7 +270,7 @@ class VlanManager(NetworkManager):
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'],
+ fixed_ip_ref['address'],
{'leased': True})
def release_fixed_ip(self, context, mac, address):
diff --git a/nova/volume/manager.py b/nova/volume/manager.py
index 034763512..8508f27b2 100644
--- a/nova/volume/manager.py
+++ b/nova/volume/manager.py
@@ -77,7 +77,7 @@ class AOEManager(manager.Manager):
size = volume_ref['size']
logging.debug("volume %s: creating lv of size %sG", volume_id, size)
- yield self.driver.create_volume(volume_ref['str_id'], size)
+ yield self.driver.create_volume(volume_ref['ec2_id'], size)
logging.debug("volume %s: allocating shelf & blade", volume_id)
self._ensure_blades(context)
@@ -87,7 +87,7 @@ class AOEManager(manager.Manager):
logging.debug("volume %s: exporting shelf %s & blade %s", volume_id,
shelf_id, blade_id)
- yield self.driver.create_export(volume_ref['str_id'],
+ yield self.driver.create_export(volume_ref['ec2_id'],
shelf_id,
blade_id)
@@ -111,10 +111,10 @@ class AOEManager(manager.Manager):
raise exception.Error("Volume is not local to this node")
shelf_id, blade_id = self.db.volume_get_shelf_and_blade(context,
volume_id)
- yield self.driver.remove_export(volume_ref['str_id'],
+ yield self.driver.remove_export(volume_ref['ec2_id'],
shelf_id,
blade_id)
- yield self.driver.delete_volume(volume_ref['str_id'])
+ yield self.driver.delete_volume(volume_ref['ec2_id'])
self.db.volume_destroy(context, volume_id)
defer.returnValue(True)
@@ -125,7 +125,7 @@ class AOEManager(manager.Manager):
Returns path to device.
"""
volume_ref = self.db.volume_get(context, volume_id)
- yield self.driver.discover_volume(volume_ref['str_id'])
+ yield self.driver.discover_volume(volume_ref['ec2_id'])
shelf_id, blade_id = self.db.volume_get_shelf_and_blade(context,
volume_id)
defer.returnValue("/dev/etherd/e%s.%s" % (shelf_id, blade_id))