diff --git a/bin/nova-objectstore b/bin/nova-objectstore index 9385fd29..c0fa815c 100755 --- a/bin/nova-objectstore +++ b/bin/nova-objectstore @@ -21,8 +21,6 @@ Twisted daemon for nova objectstore. Supports S3 API. """ -import logging - from nova import flags from nova import utils from nova import twistd @@ -33,9 +31,6 @@ FLAGS = flags.FLAGS def main(): - # FIXME: if this log statement isn't here, no logging - # appears from other files and app won't start daemonized - logging.debug('Started HTTP server on %s' % (FLAGS.s3_port)) app = handler.get_application() print app return app diff --git a/nova/adminclient.py b/nova/adminclient.py index fceeac27..25d5e71c 100644 --- a/nova/adminclient.py +++ b/nova/adminclient.py @@ -292,9 +292,13 @@ class NovaAdminClient(object): 'Operation': operation} return self.apiconn.get_status('ModifyProjectMember', params) - def get_zip(self, username): - """ returns the content of a zip file containing novarc and access credentials. """ - return self.apiconn.get_object('GenerateX509ForUser', {'Name': username}, UserInfo).file + def get_zip(self, user, project): + """ + Returns the content of a zip file containing novarc and access credentials. + """ + params = {'Name': user, 'Project': project} + zip = self.apiconn.get_object('GenerateX509ForUser', params, UserInfo) + return zip.file def get_hosts(self): return self.apiconn.get_list('DescribeHosts', {}, [('item', HostInfo)]) diff --git a/nova/auth/manager.py b/nova/auth/manager.py index cf920d60..d44ed52b 100644 --- a/nova/auth/manager.py +++ b/nova/auth/manager.py @@ -24,7 +24,6 @@ import logging import os import shutil import string -import sys import tempfile import uuid import zipfile @@ -239,8 +238,7 @@ class AuthManager(object): def __new__(cls, *args, **kwargs): """Returns the AuthManager singleton""" if not cls._instance: - cls._instance = super(AuthManager, cls).__new__( - cls, *args, **kwargs) + cls._instance = super(AuthManager, cls).__new__(cls) return cls._instance def __init__(self, driver=None, *args, **kwargs): @@ -333,6 +331,12 @@ class AuthManager(object): raise exception.NotAuthorized('Signature does not match') return (user, project) + def get_access_key(self, user, project): + """Get an access key that includes user and project""" + if not isinstance(user, User): + user = self.get_user(user) + return "%s:%s" % (user.access, Project.safe_id(project)) + def is_superuser(self, user): """Checks for superuser status, allowing user to bypass rbac diff --git a/nova/auth/signer.py b/nova/auth/signer.py index 7d747157..634f22f0 100644 --- a/nova/auth/signer.py +++ b/nova/auth/signer.py @@ -34,7 +34,7 @@ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- # ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT -# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS # IN THE SOFTWARE. @@ -48,7 +48,8 @@ import hashlib import hmac import logging import urllib -import boto.utils +import boto # NOTE(vish): for new boto +import boto.utils # NOTE(vish): for old boto from nova.exception import Error diff --git a/nova/endpoint/cloud.py b/nova/endpoint/cloud.py index 00dabba2..23ad85cd 100644 --- a/nova/endpoint/cloud.py +++ b/nova/endpoint/cloud.py @@ -294,17 +294,16 @@ class CloudController(object): return v @rbac.allow('projectmanager', 'sysadmin') + @defer.inlineCallbacks def create_volume(self, context, size, **kwargs): # TODO(vish): refactor this to create the volume object here and tell service to create it - res = rpc.call(FLAGS.volume_topic, {"method": "create_volume", + result = yield rpc.call(FLAGS.volume_topic, {"method": "create_volume", "args" : {"size": size, "user_id": context.user.id, "project_id": context.project.id}}) - def _format_result(result): - volume = self._get_volume(context, result['result']) - return {'volumeSet': [self.format_volume(context, volume)]} - res.addCallback(_format_result) - return res + # NOTE(vish): rpc returned value is in the result key in the dictionary + volume = self._get_volume(context, result['result']) + defer.returnValue({'volumeSet': [self.format_volume(context, volume)]}) def _get_address(self, context, public_ip): # FIXME(vish) this should move into network.py diff --git a/nova/endpoint/images.py b/nova/endpoint/images.py index 12876da3..fe7cb5d1 100644 --- a/nova/endpoint/images.py +++ b/nova/endpoint/images.py @@ -21,14 +21,13 @@ Proxy AMI-related calls from the cloud controller, to the running objectstore daemon. """ -import boto -import boto.s3 +import boto.s3.connection import json -import random import urllib from nova import flags from nova import utils +from nova.auth import manager FLAGS = flags.FLAGS @@ -77,13 +76,16 @@ def deregister(context, image_id): query_args=qs({'image_id': image_id})) def conn(context): - return boto.s3.connection.S3Connection ( - aws_access_key_id=str('%s:%s' % (context.user.access, context.project.name)), - aws_secret_access_key=str(context.user.secret), - is_secure=False, - calling_format=boto.s3.connection.OrdinaryCallingFormat(), - port=FLAGS.s3_port, - host=FLAGS.s3_host) + access = manager.AuthManager().get_access_key(context.user, + context.project) + secret = str(context.user.secret) + calling = boto.s3.connection.OrdinaryCallingFormat() + return boto.s3.connection.S3Connection(aws_access_key_id=access, + aws_secret_access_key=secret, + is_secure=False, + calling_format=calling, + port=FLAGS.s3_port, + host=FLAGS.s3_host) def qs(params): diff --git a/nova/tests/volume_unittest.py b/nova/tests/volume_unittest.py index b536ac38..0f4f0e34 100644 --- a/nova/tests/volume_unittest.py +++ b/nova/tests/volume_unittest.py @@ -42,15 +42,14 @@ class VolumeTestCase(test.TrialTestCase): vol_size = '0' user_id = 'fake' project_id = 'fake' - volume_id = self.volume.create_volume(vol_size, user_id, project_id) + volume_id = yield self.volume.create_volume(vol_size, user_id, project_id) # TODO(termie): get_volume returns differently than create_volume self.assertEqual(volume_id, volume_service.get_volume(volume_id)['volume_id']) rv = self.volume.delete_volume(volume_id) - self.assertRaises(exception.Error, - volume_service.get_volume, - volume_id) + self.assertFailure(volume_service.get_volume(volume_id), + exception.Error) def test_too_big_volume(self): vol_size = '1001' @@ -68,13 +67,14 @@ class VolumeTestCase(test.TrialTestCase): total_slots = FLAGS.slots_per_shelf * num_shelves vols = [] for i in xrange(total_slots): - vid = self.volume.create_volume(vol_size, user_id, project_id) + vid = yield self.volume.create_volume(vol_size, user_id, project_id) vols.append(vid) - self.assertRaises(volume_service.NoMoreVolumes, - self.volume.create_volume, - vol_size, user_id, project_id) + self.assertFailure(self.volume.create_volume(vol_size, + user_id, + project_id), + volume_service.NoMoreVolumes) for id in vols: - self.volume.delete_volume(id) + yield self.volume.delete_volume(id) def test_run_attach_detach_volume(self): # Create one volume and one compute to test with @@ -83,7 +83,7 @@ class VolumeTestCase(test.TrialTestCase): user_id = "fake" project_id = 'fake' mountpoint = "/dev/sdf" - volume_id = self.volume.create_volume(vol_size, user_id, project_id) + volume_id = yield self.volume.create_volume(vol_size, user_id, project_id) volume_obj = volume_service.get_volume(volume_id) volume_obj.start_attach(instance_id, mountpoint) diff --git a/nova/twistd.py b/nova/twistd.py index ecb6e289..c83276da 100644 --- a/nova/twistd.py +++ b/nova/twistd.py @@ -214,6 +214,9 @@ def serve(filename): FLAGS.pidfile = '%s.pid' % name elif FLAGS.pidfile.endswith('twistd.pid'): FLAGS.pidfile = FLAGS.pidfile.replace('twistd.pid', '%s.pid' % name) + # NOTE(vish): if we're running nodaemon, redirect the log to stdout + if FLAGS.nodaemon and not FLAGS.logfile: + FLAGS.logfile = "-" if not FLAGS.logfile: FLAGS.logfile = '%s.log' % name elif FLAGS.logfile.endswith('twistd.log'):