summaryrefslogtreecommitdiffstats
path: root/nova/compute
diff options
context:
space:
mode:
authorCerberus <matt.dietz@rackspace.com>2011-02-18 16:45:31 -0600
committerCerberus <matt.dietz@rackspace.com>2011-02-18 16:45:31 -0600
commit201391007e58b2f92fd7b56ccbf308e5909da7c0 (patch)
tree7965568a97336d0817f47035504ec79bcf488a70 /nova/compute
parenta43c5929de7ebf58eb9ecb8416ce3cf4194c176a (diff)
parent8de8d1d045ca9fe12596e53d2244f4f8703cc209 (diff)
downloadnova-201391007e58b2f92fd7b56ccbf308e5909da7c0.tar.gz
nova-201391007e58b2f92fd7b56ccbf308e5909da7c0.tar.xz
nova-201391007e58b2f92fd7b56ccbf308e5909da7c0.zip
Merge from trunk and merge conflict resolution
Diffstat (limited to 'nova/compute')
-rw-r--r--nova/compute/api.py15
-rw-r--r--nova/compute/manager.py61
2 files changed, 49 insertions, 27 deletions
diff --git a/nova/compute/api.py b/nova/compute/api.py
index 2eb0e0743..60ae3876e 100644
--- a/nova/compute/api.py
+++ b/nova/compute/api.py
@@ -85,10 +85,11 @@ class API(base.Base):
min_count=1, max_count=1,
display_name='', display_description='',
key_name=None, key_data=None, security_group='default',
- availability_zone=None, user_data=None):
+ availability_zone=None, user_data=None,
+ onset_files=None):
"""Create the number of instances requested if quota and
- other arguments check out ok."""
-
+ other arguments check out ok.
+ """
type_data = instance_types.INSTANCE_TYPES[instance_type]
num_instances = quota.allowed_instances(context, max_count, type_data)
if num_instances < min_count:
@@ -156,7 +157,6 @@ class API(base.Base):
'key_data': key_data,
'locked': False,
'availability_zone': availability_zone}
-
elevated = context.elevated()
instances = []
LOG.debug(_("Going to run %s instances..."), num_instances)
@@ -193,7 +193,8 @@ class API(base.Base):
{"method": "run_instance",
"args": {"topic": FLAGS.compute_topic,
"instance_id": instance_id,
- "availability_zone": availability_zone}})
+ "availability_zone": availability_zone,
+ "onset_files": onset_files}})
for group_id in security_groups:
self.trigger_security_group_members_refresh(elevated, group_id)
@@ -477,6 +478,10 @@ class API(base.Base):
"""Set the root/admin password for the given instance."""
self._cast_compute_message('set_admin_password', context, instance_id)
+ def inject_file(self, context, instance_id):
+ """Write a file to the given instance."""
+ self._cast_compute_message('inject_file', context, instance_id)
+
def get_ajax_console(self, context, instance_id):
"""Get a url to an AJAX Console"""
instance = self.get(context, instance_id)
diff --git a/nova/compute/manager.py b/nova/compute/manager.py
index 3f6c359ba..b3b66b3e3 100644
--- a/nova/compute/manager.py
+++ b/nova/compute/manager.py
@@ -34,6 +34,7 @@ terminating it.
:func:`nova.utils.import_object`
"""
+import base64
import datetime
import random
import string
@@ -130,7 +131,7 @@ class ComputeManager(manager.Manager):
state = power_state.FAILED
self.db.instance_set_state(context, instance_id, state)
- def get_console_topic(self, context, **_kwargs):
+ def get_console_topic(self, context, **kwargs):
"""Retrieves the console host for a project on this host
Currently this is just set in the flags for each compute
host."""
@@ -139,7 +140,7 @@ class ComputeManager(manager.Manager):
FLAGS.console_topic,
FLAGS.console_host)
- def get_network_topic(self, context, **_kwargs):
+ def get_network_topic(self, context, **kwargs):
"""Retrieves the network host for a project on this host"""
# TODO(vish): This method should be memoized. This will make
# the call to get_network_host cheaper, so that
@@ -158,21 +159,22 @@ class ComputeManager(manager.Manager):
@exception.wrap_exception
def refresh_security_group_rules(self, context,
- security_group_id, **_kwargs):
+ security_group_id, **kwargs):
"""This call passes straight through to the virtualization driver."""
return self.driver.refresh_security_group_rules(security_group_id)
@exception.wrap_exception
def refresh_security_group_members(self, context,
- security_group_id, **_kwargs):
+ security_group_id, **kwargs):
"""This call passes straight through to the virtualization driver."""
return self.driver.refresh_security_group_members(security_group_id)
@exception.wrap_exception
- def run_instance(self, context, instance_id, **_kwargs):
+ def run_instance(self, context, instance_id, **kwargs):
"""Launch a new instance with specified options."""
context = context.elevated()
instance_ref = self.db.instance_get(context, instance_id)
+ instance_ref.onset_files = kwargs.get('onset_files', [])
if instance_ref['name'] in self.driver.list_instances():
raise exception.Error(_("Instance has already been created"))
LOG.audit(_("instance %s: starting..."), instance_id,
@@ -323,28 +325,43 @@ class ComputeManager(manager.Manager):
"""Set the root/admin password for an instance on this server."""
context = context.elevated()
instance_ref = self.db.instance_get(context, instance_id)
- if instance_ref['state'] != power_state.RUNNING:
- logging.warn('trying to reset the password on a non-running '
- 'instance: %s (state: %s expected: %s)',
- instance_ref['id'],
- instance_ref['state'],
- power_state.RUNNING)
-
- logging.debug('instance %s: setting admin password',
+ instance_id = instance_ref['id']
+ instance_state = instance_ref['state']
+ expected_state = power_state.RUNNING
+ if instance_state != expected_state:
+ LOG.warn(_('trying to reset the password on a non-running '
+ 'instance: %(instance_id)s (state: %(instance_state)s '
+ 'expected: %(expected_state)s)') % locals())
+ LOG.audit(_('instance %s: setting admin password'),
instance_ref['name'])
if new_pass is None:
# Generate a random password
- new_pass = self._generate_password(FLAGS.password_length)
-
+ new_pass = utils.generate_password(FLAGS.password_length)
self.driver.set_admin_password(instance_ref, new_pass)
self._update_state(context, instance_id)
- def _generate_password(self, length=20):
- """Generate a random sequence of letters and digits
- to be used as a password.
- """
- chrs = string.letters + string.digits
- return "".join([random.choice(chrs) for i in xrange(length)])
+ @exception.wrap_exception
+ @checks_instance_lock
+ def inject_file(self, context, instance_id, path, file_contents):
+ """Write a file to the specified path on an instance on this server"""
+ context = context.elevated()
+ instance_ref = self.db.instance_get(context, instance_id)
+ instance_id = instance_ref['id']
+ instance_state = instance_ref['state']
+ expected_state = power_state.RUNNING
+ if instance_state != expected_state:
+ LOG.warn(_('trying to inject a file into a non-running '
+ 'instance: %(instance_id)s (state: %(instance_state)s '
+ 'expected: %(expected_state)s)') % locals())
+ # Files/paths *should* be base64-encoded at this point, but
+ # double-check to make sure.
+ b64_path = utils.ensure_b64_encoding(path)
+ b64_contents = utils.ensure_b64_encoding(file_contents)
+ plain_path = base64.b64decode(b64_path)
+ nm = instance_ref['name']
+ msg = _('instance %(nm)s: injecting file to %(plain_path)s') % locals()
+ LOG.audit(msg)
+ self.driver.inject_file(instance_ref, b64_path, b64_contents)
@exception.wrap_exception
@checks_instance_lock
@@ -629,7 +646,7 @@ class ComputeManager(manager.Manager):
def get_ajax_console(self, context, instance_id):
"""Return connection information for an ajax console"""
context = context.elevated()
- logging.debug(_("instance %s: getting ajax console"), instance_id)
+ LOG.debug(_("instance %s: getting ajax console"), instance_id)
instance_ref = self.db.instance_get(context, instance_id)
return self.driver.get_ajax_console(instance_ref)