summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--nova/api/openstack/servers.py59
-rw-r--r--nova/compute/api.py38
-rw-r--r--nova/compute/manager.py2
-rw-r--r--nova/quota.py30
-rw-r--r--nova/tests/api/openstack/test_servers.py48
-rw-r--r--nova/tests/test_quota.py60
6 files changed, 124 insertions, 113 deletions
diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py
index 7bef8eb32..adb5c5f99 100644
--- a/nova/api/openstack/servers.py
+++ b/nova/api/openstack/servers.py
@@ -169,20 +169,23 @@ class Controller(wsgi.Controller):
metadata.append({'key': k, 'value': v})
personality = env['server'].get('personality', [])
- personality_files = self._get_personality_files(personality)
-
- instances = self.compute_api.create(
- context,
- instance_types.get_by_flavor_id(env['server']['flavorId']),
- image_id,
- kernel_id=kernel_id,
- ramdisk_id=ramdisk_id,
- display_name=env['server']['name'],
- display_description=env['server']['name'],
- key_name=key_pair['name'],
- key_data=key_pair['public_key'],
- metadata=metadata,
- personality_files=personality_files)
+ onset_files = self._get_onset_files(personality)
+
+ try:
+ instances = self.compute_api.create(
+ context,
+ instance_types.get_by_flavor_id(env['server']['flavorId']),
+ image_id,
+ kernel_id=kernel_id,
+ ramdisk_id=ramdisk_id,
+ display_name=env['server']['name'],
+ display_description=env['server']['name'],
+ key_name=key_pair['name'],
+ key_data=key_pair['public_key'],
+ metadata=metadata,
+ onset_files=onset_files)
+ except QuotaError as error:
+ self._handle_quota_error(error)
server = _translate_keys(instances[0])
password = "%s%s" % (server['server']['name'][:4],
@@ -204,15 +207,15 @@ class Controller(wsgi.Controller):
else:
return self._deserialize(request.body, request.get_content_type())
- def _get_personality_files(self, personality):
+ def _get_onset_files(self, personality):
"""
- Create a list of personality files from the personality attribute
+ Create a list of onset files from the personality attribute
- At this time, personality_files must be formatted as a list of
+ At this time, onset_files must be formatted as a list of
(file_path, file_content) pairs for compatibility with the
underlying compute service.
"""
- personality_files = []
+ onset_files = []
for item in personality:
try:
path = item['path']
@@ -227,8 +230,24 @@ class Controller(wsgi.Controller):
except TypeError:
msg = 'Personality content for %s cannot be decoded' % path
raise exc.HTTPBadRequest(explanation=msg)
- personality_files.append((path, contents))
- return personality_files
+ onset_files.append((path, contents))
+ return onset_files
+
+ def _handle_quota_errors(self, error):
+ """
+ Reraise quota errors as api-specific http exceptions
+ """
+ if error.code == "OnsetFileLimitExceeded":
+ expl = "Personality file limit exceeded"
+ raise exc.HTTPBadRequest(explanation=expl)
+ if error.code == "OnsetFilePathLimitExceeded":
+ expl = "Personality file path too long"
+ raise exc.HTTPBadRequest(explanation=expl)
+ if error.code == "OnsetFileContentLimitExceeded":
+ expl = "Personality file content too long"
+ raise exc.HTTPBadRequest(explanation=expl)
+ # if the original error is okay, just reraise it
+ raise error
def update(self, req, id):
""" Updates the server name or password """
diff --git a/nova/compute/api.py b/nova/compute/api.py
index b97cadf61..140bbb3aa 100644
--- a/nova/compute/api.py
+++ b/nova/compute/api.py
@@ -80,30 +80,23 @@ class API(base.Base):
topic,
{"method": "get_network_topic", "args": {'fake': 1}})
- def _check_personality_file_quota(self, context, personality_files):
+ def _check_onset_file_quota(self, context, onset_files):
"""
- Enforce quota limits on personality files
+ Enforce quota limits on onset files
Raises a QuotaError if any limit is exceeded
"""
- limit = quota.allowed_personality_files(context)
- if len(personality_files) > limit:
- raise quota.QuotaError(_("Personality limit exceeded. You can "
- "only have %d personalities when "
- "creating an instance.") % limit,
- "PersonalityLimitExceeded")
- path_limit = quota.allowed_personality_path_bytes(context)
- content_limit = quota.allowed_personality_content_bytes(context)
- for path, content in personality_files:
+ limit = quota.allowed_onset_files(context)
+ if len(onset_files) > limit:
+ raise quota.QuotaError(code="OnsetFileLimitExceeded")
+ path_limit = quota.allowed_onset_file_path_bytes(context)
+ content_limit = quota.allowed_onset_file_content_bytes(context)
+ for path, content in onset_files:
if len(path) > path_limit:
- raise quota.QuotaError(
- _("Personality file path limit exceeded."),
- "PersonalityLimitExceeded")
+ raise quota.QuotaError(code="OnsetFilePathLimitExceeded")
if len(content) > content_limit:
- raise quota.QuotaError(
- _("Personality file content limit exceeded."),
- "PersonalityLimitExceeded")
- return personality_files
+ raise quota.QuotaError(code="OnsetFileContentLimitExceeded")
+ return onset_files
def create(self, context, instance_type,
image_id, kernel_id=None, ramdisk_id=None,
@@ -111,7 +104,7 @@ class API(base.Base):
display_name='', display_description='',
key_name=None, key_data=None, security_group='default',
availability_zone=None, user_data=None, metadata=[],
- personality_files=None):
+ onset_files=None):
"""Create the number of instances requested if quota and
other arguments check out ok."""
@@ -149,9 +142,8 @@ class API(base.Base):
LOG.warn(msg)
raise quota.QuotaError(msg, "MetadataLimitExceeded")
- if personality_files is not None:
- personality_files = \
- self._check_personality_file_quota(context, personality_files)
+ if onset_files is not None:
+ onset_files = self._check_onset_file_quota(context, onset_files)
image = self.image_service.show(context, image_id)
if kernel_id is None:
@@ -248,7 +240,7 @@ class API(base.Base):
"args": {"topic": FLAGS.compute_topic,
"instance_id": instance_id,
"availability_zone": availability_zone,
- "personality_files": personality_files}})
+ "onset_files": onset_files}})
for group_id in security_groups:
self.trigger_security_group_members_refresh(elevated, group_id)
diff --git a/nova/compute/manager.py b/nova/compute/manager.py
index d87290aae..601bb3084 100644
--- a/nova/compute/manager.py
+++ b/nova/compute/manager.py
@@ -173,7 +173,7 @@ class ComputeManager(manager.Manager):
"""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('personality_files', [])
+ 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,
diff --git a/nova/quota.py b/nova/quota.py
index fdef42bc5..e0fb97542 100644
--- a/nova/quota.py
+++ b/nova/quota.py
@@ -37,12 +37,12 @@ flags.DEFINE_integer('quota_floating_ips', 10,
'number of floating ips allowed per project')
flags.DEFINE_integer('quota_metadata_items', 128,
'number of metadata items allowed per instance')
-flags.DEFINE_integer('quota_personality_max_files', 5,
- 'number of personality files allowed')
-flags.DEFINE_integer('quota_personality_max_content_bytes', 10 * 1024,
- 'number of bytes allowed per personality file')
-flags.DEFINE_integer('quota_personality_max_path_bytes', 255,
- 'number of bytes allowed per personality file path')
+flags.DEFINE_integer('quota_max_onset_files', 5,
+ 'number of onset files allowed')
+flags.DEFINE_integer('quota_max_onset_file_content_bytes', 10 * 1024,
+ 'number of bytes allowed per onset file')
+flags.DEFINE_integer('quota_max_onset_file_path_bytes', 255,
+ 'number of bytes allowed per onset file path')
def get_quota(context, project_id):
@@ -113,19 +113,19 @@ def allowed_metadata_items(context, num_metadata_items):
return min(num_metadata_items, num_allowed_metadata_items)
-def allowed_personality_files(context):
- """Return the number of personality files allowed"""
- return int(FLAGS.quota_personality_max_files)
+def allowed_onset_files(context):
+ """Return the number of onset files allowed"""
+ return int(FLAGS.quota_max_onset_files)
-def allowed_personality_content_bytes(context):
- """Return the number of bytes allowed per personality content"""
- return int(FLAGS.quota_personality_max_content_bytes)
+def allowed_onset_file_content_bytes(context):
+ """Return the number of bytes allowed per onset file content"""
+ return int(FLAGS.quota_max_onset_file_content_bytes)
-def allowed_personality_path_bytes(context):
- """Return the number of bytes allowed in a personality file path"""
- return int(FLAGS.quota_personality_max_path_bytes)
+def allowed_onset_file_path_bytes(context):
+ """Return the number of bytes allowed in an onset file path"""
+ return int(FLAGS.quota_max_onset_file_path_bytes)
class QuotaError(exception.ApiError):
diff --git a/nova/tests/api/openstack/test_servers.py b/nova/tests/api/openstack/test_servers.py
index 0561ad499..b6d88d833 100644
--- a/nova/tests/api/openstack/test_servers.py
+++ b/nova/tests/api/openstack/test_servers.py
@@ -833,13 +833,13 @@ class TestServerInstanceCreation(test.TestCase):
class MockComputeAPI(object):
def __init__(self):
- self.personality_files = None
+ self.onset_files = None
def create(self, *args, **kwargs):
- if 'personality_files' in kwargs:
- self.personality_files = kwargs['personality_files']
+ if 'onset_files' in kwargs:
+ self.onset_files = kwargs['onset_files']
else:
- self.personality_files = None
+ self.onset_files = None
return [{'id': '1234', 'display_name': 'fakeinstance'}]
def set_admin_password(self, *args, **kwargs):
@@ -919,46 +919,46 @@ class TestServerInstanceCreation(test.TestCase):
request = self._get_create_request_json(body_dict)
compute_api, response = \
self._run_create_instance_with_mock_compute_api(request)
- return request, response, compute_api.personality_files
+ return request, response, compute_api.onset_files
def _create_instance_with_personality_xml(self, personality):
body_dict = self._create_personality_request_dict(personality)
request = self._get_create_request_xml(body_dict)
compute_api, response = \
self._run_create_instance_with_mock_compute_api(request)
- return request, response, compute_api.personality_files
+ return request, response, compute_api.onset_files
def test_create_instance_with_no_personality(self):
- request, response, personality_files = \
+ request, response, onset_files = \
self._create_instance_with_personality_json(personality=None)
self.assertEquals(response.status_int, 200)
- self.assertEquals(personality_files, [])
+ self.assertEquals(onset_files, [])
def test_create_instance_with_no_personality_xml(self):
- request, response, personality_files = \
+ request, response, onset_files = \
self._create_instance_with_personality_xml(personality=None)
self.assertEquals(response.status_int, 200)
- self.assertEquals(personality_files, [])
+ self.assertEquals(onset_files, [])
def test_create_instance_with_personality(self):
path = '/my/file/path'
contents = '#!/bin/bash\necho "Hello, World!"\n'
b64contents = base64.b64encode(contents)
personality = [(path, b64contents)]
- request, response, personality_files = \
+ request, response, onset_files = \
self._create_instance_with_personality_json(personality)
self.assertEquals(response.status_int, 200)
- self.assertEquals(personality_files, [(path, contents)])
+ self.assertEquals(onset_files, [(path, contents)])
def test_create_instance_with_personality_xml(self):
path = '/my/file/path'
contents = '#!/bin/bash\necho "Hello, World!"\n'
b64contents = base64.b64encode(contents)
personality = [(path, b64contents)]
- request, response, personality_files = \
+ request, response, onset_files = \
self._create_instance_with_personality_xml(personality)
self.assertEquals(response.status_int, 200)
- self.assertEquals(personality_files, [(path, contents)])
+ self.assertEquals(onset_files, [(path, contents)])
def test_create_instance_with_personality_no_path(self):
personality = [('/remove/this/path',
@@ -969,7 +969,7 @@ class TestServerInstanceCreation(test.TestCase):
compute_api, response = \
self._run_create_instance_with_mock_compute_api(request)
self.assertEquals(response.status_int, 400)
- self.assertEquals(compute_api.personality_files, None)
+ self.assertEquals(compute_api.onset_files, None)
def _test_create_instance_with_personality_no_path_xml(self):
personality = [('/remove/this/path',
@@ -980,7 +980,7 @@ class TestServerInstanceCreation(test.TestCase):
compute_api, response = \
self._run_create_instance_with_mock_compute_api(request)
self.assertEquals(response.status_int, 400)
- self.assertEquals(compute_api.personality_files, None)
+ self.assertEquals(compute_api.onset_files, None)
def test_create_instance_with_personality_no_contents(self):
personality = [('/test/path',
@@ -991,7 +991,7 @@ class TestServerInstanceCreation(test.TestCase):
compute_api, response = \
self._run_create_instance_with_mock_compute_api(request)
self.assertEquals(response.status_int, 400)
- self.assertEquals(compute_api.personality_files, None)
+ self.assertEquals(compute_api.onset_files, None)
def test_create_instance_with_personality_not_a_list(self):
personality = [('/test/path', base64.b64encode('test\ncontents\n'))]
@@ -1002,16 +1002,16 @@ class TestServerInstanceCreation(test.TestCase):
compute_api, response = \
self._run_create_instance_with_mock_compute_api(request)
self.assertEquals(response.status_int, 400)
- self.assertEquals(compute_api.personality_files, None)
+ self.assertEquals(compute_api.onset_files, None)
def test_create_instance_with_personality_with_non_b64_content(self):
path = '/my/file/path'
contents = '#!/bin/bash\necho "Oh no!"\n'
personality = [(path, contents)]
- request, response, personality_files = \
+ request, response, onset_files = \
self._create_instance_with_personality_json(personality)
self.assertEquals(response.status_int, 400)
- self.assertEquals(personality_files, None)
+ self.assertEquals(onset_files, None)
def test_create_instance_with_three_personalities(self):
files = [
@@ -1022,19 +1022,19 @@ class TestServerInstanceCreation(test.TestCase):
personality = []
for path, content in files:
personality.append((path, base64.b64encode(content)))
- request, response, personality_files = \
+ request, response, onset_files = \
self._create_instance_with_personality_json(personality)
self.assertEquals(response.status_int, 200)
- self.assertEquals(personality_files, files)
+ self.assertEquals(onset_files, files)
def test_create_instance_personality_empty_content(self):
path = '/my/file/path'
contents = ''
personality = [(path, contents)]
- request, response, personality_files = \
+ request, response, onset_files = \
self._create_instance_with_personality_json(personality)
self.assertEquals(response.status_int, 200)
- self.assertEquals(personality_files, [(path, contents)])
+ self.assertEquals(onset_files, [(path, contents)])
def test_create_instance_admin_pass_json(self):
request, response, dummy = \
diff --git a/nova/tests/test_quota.py b/nova/tests/test_quota.py
index 86b1d40fb..d94381aa2 100644
--- a/nova/tests/test_quota.py
+++ b/nova/tests/test_quota.py
@@ -200,66 +200,66 @@ class QuotaTestCase(test.TestCase):
image_id='fake',
metadata=metadata)
- def test_allowed_personality_files(self):
+ def test_allowed_onset_files(self):
self.assertEqual(
- quota.allowed_personality_files(self.context),
- FLAGS.quota_personality_max_files)
+ quota.allowed_onset_files(self.context),
+ FLAGS.quota_max_onset_files)
- def _create_with_personality(self, files):
+ def _create_with_onset_files(self, files):
api = compute.API(image_service=self.StubImageService())
api.create(self.context, min_count=1, max_count=1,
instance_type='m1.small', image_id='fake',
- personality_files=files)
+ onset_files=files)
- def test_no_personality_files(self):
+ def test_no_onset_files(self):
api = compute.API(image_service=self.StubImageService())
api.create(self.context, instance_type='m1.small', image_id='fake')
- def test_max_personality_files(self):
+ def test_max_onset_files(self):
files = []
- for i in xrange(FLAGS.quota_personality_max_files):
+ for i in xrange(FLAGS.quota_max_onset_files):
files.append(('/my/path%d' % i, 'config = test\n'))
- self._create_with_personality(files) # no QuotaError
+ self._create_with_onset_files(files) # no QuotaError
- def test_too_many_personality_files(self):
+ def test_too_many_onset_files(self):
files = []
- for i in xrange(FLAGS.quota_personality_max_files + 1):
+ for i in xrange(FLAGS.quota_max_onset_files + 1):
files.append(('/my/path%d' % i, 'my\ncontent%d\n' % i))
self.assertRaises(quota.QuotaError,
- self._create_with_personality, files)
+ self._create_with_onset_files, files)
- def test_allowed_personality_content_bytes(self):
+ def test_allowed_onset_file_content_bytes(self):
self.assertEqual(
- quota.allowed_personality_content_bytes(self.context),
- FLAGS.quota_personality_max_content_bytes)
+ quota.allowed_onset_file_content_bytes(self.context),
+ FLAGS.quota_max_onset_file_content_bytes)
- def test_max_personality_content_bytes(self):
- max = FLAGS.quota_personality_max_content_bytes
+ def test_max_onset_file_content_bytes(self):
+ max = FLAGS.quota_max_onset_file_content_bytes
content = ''.join(['a' for i in xrange(max)])
files = [('/test/path', content)]
- self._create_with_personality(files) # no QuotaError
+ self._create_with_onset_files(files) # no QuotaError
- def test_too_many_personality_content_bytes(self):
- max = FLAGS.quota_personality_max_content_bytes
+ def test_too_many_onset_file_content_bytes(self):
+ max = FLAGS.quota_max_onset_file_content_bytes
content = ''.join(['a' for i in xrange(max + 1)])
files = [('/test/path', content)]
self.assertRaises(quota.QuotaError,
- self._create_with_personality, files)
+ self._create_with_onset_files, files)
- def test_allowed_personality_path_bytes(self):
+ def test_allowed_onset_file_path_bytes(self):
self.assertEqual(
- quota.allowed_personality_path_bytes(self.context),
- FLAGS.quota_personality_max_path_bytes)
+ quota.allowed_onset_file_path_bytes(self.context),
+ FLAGS.quota_max_onset_file_path_bytes)
- def test_max_personality_path_bytes(self):
- max = FLAGS.quota_personality_max_path_bytes
+ def test_max_onset_file_path_bytes(self):
+ max = FLAGS.quota_max_onset_file_path_bytes
path = ''.join(['a' for i in xrange(max)])
files = [(path, 'config = quotatest')]
- self._create_with_personality(files) # no QuotaError
+ self._create_with_onset_files(files) # no QuotaError
- def test_too_many_personality_path_bytes(self):
- max = FLAGS.quota_personality_max_path_bytes
+ def test_too_many_onset_file_path_bytes(self):
+ max = FLAGS.quota_max_onset_file_path_bytes
path = ''.join(['a' for i in xrange(max + 1)])
files = [(path, 'config = quotatest')]
self.assertRaises(quota.QuotaError,
- self._create_with_personality, files)
+ self._create_with_onset_files, files)