summaryrefslogtreecommitdiffstats
path: root/nova/api
diff options
context:
space:
mode:
authorSoren Hansen <soren.hansen@rackspace.com>2010-10-08 21:41:11 +0200
committerSoren Hansen <soren.hansen@rackspace.com>2010-10-08 21:41:11 +0200
commit5be81520196c21aa9b60425bca7bf49935772cd1 (patch)
treeb2abb4d185d9c0ebfbb145f92fddc2bb201f3361 /nova/api
parent5a5da05a966dcdd3113a074468b37e12d406b350 (diff)
parentd58da66e2958ff3bb32c8f764c90526be5c601af (diff)
Merge trunk.
Diffstat (limited to 'nova/api')
-rw-r--r--nova/api/cloud.py2
-rw-r--r--nova/api/ec2/cloud.py64
-rw-r--r--nova/api/rackspace/images.py7
-rw-r--r--nova/api/rackspace/servers.py39
4 files changed, 66 insertions, 46 deletions
diff --git a/nova/api/cloud.py b/nova/api/cloud.py
index 345677d4f..57e94a17a 100644
--- a/nova/api/cloud.py
+++ b/nova/api/cloud.py
@@ -34,7 +34,7 @@ def reboot(instance_id, context=None):
#TODO(gundlach) not actually sure what context is used for by ec2 here
-- I think we can just remove it and use None all the time.
"""
- instance_ref = db.instance_get_by_ec2_id(None, instance_id)
+ instance_ref = db.instance_get_by_internal_id(None, instance_id)
host = instance_ref['host']
rpc.cast(db.queue_get_for(context, FLAGS.compute_topic, host),
{"method": "reboot_instance",
diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py
index e7147ec05..65cbe20ea 100644
--- a/nova/api/ec2/cloud.py
+++ b/nova/api/ec2/cloud.py
@@ -72,6 +72,20 @@ def _gen_key(context, user_id, key_name):
return {'private_key': private_key, 'fingerprint': fingerprint}
+def ec2_id_to_internal_id(ec2_id):
+ """Convert an ec2 ID (i-[base 36 number]) to an internal id (int)"""
+ return int(ec2_id[2:], 36)
+
+
+def internal_id_to_ec2_id(internal_id):
+ """Convert an internal ID (int) to an ec2 ID (i-[base 36 number])"""
+ digits = []
+ while internal_id != 0:
+ internal_id, remainder = divmod(internal_id, 36)
+ digits.append('0123456789abcdefghijklmnopqrstuvwxyz'[remainder])
+ return "i-%s" % ''.join(reversed(digits))
+
+
class CloudController(object):
""" CloudController provides the critical dispatch between
inbound API calls through the endpoint and messages
@@ -144,7 +158,7 @@ class CloudController(object):
},
'hostname': hostname,
'instance-action': 'none',
- 'instance-id': instance_ref['ec2_id'],
+ 'instance-id': internal_id_to_ec2_id(instance_ref['internal_id']),
'instance-type': instance_ref['instance_type'],
'local-hostname': hostname,
'local-ipv4': address,
@@ -244,9 +258,11 @@ class CloudController(object):
def delete_security_group(self, context, group_name, **kwargs):
return True
- 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_ec2_id(context, instance_id[0])
+ def get_console_output(self, context, ec2_id_list, **kwargs):
+ # ec2_id_list is passed in as a list of instances
+ ec2_id = ec2_id_list[0]
+ internal_id = ec2_id_to_internal_id(ec2_id)
+ instance_ref = db.instance_get_by_internal_id(context, internal_id)
output = rpc.call('%s.%s' % (FLAGS.compute_topic,
instance_ref['host']),
{ "method" : "get_console_output",
@@ -254,7 +270,7 @@ class CloudController(object):
"instance_id": instance_ref['id']}})
now = datetime.datetime.utcnow()
- return { "InstanceId" : instance_id,
+ return { "InstanceId" : ec2_id,
"Timestamp" : now,
"output" : base64.b64encode(output) }
@@ -331,7 +347,8 @@ class CloudController(object):
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_ec2_id(context, instance_id)
+ internal_id = ec2_id_to_internal_id(instance_id)
+ instance_ref = db.instance_get_by_internal_id(context, internal_id)
host = instance_ref['host']
rpc.cast(db.queue_get_for(context, FLAGS.compute_topic, host),
{"method": "attach_volume",
@@ -365,9 +382,11 @@ class CloudController(object):
# If the instance doesn't exist anymore,
# then we need to call detach blind
db.volume_detached(context)
+ internal_id = instance_ref['internal_id']
+ ec2_id = internal_id_to_ec2_id(internal_id)
return {'attachTime': volume_ref['attach_time'],
'device': volume_ref['mountpoint'],
- 'instanceId': instance_ref['ec2_id'],
+ 'instanceId': internal_id,
'requestId': context.request_id,
'status': volume_ref['attach_status'],
'volumeId': volume_ref['id']}
@@ -416,7 +435,9 @@ class CloudController(object):
if instance['image_id'] == FLAGS.vpn_image_id:
continue
i = {}
- i['instanceId'] = instance['ec2_id']
+ internal_id = instance['internal_id']
+ ec2_id = internal_id_to_ec2_id(internal_id)
+ i['instanceId'] = ec2_id
i['imageId'] = instance['image_id']
i['instanceState'] = {
'code': instance['state'],
@@ -469,9 +490,10 @@ class CloudController(object):
instance_id = None
if (floating_ip_ref['fixed_ip']
and floating_ip_ref['fixed_ip']['instance']):
- instance_id = floating_ip_ref['fixed_ip']['instance']['ec2_id']
+ internal_id = floating_ip_ref['fixed_ip']['instance']['ec2_id']
+ ec2_id = internal_id_to_ec2_id(internal_id)
address_rv = {'public_ip': address,
- 'instance_id': instance_id}
+ 'instance_id': ec2_id}
if context.user.is_admin():
details = "%s (%s)" % (address_rv['instance_id'],
floating_ip_ref['project_id'])
@@ -503,8 +525,9 @@ class CloudController(object):
"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_ec2_id(context, instance_id)
+ def associate_address(self, context, ec2_id, public_ip, **kwargs):
+ internal_id = ec2_id_to_internal_id(ec2_id)
+ instance_ref = db.instance_get_by_internal_id(context, internal_id)
fixed_address = db.instance_get_fixed_address(context,
instance_ref['id'])
floating_ip_ref = db.floating_ip_get_by_address(context, public_ip)
@@ -615,7 +638,9 @@ class CloudController(object):
inst = {}
inst['mac_address'] = utils.generate_mac()
inst['launch_index'] = num
- inst['hostname'] = instance_ref['ec2_id']
+ internal_id = instance_ref['internal_id']
+ ec2_id = internal_id_to_ec2_id(internal_id)
+ inst['hostname'] = ec2_id
db.instance_update(context, inst_id, inst)
address = self.network_manager.allocate_fixed_ip(context,
inst_id,
@@ -639,12 +664,14 @@ class CloudController(object):
return self._format_run_instances(context, reservation_id)
- def terminate_instances(self, context, instance_id, **kwargs):
+ def terminate_instances(self, context, ec2_id_list, **kwargs):
logging.debug("Going to start terminating instances")
- for id_str in instance_id:
+ for id_str in ec2_id_list:
+ internal_id = ec2_id_to_internal_id(id_str)
logging.debug("Going to try and terminate %s" % id_str)
try:
- instance_ref = db.instance_get_by_ec2_id(context, id_str)
+ instance_ref = db.instance_get_by_internal_id(context,
+ internal_id)
except exception.NotFound:
logging.warning("Instance %s was not found during terminate"
% id_str)
@@ -693,7 +720,7 @@ class CloudController(object):
cloud.reboot(id_str, context=context)
return True
- def update_instance(self, context, instance_id, **kwargs):
+ def update_instance(self, context, ec2_id, **kwargs):
updatable_fields = ['display_name', 'display_description']
changes = {}
for field in updatable_fields:
@@ -701,7 +728,8 @@ class CloudController(object):
changes[field] = kwargs[field]
if changes:
db_context = {}
- inst = db.instance_get_by_ec2_id(db_context, instance_id)
+ internal_id = ec2_id_to_internal_id(ec2_id)
+ inst = db.instance_get_by_internal_id(db_context, internal_id)
db.instance_update(db_context, inst['id'], kwargs)
return True
diff --git a/nova/api/rackspace/images.py b/nova/api/rackspace/images.py
index 4a7dd489c..d4ab8ce3c 100644
--- a/nova/api/rackspace/images.py
+++ b/nova/api/rackspace/images.py
@@ -17,12 +17,17 @@
from webob import exc
+from nova import flags
+from nova import utils
from nova import wsgi
from nova.api.rackspace import _id_translator
import nova.api.rackspace
import nova.image.service
from nova.api.rackspace import faults
+
+FLAGS = flags.FLAGS
+
class Controller(wsgi.Controller):
_serialization_metadata = {
@@ -35,7 +40,7 @@ class Controller(wsgi.Controller):
}
def __init__(self):
- self._service = nova.image.service.ImageService.load()
+ self._service = utils.import_object(FLAGS.image_service)
self._id_translator = _id_translator.RackspaceAPIIdTranslator(
"image", self._service.__class__.__name__)
diff --git a/nova/api/rackspace/servers.py b/nova/api/rackspace/servers.py
index 11efd8aef..b23867bbf 100644
--- a/nova/api/rackspace/servers.py
+++ b/nova/api/rackspace/servers.py
@@ -35,9 +35,6 @@ import nova.image.service
FLAGS = flags.FLAGS
-flags.DEFINE_string('rs_network_manager', 'nova.network.manager.FlatManager',
- 'Networking for rackspace')
-
def _instance_id_translator():
""" Helper method for initializing an id translator for Rackspace instance
ids """
@@ -45,7 +42,7 @@ def _instance_id_translator():
def _image_service():
""" Helper method for initializing the image id translator """
- service = nova.image.service.ImageService.load()
+ service = utils.import_object(FLAGS.image_service)
return (service, _id_translator.RackspaceAPIIdTranslator(
"image", service.__class__.__name__))
@@ -131,11 +128,8 @@ class Controller(wsgi.Controller):
def show(self, req, id):
""" Returns server details by server id """
- inst_id_trans = _instance_id_translator()
- inst_id = inst_id_trans.from_rs_id(id)
-
user_id = req.environ['nova.context']['user']['id']
- inst = self.db_driver.instance_get_by_ec2_id(None, inst_id)
+ inst = self.db_driver.instance_get_by_internal_id(None, int(id))
if inst:
if inst.user_id == user_id:
return _entity_detail(inst)
@@ -143,11 +137,8 @@ class Controller(wsgi.Controller):
def delete(self, req, id):
""" Destroys a server """
- inst_id_trans = _instance_id_translator()
- inst_id = inst_id_trans.from_rs_id(id)
-
user_id = req.environ['nova.context']['user']['id']
- instance = self.db_driver.instance_get_by_ec2_id(None, inst_id)
+ instance = self.db_driver.instance_get_by_internal_id(None, int(id))
if instance and instance['user_id'] == user_id:
self.db_driver.instance_destroy(None, id)
return faults.Fault(exc.HTTPAccepted())
@@ -160,10 +151,10 @@ class Controller(wsgi.Controller):
if not env:
return faults.Fault(exc.HTTPUnprocessableEntity())
- try:
- inst = self._build_server_instance(req, env)
- except Exception, e:
- return faults.Fault(exc.HTTPUnprocessableEntity())
+ #try:
+ inst = self._build_server_instance(req, env)
+ #except Exception, e:
+ # return faults.Fault(exc.HTTPUnprocessableEntity())
rpc.cast(
FLAGS.compute_topic, {
@@ -173,8 +164,6 @@ class Controller(wsgi.Controller):
def update(self, req, id):
""" Updates the server name or password """
- inst_id_trans = _instance_id_translator()
- inst_id = inst_id_trans.from_rs_id(id)
user_id = req.environ['nova.context']['user']['id']
inst_dict = self._deserialize(req.body, req)
@@ -182,11 +171,11 @@ class Controller(wsgi.Controller):
if not inst_dict:
return faults.Fault(exc.HTTPUnprocessableEntity())
- instance = self.db_driver.instance_get_by_ec2_id(None, inst_id)
+ instance = self.db_driver.instance_get_by_internal_id(None, int(id))
if not instance or instance.user_id != user_id:
return faults.Fault(exc.HTTPNotFound())
- self.db_driver.instance_update(None, id,
+ self.db_driver.instance_update(None, int(id),
_filter_params(inst_dict['server']))
return faults.Fault(exc.HTTPNoContent())
@@ -198,7 +187,7 @@ class Controller(wsgi.Controller):
reboot_type = input_dict['reboot']['type']
except Exception:
raise faults.Fault(webob.exc.HTTPNotImplemented())
- opaque_id = _instance_id_translator().from_rs_id(id)
+ opaque_id = _instance_id_translator().from_rs_id(int(id))
cloud.reboot(opaque_id)
def _build_server_instance(self, req, env):
@@ -206,8 +195,6 @@ class Controller(wsgi.Controller):
ltime = time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime())
inst = {}
- inst_id_trans = _instance_id_translator()
-
user_id = req.environ['nova.context']['user']['id']
flavor_id = env['server']['flavorId']
@@ -258,7 +245,7 @@ class Controller(wsgi.Controller):
inst['local_gb'] = flavor['local_gb']
ref = self.db_driver.instance_create(None, inst)
- inst['id'] = inst_id_trans.to_rs_id(ref.ec2_id)
+ inst['id'] = ref.internal_id
# TODO(dietz): this isn't explicitly necessary, but the networking
# calls depend on an object with a project_id property, and therefore
@@ -270,10 +257,10 @@ class Controller(wsgi.Controller):
#TODO(dietz) is this necessary?
inst['launch_index'] = 0
- inst['hostname'] = ref.ec2_id
+ inst['hostname'] = str(ref.internal_id)
self.db_driver.instance_update(None, inst['id'], inst)
- network_manager = utils.import_object(FLAGS.rs_network_manager)
+ network_manager = utils.import_object(FLAGS.network_manager)
address = network_manager.allocate_fixed_ip(api_context,
inst['id'])