Merge lp:~ken-pepple/nova/dynamicinstancetypes into lp:~hudson-openstack/nova/trunk

Proposed by Ken Pepple
Status: Merged
Approved by: Josh Kearney
Approved revision: 699
Merged at revision: 757
Proposed branch: lp:~ken-pepple/nova/dynamicinstancetypes
Merge into: lp:~hudson-openstack/nova/trunk
Diff against target: 1494 lines (+816/-252)
29 files modified
bin/nova-manage (+77/-1)
doc/.autogenerated (+80/-203)
doc/source/api/autoindex.rst (+6/-0)
doc/source/api/nova..db.sqlalchemy.migrate_repo.versions.005_add_instance_metadata.rst (+6/-0)
doc/source/api/nova..db.sqlalchemy.migrate_repo.versions.006_add_provider_data_to_volumes.rst (+6/-0)
doc/source/api/nova..db.sqlalchemy.migrate_repo.versions.007_add_instance_types.rst (+6/-0)
doc/source/api/nova..tests.test_instance_types.rst (+6/-0)
doc/source/api/nova..tests.test_test.rst (+6/-0)
doc/source/api/nova..tests.test_utils.rst (+6/-0)
doc/source/man/novamanage.rst (+36/-0)
doc/source/nova.concepts.rst (+5/-0)
doc/source/runnova/managing.instance.types.rst (+84/-0)
nova/api/ec2/admin.py (+5/-6)
nova/api/openstack/__init__.py (+1/-0)
nova/api/openstack/flavors.py (+11/-9)
nova/compute/api.py (+3/-3)
nova/compute/instance_types.py (+107/-16)
nova/db/api.py (+35/-0)
nova/db/sqlalchemy/api.py (+92/-0)
nova/db/sqlalchemy/migrate_repo/versions/008_add_instance_types.py (+87/-0)
nova/db/sqlalchemy/models.py (+15/-1)
nova/tests/api/openstack/test_flavors.py (+7/-1)
nova/tests/db/fakes.py (+19/-2)
nova/tests/test_instance_types.py (+86/-0)
nova/tests/test_quota.py (+14/-3)
nova/tests/test_xenapi.py (+1/-1)
nova/virt/libvirt_conn.py (+4/-2)
nova/virt/xenapi/vm_utils.py (+4/-2)
plugins/xenserver/xenapi/etc/xapi.d/plugins/glance (+1/-2)
To merge this branch: bzr merge lp:~ken-pepple/nova/dynamicinstancetypes
Reviewer Review Type Date Requested Status
Devin Carlen (community) Approve
Josh Kearney (community) Approve
Review via email: mp+50257@code.launchpad.net

Commit message

Description of the change

This allows admins to manipulate instance types at runtime via the nova-manage command.

See http://wiki.openstack.org/ConfigureInstanceTypesDynamically the full spec.

To post a comment you must log in.
Revision history for this message
Devin Carlen (devcamcar) wrote :

There are a few merge conflicts that need resolving.

review: Needs Fixing
Revision history for this message
Ken Pepple (ken-pepple) wrote :

> There are a few merge conflicts that need resolving.

sorry ... we merged yesterday but didn't see the zones blueprint come in.
i've merged but now we are deadlocked on migration numbering ... 005- has been taken by justinsb but hasn't merged yet, so our DB won't migrate (we are 006-) and tests don't run. going to go against the usual rule of "don't commit/push if tests don't run" ...

Revision history for this message
Jay Pipes (jaypipes) wrote :

Hi Ken,

Are you currently working on this branch? If so, please set the merge proposal status to Work In Progress, and then, after bzr push'ing any changes to LP, set the merge proposal status back to Needs Review. This will trigger emails to reviewers to re-review the branch.

Cheers!
jay

Revision history for this message
Ken Pepple (ken-pepple) wrote :

> Are you currently working on this branch? If so, please set the merge proposal
> status to Work In Progress, and then, after bzr push'ing any changes to LP,
> set the merge proposal status back to Needs Review. This will trigger emails
> to reviewers to re-review the branch.

I think I did the "wip" to "needs review" flip in the wrong order ... this should be ready for code review at revno 670.

thanks
/k

Revision history for this message
Ken Pepple (ken-pepple) wrote :

updated and should be ready for review at revno 682

Revision history for this message
Josh Kearney (jk0) wrote :

Looks good - I just have one little nit: the copyright headers in the new files should have a name and year in them (someone correct me if this is not true).

Revision history for this message
Ken Pepple (ken-pepple) wrote :

soooo ... i have questions about the copyrights: many of the files have NASA copyrights. i haven't included them on the new files as i don't work for NASA and have no standing to assign them copyright. what is the standard here ?

Revision history for this message
Josh Kearney (jk0) wrote :

> soooo ... i have questions about the copyrights: many of the files have NASA
> copyrights. i haven't included them on the new files as i don't work for NASA
> and have no standing to assign them copyright. what is the standard here ?

We've been using "Copyright 2011 OpenStack LLC".

Revision history for this message
Eric Day (eday) wrote :

Each file has it's own copyright. If you've written it from scratch,
you put Copyright 2011 <name> (name will be a person or some other
legal entity such as a company, depending on who's time it is). If
you make significant changes to existing files, you can also add a
copyright line to those files (never remove a line though).

-Eric

On Tue, Mar 01, 2011 at 06:08:14PM -0000, Ken Pepple wrote:
> soooo ... i have questions about the copyrights: many of the files have NASA copyrights. i haven't included them on the new files as i don't work for NASA and have no standing to assign them copyright. what is the standard here ?
> --
> https://code.launchpad.net/~ken-pepple/nova/dynamicinstancetypes/+merge/50257
> Your team Nova Core is requested to review the proposed merge of lp:~ken-pepple/nova/dynamicinstancetypes into lp:nova.

Revision history for this message
Eric Day (eday) wrote :

On Tue, Mar 01, 2011 at 06:12:28PM -0000, Josh Kearney wrote:
> We've been using "Copyright 2011 OpenStack LLC".

This really only applies to Rackspace employees for now, or folks who
wish to (and have the ability to) transfer all copyright ownership
to OpenStack LLC.

-Eric

Revision history for this message
Josh Kearney (jk0) wrote :

> On Tue, Mar 01, 2011 at 06:12:28PM -0000, Josh Kearney wrote:
> > We've been using "Copyright 2011 OpenStack LLC".
>
> This really only applies to Rackspace employees for now, or folks who
> wish to (and have the ability to) transfer all copyright ownership
> to OpenStack LLC.
>
> -Eric

Ah, that makes sense.

So Ken, feel free to use your name. :)

Revision history for this message
Ken Pepple (ken-pepple) wrote :

okay, i am going to add "Copyright 2011 Ken Pepple <email address hidden>" to the following files:

 - doc/source/runnova/managing.instance.types.rst
 - nova/db/sqlalchemy/migrate_repo/versions/007_add_instance_types.py
 - nova/compute/instance_types.py (leaving the current ones also)
 - nova/tests/test_instance_types.py

i'll wait to push this until others have weighed in.

Revision history for this message
Eric Day (eday) wrote :

Just one little thing, you shouldn't put your email address in the
copyright line. Email addresses should go in the Authors file. :)

-Eric

On Tue, Mar 01, 2011 at 06:27:57PM -0000, Ken Pepple wrote:
> okay, i am going to add "Copyright 2011 Ken Pepple <email address hidden>" to the following files:
>
> - doc/source/runnova/managing.instance.types.rst
> - nova/db/sqlalchemy/migrate_repo/versions/007_add_instance_types.py
> - nova/compute/instance_types.py (leaving the current ones also)
> - nova/tests/test_instance_types.py
>
> i'll wait to push this until others have weighed in.
> --
> https://code.launchpad.net/~ken-pepple/nova/dynamicinstancetypes/+merge/50257
> Your team Nova Core is requested to review the proposed merge of lp:~ken-pepple/nova/dynamicinstancetypes into lp:nova.

Revision history for this message
Ken Pepple (ken-pepple) wrote :

ok, "Copyright 2011 Ken Pepple" it is.

Revision history for this message
Josh Kearney (jk0) wrote :

Looks great, thanks Ken!

review: Approve
Revision history for this message
Devin Carlen (devcamcar) wrote :

33 + def create(
34 + self,
35 + name,
36 + memory,
37 + vcpus,
38 + local_gb,
39 + flavorid,
40 + swap=0,
41 + rxtx_quota=0,
42 + rxtx_cap=0):

Style nit. Nova uses this style:

def create(self, name, ...
           etc, etc, etc=0)

640 def describe_instance_types(self, _context, **_kwargs):

Change _context to context. _ is used to indicate that a variable isn't being used.

160 -source/api/nova..adminclient.rst
161 -source/api/nova..api.direct.rst
162 -source/api/nova..api.ec2.admin.rst
163 -source/api/nova..api.ec2.apirequest.rst
164 -source/api/nova..api.ec2.cloud.rst
165 -source/api/nova..api.ec2.metadatarequesthandler.rst

Why are all of these removed? There are a lot more.

697 + def create(self, req):
698 + """Create a flavor."""
699 + #TODO(jk0): Finish this later

Probably better to raise a NotImplemented here rather than give a false positive to the user.

723 + flavor_ids = [inst_types[i]['flavorid'] for i in inst_types.keys()]

We should sort this somehow. inst_types.keys() will be pretty much random because of the way python handles dicts. Wrapping in a sorted() is probably good enough.

