diff options
| author | Todd Willey <todd@ansolabs.com> | 2010-11-01 14:13:58 -0400 |
|---|---|---|
| committer | Todd Willey <todd@ansolabs.com> | 2010-11-01 14:13:58 -0400 |
| commit | b76286c5ef2b2182cb0c2cc42b31971656e8f70f (patch) | |
| tree | 8141344278733882ddd57f9b0f5dfb1991860651 | |
| parent | bf15a6eb3de8c688dc1364959dd3e00d3e26a563 (diff) | |
| parent | ab1c34f71745b901f40fd6a72dffc7a29a864990 (diff) | |
| download | nova-b76286c5ef2b2182cb0c2cc42b31971656e8f70f.tar.gz nova-b76286c5ef2b2182cb0c2cc42b31971656e8f70f.tar.xz nova-b76286c5ef2b2182cb0c2cc42b31971656e8f70f.zip | |
Merge trunk and apply some sphinx love.
| -rw-r--r-- | doc/source/_ga/layout.html (renamed from doc/source/_templates/layout.html) | 0 | ||||
| -rw-r--r-- | doc/source/_templates/.DS_Store | bin | 0 -> 6148 bytes | |||
| -rw-r--r-- | doc/source/conf.py | 8 | ||||
| -rw-r--r-- | nova/adminclient.py | 76 | ||||
| -rw-r--r-- | nova/api/ec2/cloud.py | 34 | ||||
| -rw-r--r-- | nova/api/openstack/servers.py | 25 | ||||
| -rw-r--r-- | nova/compute/manager.py | 40 | ||||
| -rw-r--r-- | nova/crypto.py | 15 | ||||
| -rw-r--r-- | nova/db/sqlalchemy/api.py | 66 | ||||
| -rw-r--r-- | nova/db/sqlalchemy/models.py | 10 | ||||
| -rw-r--r-- | nova/tests/api/openstack/fakes.py | 1 | ||||
| -rw-r--r-- | nova/tests/api/openstack/test_api.py | 6 | ||||
| -rw-r--r-- | nova/tests/api/openstack/test_servers.py | 4 | ||||
| -rw-r--r-- | nova/utils.py | 5 |
14 files changed, 173 insertions, 117 deletions
diff --git a/doc/source/_templates/layout.html b/doc/source/_ga/layout.html index 0b72a77ac..0b72a77ac 100644 --- a/doc/source/_templates/layout.html +++ b/doc/source/_ga/layout.html diff --git a/doc/source/_templates/.DS_Store b/doc/source/_templates/.DS_Store Binary files differnew file mode 100644 index 000000000..5008ddfcf --- /dev/null +++ b/doc/source/_templates/.DS_Store diff --git a/doc/source/conf.py b/doc/source/conf.py index e91860536..27bc4ea6c 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -27,7 +27,13 @@ extensions = ['sphinx.ext.autodoc', 'sphinx.ext.intersphinx', 'sphinx.ext.todo', todo_include_todos = True # Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] +# Changing the path so that the Hudson build output contains GA code and the source +# docs do not contain the code so local, offline sphinx builds are "clean." +templates_path = [] +if os.getenv('HUDSON_PUBLISH_DOCS'): + templates_path = ['_ga', '_templates'] +else: + templates_path = ['_templates'] # The suffix of source filenames. source_suffix = '.rst' diff --git a/nova/adminclient.py b/nova/adminclient.py index b7a3d2c32..0227cddd7 100644 --- a/nova/adminclient.py +++ b/nova/adminclient.py @@ -33,14 +33,15 @@ DEFAULT_SECRET_KEY = 'admin' class UserInfo(object): """ - Information about a Nova user, as parsed through SAX - fields include: - username - accesskey - secretkey - - and an optional field containing a zip with X509 cert & rc - file + Information about a Nova user, as parsed through SAX. + + **Fields Include** + + * username + * accesskey + * secretkey + * file (optional) containing zip of X509 cert & rc file + """ def __init__(self, connection=None, username=None, endpoint=None): @@ -68,9 +69,13 @@ class UserInfo(object): class UserRole(object): """ Information about a Nova user's role, as parsed through SAX. - Fields include: - role + + **Fields include** + + * role + """ + def __init__(self, connection=None): self.connection = connection self.role = None @@ -90,12 +95,15 @@ class UserRole(object): class ProjectInfo(object): """ - Information about a Nova project, as parsed through SAX - Fields include: - projectname - description - projectManagerId - memberIds + Information about a Nova project, as parsed through SAX. + + **Fields include** + + * projectname + * description + * projectManagerId + * memberIds + """ def __init__(self, connection=None): @@ -127,8 +135,11 @@ class ProjectInfo(object): class ProjectMember(object): """ Information about a Nova project member, as parsed through SAX. - Fields include: - memberId + + **Fields include** + + * memberId + """ def __init__(self, connection=None): @@ -150,14 +161,18 @@ class ProjectMember(object): class HostInfo(object): """ - Information about a Nova Host, as parsed through SAX: - Disk stats - Running Instances - Memory stats - CPU stats - Network address info - Firewall info - Bridge and devices + Information about a Nova Host, as parsed through SAX. + + **Fields Include** + + * Disk stats + * Running Instances + * Memory stats + * CPU stats + * Network address info + * Firewall info + * Bridge and devices + """ def __init__(self, connection=None): @@ -257,9 +272,12 @@ class NovaAdminClient(object): [('item', UserRole)]) def get_user_roles(self, user, project=None): - """Returns a list of roles for the given user. Omitting project will - return any global roles that the user has. Specifying project will - return only project specific roles.""" + """Returns a list of roles for the given user. + + Omitting project will return any global roles that the user has. + Specifying project will return only project specific roles. + + """ params = {'User': user} if project: params['Project'] = project diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index dd5fe4065..f2a6dc3b0 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -99,6 +99,7 @@ class CloudController(object): """ def __init__(self): self.network_manager = utils.import_object(FLAGS.network_manager) + self.compute_manager = utils.import_object(FLAGS.compute_manager) self.setup() def __str__(self): @@ -835,21 +836,21 @@ class CloudController(object): elevated = context.elevated() for num in range(num_instances): - instance_ref = db.instance_create(context, base_options) - inst_id = instance_ref['id'] - for security_group_id in security_groups: - db.instance_add_security_group(elevated, - inst_id, - security_group_id) + instance_ref = self.compute_manager.create_instance(context, + security_groups, + mac_address=utils.generate_mac(), + launch_index=num, + **base_options) + inst_id = instance_ref['id'] - inst = {} - inst['mac_address'] = utils.generate_mac() - inst['launch_index'] = num internal_id = instance_ref['internal_id'] ec2_id = internal_id_to_ec2_id(internal_id) - inst['hostname'] = ec2_id - db.instance_update(context, inst_id, inst) + + self.compute_manager.update_instance(context, + inst_id, + hostname=ec2_id) + # TODO(vish): This probably should be done in the scheduler # or in compute as a call. The network should be # allocated after the host is assigned and setup @@ -895,11 +896,12 @@ class CloudController(object): id_str) continue now = datetime.datetime.utcnow() - db.instance_update(context, - instance_ref['id'], - {'state_description': 'terminating', - 'state': 0, - 'terminated_at': now}) + self.compute_manager.update_instance(context, + instance_ref['id'], + state_description='terminating', + state=0, + terminated_at=now) + # FIXME(ja): where should network deallocate occur? address = db.instance_get_floating_address(context, instance_ref['id']) diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py index ef773c3be..1d8aa2fa4 100644 --- a/nova/api/openstack/servers.py +++ b/nova/api/openstack/servers.py @@ -95,6 +95,7 @@ class Controller(wsgi.Controller): db_driver = FLAGS.db_driver self.db_driver = utils.import_object(db_driver) self.network_manager = utils.import_object(FLAGS.network_manager) + self.compute_manager = utils.import_object(FLAGS.compute_manager) super(Controller, self).__init__() def index(self, req): @@ -242,34 +243,30 @@ class Controller(wsgi.Controller): inst['memory_mb'] = flavor['memory_mb'] inst['vcpus'] = flavor['vcpus'] inst['local_gb'] = flavor['local_gb'] - - ref = self.db_driver.instance_create(ctxt, inst) - inst['id'] = ref.internal_id - inst['mac_address'] = utils.generate_mac() - - #TODO(dietz) is this necessary? inst['launch_index'] = 0 - inst['hostname'] = str(ref.internal_id) - self.db_driver.instance_update(ctxt, inst['id'], inst) + ref = self.compute_manager.create_instance(ctxt, **inst) + inst['id'] = ref['internal_id'] + + inst['hostname'] = str(ref['internal_id']) + self.compute_manager.update_instance(ctxt, inst['id'], **inst) - network_manager = utils.import_object(FLAGS.network_manager) - address = network_manager.allocate_fixed_ip(ctxt, - inst['id']) + address = self.network_manager.allocate_fixed_ip(ctxt, + inst['id']) # TODO(vish): This probably should be done in the scheduler # network is setup when host is assigned - network_topic = self._get_network_topic(ctxt, network_manager) + network_topic = self._get_network_topic(ctxt) rpc.call(ctxt, network_topic, {"method": "setup_fixed_ip", "args": {"address": address}}) return inst - def _get_network_topic(self, context, network_manager): + def _get_network_topic(self, context): """Retrieves the network host for a project""" - network_ref = network_manager.get_network(context) + network_ref = self.network_manager.get_network(context) host = network_ref['host'] if not host: host = rpc.call(context, diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 3346d1299..d63a66b91 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -83,6 +83,46 @@ class ComputeManager(manager.Manager): """This call passes stright through to the virtualization driver.""" yield self.driver.refresh_security_group(security_group_id) + def create_instance(self, context, security_groups=[], **kwargs): + """Creates the instance in the datastore and returns the + new instance as a mapping + + :param context: The security context + :param security_groups: list of security group ids to + attach to the instance + :param kwargs: All additional keyword args are treated + as data fields of the instance to be + created + + :retval Returns a mapping of the instance information + that has just been created + + """ + instance_ref = self.db.instance_create(context, kwargs) + inst_id = instance_ref['id'] + + elevated = context.elevated() + security_groups = kwargs.get('security_groups', []) + for security_group_id in security_groups: + self.db.instance_add_security_group(elevated, + inst_id, + security_group_id) + return instance_ref + + def update_instance(self, context, instance_id, **kwargs): + """Updates the instance in the datastore. + + :param context: The security context + :param instance_id: ID of the instance to update + :param kwargs: All additional keyword args are treated + as data fields of the instance to be + updated + + :retval None + + """ + self.db.instance_update(context, instance_id, kwargs) + @defer.inlineCallbacks @exception.wrap_exception def run_instance(self, context, instance_id, **_kwargs): diff --git a/nova/crypto.py b/nova/crypto.py index 16b4f5e1f..d73559587 100644 --- a/nova/crypto.py +++ b/nova/crypto.py @@ -15,10 +15,11 @@ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. - """ -Wrappers around standard crypto, including root and intermediate CAs, -SSH key_pairs and x509 certificates. +Wrappers around standard crypto data elements. + +Includes root and intermediate CAs, SSH key_pairs and x509 certificates. + """ import base64 @@ -227,12 +228,12 @@ def mkcacert(subject='nova', years=1): def compute_md5(fp): """ - @type fp: file - @param fp: File pointer to the file to MD5 hash. The file pointer will be + :type fp: file + :param fp: File pointer to the file to MD5 hash. The file pointer will be reset to the beginning of the file before the method returns. - @rtype: tuple - @return: the hex digest version of the MD5 hash + :rtype: tuple + :return: the hex digest version of the MD5 hash """ m = hashlib.md5() fp.seek(0) diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index d9b98655e..d8a08994a 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -236,8 +236,7 @@ def service_get_by_args(context, host, binary): @require_admin_context def service_create(context, values): service_ref = models.Service() - for (key, value) in values.iteritems(): - service_ref[key] = value + service_ref.update(values) service_ref.save() return service_ref @@ -247,8 +246,7 @@ def service_update(context, service_id, values): session = get_session() with session.begin(): service_ref = service_get(context, service_id, session=session) - for (key, value) in values.iteritems(): - service_ref[key] = value + service_ref.update(values) service_ref.save(session=session) @@ -279,8 +277,7 @@ def floating_ip_allocate_address(context, host, project_id): @require_context def floating_ip_create(context, values): floating_ip_ref = models.FloatingIp() - for (key, value) in values.iteritems(): - floating_ip_ref[key] = value + floating_ip_ref.update(values) floating_ip_ref.save() return floating_ip_ref['address'] @@ -451,8 +448,7 @@ def fixed_ip_associate_pool(context, network_id, instance_id): @require_context def fixed_ip_create(_context, values): fixed_ip_ref = models.FixedIp() - for (key, value) in values.iteritems(): - fixed_ip_ref[key] = value + fixed_ip_ref.update(values) fixed_ip_ref.save() return fixed_ip_ref['address'] @@ -523,8 +519,7 @@ def fixed_ip_update(context, address, values): fixed_ip_ref = fixed_ip_get_by_address(context, address, session=session) - for (key, value) in values.iteritems(): - fixed_ip_ref[key] = value + fixed_ip_ref.update(values) fixed_ip_ref.save(session=session) @@ -537,8 +532,7 @@ def fixed_ip_update(context, address, values): @require_context def instance_create(context, values): instance_ref = models.Instance() - for (key, value) in values.iteritems(): - instance_ref[key] = value + instance_ref.update(values) session = get_session() with session.begin(): @@ -731,8 +725,7 @@ def instance_update(context, instance_id, values): session = get_session() with session.begin(): instance_ref = instance_get(context, instance_id, session=session) - for (key, value) in values.iteritems(): - instance_ref[key] = value + instance_ref.update(values) instance_ref.save(session=session) @@ -754,8 +747,7 @@ def instance_add_security_group(context, instance_id, security_group_id): @require_context def key_pair_create(context, values): key_pair_ref = models.KeyPair() - for (key, value) in values.iteritems(): - key_pair_ref[key] = value + key_pair_ref.update(values) key_pair_ref.save() return key_pair_ref @@ -870,8 +862,7 @@ def network_count_reserved_ips(context, network_id): @require_admin_context def network_create_safe(context, values): network_ref = models.Network() - for (key, value) in values.iteritems(): - network_ref[key] = value + network_ref.update(values) try: network_ref.save() return network_ref @@ -980,8 +971,7 @@ def network_update(context, network_id, values): session = get_session() with session.begin(): network_ref = network_get(context, network_id, session=session) - for (key, value) in values.iteritems(): - network_ref[key] = value + network_ref.update(values) network_ref.save(session=session) @@ -1031,8 +1021,7 @@ def export_device_count(context): @require_admin_context def export_device_create_safe(context, values): export_device_ref = models.ExportDevice() - for (key, value) in values.iteritems(): - export_device_ref[key] = value + export_device_ref.update(values) try: export_device_ref.save() return export_device_ref @@ -1060,8 +1049,7 @@ def auth_get_token(_context, token_hash): def auth_create_token(_context, token): tk = models.AuthToken() - for k, v in token.iteritems(): - tk[k] = v + tk.update(token) tk.save() return tk @@ -1087,8 +1075,7 @@ def quota_get(context, project_id, session=None): @require_admin_context def quota_create(context, values): quota_ref = models.Quota() - for (key, value) in values.iteritems(): - quota_ref[key] = value + quota_ref.update(values) quota_ref.save() return quota_ref @@ -1098,8 +1085,7 @@ def quota_update(context, project_id, values): session = get_session() with session.begin(): quota_ref = quota_get(context, project_id, session=session) - for (key, value) in values.iteritems(): - quota_ref[key] = value + quota_ref.update(values) quota_ref.save(session=session) @@ -1148,8 +1134,7 @@ def volume_attached(context, volume_id, instance_id, mountpoint): @require_context def volume_create(context, values): volume_ref = models.Volume() - for (key, value) in values.iteritems(): - volume_ref[key] = value + volume_ref.update(values) session = get_session() with session.begin(): @@ -1306,8 +1291,7 @@ def volume_update(context, volume_id, values): session = get_session() with session.begin(): volume_ref = volume_get(context, volume_id, session=session) - for (key, value) in values.iteritems(): - volume_ref[key] = value + volume_ref.update(values) volume_ref.save(session=session) @@ -1400,8 +1384,7 @@ def security_group_create(context, values): # FIXME(devcamcar): Unless I do this, rules fails with lazy load exception # once save() is called. This will get cleaned up in next orm pass. security_group_ref.rules - for (key, value) in values.iteritems(): - security_group_ref[key] = value + security_group_ref.update(values) security_group_ref.save() return security_group_ref @@ -1455,8 +1438,7 @@ def security_group_rule_get(context, security_group_rule_id, session=None): @require_context def security_group_rule_create(context, values): security_group_rule_ref = models.SecurityGroupIngressRule() - for (key, value) in values.iteritems(): - security_group_rule_ref[key] = value + security_group_rule_ref.update(values) security_group_rule_ref.save() return security_group_rule_ref @@ -1508,8 +1490,7 @@ def user_get_by_access_key(context, access_key, session=None): @require_admin_context def user_create(_context, values): user_ref = models.User() - for (key, value) in values.iteritems(): - user_ref[key] = value + user_ref.update(values) user_ref.save() return user_ref @@ -1537,8 +1518,7 @@ def user_get_all(context): def project_create(_context, values): project_ref = models.Project() - for (key, value) in values.iteritems(): - project_ref[key] = value + project_ref.update(values) project_ref.save() return project_ref @@ -1600,8 +1580,7 @@ def user_update(context, user_id, values): session = get_session() with session.begin(): user_ref = user_get(context, user_id, session=session) - for (key, value) in values.iteritems(): - user_ref[key] = value + user_ref.update(values) user_ref.save(session=session) @@ -1609,8 +1588,7 @@ def project_update(context, project_id, values): session = get_session() with session.begin(): project_ref = project_get(context, project_id, session=session) - for (key, value) in values.iteritems(): - project_ref[key] = value + project_ref.update(values) project_ref.save(session=session) diff --git a/nova/db/sqlalchemy/models.py b/nova/db/sqlalchemy/models.py index 29c3b74da..c79cc623e 100644 --- a/nova/db/sqlalchemy/models.py +++ b/nova/db/sqlalchemy/models.py @@ -81,6 +81,16 @@ class NovaBase(object): n = self._i.next().name return n, getattr(self, n) + def update(self, values): + """Make the model object behave like a dict""" + for k, v in values.iteritems(): + setattr(self, k, v) + + def iteritems(self): + """Make the model object behave like a dict""" + return iter(self) + + # TODO(vish): Store images in the database instead of file system #class Image(BASE, NovaBase): # """Represents an image in the datastore""" diff --git a/nova/tests/api/openstack/fakes.py b/nova/tests/api/openstack/fakes.py index 7ecb72ab3..1b8c18974 100644 --- a/nova/tests/api/openstack/fakes.py +++ b/nova/tests/api/openstack/fakes.py @@ -30,6 +30,7 @@ from nova import exception as exc import nova.api.openstack.auth from nova.image import service from nova.image.services import glance +from nova.tests import fake_flags from nova.wsgi import Router diff --git a/nova/tests/api/openstack/test_api.py b/nova/tests/api/openstack/test_api.py index a8c0ff9f8..dd83991b9 100644 --- a/nova/tests/api/openstack/test_api.py +++ b/nova/tests/api/openstack/test_api.py @@ -24,22 +24,28 @@ from nova.api.openstack import API from nova.api.openstack import faults from webob import Request + class APITest(unittest.TestCase): def test_exceptions_are_converted_to_faults(self): + @webob.dec.wsgify def succeed(req): return 'Succeeded' + @webob.dec.wsgify def raise_webob_exc(req): raise webob.exc.HTTPNotFound(explanation='Raised a webob.exc') + @webob.dec.wsgify def fail(req): raise Exception("Threw an exception") + @webob.dec.wsgify def raise_api_fault(req): exc = webob.exc.HTTPNotFound(explanation='Raised a webob.exc') return faults.Fault(exc) + api = API() api.application = succeed diff --git a/nova/tests/api/openstack/test_servers.py b/nova/tests/api/openstack/test_servers.py index 55efcf733..785fb6f3a 100644 --- a/nova/tests/api/openstack/test_servers.py +++ b/nova/tests/api/openstack/test_servers.py @@ -91,9 +91,7 @@ class ServersTest(unittest.TestCase): pass def instance_create(context, inst): - class Foo(object): - internal_id = 1 - return Foo() + return {'id': 1, 'internal_id': 1} def fake_method(*args, **kwargs): pass diff --git a/nova/utils.py b/nova/utils.py index 2c53b027e..bc495a691 100644 --- a/nova/utils.py +++ b/nova/utils.py @@ -213,10 +213,10 @@ def deferredToThread(f): def xhtml_escape(value): """Escapes a string so it is valid within XML or XHTML. - + Code is directly from the utf8 function in http://github.com/facebook/tornado/blob/master/tornado/escape.py - + """ return saxutils.escape(value, {'"': """}) @@ -232,4 +232,3 @@ def utf8(value): return value.encode("utf-8") assert isinstance(value, str) return value - |
