summaryrefslogtreecommitdiffstats
path: root/nova/compute
diff options
context:
space:
mode:
authorTrey Morris <trey.morris@rackspace.com>2011-06-30 14:20:59 -0500
committerTrey Morris <trey.morris@rackspace.com>2011-06-30 14:20:59 -0500
commitfa8f7421f48a3bd1f6b01b2ff3cc754c24e0a424 (patch)
treea1cbb2835c9c8bd6ea9866115d4fb22c8b1b0aae /nova/compute
parent46c321d044d6a2db44a22466624a1e7dc71d5935 (diff)
parentc7ee39c3d00fdc799850b308fefd08f482edb5e5 (diff)
trunk merge with migration renumbering
Diffstat (limited to 'nova/compute')
-rw-r--r--nova/compute/api.py169
-rw-r--r--nova/compute/manager.py7
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)