Revision df0045d8
b/kamaki/cli/__init__.py | ||
---|---|---|
33 | 33 |
|
34 | 34 |
import logging |
35 | 35 |
from sys import argv, exit, stdout |
36 |
from os.path import basename |
|
36 |
from os.path import basename, exists
|
|
37 | 37 |
from inspect import getargspec |
38 | 38 |
|
39 | 39 |
from kamaki.cli.argument import ArgumentParseManager |
... | ... | |
194 | 194 |
|
195 | 195 |
def _check_config_version(cnf): |
196 | 196 |
guess = cnf.guess_version() |
197 |
if guess < 0.9: |
|
197 |
if exists(cnf.path) and guess < 0.9:
|
|
198 | 198 |
print('Config file format version >= 9.0 is required') |
199 |
print('Configuration file "%s" format is not up to date' % ( |
|
200 |
cnf.path)) |
|
199 |
print('Configuration file: %s' % cnf.path) |
|
201 | 200 |
print('but kamaki can fix this:') |
202 | 201 |
print('Calculating changes while preserving information') |
203 | 202 |
lost_terms = cnf.rescue_old_file() |
... | ... | |
234 | 233 |
global _verbose |
235 | 234 |
_verbose = arguments['verbose'].value |
236 | 235 |
_cnf = arguments['config'] |
236 |
|
|
237 |
if _help or is_non_API: |
|
238 |
return None, None |
|
239 |
|
|
237 | 240 |
_check_config_version(_cnf.value) |
238 | 241 |
|
239 | 242 |
global _colors |
... | ... | |
244 | 247 |
_silent = arguments['silent'].value |
245 | 248 |
_setup_logging(_silent, _debug, _verbose, _include) |
246 | 249 |
|
247 |
if _help or is_non_API: |
|
248 |
return None, None |
|
249 |
|
|
250 | 250 |
cloud = arguments['cloud'].value or _cnf.value.get( |
251 | 251 |
'global', 'default_cloud') |
252 | 252 |
if not cloud: |
253 | 253 |
num_of_clouds = len(_cnf.value.keys('cloud')) |
254 | 254 |
if num_of_clouds == 1: |
255 | 255 |
cloud = _cnf.value.keys('cloud')[0] |
256 |
else:
|
|
256 |
elif num_of_clouds > 1:
|
|
257 | 257 |
raise CLIError( |
258 | 258 |
'Found %s clouds but none of them is set as default' % ( |
259 | 259 |
num_of_clouds), |
... | ... | |
268 | 268 |
' kamaki --cloud=<cloud name> ...']) |
269 | 269 |
if not cloud in _cnf.value.keys('cloud'): |
270 | 270 |
raise CLIError( |
271 |
'No cloud "%s" is configured' % cloud,
|
|
271 |
'No cloud%s is configured' % ((' "%s"' % cloud) if cloud else ''),
|
|
272 | 272 |
importance=3, details=[ |
273 |
'To configure a new cloud, find and set the', |
|
273 |
'To configure a new cloud "%s", find and set the' % ( |
|
274 |
cloud or '<cloud name>'), |
|
274 | 275 |
'single authentication URL and token:', |
275 |
' kamaki config set cloud.%s.url <URL>' % cloud, |
|
276 |
' kamaki config set cloud.%s.token <t0k3n>' % cloud]) |
|
276 |
' kamaki config set cloud.%s.url <URL>' % ( |
|
277 |
cloud or '<cloud name>'), |
|
278 |
' kamaki config set cloud.%s.token <t0k3n>' % ( |
|
279 |
cloud or '<cloud name>')]) |
|
277 | 280 |
auth_args = dict() |
278 | 281 |
for term in ('url', 'token'): |
279 | 282 |
try: |
b/kamaki/cli/commands/image.py | ||
---|---|---|
326 | 326 |
ptoken = self.client.token |
327 | 327 |
if getattr(self, 'auth_base', False): |
328 | 328 |
pithos_endpoints = self.auth_base.get_service_endpoints( |
329 |
self.config.get('pithos', 'type'), |
|
330 |
self.config.get('pithos', 'version')) |
|
329 |
'object-store') |
|
331 | 330 |
purl = pithos_endpoints['publicURL'] |
332 | 331 |
else: |
333 |
purl = self.config.get('file', 'url')\ |
|
334 |
or self.config.get('pithos', 'url') |
|
335 |
if not purl: |
|
336 |
raise CLIBaseUrlError(service='pithos') |
|
332 |
purl = self.config.get_cloud('pithos', 'url') |
|
333 |
if not purl: |
|
334 |
raise CLIBaseUrlError(service='pithos') |
|
337 | 335 |
return PithosClient(purl, ptoken, self._get_user_id(), container) |
338 | 336 |
|
339 | 337 |
def _store_remote_metafile(self, pclient, remote_path, metadata): |
b/kamaki/cli/commands/pithos.py | ||
---|---|---|
1947 | 1947 |
@errors.pithos.container |
1948 | 1948 |
def _run(self): |
1949 | 1949 |
self._print( |
1950 |
self.client.get_container_versioning(self.container) if ( |
|
1951 |
self.container) else self.client.get_account_versioning(), |
|
1952 |
print_dict) |
|
1950 |
self.client.get_container_versioning(self.container), print_dict) |
|
1953 | 1951 |
|
1954 |
def main(self, container=None):
|
|
1952 |
def main(self, container): |
|
1955 | 1953 |
super(self.__class__, self)._run() |
1956 | 1954 |
self.container = container |
1957 | 1955 |
self._run() |
... | ... | |
1971 | 1969 |
@errors.pithos.connection |
1972 | 1970 |
@errors.pithos.container |
1973 | 1971 |
def _run(self, versioning): |
1974 |
if self.container: |
|
1975 |
self.client.container = self.container |
|
1976 |
r = self.client.set_container_versioning(versioning) |
|
1977 |
else: |
|
1978 |
r = self.client.set_account_versioning(versioning) |
|
1972 |
self.client.container = self.container |
|
1973 |
r = self.client.set_container_versioning(versioning) |
|
1979 | 1974 |
self._optional_output(r) |
1980 | 1975 |
|
1981 |
def main(self, versioning, container=None):
|
|
1976 |
def main(self, versioning, container): |
|
1982 | 1977 |
super(self.__class__, self)._run() |
1983 | 1978 |
self._run(self._check_versioning(versioning)) |
1984 | 1979 |
|
b/kamaki/cli/config.py | ||
---|---|---|
230 | 230 |
log.warning('..... config file has an old global section') |
231 | 231 |
return 0.8 |
232 | 232 |
log.warning('........ nope') |
233 |
log.warning('Config file heuristic 2: missing all cloud sections ?')
|
|
233 |
log.warning('Config file heuristic 2: Any cloud sections ?')
|
|
234 | 234 |
if 'cloud' in sections: |
235 | 235 |
for r in self.keys('cloud'): |
236 | 236 |
log.warning('... found cloud "%s"' % r) |
237 | 237 |
return 0.9 |
238 |
log.warning('........ yep')
|
|
238 |
log.warning('........ nope')
|
|
239 | 239 |
log.warning('All heuristics failed, cannot decide') |
240 |
return 0.0
|
|
240 |
return 0.9
|
|
241 | 241 |
|
242 | 242 |
def get_cloud(self, cloud, option): |
243 | 243 |
""" |
b/kamaki/clients/compute/__init__.py | ||
---|---|---|
153 | 153 |
""" |
154 | 154 |
command = path4url('metadata', key) |
155 | 155 |
r = self.servers_get(server_id, command) |
156 |
return r.json['metadata']
|
|
156 |
return r.json['meta'] |
|
157 | 157 |
|
158 | 158 |
def create_server_metadata(self, server_id, key, val): |
159 | 159 |
""" |
... | ... | |
165 | 165 |
|
166 | 166 |
:returns: dict of updated key:val metadata |
167 | 167 |
""" |
168 |
req = {'metadata': {key: val}}
|
|
168 |
req = {'meta': {key: val}} |
|
169 | 169 |
r = self.servers_put( |
170 |
server_id, |
|
171 |
'metadata/' + key, |
|
172 |
json_data=req, |
|
173 |
success=201) |
|
174 |
return r.json['metadata'] |
|
170 |
server_id, 'metadata/' + key, json_data=req, success=201) |
|
171 |
return r.json['meta'] |
|
175 | 172 |
|
176 | 173 |
def update_server_metadata(self, server_id, **metadata): |
177 | 174 |
""" |
... | ... | |
183 | 180 |
""" |
184 | 181 |
req = {'metadata': metadata} |
185 | 182 |
r = self.servers_post( |
186 |
server_id, 'metadata', |
|
187 |
json_data=req, success=201) |
|
183 |
server_id, 'metadata', json_data=req, success=201) |
|
188 | 184 |
return r.json['metadata'] |
189 | 185 |
|
190 | 186 |
def delete_server_metadata(self, server_id, key): |
... | ... | |
258 | 254 |
""" |
259 | 255 |
command = path4url('metadata', key) |
260 | 256 |
r = self.images_get(image_id, command) |
261 |
return r.json['metadata']
|
|
257 |
return r.json['meta'] |
|
262 | 258 |
|
263 | 259 |
def create_image_metadata(self, image_id, key, val): |
264 | 260 |
""" |
... | ... | |
270 | 266 |
|
271 | 267 |
:returns: (dict) updated metadata |
272 | 268 |
""" |
273 |
req = {'metadata': {key: val}}
|
|
269 |
req = {'meta': {key: val}} |
|
274 | 270 |
r = self.images_put(image_id, 'metadata/' + key, json_data=req) |
275 |
return r.json['metadata']
|
|
271 |
return r.json['meta'] |
|
276 | 272 |
|
277 | 273 |
def update_image_metadata(self, image_id, **metadata): |
278 | 274 |
""" |
b/kamaki/clients/livetest/cyclades.py | ||
---|---|---|
42 | 42 |
"""Set up a Cyclades test""" |
43 | 43 |
def setUp(self): |
44 | 44 |
|
45 |
with open(self['image', 'details']) as f: |
|
45 |
with open(self['cmpimage', 'details']) as f:
|
|
46 | 46 |
self.img_details = eval(f.read()) |
47 | 47 |
self.img = self.img_details['id'] |
48 | 48 |
with open(self['flavor', 'details']) as f: |
... | ... | |
82 | 82 |
self.img) |
83 | 83 |
self.server2 = self._create_server( |
84 | 84 |
self.servname2, |
85 |
self.flavorid + 2,
|
|
85 |
self.flavorid, |
|
86 | 86 |
self.img) |
87 | 87 |
super(self.__class__, self).test_000() |
88 | 88 |
|
... | ... | |
167 | 167 |
|
168 | 168 |
def _has_status(self, servid, status): |
169 | 169 |
r = self.client.get_server_details(servid) |
170 |
#print 'MY STATUS IS ', r['status'] |
|
170 | 171 |
return r['status'] == status |
171 | 172 |
|
172 | 173 |
def _wait_for_status(self, servid, status): |
... | ... | |
188 | 189 |
c2 = SilentEvent( |
189 | 190 |
self._create_server, |
190 | 191 |
self.servname2, |
191 |
self.flavorid + 2,
|
|
192 |
self.flavorid, |
|
192 | 193 |
self.img) |
193 | 194 |
c3 = SilentEvent( |
194 | 195 |
self._create_server, |
... | ... | |
198 | 199 |
c4 = SilentEvent( |
199 | 200 |
self._create_server, |
200 | 201 |
self.servname2, |
201 |
self.flavorid + 2,
|
|
202 |
self.flavorid, |
|
202 | 203 |
self.img) |
203 | 204 |
c5 = SilentEvent( |
204 | 205 |
self._create_server, |
... | ... | |
208 | 209 |
c6 = SilentEvent( |
209 | 210 |
self._create_server, |
210 | 211 |
self.servname2, |
211 |
self.flavorid + 2,
|
|
212 |
self.flavorid, |
|
212 | 213 |
self.img) |
213 | 214 |
c7 = SilentEvent( |
214 | 215 |
self._create_server, |
... | ... | |
218 | 219 |
c8 = SilentEvent( |
219 | 220 |
self._create_server, |
220 | 221 |
self.servname2, |
221 |
self.flavorid + 2,
|
|
222 |
self.flavorid, |
|
222 | 223 |
self.img) |
223 | 224 |
c1.start() |
224 | 225 |
c2.start() |
... | ... | |
240 | 241 |
|
241 | 242 |
def _test_0010_create_server(self): |
242 | 243 |
self.assertEqual(self.server1["name"], self.servname1) |
243 |
self.assertEqual(self.server1["flavorRef"], self.flavorid)
|
|
244 |
self.assertEqual(self.server1["imageRef"], self.img)
|
|
244 |
self.assertEqual(self.server1["flavor"], self.flavorid) |
|
245 |
self.assertEqual(self.server1["image"], self.img) |
|
245 | 246 |
self.assertEqual(self.server1["status"], "BUILD") |
246 | 247 |
|
247 | 248 |
def test_list_servers(self): |
... | ... | |
252 | 253 |
self.img) |
253 | 254 |
self.server2 = self._create_server( |
254 | 255 |
self.servname2, |
255 |
self.flavorid + 2,
|
|
256 |
self.flavorid, |
|
256 | 257 |
self.img) |
257 | 258 |
self._test_0020_list_servers() |
258 | 259 |
|
... | ... | |
265 | 266 |
for i in range(len(servers)): |
266 | 267 |
for field in ( |
267 | 268 |
'created', |
268 |
'flavorRef',
|
|
269 |
'flavor', |
|
269 | 270 |
'hostId', |
270 |
'imageRef',
|
|
271 |
'image', |
|
271 | 272 |
'progress', |
272 | 273 |
'status', |
273 | 274 |
'updated'): |
... | ... | |
297 | 298 |
def _test_0040_get_server_details(self): |
298 | 299 |
r = self.client.get_server_details(self.server1['id']) |
299 | 300 |
self.assertEqual(r["name"], self.servname1) |
300 |
self.assertEqual(r["flavorRef"], self.flavorid)
|
|
301 |
self.assertEqual(r["imageRef"], self.img)
|
|
301 |
self.assertEqual(r["flavor"], self.flavorid) |
|
302 |
self.assertEqual(r["image"], self.img) |
|
302 | 303 |
self.assertEqual(r["status"], "ACTIVE") |
303 | 304 |
|
304 | 305 |
def test_update_server_name(self): |
... | ... | |
374 | 375 |
self._test_0090_get_server_metadata() |
375 | 376 |
|
376 | 377 |
def _test_0090_get_server_metadata(self): |
377 |
self.client.create_server_metadata( |
|
378 |
self.server1['id'], |
|
379 |
'mymeta_0', |
|
380 |
'val_0') |
|
378 |
self.client.update_server_metadata( |
|
379 |
self.server1['id'], mymeta_0='val_0') |
|
381 | 380 |
r = self.client.get_server_metadata(self.server1['id'], 'mymeta_0') |
382 | 381 |
self.assertEqual(r['mymeta_0'], 'val_0') |
383 | 382 |
|
... | ... | |
390 | 389 |
self._test_0100_update_server_metadata() |
391 | 390 |
|
392 | 391 |
def _test_0100_update_server_metadata(self): |
393 |
r1 = self.client.create_server_metadata( |
|
394 |
self.server1['id'], |
|
395 |
'mymeta3', |
|
396 |
'val2') |
|
392 |
r1 = self.client.update_server_metadata( |
|
393 |
self.server1['id'], mymeta3='val2') |
|
397 | 394 |
self.assertTrue('mymeta3'in r1) |
398 | 395 |
r2 = self.client.update_server_metadata( |
399 |
self.server1['id'], |
|
400 |
mymeta3='val3') |
|
396 |
self.server1['id'], mymeta3='val3') |
|
401 | 397 |
self.assertTrue(r2['mymeta3'], 'val3') |
402 | 398 |
|
403 | 399 |
def test_delete_server_metadata(self): |
404 | 400 |
"""Test delete_server_metadata""" |
405 | 401 |
self.server1 = self._create_server( |
406 |
self.servname1, |
|
407 |
self.flavorid, |
|
408 |
self.img) |
|
402 |
self.servname1, self.flavorid, self.img) |
|
409 | 403 |
self._test_0110_delete_server_metadata() |
410 | 404 |
|
411 | 405 |
def _test_0110_delete_server_metadata(self): |
412 |
r1 = self.client.create_server_metadata( |
|
413 |
self.server1['id'], |
|
414 |
'mymeta', |
|
415 |
'val') |
|
406 |
r1 = self.client.update_server_metadata( |
|
407 |
self.server1['id'], mymeta='val') |
|
416 | 408 |
self.assertTrue('mymeta' in r1) |
417 | 409 |
self.client.delete_server_metadata(self.server1['id'], 'mymeta') |
418 | 410 |
try: |
... | ... | |
467 | 459 |
def _test_0160_get_image_metadata(self): |
468 | 460 |
r = self.client.get_image_metadata(self.img) |
469 | 461 |
self.assert_dicts_are_deeply_equal( |
470 |
self.img_details['metadata']['values'], r)
|
|
471 |
for key, val in self.img_details['metadata']['values'].items():
|
|
462 |
self.img_details['metadata'], r) |
|
463 |
for key, val in self.img_details['metadata'].items(): |
|
472 | 464 |
r = self.client.get_image_metadata(self.img, key) |
473 | 465 |
self.assertEqual(r[key], val) |
474 | 466 |
|
... | ... | |
508 | 500 |
"""Test get_server_console""" |
509 | 501 |
self.server2 = self._create_server( |
510 | 502 |
self.servname2, |
511 |
self.flavorid + 2,
|
|
503 |
self.flavorid, |
|
512 | 504 |
self.img) |
513 | 505 |
self._wait_for_status(self.server2['id'], 'BUILD') |
514 | 506 |
self._test_0190_get_server_console() |
b/kamaki/clients/livetest/image.py | ||
---|---|---|
153 | 153 |
if len(img['properties']): |
154 | 154 |
for interm in ('osfamily', 'users', 'root_partition'): |
155 | 155 |
self.assertTrue(interm in img['properties']) |
156 |
size_max = 1000000000 |
|
156 |
size_max = 1000000000000
|
|
157 | 157 |
r2 = self.client.list_public(filters=dict(size_max=size_max)) |
158 | 158 |
self.assertTrue(len(r2) <= len(r)) |
159 | 159 |
for img in r2: |
b/kamaki/clients/livetest/pithos.py | ||
---|---|---|
167 | 167 |
r = self.client.get_account_quota() |
168 | 168 |
self.assertTrue('x-account-policy-quota' in r) |
169 | 169 |
|
170 |
r = self.client.get_account_versioning() |
|
171 |
self.assertTrue('x-account-policy-versioning' in r) |
|
170 |
#r = self.client.get_account_versioning()
|
|
171 |
#self.assertTrue('x-account-policy-versioning' in r)
|
|
172 | 172 |
|
173 | 173 |
"""Check if(un)modified_since""" |
174 | 174 |
for format in self.client.DATE_FORMATS: |
... | ... | |
292 | 292 |
#print(unicode(r)) |
293 | 293 |
#r = self.client.get_account_quota() |
294 | 294 |
#self.assertEqual(r['x-account-policy-quota'], newquota) |
295 |
self.client.set_account_versioning('auto') |
|
295 |
#self.client.set_account_versioning('auto')
|
|
296 | 296 |
|
297 | 297 |
def test_container_head(self): |
298 | 298 |
"""Test container_HEAD""" |
b/kamaki/clients/pithos/__init__.py | ||
---|---|---|
952 | 952 |
'X-Account-Policy-Quota', |
953 | 953 |
exactMatch=True) |
954 | 954 |
|
955 |
def get_account_versioning(self): |
|
956 |
""" |
|
957 |
:returns: (dict) |
|
958 |
""" |
|
959 |
return filter_in( |
|
960 |
self.get_account_info(), |
|
961 |
'X-Account-Policy-Versioning', |
|
962 |
exactMatch=True) |
|
955 |
#def get_account_versioning(self):
|
|
956 |
# """
|
|
957 |
# :returns: (dict)
|
|
958 |
# """
|
|
959 |
# return filter_in(
|
|
960 |
# self.get_account_info(),
|
|
961 |
# 'X-Account-Policy-Versioning',
|
|
962 |
# exactMatch=True)
|
|
963 | 963 |
|
964 | 964 |
def get_account_meta(self, until=None): |
965 | 965 |
""" |
... | ... | |
990 | 990 |
r = self.account_post(update=True, metadata={metakey: ''}) |
991 | 991 |
return r.headers |
992 | 992 |
|
993 |
""" |
|
994 |
def set_account_quota(self, quota): |
|
995 |
"" |
|
996 |
:param quota: (int) |
|
997 |
"" |
|
998 |
self.account_post(update=True, quota=quota) |
|
999 |
""" |
|
1000 |
|
|
1001 |
def set_account_versioning(self, versioning): |
|
1002 |
""" |
|
1003 |
"param versioning: (str) |
|
1004 |
""" |
|
1005 |
r = self.account_post(update=True, versioning=versioning) |
|
1006 |
return r.headers |
|
993 |
#def set_account_quota(self, quota): |
|
994 |
# """ |
|
995 |
# :param quota: (int) |
|
996 |
# """ |
|
997 |
# self.account_post(update=True, quota=quota) |
|
998 |
|
|
999 |
#def set_account_versioning(self, versioning): |
|
1000 |
# """ |
|
1001 |
# :param versioning: (str) |
|
1002 |
# """ |
|
1003 |
# r = self.account_post(update=True, versioning=versioning) |
|
1004 |
# return r.headers |
|
1007 | 1005 |
|
1008 | 1006 |
def list_containers(self): |
1009 | 1007 |
""" |
Also available in: Unified diff