Merge lp:~sandy-walsh/nova/api-parity into lp:~hudson-openstack/nova/trunk
- api-parity
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Matt Dietz |
Approved revision: | 533 |
Merged at revision: | 545 |
Proposed branch: | lp:~sandy-walsh/nova/api-parity |
Merge into: | lp:~hudson-openstack/nova/trunk |
Diff against target: |
469 lines (+125/-20) 15 files modified
krm_mapping.json.sample (+3/-0) nova/api/openstack/__init__.py (+8/-3) nova/api/openstack/backup_schedules.py (+4/-2) nova/api/openstack/common.py (+24/-0) nova/api/openstack/images.py (+18/-1) nova/api/openstack/servers.py (+27/-2) nova/api/openstack/shared_ip_groups.py (+6/-4) nova/auth/manager.py (+9/-5) nova/auth/novarc.template (+4/-0) nova/compute/api.py (+4/-1) nova/flags.py (+2/-0) nova/tests/api/openstack/test_images.py (+2/-0) nova/tests/api/openstack/test_servers.py (+10/-0) nova/tests/api/openstack/test_shared_ip_groups.py (+1/-1) nova/virt/xenapi/vm_utils.py (+3/-1) |
To merge this branch: | bzr merge lp:~sandy-walsh/nova/api-parity |
Related bugs: | |
Related blueprints: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Cory Wright (community) | Approve | ||
Matt Dietz (community) | Approve | ||
Trey Morris (community) | Approve | ||
Eric Day (community) | Needs Information | ||
Review via email: mp+45371@code.launchpad.net |
Commit message
Description of the change
Read Full Spec for implementation details and notes on how to boot an instance using OS API.
http://
Look at these notes for known issues:
http://
Sandy Walsh (sandy-walsh) wrote : | # |
Conflicts resolved, tests run. Thx dubs!
Trey Morris (tr3buchet) wrote : | # |
I like it! exporting the cloudservers environment variables was a great idea.
question about lines 190-191, I thought the current api didn't have a paused state, wouldn't returning paused cause trouble? Pause isn't implemented in the current api so i chose to set it to "error" because if an instance somehow got "paused" something weird would have happened.
Sandy Walsh (sandy-walsh) wrote : | # |
Trey I went back and forth over that decision for a while. It just looked so weird seeing "error" when it was paused. I figured since other clients are unable to issue a "pause" command, they should never see it.
But I see your point and can live with it either way.
Eric Day (eday) wrote : | # |
367/368: is this needed now that instance is returned as a dict?
Should sharedipgroups.py be renamed to shared_ip_groups.py for consistency?
I don't like the 'grab all and find w/ hash' on image ID as I mentioned in IRC, but hopefully this will get better with Glance. :)
Sandy Walsh (sandy-walsh) wrote : | # |
good point ... I will rename.
I've got a tweet out looking for a two-way function. Good idea.
Sandy Walsh (sandy-walsh) wrote : | # |
Renamed, remerged with trunk and fixed a bug in the display_name patch test.
Sandy Walsh (sandy-walsh) wrote : | # |
Hmm, this branch is busted now after the trunk merge until the instance_id thing is straightened out.
Sandy Walsh (sandy-walsh) wrote : | # |
Branch working again.
Eric, as your question about "not in", I'm not getting a dict back, but a sqlalchemy object (verified).
Trey Morris (tr3buchet) wrote : | # |
I like your point of view on pause/error sandy. Let's definitely go with pause.
Matt Dietz (cerberus) wrote : | # |
284-285: We should be consistent with the /controller/detail calls. If you look at openstack/
- 531. By Sandy Walsh
-
another merge with trunk to remedy instance_id issues
- 532. By Sandy Walsh
-
Changed shared_ip_group detail routing
- 533. By Sandy Walsh
-
Changed shared_ip_group detail routing
Sandy Walsh (sandy-walsh) wrote : | # |
> 284-285: We should be consistent with the /controller/detail calls. If you
> look at openstack/
> implemented verb in the controller itself.
All done sir. Good suggestion!
Preview Diff
1 | === added file 'krm_mapping.json.sample' | |||
2 | --- krm_mapping.json.sample 1970-01-01 00:00:00 +0000 | |||
3 | +++ krm_mapping.json.sample 2011-01-11 19:42:14 +0000 | |||
4 | @@ -0,0 +1,3 @@ | |||
5 | 1 | { | ||
6 | 2 | "machine" : ["kernel", "ramdisk"] | ||
7 | 3 | } | ||
8 | 0 | 4 | ||
9 | === modified file 'nova/api/openstack/__init__.py' | |||
10 | --- nova/api/openstack/__init__.py 2011-01-10 17:37:06 +0000 | |||
11 | +++ nova/api/openstack/__init__.py 2011-01-11 19:42:14 +0000 | |||
12 | @@ -35,7 +35,7 @@ | |||
13 | 35 | from nova.api.openstack import flavors | 35 | from nova.api.openstack import flavors |
14 | 36 | from nova.api.openstack import images | 36 | from nova.api.openstack import images |
15 | 37 | from nova.api.openstack import servers | 37 | from nova.api.openstack import servers |
17 | 38 | from nova.api.openstack import sharedipgroups | 38 | from nova.api.openstack import shared_ip_groups |
18 | 39 | 39 | ||
19 | 40 | 40 | ||
20 | 41 | LOG = logging.getLogger('nova.api.openstack') | 41 | LOG = logging.getLogger('nova.api.openstack') |
21 | @@ -48,6 +48,10 @@ | |||
22 | 48 | 'nova.api.openstack.ratelimiting.RateLimitingMiddleware', | 48 | 'nova.api.openstack.ratelimiting.RateLimitingMiddleware', |
23 | 49 | 'Default ratelimiting implementation for the Openstack API') | 49 | 'Default ratelimiting implementation for the Openstack API') |
24 | 50 | 50 | ||
25 | 51 | flags.DEFINE_string('os_krm_mapping_file', | ||
26 | 52 | 'krm_mapping.json', | ||
27 | 53 | 'Location of OpenStack Flavor/OS:EC2 Kernel/Ramdisk/Machine JSON file.') | ||
28 | 54 | |||
29 | 51 | flags.DEFINE_bool('allow_admin_api', | 55 | flags.DEFINE_bool('allow_admin_api', |
30 | 52 | False, | 56 | False, |
31 | 53 | 'When True, this API service will accept admin operations.') | 57 | 'When True, this API service will accept admin operations.') |
32 | @@ -110,8 +114,9 @@ | |||
33 | 110 | collection={'detail': 'GET'}) | 114 | collection={'detail': 'GET'}) |
34 | 111 | mapper.resource("flavor", "flavors", controller=flavors.Controller(), | 115 | mapper.resource("flavor", "flavors", controller=flavors.Controller(), |
35 | 112 | collection={'detail': 'GET'}) | 116 | collection={'detail': 'GET'}) |
38 | 113 | mapper.resource("sharedipgroup", "sharedipgroups", | 117 | mapper.resource("shared_ip_group", "shared_ip_groups", |
39 | 114 | controller=sharedipgroups.Controller()) | 118 | collection={'detail': 'GET'}, |
40 | 119 | controller=shared_ip_groups.Controller()) | ||
41 | 115 | 120 | ||
42 | 116 | super(APIRouter, self).__init__(mapper) | 121 | super(APIRouter, self).__init__(mapper) |
43 | 117 | 122 | ||
44 | 118 | 123 | ||
45 | === modified file 'nova/api/openstack/backup_schedules.py' | |||
46 | --- nova/api/openstack/backup_schedules.py 2010-12-28 21:48:48 +0000 | |||
47 | +++ nova/api/openstack/backup_schedules.py 2011-01-11 19:42:14 +0000 | |||
48 | @@ -15,7 +15,9 @@ | |||
49 | 15 | # License for the specific language governing permissions and limitations | 15 | # License for the specific language governing permissions and limitations |
50 | 16 | # under the License. | 16 | # under the License. |
51 | 17 | 17 | ||
52 | 18 | import logging | ||
53 | 18 | import time | 19 | import time |
54 | 20 | |||
55 | 19 | from webob import exc | 21 | from webob import exc |
56 | 20 | 22 | ||
57 | 21 | from nova import wsgi | 23 | from nova import wsgi |
58 | @@ -46,8 +48,8 @@ | |||
59 | 46 | def create(self, req, server_id): | 48 | def create(self, req, server_id): |
60 | 47 | """ No actual update method required, since the existing API allows | 49 | """ No actual update method required, since the existing API allows |
61 | 48 | both create and update through a POST """ | 50 | both create and update through a POST """ |
63 | 49 | return faults.Fault(exc.HTTPNotFound()) | 51 | return faults.Fault(exc.HTTPNotImplemented()) |
64 | 50 | 52 | ||
65 | 51 | def delete(self, req, server_id, id): | 53 | def delete(self, req, server_id, id): |
66 | 52 | """ Deletes an existing backup schedule """ | 54 | """ Deletes an existing backup schedule """ |
68 | 53 | return faults.Fault(exc.HTTPNotFound()) | 55 | return faults.Fault(exc.HTTPNotImplemented()) |
69 | 54 | 56 | ||
70 | === modified file 'nova/api/openstack/common.py' | |||
71 | --- nova/api/openstack/common.py 2010-12-23 19:17:53 +0000 | |||
72 | +++ nova/api/openstack/common.py 2011-01-11 19:42:14 +0000 | |||
73 | @@ -15,6 +15,8 @@ | |||
74 | 15 | # License for the specific language governing permissions and limitations | 15 | # License for the specific language governing permissions and limitations |
75 | 16 | # under the License. | 16 | # under the License. |
76 | 17 | 17 | ||
77 | 18 | from nova import exception | ||
78 | 19 | |||
79 | 18 | 20 | ||
80 | 19 | def limited(items, req): | 21 | def limited(items, req): |
81 | 20 | """Return a slice of items according to requested offset and limit. | 22 | """Return a slice of items according to requested offset and limit. |
82 | @@ -34,3 +36,25 @@ | |||
83 | 34 | limit = min(1000, limit) | 36 | limit = min(1000, limit) |
84 | 35 | range_end = offset + limit | 37 | range_end = offset + limit |
85 | 36 | return items[offset:range_end] | 38 | return items[offset:range_end] |
86 | 39 | |||
87 | 40 | |||
88 | 41 | def get_image_id_from_image_hash(image_service, context, image_hash): | ||
89 | 42 | """Given an Image ID Hash, return an objectstore Image ID. | ||
90 | 43 | |||
91 | 44 | image_service - reference to objectstore compatible image service. | ||
92 | 45 | context - security context for image service requests. | ||
93 | 46 | image_hash - hash of the image ID. | ||
94 | 47 | """ | ||
95 | 48 | |||
96 | 49 | # FIX(sandy): This is terribly inefficient. It pulls all images | ||
97 | 50 | # from objectstore in order to find the match. ObjectStore | ||
98 | 51 | # should have a numeric counterpart to the string ID. | ||
99 | 52 | try: | ||
100 | 53 | items = image_service.detail(context) | ||
101 | 54 | except NotImplementedError: | ||
102 | 55 | items = image_service.index(context) | ||
103 | 56 | for image in items: | ||
104 | 57 | image_id = image['imageId'] | ||
105 | 58 | if abs(hash(image_id)) == int(image_hash): | ||
106 | 59 | return image_id | ||
107 | 60 | raise exception.NotFound(image_hash) | ||
108 | 37 | 61 | ||
109 | === modified file 'nova/api/openstack/images.py' | |||
110 | --- nova/api/openstack/images.py 2010-12-31 03:55:00 +0000 | |||
111 | +++ nova/api/openstack/images.py 2011-01-11 19:42:14 +0000 | |||
112 | @@ -15,6 +15,8 @@ | |||
113 | 15 | # License for the specific language governing permissions and limitations | 15 | # License for the specific language governing permissions and limitations |
114 | 16 | # under the License. | 16 | # under the License. |
115 | 17 | 17 | ||
116 | 18 | import logging | ||
117 | 19 | |||
118 | 18 | from webob import exc | 20 | from webob import exc |
119 | 19 | 21 | ||
120 | 20 | from nova import compute | 22 | from nova import compute |
121 | @@ -26,6 +28,7 @@ | |||
122 | 26 | from nova.api.openstack import faults | 28 | from nova.api.openstack import faults |
123 | 27 | import nova.image.service | 29 | import nova.image.service |
124 | 28 | 30 | ||
125 | 31 | |||
126 | 29 | FLAGS = flags.FLAGS | 32 | FLAGS = flags.FLAGS |
127 | 30 | 33 | ||
128 | 31 | 34 | ||
129 | @@ -88,6 +91,12 @@ | |||
130 | 88 | return dict((k, v) for k, v in item.iteritems() if k in keys) | 91 | return dict((k, v) for k, v in item.iteritems() if k in keys) |
131 | 89 | 92 | ||
132 | 90 | 93 | ||
133 | 94 | def _convert_image_id_to_hash(image): | ||
134 | 95 | image_id = abs(hash(image['imageId'])) | ||
135 | 96 | image['imageId'] = image_id | ||
136 | 97 | image['id'] = image_id | ||
137 | 98 | |||
138 | 99 | |||
139 | 91 | class Controller(wsgi.Controller): | 100 | class Controller(wsgi.Controller): |
140 | 92 | 101 | ||
141 | 93 | _serialization_metadata = { | 102 | _serialization_metadata = { |
142 | @@ -112,6 +121,9 @@ | |||
143 | 112 | items = self._service.detail(req.environ['nova.context']) | 121 | items = self._service.detail(req.environ['nova.context']) |
144 | 113 | except NotImplementedError: | 122 | except NotImplementedError: |
145 | 114 | items = self._service.index(req.environ['nova.context']) | 123 | items = self._service.index(req.environ['nova.context']) |
146 | 124 | for image in items: | ||
147 | 125 | _convert_image_id_to_hash(image) | ||
148 | 126 | |||
149 | 115 | items = common.limited(items, req) | 127 | items = common.limited(items, req) |
150 | 116 | items = [_translate_keys(item) for item in items] | 128 | items = [_translate_keys(item) for item in items] |
151 | 117 | items = [_translate_status(item) for item in items] | 129 | items = [_translate_status(item) for item in items] |
152 | @@ -119,7 +131,12 @@ | |||
153 | 119 | 131 | ||
154 | 120 | def show(self, req, id): | 132 | def show(self, req, id): |
155 | 121 | """Return data about the given image id""" | 133 | """Return data about the given image id""" |
157 | 122 | return dict(image=self._service.show(req.environ['nova.context'], id)) | 134 | image_id = common.get_image_id_from_image_hash(self._service, |
158 | 135 | req.environ['nova.context'], id) | ||
159 | 136 | |||
160 | 137 | image = self._service.show(req.environ['nova.context'], image_id) | ||
161 | 138 | _convert_image_id_to_hash(image) | ||
162 | 139 | return dict(image=image) | ||
163 | 123 | 140 | ||
164 | 124 | def delete(self, req, id): | 141 | def delete(self, req, id): |
165 | 125 | # Only public images are supported for now. | 142 | # Only public images are supported for now. |
166 | 126 | 143 | ||
167 | === modified file 'nova/api/openstack/servers.py' | |||
168 | --- nova/api/openstack/servers.py 2011-01-07 14:46:17 +0000 | |||
169 | +++ nova/api/openstack/servers.py 2011-01-11 19:42:14 +0000 | |||
170 | @@ -15,14 +15,17 @@ | |||
171 | 15 | # License for the specific language governing permissions and limitations | 15 | # License for the specific language governing permissions and limitations |
172 | 16 | # under the License. | 16 | # under the License. |
173 | 17 | 17 | ||
174 | 18 | import json | ||
175 | 18 | import traceback | 19 | import traceback |
176 | 19 | 20 | ||
177 | 20 | from webob import exc | 21 | from webob import exc |
178 | 21 | 22 | ||
179 | 22 | from nova import compute | 23 | from nova import compute |
180 | 23 | from nova import exception | 24 | from nova import exception |
181 | 25 | from nova import flags | ||
182 | 24 | from nova import log as logging | 26 | from nova import log as logging |
183 | 25 | from nova import wsgi | 27 | from nova import wsgi |
184 | 28 | from nova import utils | ||
185 | 26 | from nova.api.openstack import common | 29 | from nova.api.openstack import common |
186 | 27 | from nova.api.openstack import faults | 30 | from nova.api.openstack import faults |
187 | 28 | from nova.auth import manager as auth_manager | 31 | from nova.auth import manager as auth_manager |
188 | @@ -35,6 +38,9 @@ | |||
189 | 35 | LOG.setLevel(logging.DEBUG) | 38 | LOG.setLevel(logging.DEBUG) |
190 | 36 | 39 | ||
191 | 37 | 40 | ||
192 | 41 | FLAGS = flags.FLAGS | ||
193 | 42 | |||
194 | 43 | |||
195 | 38 | def _translate_detail_keys(inst): | 44 | def _translate_detail_keys(inst): |
196 | 39 | """ Coerces into dictionary format, mapping everything to Rackspace-like | 45 | """ Coerces into dictionary format, mapping everything to Rackspace-like |
197 | 40 | attributes for return""" | 46 | attributes for return""" |
198 | @@ -44,7 +50,7 @@ | |||
199 | 44 | power_state.RUNNING: 'active', | 50 | power_state.RUNNING: 'active', |
200 | 45 | power_state.BLOCKED: 'active', | 51 | power_state.BLOCKED: 'active', |
201 | 46 | power_state.SUSPENDED: 'suspended', | 52 | power_state.SUSPENDED: 'suspended', |
203 | 47 | power_state.PAUSED: 'error', | 53 | power_state.PAUSED: 'paused', |
204 | 48 | power_state.SHUTDOWN: 'active', | 54 | power_state.SHUTDOWN: 'active', |
205 | 49 | power_state.SHUTOFF: 'active', | 55 | power_state.SHUTOFF: 'active', |
206 | 50 | power_state.CRASHED: 'error'} | 56 | power_state.CRASHED: 'error'} |
207 | @@ -81,6 +87,7 @@ | |||
208 | 81 | 87 | ||
209 | 82 | def __init__(self): | 88 | def __init__(self): |
210 | 83 | self.compute_api = compute.API() | 89 | self.compute_api = compute.API() |
211 | 90 | self._image_service = utils.import_object(FLAGS.image_service) | ||
212 | 84 | super(Controller, self).__init__() | 91 | super(Controller, self).__init__() |
213 | 85 | 92 | ||
214 | 86 | def index(self, req): | 93 | def index(self, req): |
215 | @@ -117,6 +124,18 @@ | |||
216 | 117 | return faults.Fault(exc.HTTPNotFound()) | 124 | return faults.Fault(exc.HTTPNotFound()) |
217 | 118 | return exc.HTTPAccepted() | 125 | return exc.HTTPAccepted() |
218 | 119 | 126 | ||
219 | 127 | def _get_kernel_ramdisk_from_image(self, image_id): | ||
220 | 128 | mapping_filename = FLAGS.os_krm_mapping_file | ||
221 | 129 | |||
222 | 130 | with open(mapping_filename) as f: | ||
223 | 131 | mapping = json.load(f) | ||
224 | 132 | if image_id in mapping: | ||
225 | 133 | return mapping[image_id] | ||
226 | 134 | |||
227 | 135 | raise exception.NotFound( | ||
228 | 136 | _("No entry for image '%s' in mapping file '%s'") % | ||
229 | 137 | (image_id, mapping_filename)) | ||
230 | 138 | |||
231 | 120 | def create(self, req): | 139 | def create(self, req): |
232 | 121 | """ Creates a new server for a given user """ | 140 | """ Creates a new server for a given user """ |
233 | 122 | env = self._deserialize(req.body, req) | 141 | env = self._deserialize(req.body, req) |
234 | @@ -125,10 +144,15 @@ | |||
235 | 125 | 144 | ||
236 | 126 | key_pair = auth_manager.AuthManager.get_key_pairs( | 145 | key_pair = auth_manager.AuthManager.get_key_pairs( |
237 | 127 | req.environ['nova.context'])[0] | 146 | req.environ['nova.context'])[0] |
238 | 147 | image_id = common.get_image_id_from_image_hash(self._image_service, | ||
239 | 148 | req.environ['nova.context'], env['server']['imageId']) | ||
240 | 149 | kernel_id, ramdisk_id = self._get_kernel_ramdisk_from_image(image_id) | ||
241 | 128 | instances = self.compute_api.create( | 150 | instances = self.compute_api.create( |
242 | 129 | req.environ['nova.context'], | 151 | req.environ['nova.context'], |
243 | 130 | instance_types.get_by_flavor_id(env['server']['flavorId']), | 152 | instance_types.get_by_flavor_id(env['server']['flavorId']), |
245 | 131 | env['server']['imageId'], | 153 | image_id, |
246 | 154 | kernel_id=kernel_id, | ||
247 | 155 | ramdisk_id=ramdisk_id, | ||
248 | 132 | display_name=env['server']['name'], | 156 | display_name=env['server']['name'], |
249 | 133 | display_description=env['server']['name'], | 157 | display_description=env['server']['name'], |
250 | 134 | key_name=key_pair['name'], | 158 | key_name=key_pair['name'], |
251 | @@ -158,6 +182,7 @@ | |||
252 | 158 | """ Multi-purpose method used to reboot, rebuild, and | 182 | """ Multi-purpose method used to reboot, rebuild, and |
253 | 159 | resize a server """ | 183 | resize a server """ |
254 | 160 | input_dict = self._deserialize(req.body, req) | 184 | input_dict = self._deserialize(req.body, req) |
255 | 185 | #TODO(sandy): rebuild/resize not supported. | ||
256 | 161 | try: | 186 | try: |
257 | 162 | reboot_type = input_dict['reboot']['type'] | 187 | reboot_type = input_dict['reboot']['type'] |
258 | 163 | except Exception: | 188 | except Exception: |
259 | 164 | 189 | ||
260 | === renamed file 'nova/api/openstack/sharedipgroups.py' => 'nova/api/openstack/shared_ip_groups.py' | |||
261 | --- nova/api/openstack/sharedipgroups.py 2010-12-28 21:48:48 +0000 | |||
262 | +++ nova/api/openstack/shared_ip_groups.py 2011-01-11 19:42:14 +0000 | |||
263 | @@ -15,6 +15,8 @@ | |||
264 | 15 | # License for the specific language governing permissions and limitations | 15 | # License for the specific language governing permissions and limitations |
265 | 16 | # under the License. | 16 | # under the License. |
266 | 17 | 17 | ||
267 | 18 | import logging | ||
268 | 19 | |||
269 | 18 | from webob import exc | 20 | from webob import exc |
270 | 19 | 21 | ||
271 | 20 | from nova import wsgi | 22 | from nova import wsgi |
272 | @@ -29,7 +31,7 @@ | |||
273 | 29 | def _translate_detail_keys(inst): | 31 | def _translate_detail_keys(inst): |
274 | 30 | """ Coerces a shared IP group instance into proper dictionary format with | 32 | """ Coerces a shared IP group instance into proper dictionary format with |
275 | 31 | correctly mapped attributes """ | 33 | correctly mapped attributes """ |
277 | 32 | return dict(sharedIpGroup=inst) | 34 | return dict(sharedIpGroups=inst) |
278 | 33 | 35 | ||
279 | 34 | 36 | ||
280 | 35 | class Controller(wsgi.Controller): | 37 | class Controller(wsgi.Controller): |
281 | @@ -54,12 +56,12 @@ | |||
282 | 54 | 56 | ||
283 | 55 | def delete(self, req, id): | 57 | def delete(self, req, id): |
284 | 56 | """ Deletes a Shared IP Group """ | 58 | """ Deletes a Shared IP Group """ |
286 | 57 | raise faults.Fault(exc.HTTPNotFound()) | 59 | raise faults.Fault(exc.HTTPNotImplemented()) |
287 | 58 | 60 | ||
289 | 59 | def detail(self, req, id): | 61 | def detail(self, req): |
290 | 60 | """ Returns a complete list of Shared IP Groups """ | 62 | """ Returns a complete list of Shared IP Groups """ |
291 | 61 | return _translate_detail_keys({}) | 63 | return _translate_detail_keys({}) |
292 | 62 | 64 | ||
293 | 63 | def create(self, req): | 65 | def create(self, req): |
294 | 64 | """ Creates a new Shared IP group """ | 66 | """ Creates a new Shared IP group """ |
296 | 65 | raise faults.Fault(exc.HTTPNotFound()) | 67 | raise faults.Fault(exc.HTTPNotImplemented()) |
297 | 66 | 68 | ||
298 | === modified file 'nova/auth/manager.py' | |||
299 | --- nova/auth/manager.py 2011-01-04 05:26:41 +0000 | |||
300 | +++ nova/auth/manager.py 2011-01-11 19:42:14 +0000 | |||
301 | @@ -684,8 +684,7 @@ | |||
302 | 684 | else: | 684 | else: |
303 | 685 | regions = {'nova': FLAGS.cc_host} | 685 | regions = {'nova': FLAGS.cc_host} |
304 | 686 | for region, host in regions.iteritems(): | 686 | for region, host in regions.iteritems(): |
307 | 687 | rc = self.__generate_rc(user.access, | 687 | rc = self.__generate_rc(user, |
306 | 688 | user.secret, | ||
308 | 689 | pid, | 688 | pid, |
309 | 690 | use_dmz, | 689 | use_dmz, |
310 | 691 | host) | 690 | host) |
311 | @@ -725,7 +724,7 @@ | |||
312 | 725 | return self.__generate_rc(user.access, user.secret, pid, use_dmz) | 724 | return self.__generate_rc(user.access, user.secret, pid, use_dmz) |
313 | 726 | 725 | ||
314 | 727 | @staticmethod | 726 | @staticmethod |
316 | 728 | def __generate_rc(access, secret, pid, use_dmz=True, host=None): | 727 | def __generate_rc(user, pid, use_dmz=True, host=None): |
317 | 729 | """Generate rc file for user""" | 728 | """Generate rc file for user""" |
318 | 730 | if use_dmz: | 729 | if use_dmz: |
319 | 731 | cc_host = FLAGS.cc_dmz | 730 | cc_host = FLAGS.cc_dmz |
320 | @@ -738,14 +737,19 @@ | |||
321 | 738 | s3_host = host | 737 | s3_host = host |
322 | 739 | cc_host = host | 738 | cc_host = host |
323 | 740 | rc = open(FLAGS.credentials_template).read() | 739 | rc = open(FLAGS.credentials_template).read() |
325 | 741 | rc = rc % {'access': access, | 740 | rc = rc % {'access': user.access, |
326 | 742 | 'project': pid, | 741 | 'project': pid, |
328 | 743 | 'secret': secret, | 742 | 'secret': user.secret, |
329 | 744 | 'ec2': '%s://%s:%s%s' % (FLAGS.ec2_prefix, | 743 | 'ec2': '%s://%s:%s%s' % (FLAGS.ec2_prefix, |
330 | 745 | cc_host, | 744 | cc_host, |
331 | 746 | FLAGS.cc_port, | 745 | FLAGS.cc_port, |
332 | 747 | FLAGS.ec2_suffix), | 746 | FLAGS.ec2_suffix), |
333 | 748 | 's3': 'http://%s:%s' % (s3_host, FLAGS.s3_port), | 747 | 's3': 'http://%s:%s' % (s3_host, FLAGS.s3_port), |
334 | 748 | 'os': '%s://%s:%s%s' % (FLAGS.os_prefix, | ||
335 | 749 | cc_host, | ||
336 | 750 | FLAGS.cc_port, | ||
337 | 751 | FLAGS.os_suffix), | ||
338 | 752 | 'user': user.name, | ||
339 | 749 | 'nova': FLAGS.ca_file, | 753 | 'nova': FLAGS.ca_file, |
340 | 750 | 'cert': FLAGS.credential_cert_file, | 754 | 'cert': FLAGS.credential_cert_file, |
341 | 751 | 'key': FLAGS.credential_key_file} | 755 | 'key': FLAGS.credential_key_file} |
342 | 752 | 756 | ||
343 | === modified file 'nova/auth/novarc.template' | |||
344 | --- nova/auth/novarc.template 2010-07-15 15:52:11 +0000 | |||
345 | +++ nova/auth/novarc.template 2011-01-11 19:42:14 +0000 | |||
346 | @@ -10,3 +10,7 @@ | |||
347 | 10 | export EUCALYPTUS_CERT=${NOVA_CERT} # euca-bundle-image seems to require this set | 10 | export EUCALYPTUS_CERT=${NOVA_CERT} # euca-bundle-image seems to require this set |
348 | 11 | alias ec2-bundle-image="ec2-bundle-image --cert ${EC2_CERT} --privatekey ${EC2_PRIVATE_KEY} --user 42 --ec2cert ${NOVA_CERT}" | 11 | alias ec2-bundle-image="ec2-bundle-image --cert ${EC2_CERT} --privatekey ${EC2_PRIVATE_KEY} --user 42 --ec2cert ${NOVA_CERT}" |
349 | 12 | alias ec2-upload-bundle="ec2-upload-bundle -a ${EC2_ACCESS_KEY} -s ${EC2_SECRET_KEY} --url ${S3_URL} --ec2cert ${NOVA_CERT}" | 12 | alias ec2-upload-bundle="ec2-upload-bundle -a ${EC2_ACCESS_KEY} -s ${EC2_SECRET_KEY} --url ${S3_URL} --ec2cert ${NOVA_CERT}" |
350 | 13 | export CLOUD_SERVERS_API_KEY="%(access)s" | ||
351 | 14 | export CLOUD_SERVERS_USERNAME="%(user)s" | ||
352 | 15 | export CLOUD_SERVERS_URL="%(os)s" | ||
353 | 16 | |||
354 | 13 | 17 | ||
355 | === modified file 'nova/compute/api.py' | |||
356 | --- nova/compute/api.py 2011-01-08 14:35:50 +0000 | |||
357 | +++ nova/compute/api.py 2011-01-11 19:42:14 +0000 | |||
358 | @@ -108,6 +108,8 @@ | |||
359 | 108 | ramdisk_id = None | 108 | ramdisk_id = None |
360 | 109 | LOG.debug(_("Creating a raw instance")) | 109 | LOG.debug(_("Creating a raw instance")) |
361 | 110 | # Make sure we have access to kernel and ramdisk (if not raw) | 110 | # Make sure we have access to kernel and ramdisk (if not raw) |
362 | 111 | logging.debug("Using Kernel=%s, Ramdisk=%s" % | ||
363 | 112 | (kernel_id, ramdisk_id)) | ||
364 | 111 | if kernel_id: | 113 | if kernel_id: |
365 | 112 | self.image_service.show(context, kernel_id) | 114 | self.image_service.show(context, kernel_id) |
366 | 113 | if ramdisk_id: | 115 | if ramdisk_id: |
367 | @@ -171,7 +173,8 @@ | |||
368 | 171 | 173 | ||
369 | 172 | # Set sane defaults if not specified | 174 | # Set sane defaults if not specified |
370 | 173 | updates = dict(hostname=generate_hostname(instance_id)) | 175 | updates = dict(hostname=generate_hostname(instance_id)) |
372 | 174 | if 'display_name' not in instance: | 176 | if (not hasattr(instance, 'display_name')) or \ |
373 | 177 | instance.display_name == None: | ||
374 | 175 | updates['display_name'] = "Server %s" % instance_id | 178 | updates['display_name'] = "Server %s" % instance_id |
375 | 176 | 179 | ||
376 | 177 | instance = self.update(context, instance_id, **updates) | 180 | instance = self.update(context, instance_id, **updates) |
377 | 178 | 181 | ||
378 | === modified file 'nova/flags.py' | |||
379 | --- nova/flags.py 2011-01-11 12:24:58 +0000 | |||
380 | +++ nova/flags.py 2011-01-11 19:42:14 +0000 | |||
381 | @@ -248,10 +248,12 @@ | |||
382 | 248 | DEFINE_integer('rabbit_max_retries', 12, 'rabbit connection attempts') | 248 | DEFINE_integer('rabbit_max_retries', 12, 'rabbit connection attempts') |
383 | 249 | DEFINE_string('control_exchange', 'nova', 'the main exchange to connect to') | 249 | DEFINE_string('control_exchange', 'nova', 'the main exchange to connect to') |
384 | 250 | DEFINE_string('ec2_prefix', 'http', 'prefix for ec2') | 250 | DEFINE_string('ec2_prefix', 'http', 'prefix for ec2') |
385 | 251 | DEFINE_string('os_prefix', 'http', 'prefix for openstack') | ||
386 | 251 | DEFINE_string('cc_host', '$my_ip', 'ip of api server') | 252 | DEFINE_string('cc_host', '$my_ip', 'ip of api server') |
387 | 252 | DEFINE_string('cc_dmz', '$my_ip', 'internal ip of api server') | 253 | DEFINE_string('cc_dmz', '$my_ip', 'internal ip of api server') |
388 | 253 | DEFINE_integer('cc_port', 8773, 'cloud controller port') | 254 | DEFINE_integer('cc_port', 8773, 'cloud controller port') |
389 | 254 | DEFINE_string('ec2_suffix', '/services/Cloud', 'suffix for ec2') | 255 | DEFINE_string('ec2_suffix', '/services/Cloud', 'suffix for ec2') |
390 | 256 | DEFINE_string('os_suffix', '/v1.0/', 'suffix for openstack') | ||
391 | 255 | 257 | ||
392 | 256 | DEFINE_string('default_project', 'openstack', 'default project for openstack') | 258 | DEFINE_string('default_project', 'openstack', 'default project for openstack') |
393 | 257 | DEFINE_string('default_image', 'ami-11111', | 259 | DEFINE_string('default_image', 'ami-11111', |
394 | 258 | 260 | ||
395 | === modified file 'nova/tests/api/openstack/test_images.py' | |||
396 | --- nova/tests/api/openstack/test_images.py 2011-01-04 05:23:35 +0000 | |||
397 | +++ nova/tests/api/openstack/test_images.py 2011-01-11 19:42:14 +0000 | |||
398 | @@ -172,6 +172,7 @@ | |||
399 | 172 | 172 | ||
400 | 173 | IMAGE_FIXTURES = [ | 173 | IMAGE_FIXTURES = [ |
401 | 174 | {'id': '23g2ogk23k4hhkk4k42l', | 174 | {'id': '23g2ogk23k4hhkk4k42l', |
402 | 175 | 'imageId': '23g2ogk23k4hhkk4k42l', | ||
403 | 175 | 'name': 'public image #1', | 176 | 'name': 'public image #1', |
404 | 176 | 'created_at': str(datetime.datetime.utcnow()), | 177 | 'created_at': str(datetime.datetime.utcnow()), |
405 | 177 | 'updated_at': str(datetime.datetime.utcnow()), | 178 | 'updated_at': str(datetime.datetime.utcnow()), |
406 | @@ -181,6 +182,7 @@ | |||
407 | 181 | 'status': 'available', | 182 | 'status': 'available', |
408 | 182 | 'image_type': 'kernel'}, | 183 | 'image_type': 'kernel'}, |
409 | 183 | {'id': 'slkduhfas73kkaskgdas', | 184 | {'id': 'slkduhfas73kkaskgdas', |
410 | 185 | 'imageId': 'slkduhfas73kkaskgdas', | ||
411 | 184 | 'name': 'public image #2', | 186 | 'name': 'public image #2', |
412 | 185 | 'created_at': str(datetime.datetime.utcnow()), | 187 | 'created_at': str(datetime.datetime.utcnow()), |
413 | 186 | 'updated_at': str(datetime.datetime.utcnow()), | 188 | 'updated_at': str(datetime.datetime.utcnow()), |
414 | 187 | 189 | ||
415 | === modified file 'nova/tests/api/openstack/test_servers.py' | |||
416 | --- nova/tests/api/openstack/test_servers.py 2011-01-06 22:35:48 +0000 | |||
417 | +++ nova/tests/api/openstack/test_servers.py 2011-01-11 19:42:14 +0000 | |||
418 | @@ -133,6 +133,12 @@ | |||
419 | 133 | def queue_get_for(context, *args): | 133 | def queue_get_for(context, *args): |
420 | 134 | return 'network_topic' | 134 | return 'network_topic' |
421 | 135 | 135 | ||
422 | 136 | def kernel_ramdisk_mapping(*args, **kwargs): | ||
423 | 137 | return (1, 1) | ||
424 | 138 | |||
425 | 139 | def image_id_from_hash(*args, **kwargs): | ||
426 | 140 | return 2 | ||
427 | 141 | |||
428 | 136 | self.stubs.Set(nova.db.api, 'project_get_network', project_get_network) | 142 | self.stubs.Set(nova.db.api, 'project_get_network', project_get_network) |
429 | 137 | self.stubs.Set(nova.db.api, 'instance_create', instance_create) | 143 | self.stubs.Set(nova.db.api, 'instance_create', instance_create) |
430 | 138 | self.stubs.Set(nova.rpc, 'cast', fake_method) | 144 | self.stubs.Set(nova.rpc, 'cast', fake_method) |
431 | @@ -142,6 +148,10 @@ | |||
432 | 142 | self.stubs.Set(nova.db.api, 'queue_get_for', queue_get_for) | 148 | self.stubs.Set(nova.db.api, 'queue_get_for', queue_get_for) |
433 | 143 | self.stubs.Set(nova.network.manager.VlanManager, 'allocate_fixed_ip', | 149 | self.stubs.Set(nova.network.manager.VlanManager, 'allocate_fixed_ip', |
434 | 144 | fake_method) | 150 | fake_method) |
435 | 151 | self.stubs.Set(nova.api.openstack.servers.Controller, | ||
436 | 152 | "_get_kernel_ramdisk_from_image", kernel_ramdisk_mapping) | ||
437 | 153 | self.stubs.Set(nova.api.openstack.common, | ||
438 | 154 | "get_image_id_from_image_hash", image_id_from_hash) | ||
439 | 145 | 155 | ||
440 | 146 | body = dict(server=dict( | 156 | body = dict(server=dict( |
441 | 147 | name='server_test', imageId=2, flavorId=2, metadata={}, | 157 | name='server_test', imageId=2, flavorId=2, metadata={}, |
442 | 148 | 158 | ||
443 | === renamed file 'nova/tests/api/openstack/test_sharedipgroups.py' => 'nova/tests/api/openstack/test_shared_ip_groups.py' | |||
444 | --- nova/tests/api/openstack/test_sharedipgroups.py 2010-10-08 20:39:00 +0000 | |||
445 | +++ nova/tests/api/openstack/test_shared_ip_groups.py 2011-01-11 19:42:14 +0000 | |||
446 | @@ -19,7 +19,7 @@ | |||
447 | 19 | 19 | ||
448 | 20 | import stubout | 20 | import stubout |
449 | 21 | 21 | ||
451 | 22 | from nova.api.openstack import sharedipgroups | 22 | from nova.api.openstack import shared_ip_groups |
452 | 23 | 23 | ||
453 | 24 | 24 | ||
454 | 25 | class SharedIpGroupsTest(unittest.TestCase): | 25 | class SharedIpGroupsTest(unittest.TestCase): |
455 | 26 | 26 | ||
456 | === modified file 'nova/virt/xenapi/vm_utils.py' | |||
457 | --- nova/virt/xenapi/vm_utils.py 2011-01-04 05:23:35 +0000 | |||
458 | +++ nova/virt/xenapi/vm_utils.py 2011-01-11 19:42:14 +0000 | |||
459 | @@ -357,7 +357,9 @@ | |||
460 | 357 | if i >= 3 and i <= 11: | 357 | if i >= 3 and i <= 11: |
461 | 358 | ref = node.childNodes | 358 | ref = node.childNodes |
462 | 359 | # Name and Value | 359 | # Name and Value |
464 | 360 | diags[ref[0].firstChild.data] = ref[6].firstChild.data | 360 | if len(ref) > 6: |
465 | 361 | diags[ref[0].firstChild.data] = \ | ||
466 | 362 | ref[6].firstChild.data | ||
467 | 361 | return diags | 363 | return diags |
468 | 362 | except cls.XenAPI.Failure as e: | 364 | except cls.XenAPI.Failure as e: |
469 | 363 | return {"Unable to retrieve diagnostics": e} | 365 | return {"Unable to retrieve diagnostics": e} |
Looks like you have a few conflicts in this commit.