Statistics
| Branch: | Tag: | Revision:

root / kamaki / cli / commands / image_cli.py @ 7493ccb6

History | View | Annotate | Download (8 kB)

1
# Copyright 2011-2012 GRNET S.A. All rights reserved.
2
#
3
# Redistribution and use in source and binary forms, with or
4
# without modification, are permitted provided that the following
5
# conditions are met:
6
#
7
#   1. Redistributions of source code must retain the above
8
#      copyright notice, this list of conditions and the following
9
#      disclaimer.
10
#
11
#   2. Redistributions in binary form must reproduce the above
12
#      copyright notice, this list of conditions and the following
13
#      disclaimer in the documentation and/or other materials
14
#      provided with the distribution.
15
#
16
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
# POSSIBILITY OF SUCH DAMAGE.
28
#
29
# The views and conclusions contained in the software and
30
# documentation are those of the authors and should not be
31
# interpreted as representing official policies, either expressed
32
# or implied, of GRNET S.A.command
33

    
34
from kamaki.cli import command, set_api_description
35
from kamaki.cli.utils import print_dict, print_items, raiseCLIError
36
set_api_description('image', "Compute/Cyclades or Glance API image commands")
37
from kamaki.clients.image import ImageClient, ClientError
38

    
39
class _init_image(object):
40
    def main(self):
41
        try:
42
            token = self.config.get('image', 'token') or self.config.get('global', 'token')
43
            base_url = self.config.get('image', 'url') or self.config.get('global', 'url')
44
            self.client = ImageClient(base_url=base_url, token=token)
45
        except ClientError as err:
46
            raiseCLIError(err)
47

    
48
@command()
49
class image_public(_init_image):
50
    """List public images"""
51

    
52
    def update_parser(self, parser):
53
        parser.add_argument('-l', dest='detail', action='store_true',
54
                default=False, help='show detailed output')
55
        parser.add_argument('--container-format', dest='container_format',
56
                metavar='FORMAT', help='filter by container format')
57
        parser.add_argument('--disk-format', dest='disk_format',
58
                metavar='FORMAT', help='filter by disk format')
59
        parser.add_argument('--name', dest='name', metavar='NAME',
60
                help='filter by name')
61
        parser.add_argument('--size-min', dest='size_min', metavar='BYTES',
62
                help='filter by minimum size')
63
        parser.add_argument('--size-max', dest='size_max', metavar='BYTES',
64
                help='filter by maximum size')
65
        parser.add_argument('--status', dest='status', metavar='STATUS',
66
                help='filter by status')
67
        parser.add_argument('--order', dest='order', metavar='FIELD',
68
                help='order by FIELD (use a - prefix to reverse order)')
69

    
70
    def main(self):
71
            super(self.__class__, self).main()
72
        filters = {}
73
        for filter in ('container_format', 'disk_format', 'name', 'size_min',
74
                       'size_max', 'status'):
75
            val = getattr(self.args, filter, None)
76
            if val is not None:
77
                filters[filter] = val
78

    
79
        order = self.args.order or ''
80
        try:
81
            images = self.client.list_public(self.args.detail,
82
                filters=filters, order=order)
83
        except ClientError as err:
84
            raiseCLIError(err)
85
        print_items(images, title=('name',))
86

    
87
@command()
88
class image_meta(_init_image):
89
    """Get image metadata"""
90

    
91
    def main(self, image_id):
92
            super(self.__class__, self).main()
93
        try:
94
            image = self.client.get_meta(image_id)
95
        except ClientError as err:
96
            raiseCLIError(err)
97
        print_dict(image)
98

    
99
@command()
100
class image_register(_init_image):
101
    """Register an image"""
102

    
103
    def update_parser(self, parser):
104
        parser.add_argument('--checksum', dest='checksum', metavar='CHECKSUM',
105
                help='set image checksum')
106
        parser.add_argument('--container-format', dest='container_format',
107
                metavar='FORMAT', help='set container format')
108
        parser.add_argument('--disk-format', dest='disk_format',
109
                metavar='FORMAT', help='set disk format')
110
        parser.add_argument('--id', dest='id',
111
                metavar='ID', help='set image ID')
112
        parser.add_argument('--owner', dest='owner',
113
                metavar='USER', help='set image owner (admin only)')
114
        parser.add_argument('--property', dest='properties', action='append',
115
                metavar='KEY=VAL',
116
                help='add a property (can be used multiple times)')
117
        parser.add_argument('--public', dest='is_public', action='store_true',
118
                help='mark image as public')
119
        parser.add_argument('--size', dest='size', metavar='SIZE',
120
                help='set image size')
121

    
122
    def main(self, name, location):
123
            super(self.__class__, self).main()
124
        if not location.startswith('pithos://'):
125
            account = self.config.get('storage', 'account').split()[0]
126
            if account[-1] == '/':
127
                account = account[:-1]
128
            container = self.config.get('storage', 'container')
129
            location = 'pithos://%s/%s'%(account, location) \
130
                if container is None or len(container) == 0 \
131
                else 'pithos://%s/%s/%s' % (account, container, location)
132

    
133
        params = {}
134
        for key in ('checksum', 'container_format', 'disk_format', 'id',
135
                    'owner', 'size'):
136
            val = getattr(self.args, key)
137
            if val is not None:
138
                params[key] = val
139

    
140
        if self.args.is_public:
141
            params['is_public'] = 'true'
142

    
143
        properties = {}
144
        for property in self.args.properties or []:
145
            key, sep, val = property.partition('=')
146
            if not sep:
147
                raise CLIError(message="Invalid property '%s'" % property, importance=1)
148
            properties[key.strip()] = val.strip()
149

    
150
        try:
151
            self.client.register(name, location, params, properties)
152
        except ClientError as err:
153
            raiseCLIError(err)
154

    
155
@command()
156
class image_members(_init_image):
157
    """Get image members"""
158

    
159
    def main(self, image_id):
160
            super(self.__class__, self).main()
161
        try:
162
            members = self.client.list_members(image_id)
163
        except ClientError as err:
164
            raiseCLIError(err)
165
        for member in members:
166
            print(member['member_id'])
167

    
168
@command()
169
class image_shared(_init_image):
170
    """List shared images"""
171

    
172
    def main(self, member):
173
            super(self.__class__, self).main()
174
        try:
175
            images = self.client.list_shared(member)
176
        except ClientError as err:
177
            raiseCLIError(err)
178
        for image in images:
179
            print(image['image_id'])
180

    
181
@command()
182
class image_addmember(_init_image):
183
    """Add a member to an image"""
184

    
185
    def main(self, image_id, member):
186
            super(self.__class__, self).main()
187
        try:
188
            self.client.add_member(image_id, member)
189
        except ClientError as err:
190
            raiseCLIError(err)
191

    
192
@command()
193
class image_delmember(_init_image):
194
    """Remove a member from an image"""
195

    
196
    def main(self, image_id, member):
197
        super(self.__class__, self).main()
198
        try:
199
            self.client.remove_member(image_id, member)
200
        except ClientError as err:
201
            raiseCLIError(err)
202

    
203
@command()
204
class image_setmembers(_init_image):
205
    """Set the members of an image"""
206

    
207
    def main(self, image_id, *member):
208
        super(self.__class__, self).main()
209
        try:
210
            self.client.set_members(image_id, member)
211
        except ClientError as err:
212
            raiseCLIError(err)