797 + dict(
798 + name=name,

Style nit, use dict(name=name,
                    ...

806 + except exception.DBError:
807 + raise exception.ApiError(_("Cannot create instance type: %s"),
808 + name)

We are losing the original exception completely in this case. Let's at least have a log.exception() before the re-raise.

687 + # FIXME(kpepple) do we really need admin context here ?
688 + ctxt = context.get_admin_context()

Use req.environ['nova.context'] for context in OpenStack API.

807 + raise exception.ApiError(_("Cannot create instance type: %s"),
808 + name)

This looks odd somehow. Is name supposed to be a param to _() or ApiError()?

954 +def instance_type_create(context, values):

When context isn't used, prefix it with _. In general if a variable on a function isn't used for some reason, it gets prefixed with a _.

review: Needs Fixing
Revision history for this message
Devin Carlen (devcamcar) wrote :

lgtm

review: Approve
Revision history for this message
OpenStack Infra (hudson-openstack) wrote :
Download full text (11.9 KiB)

The attempt to merge lp:~ken-pepple/nova/dynamicinstancetypes into lp:nova failed. Below is the output from the failed tests.

ERROR

======================================================================
ERROR: <nose.suite.ContextSuite context=nova.tests>
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib/pymodules/python2.6/nose/suite.py", line 183, in run
    self.setUp()
  File "/usr/lib/pymodules/python2.6/nose/suite.py", line 264, in setUp
    self.setupContext(ancestor)
  File "/usr/lib/pymodules/python2.6/nose/suite.py", line 287, in setupContext
    try_run(context, names)
  File "/usr/lib/pymodules/python2.6/nose/util.py", line 487, in try_run
    return func()
  File "/tmp/tmpuJJxJt/nova/tests/__init__.py", line 54, in setup
    migration.db_sync()
  File "/tmp/tmpuJJxJt/nova/db/migration.py", line 33, in db_sync
    return IMPL.db_sync(version=version)
  File "/tmp/tmpuJJxJt/nova/db/sqlalchemy/migration.py", line 41, in db_sync
    db_version()
  File "/tmp/tmpuJJxJt/nova/db/sqlalchemy/migration.py", line 49, in db_version
    return versioning_api.db_version(FLAGS.sql_connection, repo_path)
  File "<string>", line 2, in db_version
  File "/usr/lib/pymodules/python2.6/migrate/versioning/util/__init__.py", line 160, in with_engine
    return f(*a, **kw)
  File "/usr/lib/pymodules/python2.6/migrate/versioning/api.py", line 147, in db_version
    schema = ControlledSchema(engine, repository)
  File "/usr/lib/pymodules/python2.6/migrate/versioning/schema.py", line 26, in __init__
    repository = Repository(repository)
  File "/usr/lib/pymodules/python2.6/migrate/versioning/repository.py", line 80, in __init__
    self._versions))
  File "/usr/lib/pymodules/python2.6/migrate/versioning/version.py", line 83, in __init__
    self.versions[VerNum(num)] = Version(num, path, files)
  File "/usr/lib/pymodules/python2.6/migrate/versioning/version.py", line 153, in __init__
    self.add_script(os.path.join(path, script))
  File "/usr/lib/pymodules/python2.6/migrate/versioning/version.py", line 174, in add_script
    self._add_script_py(path)
  File "/usr/lib/pymodules/python2.6/migrate/versioning/version.py", line 197, in _add_script_py
    'per version, but you have: %s and %s' % (self.python, path))
ScriptError: You can only have one Python script per version, but you have: /tmp/tmpuJJxJt/nova/db/sqlalchemy/migrate_repo/versions/007_add_instance_types.py and /tmp/tmpuJJxJt/nova/db/sqlalchemy/migrate_repo/versions/007_add_ipv6_to_fixed_ips.py
-------------------- >> begin captured logging << --------------------
2011-03-03 01:47:27,391 DEBUG nova.utils [-] backend <module 'nova.db.sqlalchemy.migration' from '/tmp/tmpuJJxJt/nova/db/sqlalchemy/migration.py'> from (pid=20562) __get_backend /tmp/tmpuJJxJt/nova/utils.py:376
2011-03-03 01:47:27,391 DEBUG migrate.versioning.util [-] Constructing engine from (pid=20562) construct_engine /usr/lib/pymodules/python2.6/migrate/versioning/util/__init__.py:138
2011-03-03 01:47:27,396 DEBUG migrate.versioning.repository [-] Loading repository /tmp/tmpuJJxJt/nova/db/sqlalchemy/migrate_repo... from (pid=20562) __init__ /usr/lib/pymodules...

698. By Ken Pepple

merged trunk

699. By Ken Pepple

