diff options
| author | Trey Morris <trey.morris@rackspace.com> | 2011-06-30 14:20:59 -0500 |
|---|---|---|
| committer | Trey Morris <trey.morris@rackspace.com> | 2011-06-30 14:20:59 -0500 |
| commit | fa8f7421f48a3bd1f6b01b2ff3cc754c24e0a424 (patch) | |
| tree | a1cbb2835c9c8bd6ea9866115d4fb22c8b1b0aae /nova/compute | |
| parent | 46c321d044d6a2db44a22466624a1e7dc71d5935 (diff) | |
| parent | c7ee39c3d00fdc799850b308fefd08f482edb5e5 (diff) | |
trunk merge with migration renumbering
Diffstat (limited to 'nova/compute')
| -rw-r--r-- | nova/compute/api.py | 169 | ||||
| -rw-r--r-- | nova/compute/manager.py | 7 |
2 files changed, 106 insertions, 70 deletions
diff --git a/nova/compute/api.py b/nova/compute/api.py index ce315e23c..28459dc75 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -48,9 +48,27 @@ flags.DEFINE_integer('find_host_timeout', 30, 'Timeout after NN seconds when looking for a host.') -def generate_default_hostname(instance_id): +def generate_default_hostname(instance): """Default function to generate a hostname given an instance reference.""" - return str(instance_id) + display_name = instance['display_name'] + if display_name is None: + return 'server_%d' % (instance['id'],) + table = '' + deletions = '' + for i in xrange(256): + c = chr(i) + if ('a' <= c <= 'z') or ('0' <= c <= '9') or (c == '-'): + table += c + elif c == ' ': + table += '_' + elif ('A' <= c <= 'Z'): + table += c.lower() + else: + table += '\0' + deletions += c + if isinstance(display_name, unicode): + display_name = display_name.encode('latin-1', 'ignore') + return display_name.translate(table, deletions) def _is_able_to_shutdown(instance, instance_id): @@ -126,7 +144,7 @@ class API(base.Base): def _check_create_parameters(self, context, instance_type, image_href, kernel_id=None, ramdisk_id=None, - min_count=1, max_count=1, + min_count=None, max_count=None, display_name='', display_description='', key_name=None, key_data=None, security_group='default', availability_zone=None, user_data=None, metadata={}, @@ -137,6 +155,10 @@ class API(base.Base): if not instance_type: instance_type = instance_types.get_default_instance_type() + if not min_count: + min_count = 1 + if not max_count: + max_count = min_count num_instances = quota.allowed_instances(context, max_count, instance_type) @@ -186,18 +208,7 @@ class API(base.Base): if ramdisk_id: image_service.show(context, ramdisk_id) - if security_group is None: - security_group = ['default'] - if not type(security_group) is list: - security_group = [security_group] - - security_groups = [] self.ensure_default_security_group(context) - for security_group_name in security_group: - group = db.security_group_get_by_name(context, - context.project_id, - security_group_name) - security_groups.append(group['id']) if key_data is None and key_name: key_pair = db.key_pair_get(context, context.user_id, key_name) @@ -232,28 +243,42 @@ class API(base.Base): 'architecture': architecture, 'vm_mode': vm_mode} - return (num_instances, base_options, security_groups) + return (num_instances, base_options) def create_db_entry_for_new_instance(self, context, base_options, - security_groups, block_device_mapping, num=1): + security_group, block_device_mapping, num=1): """Create an entry in the DB for this new instance, - including any related table updates (such as security - groups, MAC address, etc). This will called by create() - in the majority of situations, but all-at-once style - Schedulers may initiate the call.""" - instance = dict(launch_index=num, - **base_options) + including any related table updates (such as security group, + etc). + + This will called by create() in the majority of situations, + but create_all_at_once() style Schedulers may initiate the call. + If you are changing this method, be sure to update both + call paths. + """ + instance = dict(launch_index=num, **base_options) instance = self.db.instance_create(context, instance) instance_id = instance['id'] elevated = context.elevated() - if not security_groups: - security_groups = [] + if security_group is None: + security_group = ['default'] + if not isinstance(security_group, list): + security_group = [security_group] + + security_groups = [] + for security_group_name in security_group: + group = db.security_group_get_by_name(context, + context.project_id, + security_group_name) + security_groups.append(group['id']) + for security_group_id in security_groups: self.db.instance_add_security_group(elevated, instance_id, security_group_id) + block_device_mapping = block_device_mapping or [] # NOTE(yamahata) # tell vm driver to attach volume at boot time by updating # BlockDeviceMapping @@ -272,10 +297,12 @@ class API(base.Base): self.db.block_device_mapping_create(elevated, values) # Set sane defaults if not specified - updates = dict(hostname=self.hostname_factory(instance_id)) + updates = {} if (not hasattr(instance, 'display_name') or instance.display_name is None): updates['display_name'] = "Server %s" % instance_id + instance['display_name'] = updates['display_name'] + updates['hostname'] = self.hostname_factory(instance) instance = self.update(context, instance_id, **updates) @@ -320,17 +347,16 @@ class API(base.Base): def create_all_at_once(self, context, instance_type, image_href, kernel_id=None, ramdisk_id=None, - min_count=1, max_count=1, + min_count=None, max_count=None, display_name='', display_description='', key_name=None, key_data=None, security_group='default', availability_zone=None, user_data=None, metadata={}, injected_files=None, admin_password=None, zone_blob=None, - reservation_id=None): + reservation_id=None, block_device_mapping=None): """Provision the instances by passing the whole request to the Scheduler for execution. Returns a Reservation ID related to the creation of all of these instances.""" - num_instances, base_options, security_groups = \ - self._check_create_parameters( + num_instances, base_options = self._check_create_parameters( context, instance_type, image_href, kernel_id, ramdisk_id, min_count, max_count, @@ -350,7 +376,7 @@ class API(base.Base): def create(self, context, instance_type, image_href, kernel_id=None, ramdisk_id=None, - min_count=1, max_count=1, + min_count=None, max_count=None, display_name='', display_description='', key_name=None, key_data=None, security_group='default', availability_zone=None, user_data=None, metadata={}, @@ -362,11 +388,13 @@ class API(base.Base): Scheduler drivers, but may remove the effectiveness of the more complicated drivers. + NOTE: If you change this method, be sure to change + create_all_at_once() at the same time! + Returns a list of instance dicts. """ - num_instances, base_options, security_groups = \ - self._check_create_parameters( + num_instances, base_options = self._check_create_parameters( context, instance_type, image_href, kernel_id, ramdisk_id, min_count, max_count, @@ -376,12 +404,11 @@ class API(base.Base): injected_files, admin_password, zone_blob, reservation_id) - block_device_mapping = block_device_mapping or [] instances = [] LOG.debug(_("Going to run %s instances..."), num_instances) for num in range(num_instances): instance = self.create_db_entry_for_new_instance(context, - base_options, security_groups, + base_options, security_group, block_device_mapping, num=num) instances.append(instance) instance_id = instance['id'] @@ -595,50 +622,60 @@ class API(base.Base): """ return self.get(context, instance_id) - def get_all_across_zones(self, context, reservation_id): - """Get all instances with this reservation_id, across - all available Zones (if any). - """ - context = context.elevated() - instances = self.db.instance_get_all_by_reservation( - context, reservation_id) - - children = scheduler_api.call_zone_method(context, "list", - novaclient_collection_name="servers", - reservation_id=reservation_id) - - for zone, servers in children: - for server in servers: - # Results are ready to send to user. No need to scrub. - server._info['_is_precooked'] = True - instances.append(server._info) - return instances - def get_all(self, context, project_id=None, reservation_id=None, - fixed_ip=None): + fixed_ip=None, recurse_zones=False): """Get all instances filtered by one of the given parameters. If there is no filter and the context is an admin, it will retreive all instances in the system. """ - if reservation_id is not None: - return self.get_all_across_zones(context, reservation_id) - - if fixed_ip is not None: - return self.db.fixed_ip_get_instance(context, fixed_ip) - if project_id or not context.is_admin: + if reservation_id is not None: + recurse_zones = True + instances = self.db.instance_get_all_by_reservation( + context, reservation_id) + elif fixed_ip is not None: + try: + instances = self.db.fixed_ip_get_instance(context, fixed_ip) + except exception.FloatingIpNotFound, e: + if not recurse_zones: + raise + instances = None + elif project_id or not context.is_admin: if not context.project: - return self.db.instance_get_all_by_user( + instances = self.db.instance_get_all_by_user( context, context.user_id) + else: + if project_id is None: + project_id = context.project_id + instances = self.db.instance_get_all_by_project( + context, project_id) + else: + instances = self.db.instance_get_all(context) + + if instances is None: + instances = [] + elif not isinstance(instances, list): + instances = [instances] - if project_id is None: - project_id = context.project_id + if not recurse_zones: + return instances - return self.db.instance_get_all_by_project( - context, project_id) + admin_context = context.elevated() + children = scheduler_api.call_zone_method(admin_context, + "list", + novaclient_collection_name="servers", + reservation_id=reservation_id, + project_id=project_id, + fixed_ip=fixed_ip, + recurse_zones=True) - return self.db.instance_get_all(context) + for zone, servers in children: + for server in servers: + # Results are ready to send to user. No need to scrub. + server._info['_is_precooked'] = True + instances.append(server._info) + return instances def _cast_compute_message(self, method, context, instance_id, host=None, params=None): diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 67fe1921f..bbbddde0a 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -50,7 +50,6 @@ import nova.image from nova import log as logging from nova import manager from nova import network -from nova import notifier from nova import rpc from nova import utils from nova import volume @@ -1153,7 +1152,7 @@ class ComputeManager(manager.SchedulerDependentManager): # Getting instance info instance_ref = self.db.instance_get(context, instance_id) - ec2_id = instance_ref['hostname'] + hostname = instance_ref['hostname'] # Getting fixed ips fixed_ips = self.db.instance_get_fixed_addresses(context, instance_id) @@ -1162,7 +1161,7 @@ class ComputeManager(manager.SchedulerDependentManager): # If any volume is mounted, prepare here. if not instance_ref['volumes']: - LOG.info(_("%s has no volume."), ec2_id) + LOG.info(_("%s has no volume."), hostname) else: for v in instance_ref['volumes']: self.volume_manager.setup_compute_volume(context, v['id']) @@ -1185,7 +1184,7 @@ class ComputeManager(manager.SchedulerDependentManager): raise else: LOG.warn(_("setup_compute_network() failed %(cnt)d." - "Retry up to %(max_retry)d for %(ec2_id)s.") + "Retry up to %(max_retry)d for %(hostname)s.") % locals()) time.sleep(1) |
