Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
K
kamaki
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
itminedu
kamaki
Commits
b0627b52
Commit
b0627b52
authored
Jun 04, 2014
by
Stavros Sachtouris
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Enrich CLI errors in "cmds.image"
Refs #21
parent
8aa5d91e
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
63 additions
and
50 deletions
+63
-50
kamaki/cli/cmds/errors.py
kamaki/cli/cmds/errors.py
+18
-15
kamaki/cli/cmds/image.py
kamaki/cli/cmds/image.py
+45
-35
No files found.
kamaki/cli/cmds/errors.py
View file @
b0627b52
...
@@ -83,22 +83,23 @@ class Generic(object):
...
@@ -83,22 +83,23 @@ class Generic(object):
' kamaki config set cloud.default.token <token>'
,
' kamaki config set cloud.default.token <token>'
,
'To get current token:'
,
'To get current token:'
,
' kamaki config get cloud.default.token'
,
' kamaki config get cloud.default.token'
,
'%s'
%
ce
,
'%s %s'
%
(
getattr
(
ce
,
'status'
,
''
),
ce
)]
+
CLOUDNAME
)
]
+
CLOUDNAME
)
elif
ce
.
status
in
range
(
-
12
,
200
)
+
[
302
,
401
,
500
]:
elif
ce
.
status
in
range
(
-
12
,
200
)
+
[
302
,
401
,
500
]:
raise
CLIError
(
'%s'
%
ce
,
importance
=
3
)
raise
CLIError
(
'%s %s'
%
(
getattr
(
ce
,
'status'
,
''
),
ce
),
importance
=
3
)
elif
ce
.
status
==
404
and
'kamakihttpresponse'
in
ce_msg
:
elif
ce
.
status
==
404
and
'kamakihttpresponse'
in
ce_msg
:
client
=
getattr
(
self
,
'client'
,
None
)
client
=
getattr
(
self
,
'client'
,
None
)
if
not
client
:
if
not
client
:
raise
raise
url
=
getattr
(
client
,
'endpoint_url'
,
'<empty>'
)
url
=
getattr
(
client
,
'endpoint_url'
,
'<empty>'
)
raise
CLIError
(
'Invalid service URL %s'
%
url
,
details
=
[
raise
CLIError
(
'Invalid service URL %s'
%
url
,
details
=
[
'%s'
%
ce
,
'Check if authentication URL is correct'
,
'Check if authentication URL is correct'
,
'To check current URL'
,
'To check current URL'
,
' kamaki config get cloud.default.url'
,
' kamaki config get cloud.default.url'
,
'To set new authentication URL'
,
'To set new authentication URL'
,
' kamaki config set cloud.default.url'
]
+
CLOUDNAME
)
' kamaki config set cloud.default.url'
,
'%s %s'
%
(
getattr
(
ce
,
'status'
,
''
),
ce
)]
+
CLOUDNAME
)
raise
raise
return
_raise
return
_raise
...
@@ -363,24 +364,26 @@ class Image(object):
...
@@ -363,24 +364,26 @@ class Image(object):
if
image_id
and
ce
.
status
in
(
404
,
400
):
if
image_id
and
ce
.
status
in
(
404
,
400
):
raise
CLIError
(
raise
CLIError
(
'No image with id %s found'
%
image_id
,
'No image with id %s found'
%
image_id
,
importance
=
2
,
importance
=
2
,
details
=
this
.
about_image_id
+
[
details
=
this
.
about_image_id
+
[
'%s'
%
ce
])
'%s %s'
%
(
getattr
(
ce
,
'status'
,
''
),
ce
)
])
raise
raise
return
_raise
return
_raise
@
classmethod
@
classmethod
def
metadata
(
this
,
func
):
def
permissions
(
this
,
func
):
def
_raise
(
self
,
*
args
,
**
kwargs
):
def
_raise
(
self
,
*
args
,
**
kwargs
):
key
=
kwargs
.
get
(
'key'
,
None
)
try
:
try
:
return
func
(
self
,
*
args
,
**
kwargs
)
func
(
self
,
*
args
,
**
kwargs
)
except
ClientError
as
ce
:
except
ClientError
as
ce
:
ce_msg
=
(
'%s'
%
ce
).
lower
()
if
ce
.
status
in
(
403
,
405
):
if
ce
.
status
==
404
or
(
ce
.
status
==
400
and
'metadata'
in
ce_msg
):
raise
CLIError
(
raise
CLIError
(
'No properties with key %s in this image'
%
key
,
'Insufficient permissions for this action'
,
details
=
[
'%s'
%
ce
,
])
importance
=
2
,
details
=
[
'To see the owner of an image'
,
' kamaki image info IMAGE_ID'
,
'To see image file permissions'
,
' kamaki file info IMAGE_LOCATION --sharing'
,
'%s %s'
%
(
getattr
(
ce
,
'status'
,
''
),
ce
)])
raise
raise
return
_raise
return
_raise
...
...
kamaki/cli/cmds/image.py
View file @
b0627b52
...
@@ -39,7 +39,7 @@ from pydoc import pager
...
@@ -39,7 +39,7 @@ from pydoc import pager
from
kamaki.cli
import
command
from
kamaki.cli
import
command
from
kamaki.cli.cmdtree
import
CommandTree
from
kamaki.cli.cmdtree
import
CommandTree
from
kamaki.cli.utils
import
filter_dicts_by_dict
from
kamaki.cli.utils
import
filter_dicts_by_dict
,
format_size
from
kamaki.clients.image
import
ImageClient
from
kamaki.clients.image
import
ImageClient
from
kamaki.clients.pithos
import
PithosClient
from
kamaki.clients.pithos
import
PithosClient
from
kamaki.clients
import
ClientError
from
kamaki.clients
import
ClientError
...
@@ -59,16 +59,15 @@ namespaces = [image_cmds, imagecompute_cmds]
...
@@ -59,16 +59,15 @@ namespaces = [image_cmds, imagecompute_cmds]
howto_image_file
=
[
howto_image_file
=
[
'Kamaki commands to:'
,
'To get current user id'
,
' kamaki user info'
,
' get current user id: kamaki user info'
,
'To list all containers'
,
' kamaki container list'
,
' check available containers: kamaki container list'
,
'To create a new container'
,
' kamaki container create CONTAINER'
,
' create a new container: kamaki container create CONTAINER'
,
'To list container contents'
,
' kamaki file list /CONTAINER'
,
' check container contents: kamaki file list /CONTAINER'
,
'To upload files'
,
' kamaki file upload FILE /CONTAINER[/PATH]'
,
' upload files: kamaki file upload IMAGE_FILE /CONTAINER[/PATH]'
,
'To register an image'
,
' register an image:'
,
' kamaki image register --name=IMAGE_NAME --location=/CONTAINER/PATH'
]
' kamaki image register --name=IMAGE_NAME --location=/CONTAINER/PATH'
]
about_image_id
=
[
'To
see a list of available image ids: /
image list'
]
about_image_id
=
[
'To
list all images'
,
' kamaki
image list'
]
log
=
getLogger
(
__name__
)
log
=
getLogger
(
__name__
)
...
@@ -86,7 +85,6 @@ class _ImageInit(CommandInit):
...
@@ -86,7 +85,6 @@ class _ImageInit(CommandInit):
# Plankton Image Commands
# Plankton Image Commands
def
load_image_meta
(
filepath
):
def
load_image_meta
(
filepath
):
"""
"""
:param filepath: (str) the (relative) path of the metafile
:param filepath: (str) the (relative) path of the metafile
...
@@ -201,9 +199,8 @@ class image_list(_ImageInit, OptionalOutput, NameFilter, IDFilter):
...
@@ -201,9 +199,8 @@ class image_list(_ImageInit, OptionalOutput, NameFilter, IDFilter):
filters
[
arg
]
=
self
[
arg
]
filters
[
arg
]
=
self
[
arg
]
order
=
self
[
'order'
]
order
=
self
[
'order'
]
detail
=
self
[
'detail'
]
or
(
detail
=
any
([
self
[
x
]
for
x
in
(
self
[
'prop'
]
or
self
[
'prop_like'
])
or
(
'detail'
,
'prop'
,
'prop_like'
,
'owner'
,
'owner_name'
)])
self
[
'owner'
]
or
self
[
'owner_name'
])
images
=
self
.
client
.
list_public
(
detail
,
filters
,
order
)
images
=
self
.
client
.
list_public
(
detail
,
filters
,
order
)
...
@@ -213,14 +210,23 @@ class image_list(_ImageInit, OptionalOutput, NameFilter, IDFilter):
...
@@ -213,14 +210,23 @@ class image_list(_ImageInit, OptionalOutput, NameFilter, IDFilter):
images
=
self
.
_filter_by_properties
(
images
)
images
=
self
.
_filter_by_properties
(
images
)
images
=
self
.
_filter_by_id
(
images
)
images
=
self
.
_filter_by_id
(
images
)
images
=
self
.
_non_exact_name_filter
(
images
)
images
=
self
.
_non_exact_name_filter
(
images
)
for
img
in
[]
if
self
[
'output_format'
]
else
images
:
try
:
img
[
'size'
]
=
format_size
(
img
[
'size'
])
except
KeyError
:
continue
if
self
[
'detail'
]
and
not
self
[
'output_format'
]:
if
self
[
'detail'
]
and
not
self
[
'output_format'
]:
images
=
self
.
_add_owner_name
(
images
)
images
=
self
.
_add_owner_name
(
images
)
elif
detail
and
not
self
[
'detail'
]:
elif
detail
and
not
self
[
'detail'
]:
for
img
in
images
:
for
img
in
images
:
for
key
in
set
(
img
).
difference
([
for
key
in
set
(
img
).
difference
([
'id'
,
'name'
,
'status'
,
'container_format'
,
'id'
,
'disk_format'
,
'size'
]):
'name'
,
'status'
,
'container_format'
,
'disk_format'
,
'size'
]):
img
.
pop
(
key
)
img
.
pop
(
key
)
kwargs
=
dict
(
with_enumeration
=
self
[
'enum'
])
kwargs
=
dict
(
with_enumeration
=
self
[
'enum'
])
if
self
[
'limit'
]:
if
self
[
'limit'
]:
...
@@ -247,7 +253,14 @@ class image_info(_ImageInit, OptionalOutput):
...
@@ -247,7 +253,14 @@ class image_info(_ImageInit, OptionalOutput):
def
_run
(
self
,
image_id
):
def
_run
(
self
,
image_id
):
meta
=
self
.
client
.
get_meta
(
image_id
)
meta
=
self
.
client
.
get_meta
(
image_id
)
if
not
self
[
'output_format'
]:
if
not
self
[
'output_format'
]:
try
:
meta
[
'owner'
]
+=
' (%s)'
%
self
.
_uuid2username
(
meta
[
'owner'
])
meta
[
'owner'
]
+=
' (%s)'
%
self
.
_uuid2username
(
meta
[
'owner'
])
except
KeyError
as
ke
:
log
.
debug
(
'%s'
%
ke
)
try
:
meta
[
'size'
]
=
format_size
(
meta
[
'size'
])
except
KeyError
as
ke
:
log
.
debug
(
'%s'
%
ke
)
self
.
print_
(
meta
,
self
.
print_dict
)
self
.
print_
(
meta
,
self
.
print_dict
)
def
main
(
self
,
image_id
):
def
main
(
self
,
image_id
):
...
@@ -258,7 +271,7 @@ class image_info(_ImageInit, OptionalOutput):
...
@@ -258,7 +271,7 @@ class image_info(_ImageInit, OptionalOutput):
@
command
(
image_cmds
)
@
command
(
image_cmds
)
class
image_modify
(
_ImageInit
):
class
image_modify
(
_ImageInit
):
"""Add / update metadata and properties for an image
"""Add / update metadata and properties for an image
The original image preserves the values that are not affect
ed
Preserves values not explicitly modifi
ed
"""
"""
arguments
=
dict
(
arguments
=
dict
(
...
@@ -286,6 +299,7 @@ class image_modify(_ImageInit):
...
@@ -286,6 +299,7 @@ class image_modify(_ImageInit):
@
errors
.
Generic
.
all
@
errors
.
Generic
.
all
@
errors
.
Image
.
connection
@
errors
.
Image
.
connection
@
errors
.
Image
.
permissions
@
errors
.
Image
.
id
@
errors
.
Image
.
id
def
_run
(
self
,
image_id
):
def
_run
(
self
,
image_id
):
for
mid
in
(
self
[
'member_ID_to_add'
]
or
[]):
for
mid
in
(
self
[
'member_ID_to_add'
]
or
[]):
...
@@ -362,18 +376,15 @@ class image_register(_ImageInit, OptionalOutput):
...
@@ -362,18 +376,15 @@ class image_register(_ImageInit, OptionalOutput):
"""(Re)Register an image file to an Image service
"""(Re)Register an image file to an Image service
The image file must be stored at a pithos repository
The image file must be stored at a pithos repository
Some metadata can be set by user (e.g., disk-format) while others are set
Some metadata can be set by user (e.g., disk-format) while others are set
only automatically (e.g., image id). There are also some custom user
by the system (e.g., image id).
metadata, called properties
.
Custom user metadata are termed as "properties"
.
A register command creates a remote meta file at
A register command creates a remote meta file at
/<container>/<image path>.meta
/CONTAINER/IMAGE_PATH.meta
Users may download and edit this file and use it to re-register one or more
Users may download and edit this file and use it to re-register.
images.
In case of a meta file, runtime arguments for metadata or properties
In case of a meta file, runtime arguments for metadata or properties
override meta file settings.
override meta file settings.
"""
"""
container_info_cache
=
{}
container_info_cache
=
{}
arguments
=
dict
(
arguments
=
dict
(
checksum
=
ValueArgument
(
'Set image checksum'
,
'--checksum'
),
checksum
=
ValueArgument
(
'Set image checksum'
,
'--checksum'
),
container_format
=
ValueArgument
(
container_format
=
ValueArgument
(
...
@@ -387,7 +398,7 @@ class image_register(_ImageInit, OptionalOutput):
...
@@ -387,7 +398,7 @@ class image_register(_ImageInit, OptionalOutput):
is_public
=
FlagArgument
(
'Mark image as public'
,
'--public'
),
is_public
=
FlagArgument
(
'Mark image as public'
,
'--public'
),
size
=
IntArgument
(
'Set image size in bytes'
,
'--size'
),
size
=
IntArgument
(
'Set image size in bytes'
,
'--size'
),
metafile
=
ValueArgument
(
metafile
=
ValueArgument
(
'Load metadata from a json-formated file
<img-file>
.meta :'
'Load metadata from a json-formated file
IMAGE_FILE
.meta :'
'{"key1": "val1", "key2": "val2", ..., "properties: {...}"}'
,
'{"key1": "val1", "key2": "val2", ..., "properties: {...}"}'
,
(
'--metafile'
)),
(
'--metafile'
)),
force_upload
=
FlagArgument
(
force_upload
=
FlagArgument
(
...
@@ -402,15 +413,15 @@ class image_register(_ImageInit, OptionalOutput):
...
@@ -402,15 +413,15 @@ class image_register(_ImageInit, OptionalOutput):
uuid
=
ValueArgument
(
'Custom user uuid'
,
'--uuid'
),
uuid
=
ValueArgument
(
'Custom user uuid'
,
'--uuid'
),
local_image_path
=
ValueArgument
(
local_image_path
=
ValueArgument
(
'Local image file path to upload and register '
'Local image file path to upload and register '
'(still need target file in the form /
container/remote-path
)'
,
'(still need target file in the form /
CONTAINER/REMOTE-PATH
)'
,
'--upload-image-file'
),
'--upload-image-file'
),
progress_bar
=
ProgressBarArgument
(
progress_bar
=
ProgressBarArgument
(
'Do not use progress bar'
,
'--no-progress-bar'
,
default
=
False
),
'Do not use progress bar'
,
'--no-progress-bar'
,
default
=
False
),
name
=
ValueArgument
(
'The name of the new image'
,
'--name'
),
name
=
ValueArgument
(
'The name of the new image'
,
'--name'
),
pithos_location
=
PithosLocationArgument
(
pithos_location
=
PithosLocationArgument
(
'The Pithos+ image location to put the image at. Format: '
'The Pithos+ image location to put the image at. Format: '
'pithos://USER_UUID/CONTAINER/IMAGE
or '
'pithos://USER_UUID/CONTAINER/IMAGE
_PATH
or '
'/CONTAINER/IMAGE'
,
'/CONTAINER/IMAGE
_PATH
'
,
'--location'
)
'--location'
)
)
)
required
=
(
'name'
,
'pithos_location'
)
required
=
(
'name'
,
'pithos_location'
)
...
@@ -458,10 +469,7 @@ class image_register(_ImageInit, OptionalOutput):
...
@@ -458,10 +469,7 @@ class image_register(_ImageInit, OptionalOutput):
if
pithos
and
not
self
[
'force_upload'
]:
if
pithos
and
not
self
[
'force_upload'
]:
try
:
try
:
pithos
.
get_object_info
(
path
)
pithos
.
get_object_info
(
path
)
raise
CLIError
(
raise
CLIError
(
'File already exists'
,
importance
=
2
,
details
=
[
'File already exists'
,
importance
=
2
,
details
=
[
'A remote file /%s/%s already exists'
%
(
'A remote file /%s/%s already exists'
%
(
pithos
.
container
,
path
),
pithos
.
container
,
path
),
'Use %s to force upload'
%
self
.
arguments
[
'Use %s to force upload'
%
self
.
arguments
[
...
@@ -556,8 +564,7 @@ class image_register(_ImageInit, OptionalOutput):
...
@@ -556,8 +564,7 @@ class image_register(_ImageInit, OptionalOutput):
'To specify a local file:'
,
'To specify a local file:'
,
' %s [pithos://UUID]/CONTAINER[/PATH] %s LOCAL_PATH'
%
(
' %s [pithos://UUID]/CONTAINER[/PATH] %s LOCAL_PATH'
%
(
locator
.
lvalue
,
locator
.
lvalue
,
self
.
arguments
[
'local_image_path'
].
lvalue
)
self
.
arguments
[
'local_image_path'
].
lvalue
)])
])
self
.
arguments
[
'pithos_location'
].
setdefault
(
self
.
arguments
[
'pithos_location'
].
setdefault
(
'uuid'
,
self
.
astakos
.
user_term
(
'id'
))
'uuid'
,
self
.
astakos
.
user_term
(
'id'
))
self
.
_run
(
self
[
'name'
],
locator
)
self
.
_run
(
self
[
'name'
],
locator
)
...
@@ -569,6 +576,7 @@ class image_unregister(_ImageInit):
...
@@ -569,6 +576,7 @@ class image_unregister(_ImageInit):
@
errors
.
Generic
.
all
@
errors
.
Generic
.
all
@
errors
.
Image
.
connection
@
errors
.
Image
.
connection
@
errors
.
Image
.
permissions
@
errors
.
Image
.
id
@
errors
.
Image
.
id
def
_run
(
self
,
image_id
):
def
_run
(
self
,
image_id
):
self
.
client
.
unregister
(
image_id
)
self
.
client
.
unregister
(
image_id
)
...
@@ -680,6 +688,7 @@ class imagecompute_delete(_CycladesInit):
...
@@ -680,6 +688,7 @@ class imagecompute_delete(_CycladesInit):
@
errors
.
Generic
.
all
@
errors
.
Generic
.
all
@
errors
.
Cyclades
.
connection
@
errors
.
Cyclades
.
connection
@
errors
.
Image
.
permissions
@
errors
.
Image
.
id
@
errors
.
Image
.
id
def
_run
(
self
,
image_id
):
def
_run
(
self
,
image_id
):
self
.
client
.
delete_image
(
image_id
)
self
.
client
.
delete_image
(
image_id
)
...
@@ -705,6 +714,7 @@ class imagecompute_modify(_CycladesInit):
...
@@ -705,6 +714,7 @@ class imagecompute_modify(_CycladesInit):
@
errors
.
Generic
.
all
@
errors
.
Generic
.
all
@
errors
.
Cyclades
.
connection
@
errors
.
Cyclades
.
connection
@
errors
.
Image
.
permissions
@
errors
.
Image
.
id
@
errors
.
Image
.
id
def
_run
(
self
,
image_id
):
def
_run
(
self
,
image_id
):
if
self
[
'property_to_add'
]:
if
self
[
'property_to_add'
]:
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment