diff options
| author | Soren Hansen <soren.hansen@rackspace.com> | 2010-10-08 21:41:11 +0200 |
|---|---|---|
| committer | Soren Hansen <soren.hansen@rackspace.com> | 2010-10-08 21:41:11 +0200 |
| commit | 5be81520196c21aa9b60425bca7bf49935772cd1 (patch) | |
| tree | b2abb4d185d9c0ebfbb145f92fddc2bb201f3361 /nova/api | |
| parent | 5a5da05a966dcdd3113a074468b37e12d406b350 (diff) | |
| parent | d58da66e2958ff3bb32c8f764c90526be5c601af (diff) | |
Merge trunk.
Diffstat (limited to 'nova/api')
| -rw-r--r-- | nova/api/cloud.py | 2 | ||||
| -rw-r--r-- | nova/api/ec2/cloud.py | 64 | ||||
| -rw-r--r-- | nova/api/rackspace/images.py | 7 | ||||
| -rw-r--r-- | nova/api/rackspace/servers.py | 39 |
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']) |
