Statistics
| Branch: | Tag: | Revision:

root / kamaki / cli / commands / image_cli.py @ f997679d

History | View | Annotate | Download (8.1 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.errors import raiseCLIError
36
from kamaki.cli.utils import print_dict, print_items
37
set_api_description('image', "Compute/Cyclades or Glance API image commands")
38
from kamaki.clients.image import ImageClient, ClientError
39

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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