merged trunk
This commit is contained in:
@@ -21,8 +21,6 @@
|
|||||||
Twisted daemon for nova objectstore. Supports S3 API.
|
Twisted daemon for nova objectstore. Supports S3 API.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import logging
|
|
||||||
|
|
||||||
from nova import flags
|
from nova import flags
|
||||||
from nova import utils
|
from nova import utils
|
||||||
from nova import twistd
|
from nova import twistd
|
||||||
@@ -33,9 +31,6 @@ FLAGS = flags.FLAGS
|
|||||||
|
|
||||||
|
|
||||||
def main():
|
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()
|
app = handler.get_application()
|
||||||
print app
|
print app
|
||||||
return app
|
return app
|
||||||
|
|||||||
@@ -292,9 +292,13 @@ class NovaAdminClient(object):
|
|||||||
'Operation': operation}
|
'Operation': operation}
|
||||||
return self.apiconn.get_status('ModifyProjectMember', params)
|
return self.apiconn.get_status('ModifyProjectMember', params)
|
||||||
|
|
||||||
def get_zip(self, username):
|
def get_zip(self, user, project):
|
||||||
""" returns the content of a zip file containing novarc and access credentials. """
|
"""
|
||||||
return self.apiconn.get_object('GenerateX509ForUser', {'Name': username}, UserInfo).file
|
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):
|
def get_hosts(self):
|
||||||
return self.apiconn.get_list('DescribeHosts', {}, [('item', HostInfo)])
|
return self.apiconn.get_list('DescribeHosts', {}, [('item', HostInfo)])
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ import logging
|
|||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
import string
|
import string
|
||||||
import sys
|
|
||||||
import tempfile
|
import tempfile
|
||||||
import uuid
|
import uuid
|
||||||
import zipfile
|
import zipfile
|
||||||
@@ -239,8 +238,7 @@ class AuthManager(object):
|
|||||||
def __new__(cls, *args, **kwargs):
|
def __new__(cls, *args, **kwargs):
|
||||||
"""Returns the AuthManager singleton"""
|
"""Returns the AuthManager singleton"""
|
||||||
if not cls._instance:
|
if not cls._instance:
|
||||||
cls._instance = super(AuthManager, cls).__new__(
|
cls._instance = super(AuthManager, cls).__new__(cls)
|
||||||
cls, *args, **kwargs)
|
|
||||||
return cls._instance
|
return cls._instance
|
||||||
|
|
||||||
def __init__(self, driver=None, *args, **kwargs):
|
def __init__(self, driver=None, *args, **kwargs):
|
||||||
@@ -333,6 +331,12 @@ class AuthManager(object):
|
|||||||
raise exception.NotAuthorized('Signature does not match')
|
raise exception.NotAuthorized('Signature does not match')
|
||||||
return (user, project)
|
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):
|
def is_superuser(self, user):
|
||||||
"""Checks for superuser status, allowing user to bypass rbac
|
"""Checks for superuser status, allowing user to bypass rbac
|
||||||
|
|
||||||
|
|||||||
@@ -48,7 +48,8 @@ import hashlib
|
|||||||
import hmac
|
import hmac
|
||||||
import logging
|
import logging
|
||||||
import urllib
|
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
|
from nova.exception import Error
|
||||||
|
|
||||||
|
|||||||
@@ -294,17 +294,16 @@ class CloudController(object):
|
|||||||
return v
|
return v
|
||||||
|
|
||||||
@rbac.allow('projectmanager', 'sysadmin')
|
@rbac.allow('projectmanager', 'sysadmin')
|
||||||
|
@defer.inlineCallbacks
|
||||||
def create_volume(self, context, size, **kwargs):
|
def create_volume(self, context, size, **kwargs):
|
||||||
# TODO(vish): refactor this to create the volume object here and tell service to create it
|
# 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,
|
"args" : {"size": size,
|
||||||
"user_id": context.user.id,
|
"user_id": context.user.id,
|
||||||
"project_id": context.project.id}})
|
"project_id": context.project.id}})
|
||||||
def _format_result(result):
|
# NOTE(vish): rpc returned value is in the result key in the dictionary
|
||||||
volume = self._get_volume(context, result['result'])
|
volume = self._get_volume(context, result['result'])
|
||||||
return {'volumeSet': [self.format_volume(context, volume)]}
|
defer.returnValue({'volumeSet': [self.format_volume(context, volume)]})
|
||||||
res.addCallback(_format_result)
|
|
||||||
return res
|
|
||||||
|
|
||||||
def _get_address(self, context, public_ip):
|
def _get_address(self, context, public_ip):
|
||||||
# FIXME(vish) this should move into network.py
|
# FIXME(vish) this should move into network.py
|
||||||
|
|||||||
@@ -21,14 +21,13 @@ Proxy AMI-related calls from the cloud controller, to the running
|
|||||||
objectstore daemon.
|
objectstore daemon.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import boto
|
import boto.s3.connection
|
||||||
import boto.s3
|
|
||||||
import json
|
import json
|
||||||
import random
|
|
||||||
import urllib
|
import urllib
|
||||||
|
|
||||||
from nova import flags
|
from nova import flags
|
||||||
from nova import utils
|
from nova import utils
|
||||||
|
from nova.auth import manager
|
||||||
|
|
||||||
|
|
||||||
FLAGS = flags.FLAGS
|
FLAGS = flags.FLAGS
|
||||||
@@ -77,11 +76,14 @@ def deregister(context, image_id):
|
|||||||
query_args=qs({'image_id': image_id}))
|
query_args=qs({'image_id': image_id}))
|
||||||
|
|
||||||
def conn(context):
|
def conn(context):
|
||||||
return boto.s3.connection.S3Connection (
|
access = manager.AuthManager().get_access_key(context.user,
|
||||||
aws_access_key_id=str('%s:%s' % (context.user.access, context.project.name)),
|
context.project)
|
||||||
aws_secret_access_key=str(context.user.secret),
|
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,
|
is_secure=False,
|
||||||
calling_format=boto.s3.connection.OrdinaryCallingFormat(),
|
calling_format=calling,
|
||||||
port=FLAGS.s3_port,
|
port=FLAGS.s3_port,
|
||||||
host=FLAGS.s3_host)
|
host=FLAGS.s3_host)
|
||||||
|
|
||||||
|
|||||||
@@ -42,15 +42,14 @@ class VolumeTestCase(test.TrialTestCase):
|
|||||||
vol_size = '0'
|
vol_size = '0'
|
||||||
user_id = 'fake'
|
user_id = 'fake'
|
||||||
project_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
|
# TODO(termie): get_volume returns differently than create_volume
|
||||||
self.assertEqual(volume_id,
|
self.assertEqual(volume_id,
|
||||||
volume_service.get_volume(volume_id)['volume_id'])
|
volume_service.get_volume(volume_id)['volume_id'])
|
||||||
|
|
||||||
rv = self.volume.delete_volume(volume_id)
|
rv = self.volume.delete_volume(volume_id)
|
||||||
self.assertRaises(exception.Error,
|
self.assertFailure(volume_service.get_volume(volume_id),
|
||||||
volume_service.get_volume,
|
exception.Error)
|
||||||
volume_id)
|
|
||||||
|
|
||||||
def test_too_big_volume(self):
|
def test_too_big_volume(self):
|
||||||
vol_size = '1001'
|
vol_size = '1001'
|
||||||
@@ -68,13 +67,14 @@ class VolumeTestCase(test.TrialTestCase):
|
|||||||
total_slots = FLAGS.slots_per_shelf * num_shelves
|
total_slots = FLAGS.slots_per_shelf * num_shelves
|
||||||
vols = []
|
vols = []
|
||||||
for i in xrange(total_slots):
|
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)
|
vols.append(vid)
|
||||||
self.assertRaises(volume_service.NoMoreVolumes,
|
self.assertFailure(self.volume.create_volume(vol_size,
|
||||||
self.volume.create_volume,
|
user_id,
|
||||||
vol_size, user_id, project_id)
|
project_id),
|
||||||
|
volume_service.NoMoreVolumes)
|
||||||
for id in vols:
|
for id in vols:
|
||||||
self.volume.delete_volume(id)
|
yield self.volume.delete_volume(id)
|
||||||
|
|
||||||
def test_run_attach_detach_volume(self):
|
def test_run_attach_detach_volume(self):
|
||||||
# Create one volume and one compute to test with
|
# Create one volume and one compute to test with
|
||||||
@@ -83,7 +83,7 @@ class VolumeTestCase(test.TrialTestCase):
|
|||||||
user_id = "fake"
|
user_id = "fake"
|
||||||
project_id = 'fake'
|
project_id = 'fake'
|
||||||
mountpoint = "/dev/sdf"
|
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 = volume_service.get_volume(volume_id)
|
||||||
volume_obj.start_attach(instance_id, mountpoint)
|
volume_obj.start_attach(instance_id, mountpoint)
|
||||||
|
|||||||
@@ -214,6 +214,9 @@ def serve(filename):
|
|||||||
FLAGS.pidfile = '%s.pid' % name
|
FLAGS.pidfile = '%s.pid' % name
|
||||||
elif FLAGS.pidfile.endswith('twistd.pid'):
|
elif FLAGS.pidfile.endswith('twistd.pid'):
|
||||||
FLAGS.pidfile = FLAGS.pidfile.replace('twistd.pid', '%s.pid' % name)
|
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:
|
if not FLAGS.logfile:
|
||||||
FLAGS.logfile = '%s.log' % name
|
FLAGS.logfile = '%s.log' % name
|
||||||
elif FLAGS.logfile.endswith('twistd.log'):
|
elif FLAGS.logfile.endswith('twistd.log'):
|
||||||
|
|||||||
Reference in New Issue
Block a user