diff options
| author | Vishvananda Ishaya <vishvananda@gmail.com> | 2010-07-26 11:06:45 -0700 |
|---|---|---|
| committer | Vishvananda Ishaya <vishvananda@gmail.com> | 2010-07-26 11:06:45 -0700 |
| commit | cacca7df569e396d76112693aab62c95d51ff035 (patch) | |
| tree | b5c5a35bc3f6155f2ab768ae1475964c4e24c2ac | |
| parent | 35fda702abf91792d3c4753a1bbccdb119eaf6eb (diff) | |
| parent | 340f9fc8d63ec931485aba1dcfeccdc1cb3849fa (diff) | |
| download | nova-cacca7df569e396d76112693aab62c95d51ff035.tar.gz nova-cacca7df569e396d76112693aab62c95d51ff035.tar.xz nova-cacca7df569e396d76112693aab62c95d51ff035.zip | |
merged trunk
| -rwxr-xr-x | CA/geninter.sh | 2 | ||||
| -rw-r--r-- | README | 14 | ||||
| -rw-r--r-- | doc/.gitignore (renamed from docs/.gitignore) | 0 | ||||
| -rw-r--r-- | doc/build/.gitignore (renamed from docs/_build/.gitignore) | 0 | ||||
| -rw-r--r-- | doc/source/Makefile (renamed from docs/Makefile) | 0 | ||||
| -rw-r--r-- | doc/source/_static/.gitignore (renamed from docs/_static/.gitignore) | 0 | ||||
| -rw-r--r-- | doc/source/_templates/.gitignore (renamed from docs/_templates/.gitignore) | 0 | ||||
| -rw-r--r-- | doc/source/architecture.rst (renamed from docs/architecture.rst) | 0 | ||||
| -rw-r--r-- | doc/source/auth.rst (renamed from docs/auth.rst) | 0 | ||||
| -rw-r--r-- | doc/source/binaries.rst (renamed from docs/binaries.rst) | 0 | ||||
| -rw-r--r-- | doc/source/compute.rst (renamed from docs/compute.rst) | 0 | ||||
| -rw-r--r-- | doc/source/conf.py (renamed from docs/conf.py) | 12 | ||||
| -rw-r--r-- | doc/source/endpoint.rst (renamed from docs/endpoint.rst) | 0 | ||||
| -rw-r--r-- | doc/source/fakes.rst (renamed from docs/fakes.rst) | 0 | ||||
| -rw-r--r-- | doc/source/getting.started.rst (renamed from docs/getting.started.rst) | 0 | ||||
| -rw-r--r-- | doc/source/index.rst (renamed from docs/index.rst) | 1 | ||||
| -rw-r--r-- | doc/source/modules.rst (renamed from docs/modules.rst) | 0 | ||||
| -rw-r--r-- | doc/source/network.rst (renamed from docs/network.rst) | 0 | ||||
| -rw-r--r-- | doc/source/nova.rst (renamed from docs/nova.rst) | 0 | ||||
| -rw-r--r-- | doc/source/objectstore.rst (renamed from docs/objectstore.rst) | 0 | ||||
| -rw-r--r-- | doc/source/packages.rst (renamed from docs/packages.rst) | 0 | ||||
| -rw-r--r-- | doc/source/storage.rst (renamed from docs/storage.rst) | 0 | ||||
| -rw-r--r-- | doc/source/volume.rst (renamed from docs/volume.rst) | 0 | ||||
| -rwxr-xr-x | nova/cloudpipe/bootscript.sh | 2 | ||||
| -rw-r--r-- | nova/compute/disk.py | 7 | ||||
| -rw-r--r-- | nova/endpoint/cloud.py | 26 | ||||
| -rw-r--r-- | nova/exception.py | 3 | ||||
| -rw-r--r-- | nova/objectstore/bucket.py | 4 | ||||
| -rw-r--r-- | nova/objectstore/handler.py | 22 | ||||
| -rw-r--r-- | nova/rpc.py | 3 | ||||
| -rw-r--r-- | nova/tests/network_unittest.py | 2 | ||||
| -rw-r--r-- | nova/tests/objectstore_unittest.py | 68 | ||||
| -rw-r--r-- | setup.cfg | 4 |
33 files changed, 69 insertions, 101 deletions
diff --git a/CA/geninter.sh b/CA/geninter.sh index 6c0528d1b..7d6c280d5 100755 --- a/CA/geninter.sh +++ b/CA/geninter.sh @@ -17,7 +17,7 @@ # under the License. # ARG is the id of the user -export SUBJ=/C=US/ST=California/L=Mountain View/O=Anso Labs/OU=Nova Dev/CN=customer-intCA-$3 +export SUBJ="/C=US/ST=California/L=MountainView/O=AnsoLabs/OU=NovaDev/CN=customer-intCA-$1" mkdir INTER/$1 cd INTER/$1 cp ../../openssl.cnf.tmpl openssl.cnf @@ -6,15 +6,19 @@ The Choose Your Own Adventure README for Nova: To monitor it from a distance: follow @novacc on twitter -To tame it for use in your own cloud: read http://docs.novacc.org/getting.started.html +To tame it for use in your own cloud: read http://nova.openstack.org/getting.started.html -To study its anatomy: read http://docs.novacc.org/architecture.html +To study its anatomy: read http://nova.openstack.org/architecture.html -To disect it in detail: visit http://github.com/nova/cc +To disect it in detail: visit http://code.launchpad.net/nova -To taunt it with its weaknesses: use http://github.com/nova/cc/issues +To taunt it with its weaknesses: use http://bugs.launchpad.net/nova + +To watch it: http://hudson.openstack.org To hack at it: read HACKING -To watch it: http://test.novacc.org/waterfall +To laugh at its PEP8 problems: http://hudson.openstack.org/job/nova-pep8/violations + +To cry over its pylint problems: http://hudson.openstack.org/job/nova-pylint/violations diff --git a/docs/.gitignore b/doc/.gitignore index 88f9974bd..88f9974bd 100644 --- a/docs/.gitignore +++ b/doc/.gitignore diff --git a/docs/_build/.gitignore b/doc/build/.gitignore index 72e8ffc0d..72e8ffc0d 100644 --- a/docs/_build/.gitignore +++ b/doc/build/.gitignore diff --git a/docs/Makefile b/doc/source/Makefile index b2f74e85a..b2f74e85a 100644 --- a/docs/Makefile +++ b/doc/source/Makefile diff --git a/docs/_static/.gitignore b/doc/source/_static/.gitignore index e69de29bb..e69de29bb 100644 --- a/docs/_static/.gitignore +++ b/doc/source/_static/.gitignore diff --git a/docs/_templates/.gitignore b/doc/source/_templates/.gitignore index e69de29bb..e69de29bb 100644 --- a/docs/_templates/.gitignore +++ b/doc/source/_templates/.gitignore diff --git a/docs/architecture.rst b/doc/source/architecture.rst index 11813d2c8..11813d2c8 100644 --- a/docs/architecture.rst +++ b/doc/source/architecture.rst diff --git a/docs/auth.rst b/doc/source/auth.rst index 70aca704a..70aca704a 100644 --- a/docs/auth.rst +++ b/doc/source/auth.rst diff --git a/docs/binaries.rst b/doc/source/binaries.rst index 90a9581f7..90a9581f7 100644 --- a/docs/binaries.rst +++ b/doc/source/binaries.rst diff --git a/docs/compute.rst b/doc/source/compute.rst index 5b08dbd5b..5b08dbd5b 100644 --- a/docs/compute.rst +++ b/doc/source/compute.rst diff --git a/docs/conf.py b/doc/source/conf.py index fb3fd1a30..1c1ae7f48 100644 --- a/docs/conf.py +++ b/doc/source/conf.py @@ -16,8 +16,7 @@ import sys, os # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. -sys.path.append(os.path.abspath('/Users/jmckenty/Projects/cc')) -sys.path.append([os.path.abspath('../nova'),os.path.abspath('../'),os.path.abspath('../vendor')]) +sys.path.append([os.path.abspath('../nova'), os.path.abspath('..'), os.path.abspath('../bin')]) # -- General configuration ----------------------------------------------------- @@ -25,7 +24,6 @@ sys.path.append([os.path.abspath('../nova'),os.path.abspath('../'),os.path.abspa # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. extensions = ['sphinx.ext.autodoc', 'sphinx.ext.intersphinx', 'sphinx.ext.todo', 'sphinx.ext.coverage', 'sphinx.ext.pngmath', 'sphinx.ext.ifconfig'] -#sphinx_to_github = False todo_include_todos = True # Add any paths that contain templates here, relative to this directory. @@ -68,7 +66,7 @@ release = '0.42' # List of directories, relative to source directory, that shouldn't be searched # for source files. -exclude_trees = ['_build'] +exclude_trees = [] # The reST default role (used for this markup: `text`) to use for all documents. #default_role = None @@ -176,7 +174,7 @@ htmlhelp_basename = 'novadoc' # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, documentclass [howto/manual]). latex_documents = [ - ('index', 'nova.tex', u'nova Documentation', + ('index', 'Nova.tex', u'Nova Documentation', u'Anso Labs, LLC', 'manual'), ] @@ -199,4 +197,6 @@ latex_documents = [ # Example configuration for intersphinx: refer to the Python standard library. -intersphinx_mapping = {'http://docs.python.org/': None} +intersphinx_mapping = {'python': ('http://docs.python.org/', None), + 'swift': ('http://swift.openstack.org', None)} + diff --git a/docs/endpoint.rst b/doc/source/endpoint.rst index 399df4161..399df4161 100644 --- a/docs/endpoint.rst +++ b/doc/source/endpoint.rst diff --git a/docs/fakes.rst b/doc/source/fakes.rst index bea8bc4e9..bea8bc4e9 100644 --- a/docs/fakes.rst +++ b/doc/source/fakes.rst diff --git a/docs/getting.started.rst b/doc/source/getting.started.rst index 3eadd0882..3eadd0882 100644 --- a/docs/getting.started.rst +++ b/doc/source/getting.started.rst diff --git a/docs/index.rst b/doc/source/index.rst index ef2e8f63e..6627fe066 100644 --- a/docs/index.rst +++ b/doc/source/index.rst @@ -43,7 +43,6 @@ Contents: nova fakes binaries - todo modules packages diff --git a/docs/modules.rst b/doc/source/modules.rst index 82c61f008..82c61f008 100644 --- a/docs/modules.rst +++ b/doc/source/modules.rst diff --git a/docs/network.rst b/doc/source/network.rst index 357a0517f..357a0517f 100644 --- a/docs/network.rst +++ b/doc/source/network.rst diff --git a/docs/nova.rst b/doc/source/nova.rst index 4b9c44a5f..4b9c44a5f 100644 --- a/docs/nova.rst +++ b/doc/source/nova.rst diff --git a/docs/objectstore.rst b/doc/source/objectstore.rst index 6b8d293f4..6b8d293f4 100644 --- a/docs/objectstore.rst +++ b/doc/source/objectstore.rst diff --git a/docs/packages.rst b/doc/source/packages.rst index 6029ad7d7..6029ad7d7 100644 --- a/docs/packages.rst +++ b/doc/source/packages.rst diff --git a/docs/storage.rst b/doc/source/storage.rst index f77e5f0e5..f77e5f0e5 100644 --- a/docs/storage.rst +++ b/doc/source/storage.rst diff --git a/docs/volume.rst b/doc/source/volume.rst index 619968458..619968458 100644 --- a/docs/volume.rst +++ b/doc/source/volume.rst diff --git a/nova/cloudpipe/bootscript.sh b/nova/cloudpipe/bootscript.sh index 43fc2ecab..82ec2012a 100755 --- a/nova/cloudpipe/bootscript.sh +++ b/nova/cloudpipe/bootscript.sh @@ -24,7 +24,7 @@ export VPN_IP=`ifconfig | grep 'inet addr:'| grep -v '127.0.0.1' | cut -d: -f2 export BROADCAST=`ifconfig | grep 'inet addr:'| grep -v '127.0.0.1' | cut -d: -f3 | awk '{print $1}'` export DHCP_MASK=`ifconfig | grep 'inet addr:'| grep -v '127.0.0.1' | cut -d: -f4 | awk '{print $1}'` export GATEWAY=`netstat -r | grep default | cut -d' ' -f10` -export SUBJ=/C=US/ST=California/L=Mountain View/O=Anso Labs/OU=Nova Dev/CN=customer-vpn-$VPN_IP +export SUBJ="/C=US/ST=California/L=MountainView/O=AnsoLabs/OU=NovaDev/CN=customer-vpn-$VPN_IP" DHCP_LOWER=`echo $BROADCAST | awk -F. '{print $1"."$2"."$3"." $4 - 10 }'` DHCP_UPPER=`echo $BROADCAST | awk -F. '{print $1"."$2"."$3"." $4 - 1 }'` diff --git a/nova/compute/disk.py b/nova/compute/disk.py index 08a22556e..1ffcca685 100644 --- a/nova/compute/disk.py +++ b/nova/compute/disk.py @@ -40,7 +40,8 @@ def partition(infile, outfile, local_bytes=0, local_type='ext2', execute=None): formatted as ext2. In the diagram below, dashes represent drive sectors. - 0 a b c d e + +-----+------. . .-------+------. . .------+ + | 0 a| b c|d e| +-----+------. . .-------+------. . .------+ | mbr | primary partiton | local partition | +-----+------. . .-------+------. . .------+ @@ -64,8 +65,8 @@ def partition(infile, outfile, local_bytes=0, local_type='ext2', execute=None): last_sector = local_last # e # create an empty file - execute('dd if=/dev/zero of=%s count=1 seek=%d bs=%d' - % (outfile, last_sector, sector_size)) + yield execute('dd if=/dev/zero of=%s count=1 seek=%d bs=%d' + % (outfile, last_sector, sector_size)) # make mbr partition yield execute('parted --script %s mklabel msdos' % outfile) diff --git a/nova/endpoint/cloud.py b/nova/endpoint/cloud.py index 6e9bdead8..56d474fd9 100644 --- a/nova/endpoint/cloud.py +++ b/nova/endpoint/cloud.py @@ -452,21 +452,21 @@ class CloudController(object): def format_addresses(self, context): addresses = [] - # TODO(vish): move authorization checking into network.py for address in self.network.host_objs: - #logging.debug(address_record) - address_rv = { - 'public_ip': address['address'], - 'instance_id' : address.get('instance_id', 'free') - } - if context.user.is_admin(): - address_rv['instance_id'] = "%s (%s, %s)" % ( - address['instance_id'], - address['user_id'], - address['project_id'], - ) + # TODO(vish): implement a by_project iterator for addresses + if (context.user.is_admin() or + address['project_id'] == self.project.id): + address_rv = { + 'public_ip': address['address'], + 'instance_id' : address.get('instance_id', 'free') + } + if context.user.is_admin(): + address_rv['instance_id'] = "%s (%s, %s)" % ( + address['instance_id'], + address['user_id'], + address['project_id'], + ) addresses.append(address_rv) - # logging.debug(addresses) return {'addressesSet': addresses} @rbac.allow('netadmin') diff --git a/nova/exception.py b/nova/exception.py index bda002d1e..2108123de 100644 --- a/nova/exception.py +++ b/nova/exception.py @@ -44,6 +44,9 @@ class Duplicate(Error): class NotAuthorized(Error): pass +class NotEmpty(Error): + pass + def wrap_exception(f): def _wrap(*args, **kw): try: diff --git a/nova/objectstore/bucket.py b/nova/objectstore/bucket.py index 090ef4e61..b42a96233 100644 --- a/nova/objectstore/bucket.py +++ b/nova/objectstore/bucket.py @@ -107,7 +107,7 @@ class Bucket(object): try: return context.user.is_admin() or self.owner_id == context.project.id except Exception, e: - pass + return False def list_keys(self, prefix='', marker=None, max_keys=1000, terse=False): object_names = [] @@ -161,7 +161,7 @@ class Bucket(object): def delete(self): if len(os.listdir(self.path)) > 0: - raise exception.NotAuthorized() + raise exception.NotEmpty() os.rmdir(self.path) os.remove(self.path+'.json') diff --git a/nova/objectstore/handler.py b/nova/objectstore/handler.py index b2ed3d482..ae3ffa0eb 100644 --- a/nova/objectstore/handler.py +++ b/nova/objectstore/handler.py @@ -103,13 +103,16 @@ def get_argument(request, key, default_value): def get_context(request): try: # Authorization Header format: 'AWS <access>:<secret>' - access, sep, secret = request.getHeader('Authorization').split(' ')[1].rpartition(':') + authorization_header = request.getHeader('Authorization') + if not authorization_header: + raise exception.NotAuthorized + access, sep, secret = authorization_header.split(' ')[1].rpartition(':') um = users.UserManager.instance() print 'um %s' % um (user, project) = um.authenticate(access, secret, {}, request.method, request.host, request.uri, False) # FIXME: check signature here! return api.APIRequestContext(None, user, project) - except exception.Error, ex: + except exception.Error as ex: logging.debug("Authentication Failure: %s" % ex) raise exception.NotAuthorized @@ -165,7 +168,7 @@ class BucketResource(Resource): logging.debug("Creating bucket %s" % (self.name)) try: print 'user is %s' % request.context - except Exception, e: + except Exception as e: logging.exception(e) logging.debug("calling bucket.Bucket.create(%r, %r)" % (self.name, request.context)) bucket.Bucket.create(self.name, request.context) @@ -239,9 +242,10 @@ class ImageResource(Resource): """ returns a json listing of all images that a user has permissions to see """ - images = [i for i in image.Image.all() if i.is_authorized(self.context)] + images = [i for i in image.Image.all() if i.is_authorized(request.context)] request.write(json.dumps([i.metadata for i in images])) + request.finish() return server.NOT_DONE_YET def render_PUT(self, request): @@ -269,12 +273,12 @@ class ImageResource(Resource): def render_POST(self, request): """ update image attributes: public/private """ - image_id = self.get_argument('image_id', u'') - operation = self.get_argument('operation', u'') + image_id = get_argument(request, 'image_id', u'') + operation = get_argument(request, 'operation', u'') image_object = image.Image(image_id) - if not image.is_authorized(request.context): + if not image_object.is_authorized(request.context): raise exception.NotAuthorized image_object.set_public(operation=='add') @@ -283,10 +287,10 @@ class ImageResource(Resource): def render_DELETE(self, request): """ delete a registered image """ - image_id = self.get_argument("image_id", u"") + image_id = get_argument(request, "image_id", u"") image_object = image.Image(image_id) - if not image.is_authorized(request.context): + if not image_object.is_authorized(request.context): raise exception.NotAuthorized image_object.delete() diff --git a/nova/rpc.py b/nova/rpc.py index ef463e84b..ebf140d92 100644 --- a/nova/rpc.py +++ b/nova/rpc.py @@ -151,6 +151,7 @@ class TopicPublisher(Publisher): def __init__(self, connection=None, topic="broadcast"): self.routing_key = topic self.exchange = FLAGS.control_exchange + self.durable = False super(TopicPublisher, self).__init__(connection=connection) @@ -242,7 +243,7 @@ def send_message(topic, message, wait=True): consumer.register_callback(generic_response) publisher = messaging.Publisher(connection=Connection.instance(), - exchange="nova", + exchange=FLAGS.control_exchange, exchange_type="topic", routing_key=topic) publisher.send(message) diff --git a/nova/tests/network_unittest.py b/nova/tests/network_unittest.py index f3a5868d1..a1d1789e2 100644 --- a/nova/tests/network_unittest.py +++ b/nova/tests/network_unittest.py @@ -137,7 +137,7 @@ class NetworkTestCase(test.TrialTestCase): self.dnsmasq.release_ip(mac3, address3, hostname, net.bridge_name) net = network.get_project_network("project0", "default") rv = network.deallocate_ip(secondaddress) - self.dnsmasq.release_ip(mac, address, hostname, net.bridge_name) + self.dnsmasq.release_ip(mac, secondaddress, hostname, net.bridge_name) def test_release_before_deallocate(self): pass diff --git a/nova/tests/objectstore_unittest.py b/nova/tests/objectstore_unittest.py index f47ca7f00..8ae1f6e78 100644 --- a/nova/tests/objectstore_unittest.py +++ b/nova/tests/objectstore_unittest.py @@ -27,6 +27,7 @@ from nova import flags from nova import objectstore from nova import test from nova.auth import users +from nova.exception import NotEmpty, NotFound, NotAuthorized FLAGS = flags.FLAGS @@ -96,49 +97,37 @@ class ObjectStoreTestCase(test.BaseTestCase): # another user is not authorized self.context.user = self.um.get_user('user2') self.context.project = self.um.get_project('proj2') - self.assert_(bucket.is_authorized(self.context) == False) + self.assertFalse(bucket.is_authorized(self.context)) # admin is authorized to use bucket self.context.user = self.um.get_user('admin_user') self.context.project = None - self.assert_(bucket.is_authorized(self.context)) + self.assertTrue(bucket.is_authorized(self.context)) # new buckets are empty - self.assert_(bucket.list_keys()['Contents'] == []) + self.assertTrue(bucket.list_keys()['Contents'] == []) # storing keys works bucket['foo'] = "bar" - self.assert_(len(bucket.list_keys()['Contents']) == 1) + self.assertEquals(len(bucket.list_keys()['Contents']), 1) - self.assert_(bucket['foo'].read() == 'bar') + self.assertEquals(bucket['foo'].read(), 'bar') # md5 of key works - self.assert_(bucket['foo'].md5 == hashlib.md5('bar').hexdigest()) - - # deleting non-empty bucket throws exception - exception = False - try: - bucket.delete() - except: - exception = True + self.assertEquals(bucket['foo'].md5, hashlib.md5('bar').hexdigest()) - self.assert_(exception) + # deleting non-empty bucket should throw a NotEmpty exception + self.assertRaises(NotEmpty, bucket.delete) # deleting key del bucket['foo'] - # deleting empty button + # deleting empty bucket bucket.delete() # accessing deleted bucket throws exception - exception = False - try: - objectstore.bucket.Bucket('new_bucket') - except: - exception = True - - self.assert_(exception) + self.assertRaises(NotFound, objectstore.bucket.Bucket, 'new_bucket') def test_images(self): self.context.user = self.um.get_user('user1') @@ -167,37 +156,4 @@ class ObjectStoreTestCase(test.BaseTestCase): # verify image permissions self.context.user = self.um.get_user('user2') self.context.project = self.um.get_project('proj2') - self.assert_(my_img.is_authorized(self.context) == False) - -# class ApiObjectStoreTestCase(test.BaseTestCase): -# def setUp(self): -# super(ApiObjectStoreTestCase, self).setUp() -# FLAGS.fake_users = True -# FLAGS.buckets_path = os.path.join(tempdir, 'buckets') -# FLAGS.images_path = os.path.join(tempdir, 'images') -# FLAGS.ca_path = os.path.join(os.path.dirname(__file__), 'CA') -# -# self.users = users.UserManager.instance() -# self.app = handler.Application(self.users) -# -# self.host = '127.0.0.1' -# -# self.conn = boto.s3.connection.S3Connection( -# aws_access_key_id=user.access, -# aws_secret_access_key=user.secret, -# is_secure=False, -# calling_format=boto.s3.connection.OrdinaryCallingFormat(), -# port=FLAGS.s3_port, -# host=FLAGS.s3_host) -# -# self.mox.StubOutWithMock(self.ec2, 'new_http_connection') -# -# def tearDown(self): -# FLAGS.Reset() -# super(ApiObjectStoreTestCase, self).tearDown() -# -# def test_describe_instances(self): -# self.expect_http() -# self.mox.ReplayAll() -# -# self.assertEqual(self.ec2.get_all_instances(), []) + self.assertFalse(my_img.is_authorized(self.context)) @@ -1,4 +1,4 @@ [build_sphinx] -source-dir = docs -build-dir = docs/_build +source-dir = doc/source +build-dir = doc/build all_files = 1 |