moved migration to 008 (sigh)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'bin/nova-manage'
2--- bin/nova-manage 2011-02-26 09:05:03 +0000
3+++ bin/nova-manage 2011-03-03 01:57:15 +0000
4@@ -84,6 +84,7 @@
5 from nova.api.ec2.cloud import ec2_id_to_id
6 from nova.auth import manager
7 from nova.cloudpipe import pipelib
8+from nova.compute import instance_types
9 from nova.db import migration
10
11 FLAGS = flags.FLAGS
12@@ -661,6 +662,79 @@
13 "mountpoint": volume['mountpoint']}})
14
15
16+class InstanceTypeCommands(object):
17+ """Class for managing instance types / flavors."""
18+
19+ def _print_instance_types(self, n, val):
20+ deleted = ('', ', inactive')[val["deleted"] == 1]
21+ print ("%s: Memory: %sMB, VCPUS: %s, Storage: %sGB, FlavorID: %s, "
22+ "Swap: %sGB, RXTX Quota: %sGB, RXTX Cap: %sMB%s") % (
23+ n, val["memory_mb"], val["vcpus"], val["local_gb"],
24+ val["flavorid"], val["swap"], val["rxtx_quota"],
25+ val["rxtx_cap"], deleted)
26+
27+ def create(self, name, memory, vcpus, local_gb, flavorid,
28+ swap=0, rxtx_quota=0, rxtx_cap=0):
29+ """Creates instance types / flavors
30+ arguments: name memory vcpus local_gb flavorid [swap] [rxtx_quota]
31+ [rxtx_cap]
32+ """
33+ try:
34+ instance_types.create(name, memory, vcpus, local_gb,
35+ flavorid, swap, rxtx_quota, rxtx_cap)
36+ except exception.InvalidInputException:
37+ print "Must supply valid parameters to create instance type"
38+ print e
39+ sys.exit(1)
40+ except exception.DBError, e:
41+ print "DB Error: %s" % e
42+ sys.exit(2)
43+ except:
44+ print "Unknown error"
45+ sys.exit(3)
46+ else:
47+ print "%s created" % name
48+
49+ def delete(self, name, purge=None):
50+ """Marks instance types / flavors as deleted
51+ arguments: name"""
52+ try:
53+ if purge == "--purge":
54+ instance_types.purge(name)
55+ verb = "purged"
56+ else:
57+ instance_types.destroy(name)
58+ verb = "deleted"
59+ except exception.ApiError:
60+ print "Valid instance type name is required"
61+ sys.exit(1)
62+ except exception.DBError, e:
63+ print "DB Error: %s" % e
64+ sys.exit(2)
65+ except:
66+ sys.exit(3)
67+ else:
68+ print "%s %s" % (name, verb)
69+
70+ def list(self, name=None):
71+ """Lists all active or specific instance types / flavors
72+ arguments: [name]"""
73+ try:
74+ if name == None:
75+ inst_types = instance_types.get_all_types()
76+ elif name == "--all":
77+ inst_types = instance_types.get_all_types(1)
78+ else:
79+ inst_types = instance_types.get_instance_type(name)
80+ except exception.DBError, e:
81+ _db_error(e)
82+ if isinstance(inst_types.values()[0], dict):
83+ for k, v in inst_types.iteritems():
84+ self._print_instance_types(k, v)
85+ else:
86+ self._print_instance_types(name, inst_types)
87+
88+
89 CATEGORIES = [
90 ('user', UserCommands),
91 ('project', ProjectCommands),
92@@ -673,7 +747,9 @@
93 ('service', ServiceCommands),
94 ('log', LogCommands),
95 ('db', DbCommands),
96- ('volume', VolumeCommands)]
97+ ('volume', VolumeCommands),
98+ ('instance_type', InstanceTypeCommands),
99+ ('flavor', InstanceTypeCommands)]
100
101
102 def lazy_match(name, key_value_tuples):
103
104=== modified file 'doc/.autogenerated'
105--- doc/.autogenerated 2011-02-21 20:30:20 +0000
106+++ doc/.autogenerated 2011-03-03 01:57:15 +0000
107@@ -40,6 +40,9 @@
108 source/api/nova..db.sqlalchemy.migrate_repo.versions.002_bexar.rst
109 source/api/nova..db.sqlalchemy.migrate_repo.versions.003_add_label_to_networks.rst
110 source/api/nova..db.sqlalchemy.migrate_repo.versions.004_add_zone_tables.rst
111+source/api/nova..db.sqlalchemy.migrate_repo.versions.005_add_instance_metadata.rst
112+source/api/nova..db.sqlalchemy.migrate_repo.versions.006_add_provider_data_to_volumes.rst
113+source/api/nova..db.sqlalchemy.migrate_repo.versions.007_add_instance_types.rst
114 source/api/nova..db.sqlalchemy.migration.rst
115 source/api/nova..db.sqlalchemy.models.rst
116 source/api/nova..db.sqlalchemy.session.rst
117@@ -98,6 +101,7 @@
118 source/api/nova..tests.test_console.rst
119 source/api/nova..tests.test_direct.rst
120 source/api/nova..tests.test_flags.rst
121+source/api/nova..tests.test_instance_types.rst
122 source/api/nova..tests.test_localization.rst
123 source/api/nova..tests.test_log.rst
124 source/api/nova..tests.test_middleware.rst
125@@ -107,7 +111,9 @@
126 source/api/nova..tests.test_rpc.rst
127 source/api/nova..tests.test_scheduler.rst
128 source/api/nova..tests.test_service.rst
129+source/api/nova..tests.test_test.rst
130 source/api/nova..tests.test_twistd.rst
131+source/api/nova..tests.test_utils.rst
132 source/api/nova..tests.test_virt.rst
133 source/api/nova..tests.test_volume.rst
134 source/api/nova..tests.test_xenapi.rst
135@@ -176,209 +182,80 @@
136 source/api/nova..db.sqlalchemy.migrate_repo.versions.002_bexar.rst
137 source/api/nova..db.sqlalchemy.migrate_repo.versions.003_add_label_to_networks.rst
138 source/api/nova..db.sqlalchemy.migrate_repo.versions.004_add_zone_tables.rst
139-source/api/nova..db.sqlalchemy.migration.rst
140-source/api/nova..db.sqlalchemy.models.rst
141-source/api/nova..db.sqlalchemy.session.rst
142-source/api/nova..exception.rst
143-source/api/nova..fakememcache.rst
144-source/api/nova..fakerabbit.rst
145-source/api/nova..flags.rst
146-source/api/nova..image.glance.rst
147-source/api/nova..image.local.rst
148-source/api/nova..image.s3.rst
149-source/api/nova..image.service.rst
150-source/api/nova..log.rst
151-source/api/nova..manager.rst
152-source/api/nova..network.api.rst
153-source/api/nova..network.linux_net.rst
154-source/api/nova..network.manager.rst
155-source/api/nova..objectstore.bucket.rst
156-source/api/nova..objectstore.handler.rst
157-source/api/nova..objectstore.image.rst
158-source/api/nova..objectstore.stored.rst
159-source/api/nova..quota.rst
160-source/api/nova..rpc.rst
161-source/api/nova..scheduler.chance.rst
162-source/api/nova..scheduler.driver.rst
163-source/api/nova..scheduler.manager.rst
164-source/api/nova..scheduler.simple.rst
165-source/api/nova..scheduler.zone.rst
166-source/api/nova..service.rst
167-source/api/nova..test.rst
168-source/api/nova..tests.api.openstack.fakes.rst
169-source/api/nova..tests.api.openstack.test_adminapi.rst
170-source/api/nova..tests.api.openstack.test_api.rst
171-source/api/nova..tests.api.openstack.test_auth.rst
172-source/api/nova..tests.api.openstack.test_common.rst
173-source/api/nova..tests.api.openstack.test_faults.rst
174-source/api/nova..tests.api.openstack.test_flavors.rst
175-source/api/nova..tests.api.openstack.test_images.rst
176-source/api/nova..tests.api.openstack.test_ratelimiting.rst
177-source/api/nova..tests.api.openstack.test_servers.rst
178-source/api/nova..tests.api.openstack.test_shared_ip_groups.rst
179-source/api/nova..tests.api.openstack.test_zones.rst
180-source/api/nova..tests.api.test_wsgi.rst
181-source/api/nova..tests.db.fakes.rst
182-source/api/nova..tests.declare_flags.rst
183-source/api/nova..tests.fake_flags.rst
184-source/api/nova..tests.glance.stubs.rst
185-source/api/nova..tests.hyperv_unittest.rst
186-source/api/nova..tests.objectstore_unittest.rst
187-source/api/nova..tests.real_flags.rst
188-source/api/nova..tests.runtime_flags.rst
189-source/api/nova..tests.test_access.rst
190-source/api/nova..tests.test_api.rst
191-source/api/nova..tests.test_auth.rst
192-source/api/nova..tests.test_cloud.rst
193-source/api/nova..tests.test_compute.rst
194-source/api/nova..tests.test_console.rst
195-source/api/nova..tests.test_direct.rst
196-source/api/nova..tests.test_flags.rst
197-source/api/nova..tests.test_localization.rst
198-source/api/nova..tests.test_log.rst
199-source/api/nova..tests.test_middleware.rst
200-source/api/nova..tests.test_misc.rst
201-source/api/nova..tests.test_network.rst
202-source/api/nova..tests.test_quota.rst
203-source/api/nova..tests.test_rpc.rst
204-source/api/nova..tests.test_scheduler.rst
205-source/api/nova..tests.test_service.rst
206-source/api/nova..tests.test_twistd.rst
207-source/api/nova..tests.test_virt.rst
208-source/api/nova..tests.test_volume.rst
209-source/api/nova..tests.test_xenapi.rst
210-source/api/nova..tests.xenapi.stubs.rst
211-source/api/nova..twistd.rst
212-source/api/nova..utils.rst
213-source/api/nova..version.rst
214-source/api/nova..virt.connection.rst
215-source/api/nova..virt.disk.rst
216-source/api/nova..virt.fake.rst
217-source/api/nova..virt.hyperv.rst
218-source/api/nova..virt.images.rst
219-source/api/nova..virt.libvirt_conn.rst
220-source/api/nova..virt.xenapi.fake.rst
221-source/api/nova..virt.xenapi.network_utils.rst
222-source/api/nova..virt.xenapi.vm_utils.rst
223-source/api/nova..virt.xenapi.vmops.rst
224-source/api/nova..virt.xenapi.volume_utils.rst
225-source/api/nova..virt.xenapi.volumeops.rst
226-source/api/nova..virt.xenapi_conn.rst
227-source/api/nova..volume.api.rst
228-source/api/nova..volume.driver.rst
229-source/api/nova..volume.manager.rst
230-source/api/nova..volume.san.rst
231-source/api/nova..wsgi.rst
232-source/api/nova..adminclient.rst
233-source/api/nova..api.direct.rst
234-source/api/nova..api.ec2.admin.rst
235-source/api/nova..api.ec2.apirequest.rst
236-source/api/nova..api.ec2.cloud.rst
237-source/api/nova..api.ec2.metadatarequesthandler.rst
238-source/api/nova..api.openstack.auth.rst
239-source/api/nova..api.openstack.backup_schedules.rst
240-source/api/nova..api.openstack.common.rst
241-source/api/nova..api.openstack.consoles.rst
242-source/api/nova..api.openstack.faults.rst
243-source/api/nova..api.openstack.flavors.rst
244-source/api/nova..api.openstack.images.rst
245-source/api/nova..api.openstack.servers.rst
246-source/api/nova..api.openstack.shared_ip_groups.rst
247-source/api/nova..api.openstack.zones.rst
248-source/api/nova..auth.dbdriver.rst
249-source/api/nova..auth.fakeldap.rst
250-source/api/nova..auth.ldapdriver.rst
251-source/api/nova..auth.manager.rst
252-source/api/nova..auth.signer.rst
253-source/api/nova..cloudpipe.pipelib.rst
254-source/api/nova..compute.api.rst
255-source/api/nova..compute.instance_types.rst
256-source/api/nova..compute.manager.rst
257-source/api/nova..compute.monitor.rst
258-source/api/nova..compute.power_state.rst
259-source/api/nova..console.api.rst
260-source/api/nova..console.fake.rst
261-source/api/nova..console.manager.rst
262-source/api/nova..console.xvp.rst
263-source/api/nova..context.rst
264-source/api/nova..crypto.rst
265-source/api/nova..db.api.rst
266-source/api/nova..db.base.rst
267-source/api/nova..db.migration.rst
268-source/api/nova..db.sqlalchemy.api.rst
269-source/api/nova..db.sqlalchemy.migrate_repo.manage.rst
270-source/api/nova..db.sqlalchemy.migrate_repo.versions.001_austin.rst
271-source/api/nova..db.sqlalchemy.migrate_repo.versions.002_bexar.rst
272-source/api/nova..db.sqlalchemy.migrate_repo.versions.003_add_label_to_networks.rst
273-source/api/nova..db.sqlalchemy.migrate_repo.versions.004_add_zone_tables.rst
274-source/api/nova..db.sqlalchemy.migration.rst
275-source/api/nova..db.sqlalchemy.models.rst
276-source/api/nova..db.sqlalchemy.session.rst
277-source/api/nova..exception.rst
278-source/api/nova..fakememcache.rst
279-source/api/nova..fakerabbit.rst
280-source/api/nova..flags.rst
281-source/api/nova..image.glance.rst
282-source/api/nova..image.local.rst
283-source/api/nova..image.s3.rst
284-source/api/nova..image.service.rst
285-source/api/nova..log.rst
286-source/api/nova..manager.rst
287-source/api/nova..network.api.rst
288-source/api/nova..network.linux_net.rst
289-source/api/nova..network.manager.rst
290-source/api/nova..objectstore.bucket.rst
291-source/api/nova..objectstore.handler.rst
292-source/api/nova..objectstore.image.rst
293-source/api/nova..objectstore.stored.rst
294-source/api/nova..quota.rst
295-source/api/nova..rpc.rst
296-source/api/nova..scheduler.chance.rst
297-source/api/nova..scheduler.driver.rst
298-source/api/nova..scheduler.manager.rst
299-source/api/nova..scheduler.simple.rst
300-source/api/nova..scheduler.zone.rst
301-source/api/nova..service.rst
302-source/api/nova..test.rst
303-source/api/nova..tests.api.openstack.fakes.rst
304-source/api/nova..tests.api.openstack.test_adminapi.rst
305-source/api/nova..tests.api.openstack.test_api.rst
306-source/api/nova..tests.api.openstack.test_auth.rst
307-source/api/nova..tests.api.openstack.test_common.rst
308-source/api/nova..tests.api.openstack.test_faults.rst
309-source/api/nova..tests.api.openstack.test_flavors.rst
310-source/api/nova..tests.api.openstack.test_images.rst
311-source/api/nova..tests.api.openstack.test_ratelimiting.rst
312-source/api/nova..tests.api.openstack.test_servers.rst
313-source/api/nova..tests.api.openstack.test_shared_ip_groups.rst
314-source/api/nova..tests.api.openstack.test_zones.rst
315-source/api/nova..tests.api.test_wsgi.rst
316-source/api/nova..tests.db.fakes.rst
317-source/api/nova..tests.declare_flags.rst
318-source/api/nova..tests.fake_flags.rst
319-source/api/nova..tests.glance.stubs.rst
320-source/api/nova..tests.hyperv_unittest.rst
321-source/api/nova..tests.objectstore_unittest.rst
322-source/api/nova..tests.real_flags.rst
323-source/api/nova..tests.runtime_flags.rst
324-source/api/nova..tests.test_access.rst
325-source/api/nova..tests.test_api.rst
326-source/api/nova..tests.test_auth.rst
327-source/api/nova..tests.test_cloud.rst
328-source/api/nova..tests.test_compute.rst
329-source/api/nova..tests.test_console.rst
330-source/api/nova..tests.test_direct.rst
331-source/api/nova..tests.test_flags.rst
332-source/api/nova..tests.test_localization.rst
333-source/api/nova..tests.test_log.rst
334-source/api/nova..tests.test_middleware.rst
335-source/api/nova..tests.test_misc.rst
336-source/api/nova..tests.test_network.rst
337-source/api/nova..tests.test_quota.rst
338-source/api/nova..tests.test_rpc.rst
339-source/api/nova..tests.test_scheduler.rst
340-source/api/nova..tests.test_service.rst
341-source/api/nova..tests.test_twistd.rst
342+source/api/nova..db.sqlalchemy.migrate_repo.versions.005_add_instance_metadata.rst
343+source/api/nova..db.sqlalchemy.migrate_repo.versions.006_add_provider_data_to_volumes.rst
344+source/api/nova..db.sqlalchemy.migrate_repo.versions.007_add_instance_types.rst
345+source/api/nova..db.sqlalchemy.migration.rst
346+source/api/nova..db.sqlalchemy.models.rst
347+source/api/nova..db.sqlalchemy.session.rst
348+source/api/nova..exception.rst
349+source/api/nova..fakememcache.rst
350+source/api/nova..fakerabbit.rst
351+source/api/nova..flags.rst
352+source/api/nova..image.glance.rst
353+source/api/nova..image.local.rst
354+source/api/nova..image.s3.rst
355+source/api/nova..image.service.rst
356+source/api/nova..log.rst
357+source/api/nova..manager.rst
358+source/api/nova..network.api.rst
359+source/api/nova..network.linux_net.rst
360+source/api/nova..network.manager.rst
361+source/api/nova..objectstore.bucket.rst
362+source/api/nova..objectstore.handler.rst
363+source/api/nova..objectstore.image.rst
364+source/api/nova..objectstore.stored.rst
365+source/api/nova..quota.rst
366+source/api/nova..rpc.rst
367+source/api/nova..scheduler.chance.rst
368+source/api/nova..scheduler.driver.rst
369+source/api/nova..scheduler.manager.rst
370+source/api/nova..scheduler.simple.rst
371+source/api/nova..scheduler.zone.rst
372+source/api/nova..service.rst
373+source/api/nova..test.rst
374+source/api/nova..tests.api.openstack.fakes.rst
375+source/api/nova..tests.api.openstack.test_adminapi.rst
376+source/api/nova..tests.api.openstack.test_api.rst
377+source/api/nova..tests.api.openstack.test_auth.rst
378+source/api/nova..tests.api.openstack.test_common.rst
379+source/api/nova..tests.api.openstack.test_faults.rst
380+source/api/nova..tests.api.openstack.test_flavors.rst
381+source/api/nova..tests.api.openstack.test_images.rst
382+source/api/nova..tests.api.openstack.test_ratelimiting.rst
383+source/api/nova..tests.api.openstack.test_servers.rst
384+source/api/nova..tests.api.openstack.test_shared_ip_groups.rst
385+source/api/nova..tests.api.openstack.test_zones.rst
386+source/api/nova..tests.api.test_wsgi.rst
387+source/api/nova..tests.db.fakes.rst
388+source/api/nova..tests.declare_flags.rst
389+source/api/nova..tests.fake_flags.rst
390+source/api/nova..tests.glance.stubs.rst
391+source/api/nova..tests.hyperv_unittest.rst
392+source/api/nova..tests.objectstore_unittest.rst
393+source/api/nova..tests.real_flags.rst
394+source/api/nova..tests.runtime_flags.rst
395+source/api/nova..tests.test_access.rst
396+source/api/nova..tests.test_api.rst
397+source/api/nova..tests.test_auth.rst
398+source/api/nova..tests.test_cloud.rst
399+source/api/nova..tests.test_compute.rst
400+source/api/nova..tests.test_console.rst
401+source/api/nova..tests.test_direct.rst
402+source/api/nova..tests.test_flags.rst
403+source/api/nova..tests.test_instance_types.rst
404+source/api/nova..tests.test_localization.rst
405+source/api/nova..tests.test_log.rst
406+source/api/nova..tests.test_middleware.rst
407+source/api/nova..tests.test_misc.rst
408+source/api/nova..tests.test_network.rst
409+source/api/nova..tests.test_quota.rst
410+source/api/nova..tests.test_rpc.rst
411+source/api/nova..tests.test_scheduler.rst
412+source/api/nova..tests.test_service.rst
413+source/api/nova..tests.test_test.rst
414+source/api/nova..tests.test_twistd.rst
415+source/api/nova..tests.test_utils.rst
416 source/api/nova..tests.test_virt.rst
417 source/api/nova..tests.test_volume.rst
418 source/api/nova..tests.test_xenapi.rst
419
420=== modified file 'doc/source/api/autoindex.rst'
421--- doc/source/api/autoindex.rst 2011-02-21 20:30:20 +0000
422+++ doc/source/api/autoindex.rst 2011-03-03 01:57:15 +0000
423@@ -43,6 +43,9 @@
424 nova..db.sqlalchemy.migrate_repo.versions.002_bexar.rst
425 nova..db.sqlalchemy.migrate_repo.versions.003_add_label_to_networks.rst
426 nova..db.sqlalchemy.migrate_repo.versions.004_add_zone_tables.rst
427+ nova..db.sqlalchemy.migrate_repo.versions.005_add_instance_metadata.rst
428+ nova..db.sqlalchemy.migrate_repo.versions.006_add_provider_data_to_volumes.rst
429+ nova..db.sqlalchemy.migrate_repo.versions.007_add_instance_types.rst
430 nova..db.sqlalchemy.migration.rst
431 nova..db.sqlalchemy.models.rst
432 nova..db.sqlalchemy.session.rst
433@@ -101,6 +104,7 @@
434 nova..tests.test_console.rst
435 nova..tests.test_direct.rst
436 nova..tests.test_flags.rst
437+ nova..tests.test_instance_types.rst
438 nova..tests.test_localization.rst
439 nova..tests.test_log.rst
440 nova..tests.test_middleware.rst
441@@ -110,7 +114,9 @@
442 nova..tests.test_rpc.rst
443 nova..tests.test_scheduler.rst
444 nova..tests.test_service.rst
445+ nova..tests.test_test.rst
446 nova..tests.test_twistd.rst
447+ nova..tests.test_utils.rst
448 nova..tests.test_virt.rst
449 nova..tests.test_volume.rst
450 nova..tests.test_xenapi.rst
451
452=== added file 'doc/source/api/nova..db.sqlalchemy.migrate_repo.versions.005_add_instance_metadata.rst'
453--- doc/source/api/nova..db.sqlalchemy.migrate_repo.versions.005_add_instance_metadata.rst 1970-01-01 00:00:00 +0000
454+++ doc/source/api/nova..db.sqlalchemy.migrate_repo.versions.005_add_instance_metadata.rst 2011-03-03 01:57:15 +0000
455@@ -0,0 +1,6 @@
456+The :mod:`nova..db.sqlalchemy.migrate_repo.versions.005_add_instance_metadata` Module
457+==============================================================================
458+.. automodule:: nova..db.sqlalchemy.migrate_repo.versions.005_add_instance_metadata
459+ :members:
460+ :undoc-members:
461+ :show-inheritance:
462
463=== added file 'doc/source/api/nova..db.sqlalchemy.migrate_repo.versions.006_add_provider_data_to_volumes.rst'
464--- doc/source/api/nova..db.sqlalchemy.migrate_repo.versions.006_add_provider_data_to_volumes.rst 1970-01-01 00:00:00 +0000
465+++ doc/source/api/nova..db.sqlalchemy.migrate_repo.versions.006_add_provider_data_to_volumes.rst 2011-03-03 01:57:15 +0000
466@@ -0,0 +1,6 @@
467+The :mod:`nova..db.sqlalchemy.migrate_repo.versions.006_add_provider_data_to_volumes` Module
468+==============================================================================
469+.. automodule:: nova..db.sqlalchemy.migrate_repo.versions.006_add_provider_data_to_volumes
470+ :members:
471+ :undoc-members:
472+ :show-inheritance:
473
474=== added file 'doc/source/api/nova..db.sqlalchemy.migrate_repo.versions.007_add_instance_types.rst'
475--- doc/source/api/nova..db.sqlalchemy.migrate_repo.versions.007_add_instance_types.rst 1970-01-01 00:00:00 +0000
476+++ doc/source/api/nova..db.sqlalchemy.migrate_repo.versions.007_add_instance_types.rst 2011-03-03 01:57:15 +0000
477@@ -0,0 +1,6 @@
478+The :mod:`nova..db.sqlalchemy.migrate_repo.versions.007_add_instance_types` Module
479+==============================================================================
480+.. automodule:: nova..db.sqlalchemy.migrate_repo.versions.007_add_instance_types
481+ :members:
482+ :undoc-members:
483+ :show-inheritance:
484
485=== added file 'doc/source/api/nova..tests.test_instance_types.rst'
486--- doc/source/api/nova..tests.test_instance_types.rst 1970-01-01 00:00:00 +0000
487+++ doc/source/api/nova..tests.test_instance_types.rst 2011-03-03 01:57:15 +0000
488@@ -0,0 +1,6 @@
489+The :mod:`nova..tests.test_instance_types` Module
490+==============================================================================
491+.. automodule:: nova..tests.test_instance_types
492+ :members:
493+ :undoc-members:
494+ :show-inheritance:
495
496=== added file 'doc/source/api/nova..tests.test_test.rst'
497--- doc/source/api/nova..tests.test_test.rst 1970-01-01 00:00:00 +0000
498+++ doc/source/api/nova..tests.test_test.rst 2011-03-03 01:57:15 +0000
499@@ -0,0 +1,6 @@
500+The :mod:`nova..tests.test_test` Module
501+==============================================================================
502+.. automodule:: nova..tests.test_test
503+ :members:
504+ :undoc-members:
505+ :show-inheritance:
506
507=== added file 'doc/source/api/nova..tests.test_utils.rst'
508--- doc/source/api/nova..tests.test_utils.rst 1970-01-01 00:00:00 +0000
509+++ doc/source/api/nova..tests.test_utils.rst 2011-03-03 01:57:15 +0000
510@@ -0,0 +1,6 @@
511+The :mod:`nova..tests.test_utils` Module
512+==============================================================================
513+.. automodule:: nova..tests.test_utils
514+ :members:
515+ :undoc-members:
516+ :show-inheritance:
517
518=== modified file 'doc/source/man/novamanage.rst'
519--- doc/source/man/novamanage.rst 2011-01-19 18:43:50 +0000
520+++ doc/source/man/novamanage.rst 2011-03-03 01:57:15 +0000
521@@ -179,6 +179,42 @@
522
523 Displays a list of all floating IP addresses.
524
525+Nova Flavor
526+~~~~~~~~~~~
527+
528+``nova-manage flavor list``
529+
530+ Outputs a list of all active flavors to the screen.
531+
532+``nova-manage flavor list --all``
533+
534+ Outputs a list of all flavors (active and inactive) to the screen.
535+
536+``nova-manage flavor create <name> <memory> <vCPU> <local_storage> <flavorID> <(optional) swap> <(optional) RXTX Quota> <(optional) RXTX Cap>``
537+
538+ creates a flavor with the following positional arguments:
539+ * memory (expressed in megabytes)
540+ * vcpu(s) (integer)
541+ * local storage (expressed in gigabytes)
542+ * flavorid (unique integer)
543+ * swap space (expressed in megabytes, defaults to zero, optional)
544+ * RXTX quotas (expressed in gigabytes, defaults to zero, optional)
545+ * RXTX cap (expressed in gigabytes, defaults to zero, optional)
546+
547+``nova-manage flavor delete <name>``
548+
549+ Delete the flavor with the name <name>. This marks the flavor as inactive and cannot be launched. However, the record stays in the database for archival and billing purposes.
550+
551+``nova-manage flavor delete <name> --purge``
552+
553+ Purges the flavor with the name <name>. This removes this flavor from the database.
554+
555+
556+Nova Instance_type
557+~~~~~~~~~~~~~~~~~~
558+
559+The instance_type command is provided as an alias for the flavor command. All the same subcommands and arguments from nova-manage flavor can be used.
560+
561
562 FILES
563 ========
564
565=== modified file 'doc/source/nova.concepts.rst'
566--- doc/source/nova.concepts.rst 2011-01-04 22:58:08 +0000
567+++ doc/source/nova.concepts.rst 2011-03-03 01:57:15 +0000
568@@ -64,6 +64,11 @@
569
570 An 'instance' is a word for a virtual machine that runs inside the cloud.
571
572+Concept: Instance Type
573+----------------------
574+
575+An 'instance type' describes the compute, memory and storage capacity of nova computing instances. In layman terms, this is the size (in terms of vCPUs, RAM, etc.) of the virtual server that you will be launching.
576+
577 Concept: System Architecture
578 ----------------------------
579
580
581=== added file 'doc/source/runnova/managing.instance.types.rst'
582--- doc/source/runnova/managing.instance.types.rst 1970-01-01 00:00:00 +0000
583+++ doc/source/runnova/managing.instance.types.rst 2011-03-03 01:57:15 +0000
584@@ -0,0 +1,84 @@
585+..
586+ Copyright 2011 Ken Pepple
587+
588+ Licensed under the Apache License, Version 2.0 (the "License"); you may
589+ not use this file except in compliance with the License. You may obtain
590+ a copy of the License at
591+
592+ http://www.apache.org/licenses/LICENSE-2.0
593+
594+ Unless required by applicable law or agreed to in writing, software
595+ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
596+ WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
597+ License for the specific language governing permissions and limitations
598+ under the License.
599+
600+Managing Instance Types and Flavors
601+===================================
602+
603+What are Instance Types or Flavors ?
604+------------------------------------
605+
606+Instance types describe the compute, memory and storage capacity of nova computing instances. In layman terms, this is the size (in terms of vCPUs, RAM, etc.) of the virtual server that you will be launching. In the EC2 API, these are called by names such as "m1.large" or "m1.tiny", while the OpenStack API terms these "flavors" with names like "512 MB Server".
607+
608+In Nova, "flavor" and "instance type" are equivalent terms. When you create an EC2 instance type, you are also creating a OpenStack API flavor. To reduce repetition, for the rest of this document I will refer to these as instance types.
609+
610+Instance types can be in either the active or inactive state:
611+ * Active instance types are available to be used for launching instances
612+ * Inactive instance types are not available for launching instances
613+
614+In the current (Cactus) version of nova, instance types can only be created by the nova administrator through the nova-manage command. Future versions of nova (in concert with the OpenStack API or EC2 API), may expose this functionality directly to users.
615+
616+Basic Management
617+----------------
618+
619+Instance types / flavor are managed through the nova-manage binary with
620+the "instance_type" command and an appropriate subcommand. Note that you can also use
621+the "flavor" command as a synonym for "instance_types".
622+
623+To see all currently active instance types, use the list subcommand::
624+
625+ # nova-manage instance_type list
626+ m1.medium: Memory: 4096MB, VCPUS: 2, Storage: 40GB, FlavorID: 3, Swap: 0GB, RXTX Quota: 0GB, RXTX Cap: 0MB
627+ m1.large: Memory: 8192MB, VCPUS: 4, Storage: 80GB, FlavorID: 4, Swap: 0GB, RXTX Quota: 0GB, RXTX Cap: 0MB
628+ m1.tiny: Memory: 512MB, VCPUS: 1, Storage: 0GB, FlavorID: 1, Swap: 0GB, RXTX Quota: 0GB, RXTX Cap: 0MB
629+ m1.xlarge: Memory: 16384MB, VCPUS: 8, Storage: 160GB, FlavorID: 5, Swap: 0GB, RXTX Quota: 0GB, RXTX Cap: 0MB
630+ m1.small: Memory: 2048MB, VCPUS: 1, Storage: 20GB, FlavorID: 2, Swap: 0GB, RXTX Quota: 0GB, RXTX Cap: 0MB
631+
632+By default, the list subcommand only shows active instance types. To see all instance types (inactive and active), use the list subcommand with the "--all" flag::
633+
634+ # nova-manage instance_type list --all
635+ m1.medium: Memory: 4096MB, VCPUS: 2, Storage: 40GB, FlavorID: 3, Swap: 0GB, RXTX Quota: 0GB, RXTX Cap: 0MB
636+ m1.large: Memory: 8192MB, VCPUS: 4, Storage: 80GB, FlavorID: 4, Swap: 0GB, RXTX Quota: 0GB, RXTX Cap: 0MB
637+ m1.tiny: Memory: 512MB, VCPUS: 1, Storage: 0GB, FlavorID: 1, Swap: 0GB, RXTX Quota: 0GB, RXTX Cap: 0MB
638+ m1.xlarge: Memory: 16384MB, VCPUS: 8, Storage: 160GB, FlavorID: 5, Swap: 0GB, RXTX Quota: 0GB, RXTX Cap: 0MB
639+ m1.small: Memory: 2048MB, VCPUS: 1, Storage: 20GB, FlavorID: 2, Swap: 0GB, RXTX Quota: 0GB, RXTX Cap: 0MB
640+ m1.deleted: Memory: 2048MB, VCPUS: 1, Storage: 20GB, FlavorID: 2, Swap: 0GB, RXTX Quota: 0GB, RXTX Cap: 0MB, inactive
641+
642+To create an instance type, use the "create" subcommand with the following positional arguments:
643+ * memory (expressed in megabytes)
644+ * vcpu(s) (integer)
645+ * local storage (expressed in gigabytes)
646+ * flavorid (unique integer)
647+ * swap space (expressed in megabytes, defaults to zero, optional)
648+ * RXTX quotas (expressed in gigabytes, defaults to zero, optional)
649+ * RXTX cap (expressed in gigabytes, defaults to zero, optional)
650+
651+The following example creates an instance type named "m1.xxlarge"::
652+
653+ # nova-manage instance_type create m1.xxlarge 32768 16 320 0 0 0
654+ m1.xxlarge created
655+
656+To delete an instance type, use the "delete" subcommand and specify the name::
657+
658+ # nova-manage instance_type delete m1.xxlarge
659+ m1.xxlarge deleted
660+
661+Please note that the "delete" command only marks the instance type as
662+inactive in the database; it does not actually remove the instance type. This is done
663+to preserve the instance type definition for long running instances (which may not
664+terminate for months or years). If you are sure that you want to delete this instance
665+type from the database, pass the "--purge" flag after the name::
666+
667+ # nova-manage instance_type delete m1.xxlarge --purge
668+ m1.xxlarge purged
669
670=== modified file 'nova/api/ec2/admin.py'
671--- nova/api/ec2/admin.py 2011-02-23 04:42:49 +0000
672+++ nova/api/ec2/admin.py 2011-03-03 01:57:15 +0000
673@@ -29,7 +29,6 @@
674 from nova import log as logging
675 from nova import utils
676 from nova.auth import manager
677-from nova.compute import instance_types
678
679
680 FLAGS = flags.FLAGS
681@@ -80,8 +79,8 @@
682 return rv
683
684
685-def instance_dict(name, inst):
686- return {'name': name,
687+def instance_dict(inst):
688+ return {'name': inst['name'],
689 'memory_mb': inst['memory_mb'],
690 'vcpus': inst['vcpus'],
691 'disk_gb': inst['local_gb'],
692@@ -115,9 +114,9 @@
693 def __str__(self):
694 return 'AdminController'
695
696- def describe_instance_types(self, _context, **_kwargs):
697- return {'instanceTypeSet': [instance_dict(n, v) for n, v in
698- instance_types.INSTANCE_TYPES.iteritems()]}
699+ def describe_instance_types(self, context, **_kwargs):
700+ """Returns all active instance types data (vcpus, memory, etc.)"""
701+ return {'instanceTypeSet': [db.instance_type_get_all(context)]}
702
703 def describe_user(self, _context, name, **_kwargs):
704 """Returns user data, including access and secret keys."""
705
706=== modified file 'nova/api/openstack/__init__.py'
707--- nova/api/openstack/__init__.py 2011-02-25 17:00:01 +0000
708+++ nova/api/openstack/__init__.py 2011-03-03 01:57:15 +0000
709@@ -74,6 +74,7 @@
710 server_members = {'action': 'POST'}
711 if FLAGS.allow_admin_api:
712 LOG.debug(_("Including admin operations in API."))
713+
714 server_members['pause'] = 'POST'
715 server_members['unpause'] = 'POST'
716 server_members["diagnostics"] = "GET"
717
718=== modified file 'nova/api/openstack/flavors.py'
719--- nova/api/openstack/flavors.py 2010-12-16 18:09:38 +0000
720+++ nova/api/openstack/flavors.py 2011-03-03 01:57:15 +0000
721@@ -17,6 +17,8 @@
722
723 from webob import exc
724
725+from nova import db
726+from nova import context
727 from nova.api.openstack import faults
728 from nova.api.openstack import common
729 from nova.compute import instance_types
730@@ -39,19 +41,19 @@
731
732 def detail(self, req):
733 """Return all flavors in detail."""
734- items = [self.show(req, id)['flavor'] for id in self._all_ids()]
735- items = common.limited(items, req)
736+ items = [self.show(req, id)['flavor'] for id in self._all_ids(req)]
737 return dict(flavors=items)
738
739 def show(self, req, id):
740 """Return data about the given flavor id."""
741- for name, val in instance_types.INSTANCE_TYPES.iteritems():
742- if val['flavorid'] == int(id):
743- item = dict(ram=val['memory_mb'], disk=val['local_gb'],
744- id=val['flavorid'], name=name)
745- return dict(flavor=item)
746+ ctxt = req.environ['nova.context']
747+ values = db.instance_type_get_by_flavor_id(ctxt, id)
748+ return dict(flavor=values)
749 raise faults.Fault(exc.HTTPNotFound())
750
751- def _all_ids(self):
752+ def _all_ids(self, req):
753 """Return the list of all flavorids."""
754- return [i['flavorid'] for i in instance_types.INSTANCE_TYPES.values()]
755+ ctxt = req.environ['nova.context']
756+ inst_types = db.instance_type_get_all(ctxt)
757+ flavor_ids = [inst_types[i]['flavorid'] for i in inst_types.keys()]
758+ return sorted(flavor_ids)
759
760=== modified file 'nova/compute/api.py'
761--- nova/compute/api.py 2011-03-01 16:53:19 +0000
762+++ nova/compute/api.py 2011-03-03 01:57:15 +0000
763@@ -88,9 +88,9 @@
764 availability_zone=None, user_data=None, metadata=[],
765 onset_files=None):
766 """Create the number of instances requested if quota and
767- other arguments check out ok.
768- """
769- type_data = instance_types.INSTANCE_TYPES[instance_type]
770+ other arguments check out ok."""
771+
772+ type_data = instance_types.get_instance_type(instance_type)
773 num_instances = quota.allowed_instances(context, max_count, type_data)
774 if num_instances < min_count:
775 pid = context.project_id
776
777=== modified file 'nova/compute/instance_types.py'
778--- nova/compute/instance_types.py 2011-02-17 23:13:59 +0000
779+++ nova/compute/instance_types.py 2011-03-03 01:57:15 +0000
780@@ -4,6 +4,7 @@
781 # Administrator of the National Aeronautics and Space Administration.
782 # All Rights Reserved.
783 # Copyright (c) 2010 Citrix Systems, Inc.
784+# Copyright 2011 Ken Pepple
785 #
786 # Licensed under the Apache License, Version 2.0 (the "License"); you may
787 # not use this file except in compliance with the License. You may obtain
788@@ -21,30 +22,120 @@
789 The built-in instance properties.
790 """
791
792+from nova import context
793+from nova import db
794+from nova import exception
795 from nova import flags
796-from nova import exception
797+from nova import log as logging
798
799 FLAGS = flags.FLAGS
800-INSTANCE_TYPES = {
801- 'm1.tiny': dict(memory_mb=512, vcpus=1, local_gb=0, flavorid=1),
802- 'm1.small': dict(memory_mb=2048, vcpus=1, local_gb=20, flavorid=2),
803- 'm1.medium': dict(memory_mb=4096, vcpus=2, local_gb=40, flavorid=3),
804- 'm1.large': dict(memory_mb=8192, vcpus=4, local_gb=80, flavorid=4),
805- 'm1.xlarge': dict(memory_mb=16384, vcpus=8, local_gb=160, flavorid=5)}
806+LOG = logging.getLogger('nova.instance_types')
807+
808+
809+def create(name, memory, vcpus, local_gb, flavorid, swap=0,
810+ rxtx_quota=0, rxtx_cap=0):
811+ """Creates instance types / flavors
812+ arguments: name memory vcpus local_gb flavorid swap rxtx_quota rxtx_cap
813+ """
814+ for option in [memory, vcpus, local_gb, flavorid]:
815+ try:
816+ int(option)
817+ except ValueError:
818+ raise exception.InvalidInputException(
819+ _("create arguments must be positive integers"))
820+ if (int(memory) <= 0) or (int(vcpus) <= 0) or (int(local_gb) < 0):
821+ raise exception.InvalidInputException(
822+ _("create arguments must be positive integers"))
823+
824+ try:
825+ db.instance_type_create(
826+ context.get_admin_context(),
827+ dict(name=name,
828+ memory_mb=memory,
829+ vcpus=vcpus,
830+ local_gb=local_gb,
831+ flavorid=flavorid,
832+ swap=swap,
833+ rxtx_quota=rxtx_quota,
834+ rxtx_cap=rxtx_cap))
835+ except exception.DBError, e:
836+ LOG.exception(_('DB error: %s' % e))
837+ raise exception.ApiError(_("Cannot create instance type: %s" % name))
838+
839+
840+def destroy(name):
841+ """Marks instance types / flavors as deleted
842+ arguments: name"""
843+ if name == None:
844+ raise exception.InvalidInputException(_("No instance type specified"))
845+ else:
846+ try:
847+ db.instance_type_destroy(context.get_admin_context(), name)
848+ except exception.NotFound:
849+ LOG.exception(_('Instance type %s not found for deletion' % name))
850+ raise exception.ApiError(_("Unknown instance type: %s" % name))
851+
852+
853+def purge(name):
854+ """Removes instance types / flavors from database
855+ arguments: name"""
856+ if name == None:
857+ raise exception.InvalidInputException(_("No instance type specified"))
858+ else:
859+ try:
860+ db.instance_type_purge(context.get_admin_context(), name)
861+ except exception.NotFound:
862+ LOG.exception(_('Instance type %s not found for purge' % name))
863+ raise exception.ApiError(_("Unknown instance type: %s" % name))
864+
865+
866+def get_all_types(inactive=0):
867+ """Retrieves non-deleted instance_types.
868+ Pass true as argument if you want deleted instance types returned also."""
869+ return db.instance_type_get_all(context.get_admin_context(), inactive)
870+
871+
872+def get_all_flavors():
873+ """retrieves non-deleted flavors. alias for instance_types.get_all_types().
874+ Pass true as argument if you want deleted instance types returned also."""
875+ return get_all_types(context.get_admin_context())
876+
877+
878+def get_instance_type(name):
879+ """Retrieves single instance type by name"""
880+ if name is None:
881+ return FLAGS.default_instance_type
882+ try:
883+ ctxt = context.get_admin_context()
884+ inst_type = db.instance_type_get_by_name(ctxt, name)
885+ return inst_type
886+ except exception.DBError:
887+ raise exception.ApiError(_("Unknown instance type: %s" % name))
888
889
890 def get_by_type(instance_type):
891- """Build instance data structure and save it to the data store."""
892+ """retrieve instance type name"""
893 if instance_type is None:
894 return FLAGS.default_instance_type
895- if instance_type not in INSTANCE_TYPES:
896- raise exception.ApiError(_("Unknown instance type: %s") % \
897- instance_type, "Invalid")
898- return instance_type
899+
900+ try:
901+ ctxt = context.get_admin_context()
902+ inst_type = db.instance_type_get_by_name(ctxt, instance_type)
903+ return inst_type['name']
904+ except exception.DBError, e:
905+ LOG.exception(_('DB error: %s' % e))
906+ raise exception.ApiError(_("Unknown instance type: %s" %\
907+ instance_type))
908
909
910 def get_by_flavor_id(flavor_id):
911- for instance_type, details in INSTANCE_TYPES.iteritems():
912- if details['flavorid'] == int(flavor_id):
913- return instance_type
914- return FLAGS.default_instance_type
915+ """retrieve instance type's name by flavor_id"""
916+ if flavor_id is None:
917+ return FLAGS.default_instance_type
918+ try:
919+ ctxt = context.get_admin_context()
920+ flavor = db.instance_type_get_by_flavor_id(ctxt, flavor_id)
921+ return flavor['name']
922+ except exception.DBError, e:
923+ LOG.exception(_('DB error: %s' % e))
924+ raise exception.ApiError(_("Unknown flavor: %s" % flavor_id))
925
926=== modified file 'nova/db/api.py'
927--- nova/db/api.py 2011-03-18 02:09:46 +0000
928+++ nova/db/api.py 2011-03-03 01:57:15 +0000
929@@ -1007,6 +1007,41 @@
930 return IMPL.console_get(context, console_id, instance_id)
931
932
933+ ##################
934+
935+
936+def instance_type_create(context, values):
937+ """Create a new instance type"""
938+ return IMPL.instance_type_create(context, values)
939+
940+
941+def instance_type_get_all(context, inactive=0):
942+ """Get all instance types"""
943+ return IMPL.instance_type_get_all(context, inactive)
944+
945+
946+def instance_type_get_by_name(context, name):
947+ """Get instance type by name"""
948+ return IMPL.instance_type_get_by_name(context, name)
949+
950+
951+def instance_type_get_by_flavor_id(context, id):
952+ """Get instance type by name"""
953+ return IMPL.instance_type_get_by_flavor_id(context, id)
954+
955+
956+def instance_type_destroy(context, name):
957+ """Delete a instance type"""
958+ return IMPL.instance_type_destroy(context, name)
959+
960+
961+def instance_type_purge(context, name):
962+ """Purges (removes) an instance type from DB
963+ Use instance_type_destroy for most cases
964+ """
965+ return IMPL.instance_type_purge(context, name)
966+
967+
968 ####################
969
970
971
972=== modified file 'nova/db/sqlalchemy/api.py'
973--- nova/db/sqlalchemy/api.py 2011-03-18 02:09:46 +0000
974+++ nova/db/sqlalchemy/api.py 2011-03-03 01:57:15 +0000
975@@ -2073,6 +2073,98 @@
976 return result
977
978
979+ ##################
980+
981+
982+@require_admin_context
983+def instance_type_create(_context, values):
984+ try:
985+ instance_type_ref = models.InstanceTypes()
986+ instance_type_ref.update(values)
987+ instance_type_ref.save()
988+ except:
989+ raise exception.DBError
990+ return instance_type_ref
991+
992+
993+@require_context
994+def instance_type_get_all(context, inactive=0):
995+ """
996+ Returns a dict describing all instance_types with name as key.
997+ """
998+ session = get_session()
999+ if inactive:
1000+ inst_types = session.query(models.InstanceTypes).\
1001+ order_by("name").\
1002+ all()
1003+ else:
1004+ inst_types = session.query(models.InstanceTypes).\
1005+ filter_by(deleted=inactive).\
1006+ order_by("name").\
1007+ all()
1008+ if inst_types:
1009+ inst_dict = {}
1010+ for i in inst_types:
1011+ inst_dict[i['name']] = dict(i)
1012+ return inst_dict
1013+ else:
1014+ raise exception.NotFound
1015+
1016+
1017+@require_context
1018+def instance_type_get_by_name(context, name):
1019+ """Returns a dict describing specific instance_type"""
1020+ session = get_session()
1021+ inst_type = session.query(models.InstanceTypes).\
1022+ filter_by(name=name).\
1023+ first()
1024+ if not inst_type:
1025+ raise exception.NotFound(_("No instance type with name %s") % name)
1026+ else:
1027+ return dict(inst_type)
1028+
1029+
1030+@require_context
1031+def instance_type_get_by_flavor_id(context, id):
1032+ """Returns a dict describing specific flavor_id"""
1033+ session = get_session()
1034+ inst_type = session.query(models.InstanceTypes).\
1035+ filter_by(flavorid=int(id)).\
1036+ first()
1037+ if not inst_type:
1038+ raise exception.NotFound(_("No flavor with name %s") % id)
1039+ else:
1040+ return dict(inst_type)
1041+
1042+
1043+@require_admin_context
1044+def instance_type_destroy(context, name):
1045+ """ Marks specific instance_type as deleted"""
1046+ session = get_session()
1047+ instance_type_ref = session.query(models.InstanceTypes).\
1048+ filter_by(name=name)
1049+ records = instance_type_ref.update(dict(deleted=1))
1050+ if records == 0:
1051+ raise exception.NotFound
1052+ else:
1053+ return instance_type_ref
1054+
1055+
1056+@require_admin_context
1057+def instance_type_purge(context, name):
1058+ """ Removes specific instance_type from DB
1059+ Usually instance_type_destroy should be used
1060+ """
1061+ session = get_session()
1062+ instance_type_ref = session.query(models.InstanceTypes).\
1063+ filter_by(name=name)
1064+ records = instance_type_ref.delete()
1065+ if records == 0:
1066+ raise exception.NotFound
1067+ else:
1068+ return instance_type_ref
1069+
1070+
1071 ####################
1072
1073
1074
1075=== added file 'nova/db/sqlalchemy/migrate_repo/versions/008_add_instance_types.py'
1076--- nova/db/sqlalchemy/migrate_repo/versions/008_add_instance_types.py 1970-01-01 00:00:00 +0000
1077+++ nova/db/sqlalchemy/migrate_repo/versions/008_add_instance_types.py 2011-03-03 01:57:15 +0000
1078@@ -0,0 +1,87 @@
1079+# vim: tabstop=4 shiftwidth=4 softtabstop=4
1080+
1081+# Copyright 2011 Ken Pepple
1082+# Licensed under the Apache License, Version 2.0 (the "License"); you may
1083+# not use this file except in compliance with the License. You may obtain
1084+# a copy of the License at
1085+#
1086+# http://www.apache.org/licenses/LICENSE-2.0
1087+#
1088+# Unless required by applicable law or agreed to in writing, software
1089+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
1090+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
1091+# License for the specific language governing permissions and limitations
1092+# under the License.
1093+
1094+from sqlalchemy import *
1095+from migrate import *
1096+
1097+from nova import api
1098+from nova import db
1099+from nova import log as logging
1100+
1101+import datetime
1102+
1103+meta = MetaData()
1104+
1105+
1106+#
1107+# New Tables
1108+#
1109+instance_types = Table('instance_types', meta,
1110+ Column('created_at', DateTime(timezone=False)),
1111+ Column('updated_at', DateTime(timezone=False)),
1112+ Column('deleted_at', DateTime(timezone=False)),
1113+ Column('deleted', Boolean(create_constraint=True, name=None)),
1114+ Column('name',
1115+ String(length=255, convert_unicode=False, assert_unicode=None,
1116+ unicode_error=None, _warn_on_bytestring=False),
1117+ unique=True),
1118+ Column('id', Integer(), primary_key=True, nullable=False),
1119+ Column('memory_mb', Integer(), nullable=False),
1120+ Column('vcpus', Integer(), nullable=False),
1121+ Column('local_gb', Integer(), nullable=False),
1122+ Column('flavorid', Integer(), nullable=False, unique=True),
1123+ Column('swap', Integer(), nullable=False, default=0),
1124+ Column('rxtx_quota', Integer(), nullable=False, default=0),
1125+ Column('rxtx_cap', Integer(), nullable=False, default=0))
1126+
1127+
1128+def upgrade(migrate_engine):
1129+ # Upgrade operations go here
1130+ # Don't create your own engine; bind migrate_engine
1131+ # to your metadata
1132+ meta.bind = migrate_engine
1133+ try:
1134+ instance_types.create()
1135+ except Exception:
1136+ logging.info(repr(table))
1137+ logging.exception('Exception while creating instance_types table')
1138+ raise
1139+
1140+ # Here are the old static instance types
1141+ INSTANCE_TYPES = {
1142+ 'm1.tiny': dict(memory_mb=512, vcpus=1, local_gb=0, flavorid=1),
1143+ 'm1.small': dict(memory_mb=2048, vcpus=1, local_gb=20, flavorid=2),
1144+ 'm1.medium': dict(memory_mb=4096, vcpus=2, local_gb=40, flavorid=3),
1145+ 'm1.large': dict(memory_mb=8192, vcpus=4, local_gb=80, flavorid=4),
1146+ 'm1.xlarge': dict(memory_mb=16384, vcpus=8, local_gb=160, flavorid=5)}
1147+ try:
1148+ i = instance_types.insert()
1149+ for name, values in INSTANCE_TYPES.iteritems():
1150+ # FIXME(kpepple) should we be seeding created_at / updated_at ?
1151+ # now = datetime.datatime.utcnow()
1152+ i.execute({'name': name, 'memory_mb': values["memory_mb"],
1153+ 'vcpus': values["vcpus"], 'deleted': 0,
1154+ 'local_gb': values["local_gb"],
1155+ 'flavorid': values["flavorid"]})
1156+ except Exception:
1157+ logging.info(repr(table))
1158+ logging.exception('Exception while seeding instance_types table')
1159+ raise
1160+
1161+
1162+def downgrade(migrate_engine):
1163+ # Operations to reverse the above upgrade go here.
1164+ for table in (instance_types):
1165+ table.drop()
1166
1167=== modified file 'nova/db/sqlalchemy/models.py'
1168--- nova/db/sqlalchemy/models.py 2011-03-02 23:37:31 +0000
1169+++ nova/db/sqlalchemy/models.py 2011-03-03 01:57:15 +0000
1170@@ -215,6 +215,20 @@
1171 error = Column(Text)
1172
1173
1174+class InstanceTypes(BASE, NovaBase):
1175+ """Represent possible instance_types or flavor of VM offered"""
1176+ __tablename__ = "instance_types"
1177+ id = Column(Integer, primary_key=True)
1178+ name = Column(String(255), unique=True)
1179+ memory_mb = Column(Integer)
1180+ vcpus = Column(Integer)
1181+ local_gb = Column(Integer)
1182+ flavorid = Column(Integer, unique=True)
1183+ swap = Column(Integer, nullable=False, default=0)
1184+ rxtx_quota = Column(Integer, nullable=False, default=0)
1185+ rxtx_cap = Column(Integer, nullable=False, default=0)
1186+
1187+
1188 class Volume(BASE, NovaBase):
1189 """Represents a block storage device that can be attached to a vm."""
1190 __tablename__ = 'volumes'
1191@@ -579,7 +593,7 @@
1192 connection is lost and needs to be reestablished.
1193 """
1194 from sqlalchemy import create_engine
1195- models = (Service, Instance, InstanceActions,
1196+ models = (Service, Instance, InstanceActions, InstanceTypes,
1197 Volume, ExportDevice, IscsiTarget, FixedIp, FloatingIp,
1198 Network, SecurityGroup, SecurityGroupIngressRule,
1199 SecurityGroupInstanceAssociation, AuthToken, User,
1200
1201=== modified file 'nova/tests/api/openstack/test_flavors.py'
1202--- nova/tests/api/openstack/test_flavors.py 2011-02-23 19:56:37 +0000
1203+++ nova/tests/api/openstack/test_flavors.py 2011-03-03 01:57:15 +0000
1204@@ -20,6 +20,8 @@
1205
1206 from nova import test
1207 import nova.api
1208+from nova import context
1209+from nova import db
1210 from nova.api.openstack import flavors
1211 from nova.tests.api.openstack import fakes
1212
1213@@ -33,6 +35,7 @@
1214 fakes.stub_out_networking(self.stubs)
1215 fakes.stub_out_rate_limiting(self.stubs)
1216 fakes.stub_out_auth(self.stubs)
1217+ self.context = context.get_admin_context()
1218
1219 def tearDown(self):
1220 self.stubs.UnsetAll()
1221@@ -41,6 +44,9 @@
1222 def test_get_flavor_list(self):
1223 req = webob.Request.blank('/v1.0/flavors')
1224 res = req.get_response(fakes.wsgi_app())
1225+ self.assertEqual(res.status_int, 200)
1226
1227 def test_get_flavor_by_id(self):
1228- pass
1229+ req = webob.Request.blank('/v1.0/flavors/1')
1230+ res = req.get_response(fakes.wsgi_app())
1231+ self.assertEqual(res.status_int, 200)
1232
1233=== modified file 'nova/tests/db/fakes.py'
1234--- nova/tests/db/fakes.py 2010-12-23 03:35:41 +0000
1235+++ nova/tests/db/fakes.py 2011-03-03 01:57:15 +0000
1236@@ -20,13 +20,22 @@
1237 import time
1238
1239 from nova import db
1240+from nova import test
1241 from nova import utils
1242-from nova.compute import instance_types
1243
1244
1245 def stub_out_db_instance_api(stubs):
1246 """ Stubs out the db API for creating Instances """
1247
1248+ INSTANCE_TYPES = {
1249+ 'm1.tiny': dict(memory_mb=512, vcpus=1, local_gb=0, flavorid=1),
1250+ 'm1.small': dict(memory_mb=2048, vcpus=1, local_gb=20, flavorid=2),
1251+ 'm1.medium':
1252+ dict(memory_mb=4096, vcpus=2, local_gb=40, flavorid=3),
1253+ 'm1.large': dict(memory_mb=8192, vcpus=4, local_gb=80, flavorid=4),
1254+ 'm1.xlarge':
1255+ dict(memory_mb=16384, vcpus=8, local_gb=160, flavorid=5)}
1256+
1257 class FakeModel(object):
1258 """ Stubs out for model """
1259 def __init__(self, values):
1260@@ -41,10 +50,16 @@
1261 else:
1262 raise NotImplementedError()
1263
1264+ def fake_instance_type_get_all(context, inactive=0):
1265+ return INSTANCE_TYPES
1266+
1267+ def fake_instance_type_get_by_name(context, name):
1268+ return INSTANCE_TYPES[name]
1269+
1270 def fake_instance_create(values):
1271 """ Stubs out the db.instance_create method """
1272
1273- type_data = instance_types.INSTANCE_TYPES[values['instance_type']]
1274+ type_data = INSTANCE_TYPES[values['instance_type']]
1275
1276 base_options = {
1277 'name': values['name'],
1278@@ -73,3 +88,5 @@
1279
1280 stubs.Set(db, 'instance_create', fake_instance_create)
1281 stubs.Set(db, 'network_get_by_instance', fake_network_get_by_instance)
1282+ stubs.Set(db, 'instance_type_get_all', fake_instance_type_get_all)
1283+ stubs.Set(db, 'instance_type_get_by_name', fake_instance_type_get_by_name)
1284
1285=== added file 'nova/tests/test_instance_types.py'
1286--- nova/tests/test_instance_types.py 1970-01-01 00:00:00 +0000
1287+++ nova/tests/test_instance_types.py 2011-03-03 01:57:15 +0000
1288@@ -0,0 +1,86 @@
1289+# vim: tabstop=4 shiftwidth=4 softtabstop=4
1290+
1291+# Copyright 2011 Ken Pepple
1292+# Licensed under the Apache License, Version 2.0 (the "License"); you may
1293+# not use this file except in compliance with the License. You may obtain
1294+# a copy of the License at
1295+#
1296+# http://www.apache.org/licenses/LICENSE-2.0
1297+#
1298+# Unless required by applicable law or agreed to in writing, software
1299+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
1300+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
1301+# License for the specific language governing permissions and limitations
1302+# under the License.
1303+"""
1304+Unit Tests for instance types code
1305+"""
1306+import time
1307+
1308+from nova import context
1309+from nova import db
1310+from nova import exception
1311+from nova import flags
1312+from nova import log as logging
1313+from nova import test
1314+from nova import utils
1315+from nova.compute import instance_types
1316+from nova.db.sqlalchemy.session import get_session
1317+from nova.db.sqlalchemy import models
1318+
1319+FLAGS = flags.FLAGS
1320+LOG = logging.getLogger('nova.tests.compute')
1321+
1322+
1323+class InstanceTypeTestCase(test.TestCase):
1324+ """Test cases for instance type code"""
1325+ def setUp(self):
1326+ super(InstanceTypeTestCase, self).setUp()
1327+ session = get_session()
1328+ max_flavorid = session.query(models.InstanceTypes).\
1329+ order_by("flavorid desc").\
1330+ first()
1331+ self.flavorid = max_flavorid["flavorid"] + 1
1332+ self.name = str(int(time.time()))
1333+
1334+ def test_instance_type_create_then_delete(self):
1335+ """Ensure instance types can be created"""
1336+ starting_inst_list = instance_types.get_all_types()
1337+ instance_types.create(self.name, 256, 1, 120, self.flavorid)
1338+ new = instance_types.get_all_types()
1339+ self.assertNotEqual(len(starting_inst_list),
1340+ len(new),
1341+ 'instance type was not created')
1342+ instance_types.destroy(self.name)
1343+ self.assertEqual(1,
1344+ instance_types.get_instance_type(self.name)["deleted"])
1345+ self.assertEqual(starting_inst_list, instance_types.get_all_types())
1346+ instance_types.purge(self.name)
1347+ self.assertEqual(len(starting_inst_list),
1348+ len(instance_types.get_all_types()),
1349+ 'instance type not purged')
1350+
1351+ def test_get_all_instance_types(self):
1352+ """Ensures that all instance types can be retrieved"""
1353+ session = get_session()
1354+ total_instance_types = session.query(models.InstanceTypes).\
1355+ count()
1356+ inst_types = instance_types.get_all_types()
1357+ self.assertEqual(total_instance_types, len(inst_types))
1358+
1359+ def test_invalid_create_args_should_fail(self):
1360+ """Ensures that instance type creation fails with invalid args"""
1361+ self.assertRaises(
1362+ exception.InvalidInputException,
1363+ instance_types.create, self.name, 0, 1, 120, self.flavorid)
1364+ self.assertRaises(
1365+ exception.InvalidInputException,
1366+ instance_types.create, self.name, 256, -1, 120, self.flavorid)
1367+ self.assertRaises(
1368+ exception.InvalidInputException,
1369+ instance_types.create, self.name, 256, 1, "aa", self.flavorid)
1370+
1371+ def test_non_existant_inst_type_shouldnt_delete(self):
1372+ """Ensures that instance type creation fails with invalid args"""
1373+ self.assertRaises(exception.ApiError,
1374+ instance_types.destroy, "sfsfsdfdfs")
1375
1376=== modified file 'nova/tests/test_quota.py'
1377--- nova/tests/test_quota.py 2011-02-23 17:40:43 +0000
1378+++ nova/tests/test_quota.py 2011-03-03 01:57:15 +0000
1379@@ -74,19 +74,30 @@
1380 vol['size'] = size
1381 return db.volume_create(self.context, vol)['id']
1382
1383+ def _get_instance_type(self, name):
1384+ instance_types = {
1385+ 'm1.tiny': dict(memory_mb=512, vcpus=1, local_gb=0, flavorid=1),
1386+ 'm1.small': dict(memory_mb=2048, vcpus=1, local_gb=20, flavorid=2),
1387+ 'm1.medium':
1388+ dict(memory_mb=4096, vcpus=2, local_gb=40, flavorid=3),
1389+ 'm1.large': dict(memory_mb=8192, vcpus=4, local_gb=80, flavorid=4),
1390+ 'm1.xlarge':
1391+ dict(memory_mb=16384, vcpus=8, local_gb=160, flavorid=5)}
1392+ return instance_types[name]
1393+
1394 def test_quota_overrides(self):
1395 """Make sure overriding a projects quotas works"""
1396 num_instances = quota.allowed_instances(self.context, 100,
1397- instance_types.INSTANCE_TYPES['m1.small'])
1398+ self._get_instance_type('m1.small'))
1399 self.assertEqual(num_instances, 2)
1400 db.quota_create(self.context, {'project_id': self.project.id,
1401 'instances': 10})
1402 num_instances = quota.allowed_instances(self.context, 100,
1403- instance_types.INSTANCE_TYPES['m1.small'])
1404+ self._get_instance_type('m1.small'))
1405 self.assertEqual(num_instances, 4)
1406 db.quota_update(self.context, self.project.id, {'cores': 100})
1407 num_instances = quota.allowed_instances(self.context, 100,
1408- instance_types.INSTANCE_TYPES['m1.small'])
1409+ self._get_instance_type('m1.small'))
1410 self.assertEqual(num_instances, 10)
1411
1412 # metadata_items
1413
1414=== modified file 'nova/tests/test_xenapi.py'
1415--- nova/tests/test_xenapi.py 2011-02-25 16:47:08 +0000
1416+++ nova/tests/test_xenapi.py 2011-03-03 01:57:15 +0000
1417@@ -233,7 +233,7 @@
1418 vm = vms[0]
1419
1420 # Check that m1.large above turned into the right thing.
1421- instance_type = instance_types.INSTANCE_TYPES['m1.large']
1422+ instance_type = db.instance_type_get_by_name(conn, 'm1.large')
1423 mem_kib = long(instance_type['memory_mb']) << 10
1424 mem_bytes = str(mem_kib << 10)
1425 vcpus = instance_type['vcpus']
1426
1427=== modified file 'nova/virt/libvirt_conn.py'
1428--- nova/virt/libvirt_conn.py 2011-01-31 15:23:57 +0000
1429+++ nova/virt/libvirt_conn.py 2011-03-03 01:57:15 +0000
1430@@ -55,6 +55,7 @@
1431 from nova import exception
1432 from nova import flags
1433 from nova import log as logging
1434+#from nova import test
1435 from nova import utils
1436 #from nova.api import context
1437 from nova.auth import manager
1438@@ -606,7 +607,7 @@
1439 user=user,
1440 project=project,
1441 size=size)
1442- type_data = instance_types.INSTANCE_TYPES[inst['instance_type']]
1443+ type_data = instance_types.get_instance_type([inst['instance_type']])
1444
1445 if type_data['local_gb']:
1446 self._cache_image(fn=self._create_local,
1447@@ -667,7 +668,8 @@
1448 instance['id'])
1449 # FIXME(vish): stick this in db
1450 instance_type = instance['instance_type']
1451- instance_type = instance_types.INSTANCE_TYPES[instance_type]
1452+ # instance_type = test.INSTANCE_TYPES[instance_type]
1453+ instance_type = instance_types.get_instance_type(instance_type)
1454 ip_address = db.instance_get_fixed_address(context.get_admin_context(),
1455 instance['id'])
1456 # Assume that the gateway also acts as the dhcp server.
1457
1458=== modified file 'nova/virt/xenapi/vm_utils.py'
1459--- nova/virt/xenapi/vm_utils.py 2011-03-01 16:55:13 +0000
1460+++ nova/virt/xenapi/vm_utils.py 2011-03-03 01:57:15 +0000
1461@@ -86,7 +86,8 @@
1462 the pv_kernel flag indicates whether the guest is HVM or PV
1463 """
1464
1465- instance_type = instance_types.INSTANCE_TYPES[instance.instance_type]
1466+ instance_type = instance_types.\
1467+ get_instance_type(instance.instance_type)
1468 mem = str(long(instance_type['memory_mb']) * 1024 * 1024)
1469 vcpus = str(instance_type['vcpus'])
1470 rec = {
1471@@ -144,7 +145,8 @@
1472
1473 @classmethod
1474 def ensure_free_mem(cls, session, instance):
1475- instance_type = instance_types.INSTANCE_TYPES[instance.instance_type]
1476+ instance_type = instance_types.get_instance_type(
1477+ instance.instance_type)
1478 mem = long(instance_type['memory_mb']) * 1024 * 1024
1479 #get free memory from host
1480 host = session.get_xenapi_host()
1481
1482=== modified file 'plugins/xenserver/xenapi/etc/xapi.d/plugins/glance'
1483--- plugins/xenserver/xenapi/etc/xapi.d/plugins/glance 2011-02-25 03:16:04 +0000
1484+++ plugins/xenserver/xenapi/etc/xapi.d/plugins/glance 2011-03-03 01:57:15 +0000
1485@@ -207,8 +207,7 @@
1486 'transfer-encoding': 'chunked',
1487 'x-image-meta-is_public': 'True',
1488 'x-image-meta-status': 'queued',
1489- 'x-image-meta-type': 'vhd'
1490- }
1491+ 'x-image-meta-type': 'vhd'}
1492 for header, value in headers.iteritems():
1493 conn.putheader(header, value)
1494 conn.endheaders()