summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWilliam Wolf <throughnothing@gmail.com>2011-08-18 22:24:31 -0400
committerWilliam Wolf <throughnothing@gmail.com>2011-08-18 22:24:31 -0400
commit254d45ac22c1f4f9cb6e6b02e7a416e5d94f401e (patch)
tree1b20bd870c3e710803c9e6c1d386bc1c1ed392f4
parenta711bf61b274eb38face3957549acd4ee3c9b6a1 (diff)
parent2d21bd0fdd392d9b3b79876c4962bf2757a3e679 (diff)
merge
-rw-r--r--nova/api/openstack/auth.py1
-rw-r--r--nova/api/openstack/contrib/security_groups.py2
-rw-r--r--nova/api/openstack/create_instance_helper.py2
-rw-r--r--nova/compute/api.py12
-rw-r--r--nova/compute/manager.py6
-rw-r--r--nova/db/sqlalchemy/api.py3
-rw-r--r--nova/db/sqlalchemy/migrate_repo/versions/037_instances_drop_admin_pass.py37
-rw-r--r--nova/db/sqlalchemy/models.py1
-rw-r--r--nova/tests/test_cloud.py11
-rw-r--r--nova/tests/test_db_api.py17
-rw-r--r--nova/tests/test_libvirt.py1
-rw-r--r--nova/tests/test_metadata.py40
-rw-r--r--nova/virt/xenapi/vmops.py3
13 files changed, 123 insertions, 13 deletions
diff --git a/nova/api/openstack/auth.py b/nova/api/openstack/auth.py
index d14553cd4..b6ff1126b 100644
--- a/nova/api/openstack/auth.py
+++ b/nova/api/openstack/auth.py
@@ -113,7 +113,6 @@ class AuthMiddleware(wsgi.Middleware):
LOG.warn(msg)
return faults.Fault(webob.exc.HTTPUnauthorized(explanation=msg))
- # Gabe did this.
def _get_auth_header(key):
"""Ensures that the KeyError returned is meaningful."""
try:
diff --git a/nova/api/openstack/contrib/security_groups.py b/nova/api/openstack/contrib/security_groups.py
index d1230df69..6c57fbb51 100644
--- a/nova/api/openstack/contrib/security_groups.py
+++ b/nova/api/openstack/contrib/security_groups.py
@@ -458,7 +458,7 @@ class SecurityGroupRulesXMLDeserializer(wsgi.MetadataXMLDeserializer):
def _get_metadata():
metadata = {
"attributes": {
- "security_group": ["id", "project_id", "name"],
+ "security_group": ["id", "tenant_id", "name"],
"rule": ["id", "parent_group_id"],
"security_group_rule": ["id", "parent_group_id"],
}
diff --git a/nova/api/openstack/create_instance_helper.py b/nova/api/openstack/create_instance_helper.py
index b4a08dac0..978741682 100644
--- a/nova/api/openstack/create_instance_helper.py
+++ b/nova/api/openstack/create_instance_helper.py
@@ -122,6 +122,7 @@ class CreateInstanceHelper(object):
raise exc.HTTPBadRequest(explanation=msg)
zone_blob = server_dict.get('blob')
+ user_data = server_dict.get('user_data')
availability_zone = server_dict.get('availability_zone')
name = server_dict['name']
self._validate_server_name(name)
@@ -163,6 +164,7 @@ class CreateInstanceHelper(object):
reservation_id=reservation_id,
min_count=min_count,
max_count=max_count,
+ user_data=user_data,
availability_zone=availability_zone))
except quota.QuotaError as error:
self._handle_quota_error(error)
diff --git a/nova/compute/api.py b/nova/compute/api.py
index e909e9959..b3932c644 100644
--- a/nova/compute/api.py
+++ b/nova/compute/api.py
@@ -1068,15 +1068,21 @@ class API(base.Base):
"""Unpause the given instance."""
self._cast_compute_message('unpause_instance', context, instance_id)
+ def _call_compute_message_for_host(self, action, context, host, params):
+ """Call method deliberately designed to make host/service only calls"""
+ queue = self.db.queue_get_for(context, FLAGS.compute_topic, host)
+ kwargs = {'method': action, 'args': params}
+ return rpc.call(context, queue, kwargs)
+
def set_host_enabled(self, context, host, enabled):
"""Sets the specified host's ability to accept new instances."""
- return self._call_compute_message("set_host_enabled", context,
+ return self._call_compute_message_for_host("set_host_enabled", context,
host=host, params={"enabled": enabled})
def host_power_action(self, context, host, action):
"""Reboots, shuts down or powers up the host."""
- return self._call_compute_message("host_power_action", context,
- host=host, params={"action": action})
+ return self._call_compute_message_for_host("host_power_action",
+ context, host=host, params={"action": action})
@scheduler_api.reroute_compute("diagnostics")
def get_diagnostics(self, context, instance_id):
diff --git a/nova/compute/manager.py b/nova/compute/manager.py
index 66458fb36..091b3b6b2 100644
--- a/nova/compute/manager.py
+++ b/nova/compute/manager.py
@@ -392,12 +392,12 @@ class ComputeManager(manager.SchedulerDependentManager):
updates = {}
updates['host'] = self.host
updates['launched_on'] = self.host
- # NOTE(vish): used by virt but not in database
- updates['injected_files'] = kwargs.get('injected_files', [])
- updates['admin_pass'] = kwargs.get('admin_password', None)
instance = self.db.instance_update(context,
instance_id,
updates)
+ instance['injected_files'] = kwargs.get('injected_files', [])
+ instance['admin_pass'] = kwargs.get('admin_password', None)
+
self.db.instance_set_state(context,
instance_id,
power_state.NOSTATE,
diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py
index 95ec3f715..fe80056ab 100644
--- a/nova/db/sqlalchemy/api.py
+++ b/nova/db/sqlalchemy/api.py
@@ -1222,7 +1222,8 @@ def instance_get_all_by_filters(context, filters):
options(joinedload('security_groups')).\
options(joinedload_all('fixed_ips.network')).\
options(joinedload('metadata')).\
- options(joinedload('instance_type'))
+ options(joinedload('instance_type')).\
+ filter_by(deleted=can_read_deleted(context))
# Make a copy of the filters dictionary to use going forward, as we'll
# be modifying it and we shouldn't affect the caller's use of it.
diff --git a/nova/db/sqlalchemy/migrate_repo/versions/037_instances_drop_admin_pass.py b/nova/db/sqlalchemy/migrate_repo/versions/037_instances_drop_admin_pass.py
new file mode 100644
index 000000000..b957666c2
--- /dev/null
+++ b/nova/db/sqlalchemy/migrate_repo/versions/037_instances_drop_admin_pass.py
@@ -0,0 +1,37 @@
+# Copyright 2011 OpenStack LLC.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from sqlalchemy import Column, MetaData, Table, String
+
+meta = MetaData()
+
+admin_pass = Column(
+ 'admin_pass',
+ String(length=255, convert_unicode=False, assert_unicode=None,
+ unicode_error=None, _warn_on_bytestring=False),
+ nullable=True)
+
+
+def upgrade(migrate_engine):
+ meta.bind = migrate_engine
+ instances = Table('instances', meta, autoload=True,
+ autoload_with=migrate_engine)
+ instances.drop_column('admin_pass')
+
+
+def downgrade(migrate_engine):
+ meta.bind = migrate_engine
+ instances = Table('instances', meta, autoload=True,
+ autoload_with=migrate_engine)
+ instances.create_column(admin_pass)
diff --git a/nova/db/sqlalchemy/models.py b/nova/db/sqlalchemy/models.py
index f2a4680b0..a8e9c36db 100644
--- a/nova/db/sqlalchemy/models.py
+++ b/nova/db/sqlalchemy/models.py
@@ -173,7 +173,6 @@ class Instance(BASE, NovaBase):
base_name += "-rescue"
return base_name
- admin_pass = Column(String(255))
user_id = Column(String(255))
project_id = Column(String(255))
diff --git a/nova/tests/test_cloud.py b/nova/tests/test_cloud.py
index b2afc53c9..0793784f8 100644
--- a/nova/tests/test_cloud.py
+++ b/nova/tests/test_cloud.py
@@ -487,6 +487,17 @@ class CloudTestCase(test.TestCase):
db.service_destroy(self.context, comp1['id'])
db.service_destroy(self.context, comp2['id'])
+ def test_describe_instances_deleted(self):
+ args1 = {'reservation_id': 'a', 'image_ref': 1, 'host': 'host1'}
+ inst1 = db.instance_create(self.context, args1)
+ args2 = {'reservation_id': 'b', 'image_ref': 1, 'host': 'host1'}
+ inst2 = db.instance_create(self.context, args2)
+ db.instance_destroy(self.context, inst1.id)
+ result = self.cloud.describe_instances(self.context)
+ result = result['reservationSet'][0]['instancesSet']
+ self.assertEqual(result[0]['instanceId'],
+ ec2utils.id_to_ec2_id(inst2.id))
+
def _block_device_mapping_create(self, instance_id, mappings):
volumes = []
for bdm in mappings:
diff --git a/nova/tests/test_db_api.py b/nova/tests/test_db_api.py
index 0c07cbb7c..038c07f40 100644
--- a/nova/tests/test_db_api.py
+++ b/nova/tests/test_db_api.py
@@ -76,3 +76,20 @@ class DbApiTestCase(test.TestCase):
self.assertEqual(instance['id'], result['id'])
self.assertEqual(result['fixed_ips'][0]['floating_ips'][0].address,
'1.2.1.2')
+
+ def test_instance_get_all_by_filters(self):
+ args = {'reservation_id': 'a', 'image_ref': 1, 'host': 'host1'}
+ inst1 = db.instance_create(self.context, args)
+ inst2 = db.instance_create(self.context, args)
+ result = db.instance_get_all_by_filters(self.context, {})
+ self.assertTrue(2, len(result))
+
+ def test_instance_get_all_by_filters_deleted(self):
+ args1 = {'reservation_id': 'a', 'image_ref': 1, 'host': 'host1'}
+ inst1 = db.instance_create(self.context, args1)
+ args2 = {'reservation_id': 'b', 'image_ref': 1, 'host': 'host1'}
+ inst2 = db.instance_create(self.context, args2)
+ db.instance_destroy(self.context, inst1.id)
+ result = db.instance_get_all_by_filters(self.context.elevated(), {})
+ self.assertEqual(1, len(result))
+ self.assertEqual(result[0].id, inst2.id)
diff --git a/nova/tests/test_libvirt.py b/nova/tests/test_libvirt.py
index 688518bb8..6a213b4f0 100644
--- a/nova/tests/test_libvirt.py
+++ b/nova/tests/test_libvirt.py
@@ -836,6 +836,7 @@ class LibvirtConnTestCase(test.TestCase):
count = (0 <= str(e.message).find('Unexpected method call'))
shutil.rmtree(os.path.join(FLAGS.instances_path, instance.name))
+ shutil.rmtree(os.path.join(FLAGS.instances_path, '_base'))
self.assertTrue(count)
diff --git a/nova/tests/test_metadata.py b/nova/tests/test_metadata.py
index bfc7a6d44..b06e5c136 100644
--- a/nova/tests/test_metadata.py
+++ b/nova/tests/test_metadata.py
@@ -23,12 +23,21 @@ import httplib
import webob
+from nova import exception
from nova import test
from nova import wsgi
from nova.api.ec2 import metadatarequesthandler
from nova.db.sqlalchemy import api
+USER_DATA_STRING = ("This is an encoded string")
+ENCODE_USER_DATA_STRING = base64.b64encode(USER_DATA_STRING)
+
+
+def return_non_existing_server_by_address(context, address):
+ raise exception.NotFound()
+
+
class MetadataTestCase(test.TestCase):
"""Test that metadata is returning proper values."""
@@ -79,3 +88,34 @@ class MetadataTestCase(test.TestCase):
self.stubs.Set(api, 'security_group_get_by_instance', sg_get)
self.assertEqual(self.request('/meta-data/security-groups'),
'default\nother')
+
+ def test_user_data_non_existing_fixed_address(self):
+ self.stubs.Set(api, 'instance_get_all_by_filters',
+ return_non_existing_server_by_address)
+ request = webob.Request.blank('/user-data')
+ request.remote_addr = "127.1.1.1"
+ response = request.get_response(self.app)
+ self.assertEqual(response.status_int, 404)
+
+ def test_user_data_none_fixed_address(self):
+ self.stubs.Set(api, 'instance_get_all_by_filters',
+ return_non_existing_server_by_address)
+ request = webob.Request.blank('/user-data')
+ request.remote_addr = None
+ response = request.get_response(self.app)
+ self.assertEqual(response.status_int, 500)
+
+ def test_user_data_invalid_url(self):
+ request = webob.Request.blank('/user-data-invalid')
+ request.remote_addr = "127.0.0.1"
+ response = request.get_response(self.app)
+ self.assertEqual(response.status_int, 404)
+
+ def test_user_data_with_use_forwarded_header(self):
+ self.instance['user_data'] = ENCODE_USER_DATA_STRING
+ self.flags(use_forwarded_for=True)
+ request = webob.Request.blank('/user-data')
+ request.remote_addr = "127.0.0.1"
+ response = request.get_response(self.app)
+ self.assertEqual(response.status_int, 200)
+ self.assertEqual(response.body, USER_DATA_STRING)
diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py
index eb0a846b5..9a6215f88 100644
--- a/nova/virt/xenapi/vmops.py
+++ b/nova/virt/xenapi/vmops.py
@@ -709,9 +709,6 @@ class VMOps(object):
if resp['returncode'] != '0':
LOG.error(_('Failed to update password: %(resp)r') % locals())
return None
- db.instance_update(nova_context.get_admin_context(),
- instance['id'],
- dict(admin_pass=new_pass))
return resp['message']
def inject_file(self, instance, path, contents):