Statistics
| Branch: | Tag: | Revision:

root / kamaki / cli / commands / image.py @ 623a4ceb

History | View | Annotate | Download (19.7 kB)

1 234954d1 Stavros Sachtouris
# Copyright 2012 GRNET S.A. All rights reserved.
2 7493ccb6 Stavros Sachtouris
#
3 7493ccb6 Stavros Sachtouris
# Redistribution and use in source and binary forms, with or
4 7493ccb6 Stavros Sachtouris
# without modification, are permitted provided that the following
5 7493ccb6 Stavros Sachtouris
# conditions are met:
6 7493ccb6 Stavros Sachtouris
#
7 7493ccb6 Stavros Sachtouris
#   1. Redistributions of source code must retain the above
8 7493ccb6 Stavros Sachtouris
#      copyright notice, this list of conditions and the following
9 7493ccb6 Stavros Sachtouris
#      disclaimer.
10 7493ccb6 Stavros Sachtouris
#
11 7493ccb6 Stavros Sachtouris
#   2. Redistributions in binary form must reproduce the above
12 7493ccb6 Stavros Sachtouris
#      copyright notice, this list of conditions and the following
13 7493ccb6 Stavros Sachtouris
#      disclaimer in the documentation and/or other materials
14 7493ccb6 Stavros Sachtouris
#      provided with the distribution.
15 7493ccb6 Stavros Sachtouris
#
16 7493ccb6 Stavros Sachtouris
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 7493ccb6 Stavros Sachtouris
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 7493ccb6 Stavros Sachtouris
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 7493ccb6 Stavros Sachtouris
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 7493ccb6 Stavros Sachtouris
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 7493ccb6 Stavros Sachtouris
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 7493ccb6 Stavros Sachtouris
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 7493ccb6 Stavros Sachtouris
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 7493ccb6 Stavros Sachtouris
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 7493ccb6 Stavros Sachtouris
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 7493ccb6 Stavros Sachtouris
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 7493ccb6 Stavros Sachtouris
# POSSIBILITY OF SUCH DAMAGE.
28 7493ccb6 Stavros Sachtouris
#
29 7493ccb6 Stavros Sachtouris
# The views and conclusions contained in the software and
30 7493ccb6 Stavros Sachtouris
# documentation are those of the authors and should not be
31 7493ccb6 Stavros Sachtouris
# interpreted as representing official policies, either expressed
32 7493ccb6 Stavros Sachtouris
# or implied, of GRNET S.A.command
33 7493ccb6 Stavros Sachtouris
34 623a4ceb Stavros Sachtouris
from json import load, dumps
35 623a4ceb Stavros Sachtouris
from os.path import abspath
36 623a4ceb Stavros Sachtouris
from logging import getLogger
37 623a4ceb Stavros Sachtouris
38 f3e94e06 Stavros Sachtouris
from kamaki.cli import command
39 d486baec Stavros Sachtouris
from kamaki.cli.command_tree import CommandTree
40 f5f35422 Stavros Sachtouris
from kamaki.cli.utils import print_dict, print_items, print_json
41 1395c40e Stavros Sachtouris
from kamaki.clients.image import ImageClient
42 83c3ba87 Stavros Sachtouris
from kamaki.cli.argument import FlagArgument, ValueArgument, KeyValueArgument
43 83c3ba87 Stavros Sachtouris
from kamaki.cli.argument import IntArgument
44 bfb54881 Stavros Sachtouris
from kamaki.cli.commands.cyclades import _init_cyclades
45 f5f35422 Stavros Sachtouris
from kamaki.cli.commands import _command_init, errors, _optional_output_cmd
46 0b368c8c Stavros Sachtouris
47 234954d1 Stavros Sachtouris
48 a29d2f88 Stavros Sachtouris
image_cmds = CommandTree(
49 a29d2f88 Stavros Sachtouris
    'image',
50 a29d2f88 Stavros Sachtouris
    'Cyclades/Plankton API image commands\n'
51 a29d2f88 Stavros Sachtouris
    'image compute:\tCyclades/Compute API image commands')
52 d486baec Stavros Sachtouris
_commands = [image_cmds]
53 234954d1 Stavros Sachtouris
54 234954d1 Stavros Sachtouris
55 573be34f Stavros Sachtouris
about_image_id = [
56 573be34f Stavros Sachtouris
    'To see a list of available image ids: /image list']
57 15142309 Stavros Sachtouris
58 15142309 Stavros Sachtouris
59 623a4ceb Stavros Sachtouris
log = getLogger(__name__)
60 623a4ceb Stavros Sachtouris
61 623a4ceb Stavros Sachtouris
62 5eae854d Stavros Sachtouris
class _init_image(_command_init):
63 a03ade9e Stavros Sachtouris
    @errors.generic.all
64 a03ade9e Stavros Sachtouris
    def _run(self):
65 a03ade9e Stavros Sachtouris
        token = self.config.get('image', 'token')\
66 a03ade9e Stavros Sachtouris
            or self.config.get('compute', 'token')\
67 a03ade9e Stavros Sachtouris
            or self.config.get('global', 'token')
68 a03ade9e Stavros Sachtouris
        base_url = self.config.get('image', 'url')\
69 a03ade9e Stavros Sachtouris
            or self.config.get('compute', 'url')\
70 a03ade9e Stavros Sachtouris
            or self.config.get('global', 'url')
71 a03ade9e Stavros Sachtouris
        self.client = ImageClient(base_url=base_url, token=token)
72 f47417e7 Stavros Sachtouris
        self._set_log_params()
73 c5b9380c Stavros Sachtouris
        self._update_max_threads()
74 a03ade9e Stavros Sachtouris
75 7493ccb6 Stavros Sachtouris
    def main(self):
76 a03ade9e Stavros Sachtouris
        self._run()
77 7493ccb6 Stavros Sachtouris
78 234954d1 Stavros Sachtouris
79 573be34f Stavros Sachtouris
# Plankton Image Commands
80 573be34f Stavros Sachtouris
81 573be34f Stavros Sachtouris
82 623a4ceb Stavros Sachtouris
def _validate_image_props(json_dict, return_str=False):
83 623a4ceb Stavros Sachtouris
    """
84 623a4ceb Stavros Sachtouris
    :param json_dict" (dict) json-formated, of the form
85 623a4ceb Stavros Sachtouris
        {"key1": "val1", "key2": "val2", ...}
86 623a4ceb Stavros Sachtouris

87 623a4ceb Stavros Sachtouris
    :param return_str: (boolean) if true, return a json dump
88 623a4ceb Stavros Sachtouris

89 623a4ceb Stavros Sachtouris
    :returns: (dict)
90 623a4ceb Stavros Sachtouris

91 623a4ceb Stavros Sachtouris
    :raises TypeError, AttributeError: Invalid json format
92 623a4ceb Stavros Sachtouris

93 623a4ceb Stavros Sachtouris
    :raises AssertionError: Valid json but invalid image properties dict
94 623a4ceb Stavros Sachtouris
    """
95 623a4ceb Stavros Sachtouris
    json_str = dumps(json_dict)
96 623a4ceb Stavros Sachtouris
    for k, v in json_dict.items():
97 623a4ceb Stavros Sachtouris
        dealbreaker = isinstance(v, dict) or isinstance(v, list)
98 623a4ceb Stavros Sachtouris
        assert not dealbreaker, 'Invalid property value for key %s' % k
99 623a4ceb Stavros Sachtouris
        dealbreaker = ' ' in k
100 623a4ceb Stavros Sachtouris
        assert not dealbreaker, 'Invalid key [%s]' % k
101 623a4ceb Stavros Sachtouris
        json_dict[k] = '%s' % v
102 623a4ceb Stavros Sachtouris
    return json_str if return_str else json_dict
103 623a4ceb Stavros Sachtouris
104 623a4ceb Stavros Sachtouris
105 623a4ceb Stavros Sachtouris
def _load_image_props(filepath):
106 623a4ceb Stavros Sachtouris
    """
107 623a4ceb Stavros Sachtouris
    :param filepath: (str) the (relative) path of the metafile
108 623a4ceb Stavros Sachtouris

109 623a4ceb Stavros Sachtouris
    :returns: (dict) json_formated
110 623a4ceb Stavros Sachtouris

111 623a4ceb Stavros Sachtouris
    :raises TypeError, AttributeError: Invalid json format
112 623a4ceb Stavros Sachtouris

113 623a4ceb Stavros Sachtouris
    :raises AssertionError: Valid json but invalid image properties dict
114 623a4ceb Stavros Sachtouris
    """
115 623a4ceb Stavros Sachtouris
    with open(abspath(filepath)) as f:
116 623a4ceb Stavros Sachtouris
        meta_dict = load(f)
117 623a4ceb Stavros Sachtouris
        try:
118 623a4ceb Stavros Sachtouris
            return _validate_image_props(meta_dict)
119 623a4ceb Stavros Sachtouris
        except AssertionError:
120 623a4ceb Stavros Sachtouris
            log.debug('Failed to load properties from file %s' % filepath)
121 623a4ceb Stavros Sachtouris
            raise
122 623a4ceb Stavros Sachtouris
123 623a4ceb Stavros Sachtouris
124 d486baec Stavros Sachtouris
@command(image_cmds)
125 573be34f Stavros Sachtouris
class image_list(_init_image):
126 573be34f Stavros Sachtouris
    """List images accessible by user"""
127 7493ccb6 Stavros Sachtouris
128 1ae79e60 Stavros Sachtouris
    arguments = dict(
129 f40f0cb7 Stavros Sachtouris
        detail=FlagArgument('show detailed output', ('-l', '--details')),
130 1ae79e60 Stavros Sachtouris
        container_format=ValueArgument(
131 1ae79e60 Stavros Sachtouris
            'filter by container format',
132 1ae79e60 Stavros Sachtouris
            '--container-format'),
133 1ae79e60 Stavros Sachtouris
        disk_format=ValueArgument('filter by disk format', '--disk-format'),
134 1ae79e60 Stavros Sachtouris
        name=ValueArgument('filter by name', '--name'),
135 faeccbf9 Stavros Sachtouris
        name_pref=ValueArgument(
136 faeccbf9 Stavros Sachtouris
            'filter by name prefix (case insensitive)',
137 faeccbf9 Stavros Sachtouris
            '--name-prefix'),
138 faeccbf9 Stavros Sachtouris
        name_suff=ValueArgument(
139 faeccbf9 Stavros Sachtouris
            'filter by name suffix (case insensitive)',
140 faeccbf9 Stavros Sachtouris
            '--name-suffix'),
141 faeccbf9 Stavros Sachtouris
        name_like=ValueArgument(
142 faeccbf9 Stavros Sachtouris
            'print only if name contains this (case insensitive)',
143 faeccbf9 Stavros Sachtouris
            '--name-like'),
144 1ae79e60 Stavros Sachtouris
        size_min=IntArgument('filter by minimum size', '--size-min'),
145 1ae79e60 Stavros Sachtouris
        size_max=IntArgument('filter by maximum size', '--size-max'),
146 1ae79e60 Stavros Sachtouris
        status=ValueArgument('filter by status', '--status'),
147 f9457c89 Stavros Sachtouris
        owner=ValueArgument('filter by owner', '--owner'),
148 1ae79e60 Stavros Sachtouris
        order=ValueArgument(
149 1ae79e60 Stavros Sachtouris
            'order by FIELD ( - to reverse order)',
150 1ae79e60 Stavros Sachtouris
            '--order',
151 83c3ba87 Stavros Sachtouris
            default=''),
152 f40f0cb7 Stavros Sachtouris
        limit=IntArgument('limit number of listed images', ('-n', '--number')),
153 83c3ba87 Stavros Sachtouris
        more=FlagArgument(
154 83c3ba87 Stavros Sachtouris
            'output results in pages (-n to set items per page, default 10)',
155 ed9af02c Stavros Sachtouris
            '--more'),
156 f5f35422 Stavros Sachtouris
        enum=FlagArgument('Enumerate results', '--enumerate'),
157 f5f35422 Stavros Sachtouris
        json_output=FlagArgument('Show results in json', ('-j', '--json'))
158 1ae79e60 Stavros Sachtouris
    )
159 7493ccb6 Stavros Sachtouris
160 f9457c89 Stavros Sachtouris
    def _filtered_by_owner(self, detail, *list_params):
161 f9457c89 Stavros Sachtouris
        images = []
162 f9457c89 Stavros Sachtouris
        MINKEYS = set([
163 f9457c89 Stavros Sachtouris
            'id', 'size', 'status', 'disk_format', 'container_format', 'name'])
164 f9457c89 Stavros Sachtouris
        for img in self.client.list_public(True, *list_params):
165 f9457c89 Stavros Sachtouris
            if img['owner'] == self['owner']:
166 f9457c89 Stavros Sachtouris
                if not detail:
167 f9457c89 Stavros Sachtouris
                    for key in set(img.keys()).difference(MINKEYS):
168 f9457c89 Stavros Sachtouris
                        img.pop(key)
169 f9457c89 Stavros Sachtouris
                images.append(img)
170 f9457c89 Stavros Sachtouris
        return images
171 f9457c89 Stavros Sachtouris
172 faeccbf9 Stavros Sachtouris
    def _filtered_by_name(self, images):
173 faeccbf9 Stavros Sachtouris
        np, ns, nl = self['name_pref'], self['name_suff'], self['name_like']
174 faeccbf9 Stavros Sachtouris
        return [img for img in images if (
175 faeccbf9 Stavros Sachtouris
            (not np) or img['name'].lower().startswith(np.lower())) and (
176 faeccbf9 Stavros Sachtouris
            (not ns) or img['name'].lower().endswith(ns.lower())) and (
177 faeccbf9 Stavros Sachtouris
            (not nl) or nl.lower() in img['name'].lower())]
178 faeccbf9 Stavros Sachtouris
179 a03ade9e Stavros Sachtouris
    @errors.generic.all
180 a03ade9e Stavros Sachtouris
    @errors.cyclades.connection
181 a03ade9e Stavros Sachtouris
    def _run(self):
182 a03ade9e Stavros Sachtouris
        super(self.__class__, self)._run()
183 7493ccb6 Stavros Sachtouris
        filters = {}
184 fa984c2c Stavros Sachtouris
        for arg in set([
185 1ae79e60 Stavros Sachtouris
                'container_format',
186 1ae79e60 Stavros Sachtouris
                'disk_format',
187 1ae79e60 Stavros Sachtouris
                'name',
188 1ae79e60 Stavros Sachtouris
                'size_min',
189 1ae79e60 Stavros Sachtouris
                'size_max',
190 de73876b Stavros Sachtouris
                'status']).intersection(self.arguments):
191 1ae79e60 Stavros Sachtouris
            filters[arg] = self[arg]
192 1ae79e60 Stavros Sachtouris
193 1ae79e60 Stavros Sachtouris
        order = self['order']
194 1ae79e60 Stavros Sachtouris
        detail = self['detail']
195 f9457c89 Stavros Sachtouris
        if self['owner']:
196 f9457c89 Stavros Sachtouris
            images = self._filtered_by_owner(detail, filters, order)
197 f9457c89 Stavros Sachtouris
        else:
198 f9457c89 Stavros Sachtouris
            images = self.client.list_public(detail, filters, order)
199 f9457c89 Stavros Sachtouris
200 f5f35422 Stavros Sachtouris
        if self['json_output']:
201 f5f35422 Stavros Sachtouris
            print_json(images)
202 f5f35422 Stavros Sachtouris
            return
203 f5f35422 Stavros Sachtouris
        images = self._filtered_by_name(images)
204 83c3ba87 Stavros Sachtouris
        if self['more']:
205 83c3ba87 Stavros Sachtouris
            print_items(
206 83c3ba87 Stavros Sachtouris
                images,
207 ed9af02c Stavros Sachtouris
                with_enumeration=self['enum'], page_size=self['limit'] or 10)
208 83c3ba87 Stavros Sachtouris
        elif self['limit']:
209 ed9af02c Stavros Sachtouris
            print_items(images[:self['limit']], with_enumeration=self['enum'])
210 83c3ba87 Stavros Sachtouris
        else:
211 ed9af02c Stavros Sachtouris
            print_items(images, with_enumeration=self['enum'])
212 7493ccb6 Stavros Sachtouris
213 a03ade9e Stavros Sachtouris
    def main(self):
214 a03ade9e Stavros Sachtouris
        super(self.__class__, self)._run()
215 a03ade9e Stavros Sachtouris
        self._run()
216 a03ade9e Stavros Sachtouris
217 234954d1 Stavros Sachtouris
218 d486baec Stavros Sachtouris
@command(image_cmds)
219 7493ccb6 Stavros Sachtouris
class image_meta(_init_image):
220 15142309 Stavros Sachtouris
    """Get image metadata
221 15142309 Stavros Sachtouris
    Image metadata include:
222 439826ec Stavros Sachtouris
    - image file information (location, size, etc.)
223 439826ec Stavros Sachtouris
    - image information (id, name, etc.)
224 439826ec Stavros Sachtouris
    - image os properties (os, fs, etc.)
225 15142309 Stavros Sachtouris
    """
226 7493ccb6 Stavros Sachtouris
227 f5f35422 Stavros Sachtouris
    arguments = dict(
228 f5f35422 Stavros Sachtouris
        json_output=FlagArgument('Show results in json', ('-j', '--json'))
229 f5f35422 Stavros Sachtouris
    )
230 f5f35422 Stavros Sachtouris
231 a03ade9e Stavros Sachtouris
    @errors.generic.all
232 a03ade9e Stavros Sachtouris
    @errors.plankton.connection
233 a03ade9e Stavros Sachtouris
    @errors.plankton.id
234 a03ade9e Stavros Sachtouris
    def _run(self, image_id):
235 f5f35422 Stavros Sachtouris
        printer = print_json if self['json_output'] else print_dict
236 f5f35422 Stavros Sachtouris
        printer(self.client.get_meta(image_id))
237 7493ccb6 Stavros Sachtouris
238 a03ade9e Stavros Sachtouris
    def main(self, image_id):
239 a03ade9e Stavros Sachtouris
        super(self.__class__, self)._run()
240 b04288f7 Stavros Sachtouris
        self._run(image_id=image_id)
241 a03ade9e Stavros Sachtouris
242 234954d1 Stavros Sachtouris
243 d486baec Stavros Sachtouris
@command(image_cmds)
244 7493ccb6 Stavros Sachtouris
class image_register(_init_image):
245 fc903073 Stavros Sachtouris
    """(Re)Register an image"""
246 7493ccb6 Stavros Sachtouris
247 1ae79e60 Stavros Sachtouris
    arguments = dict(
248 1ae79e60 Stavros Sachtouris
        checksum=ValueArgument('set image checksum', '--checksum'),
249 1ae79e60 Stavros Sachtouris
        container_format=ValueArgument(
250 1ae79e60 Stavros Sachtouris
            'set container format',
251 1ae79e60 Stavros Sachtouris
            '--container-format'),
252 1ae79e60 Stavros Sachtouris
        disk_format=ValueArgument('set disk format', '--disk-format'),
253 2dc39c27 Stavros Sachtouris
        #id=ValueArgument('set image ID', '--id'),
254 1ae79e60 Stavros Sachtouris
        owner=ValueArgument('set image owner (admin only)', '--owner'),
255 1ae79e60 Stavros Sachtouris
        properties=KeyValueArgument(
256 1ae79e60 Stavros Sachtouris
            'add property in key=value form (can be repeated)',
257 1736e06d Stavros Sachtouris
            ('-p', '--property')),
258 1ae79e60 Stavros Sachtouris
        is_public=FlagArgument('mark image as public', '--public'),
259 1ae79e60 Stavros Sachtouris
        size=IntArgument('set image size', '--size'),
260 f5f35422 Stavros Sachtouris
        #update=FlagArgument(
261 f5f35422 Stavros Sachtouris
        #    'update existing image properties',
262 f5f35422 Stavros Sachtouris
        #    ('-u', '--update')),
263 623a4ceb Stavros Sachtouris
        json_output=FlagArgument('Show results in json', ('-j', '--json')),
264 623a4ceb Stavros Sachtouris
        property_file=ValueArgument(
265 623a4ceb Stavros Sachtouris
            'Load properties from a json-formated file. Contents:'
266 623a4ceb Stavros Sachtouris
            '{"key1": "val1", "key2": "val2", ...}',
267 623a4ceb Stavros Sachtouris
            ('--property-file'))
268 1ae79e60 Stavros Sachtouris
    )
269 7493ccb6 Stavros Sachtouris
270 a03ade9e Stavros Sachtouris
    @errors.generic.all
271 a03ade9e Stavros Sachtouris
    @errors.plankton.connection
272 a03ade9e Stavros Sachtouris
    def _run(self, name, location):
273 7493ccb6 Stavros Sachtouris
        if not location.startswith('pithos://'):
274 3ae60112 Stavros Sachtouris
            account = self.config.get('file', 'account') \
275 f3e94e06 Stavros Sachtouris
                or self.config.get('global', 'account')
276 8741c407 Stavros Sachtouris
            assert account, 'No user account provided'
277 7493ccb6 Stavros Sachtouris
            if account[-1] == '/':
278 7493ccb6 Stavros Sachtouris
                account = account[:-1]
279 3ae60112 Stavros Sachtouris
            container = self.config.get('file', 'container') \
280 f3e94e06 Stavros Sachtouris
                or self.config.get('global', 'container')
281 f769a16a Stavros Sachtouris
            if not container:
282 234954d1 Stavros Sachtouris
                location = 'pithos://%s/%s' % (account, location)
283 234954d1 Stavros Sachtouris
            else:
284 234954d1 Stavros Sachtouris
                location = 'pithos://%s/%s/%s' % (account, container, location)
285 7493ccb6 Stavros Sachtouris
286 7493ccb6 Stavros Sachtouris
        params = {}
287 f769a16a Stavros Sachtouris
        for key in set([
288 1ae79e60 Stavros Sachtouris
                'checksum',
289 1ae79e60 Stavros Sachtouris
                'container_format',
290 1ae79e60 Stavros Sachtouris
                'disk_format',
291 1ae79e60 Stavros Sachtouris
                'owner',
292 1ae79e60 Stavros Sachtouris
                'size',
293 de73876b Stavros Sachtouris
                'is_public']).intersection(self.arguments):
294 1ae79e60 Stavros Sachtouris
            params[key] = self[key]
295 1ae79e60 Stavros Sachtouris
296 623a4ceb Stavros Sachtouris
            #load properties
297 623a4ceb Stavros Sachtouris
            properties = _load_image_props(self['property_file']) if (
298 623a4ceb Stavros Sachtouris
                self['property_file']) else dict()
299 623a4ceb Stavros Sachtouris
            properties.update(self['properties'])
300 f5f35422 Stavros Sachtouris
301 f5f35422 Stavros Sachtouris
        printer = print_json if self['json_output'] else print_dict
302 f5f35422 Stavros Sachtouris
        printer(self.client.register(name, location, params, properties))
303 a03ade9e Stavros Sachtouris
304 a03ade9e Stavros Sachtouris
    def main(self, name, location):
305 a03ade9e Stavros Sachtouris
        super(self.__class__, self)._run()
306 a03ade9e Stavros Sachtouris
        self._run(name, location)
307 7493ccb6 Stavros Sachtouris
308 234954d1 Stavros Sachtouris
309 d486baec Stavros Sachtouris
@command(image_cmds)
310 f5f35422 Stavros Sachtouris
class image_unregister(_init_image, _optional_output_cmd):
311 4a17d307 Stavros Sachtouris
    """Unregister an image (does not delete the image file)"""
312 4a17d307 Stavros Sachtouris
313 4a17d307 Stavros Sachtouris
    @errors.generic.all
314 4a17d307 Stavros Sachtouris
    @errors.plankton.connection
315 4a17d307 Stavros Sachtouris
    @errors.plankton.id
316 4a17d307 Stavros Sachtouris
    def _run(self, image_id):
317 f5f35422 Stavros Sachtouris
        self._optional_output(self.client.unregister(image_id))
318 4a17d307 Stavros Sachtouris
319 4a17d307 Stavros Sachtouris
    def main(self, image_id):
320 4a17d307 Stavros Sachtouris
        super(self.__class__, self)._run()
321 4a17d307 Stavros Sachtouris
        self._run(image_id=image_id)
322 4a17d307 Stavros Sachtouris
323 4a17d307 Stavros Sachtouris
324 4a17d307 Stavros Sachtouris
@command(image_cmds)
325 f5f35422 Stavros Sachtouris
class image_shared(_init_image):
326 f5f35422 Stavros Sachtouris
    """List images shared by a member"""
327 f5f35422 Stavros Sachtouris
328 f5f35422 Stavros Sachtouris
    arguments = dict(
329 f5f35422 Stavros Sachtouris
        json_output=FlagArgument('Show results in json', ('-j', '--json'))
330 f5f35422 Stavros Sachtouris
    )
331 7493ccb6 Stavros Sachtouris
332 236e7d08 Stavros Sachtouris
    @errors.generic.all
333 236e7d08 Stavros Sachtouris
    @errors.plankton.connection
334 f5f35422 Stavros Sachtouris
    def _run(self, member):
335 f5f35422 Stavros Sachtouris
        r = self.client.list_shared(member)
336 f5f35422 Stavros Sachtouris
        if self['json_output']:
337 f5f35422 Stavros Sachtouris
            print_json(r)
338 f5f35422 Stavros Sachtouris
        else:
339 f5f35422 Stavros Sachtouris
            print_items(r, title=('image_id',))
340 7493ccb6 Stavros Sachtouris
341 f5f35422 Stavros Sachtouris
    def main(self, member):
342 236e7d08 Stavros Sachtouris
        super(self.__class__, self)._run()
343 f5f35422 Stavros Sachtouris
        self._run(member)
344 236e7d08 Stavros Sachtouris
345 234954d1 Stavros Sachtouris
346 d486baec Stavros Sachtouris
@command(image_cmds)
347 f5f35422 Stavros Sachtouris
class image_members(_init_image):
348 f5f35422 Stavros Sachtouris
    """Manage members. Members of an image are users who can modify it"""
349 f5f35422 Stavros Sachtouris
350 f5f35422 Stavros Sachtouris
351 f5f35422 Stavros Sachtouris
@command(image_cmds)
352 f5f35422 Stavros Sachtouris
class image_members_list(_init_image):
353 f5f35422 Stavros Sachtouris
    """List members of an image"""
354 f5f35422 Stavros Sachtouris
355 f5f35422 Stavros Sachtouris
    arguments = dict(
356 f5f35422 Stavros Sachtouris
        json_output=FlagArgument('Show results in json', ('-j', '--json'))
357 f5f35422 Stavros Sachtouris
    )
358 7493ccb6 Stavros Sachtouris
359 236e7d08 Stavros Sachtouris
    @errors.generic.all
360 236e7d08 Stavros Sachtouris
    @errors.plankton.connection
361 f5f35422 Stavros Sachtouris
    @errors.plankton.id
362 f5f35422 Stavros Sachtouris
    def _run(self, image_id):
363 f5f35422 Stavros Sachtouris
        members = self.client.list_members(image_id)
364 f5f35422 Stavros Sachtouris
        if self['json_output']:
365 f5f35422 Stavros Sachtouris
            print_json(members)
366 f5f35422 Stavros Sachtouris
        else:
367 f5f35422 Stavros Sachtouris
            print_items(members, title=('member_id',), with_redundancy=True)
368 7493ccb6 Stavros Sachtouris
369 f5f35422 Stavros Sachtouris
    def main(self, image_id):
370 236e7d08 Stavros Sachtouris
        super(self.__class__, self)._run()
371 f5f35422 Stavros Sachtouris
        self._run(image_id=image_id)
372 236e7d08 Stavros Sachtouris
373 234954d1 Stavros Sachtouris
374 d486baec Stavros Sachtouris
@command(image_cmds)
375 f5f35422 Stavros Sachtouris
class image_members_add(_init_image, _optional_output_cmd):
376 7493ccb6 Stavros Sachtouris
    """Add a member to an image"""
377 7493ccb6 Stavros Sachtouris
378 236e7d08 Stavros Sachtouris
    @errors.generic.all
379 236e7d08 Stavros Sachtouris
    @errors.plankton.connection
380 236e7d08 Stavros Sachtouris
    @errors.plankton.id
381 b04288f7 Stavros Sachtouris
    def _run(self, image_id=None, member=None):
382 f5f35422 Stavros Sachtouris
            self._optional_output(self.client.add_member(image_id, member))
383 236e7d08 Stavros Sachtouris
384 236e7d08 Stavros Sachtouris
    def main(self, image_id, member):
385 236e7d08 Stavros Sachtouris
        super(self.__class__, self)._run()
386 b04288f7 Stavros Sachtouris
        self._run(image_id=image_id, member=member)
387 7493ccb6 Stavros Sachtouris
388 234954d1 Stavros Sachtouris
389 d486baec Stavros Sachtouris
@command(image_cmds)
390 f5f35422 Stavros Sachtouris
class image_members_delete(_init_image, _optional_output_cmd):
391 7493ccb6 Stavros Sachtouris
    """Remove a member from an image"""
392 7493ccb6 Stavros Sachtouris
393 236e7d08 Stavros Sachtouris
    @errors.generic.all
394 236e7d08 Stavros Sachtouris
    @errors.plankton.connection
395 236e7d08 Stavros Sachtouris
    @errors.plankton.id
396 b04288f7 Stavros Sachtouris
    def _run(self, image_id=None, member=None):
397 f5f35422 Stavros Sachtouris
            self._optional_output(self.client.remove_member(image_id, member))
398 236e7d08 Stavros Sachtouris
399 236e7d08 Stavros Sachtouris
    def main(self, image_id, member):
400 236e7d08 Stavros Sachtouris
        super(self.__class__, self)._run()
401 b04288f7 Stavros Sachtouris
        self._run(image_id=image_id, member=member)
402 7493ccb6 Stavros Sachtouris
403 234954d1 Stavros Sachtouris
404 d486baec Stavros Sachtouris
@command(image_cmds)
405 f5f35422 Stavros Sachtouris
class image_members_set(_init_image, _optional_output_cmd):
406 7493ccb6 Stavros Sachtouris
    """Set the members of an image"""
407 7493ccb6 Stavros Sachtouris
408 236e7d08 Stavros Sachtouris
    @errors.generic.all
409 236e7d08 Stavros Sachtouris
    @errors.plankton.connection
410 236e7d08 Stavros Sachtouris
    @errors.plankton.id
411 b04288f7 Stavros Sachtouris
    def _run(self, image_id, members):
412 f5f35422 Stavros Sachtouris
            self._optional_output(self.client.set_members(image_id, members))
413 236e7d08 Stavros Sachtouris
414 236e7d08 Stavros Sachtouris
    def main(self, image_id, *members):
415 236e7d08 Stavros Sachtouris
        super(self.__class__, self)._run()
416 b04288f7 Stavros Sachtouris
        self._run(image_id=image_id, members=members)
417 f3e94e06 Stavros Sachtouris
418 f3e94e06 Stavros Sachtouris
419 573be34f Stavros Sachtouris
# Compute Image Commands
420 573be34f Stavros Sachtouris
421 573be34f Stavros Sachtouris
422 d486baec Stavros Sachtouris
@command(image_cmds)
423 8741c407 Stavros Sachtouris
class image_compute(_init_cyclades):
424 a29d2f88 Stavros Sachtouris
    """Cyclades/Compute API image commands"""
425 8741c407 Stavros Sachtouris
426 8741c407 Stavros Sachtouris
427 8741c407 Stavros Sachtouris
@command(image_cmds)
428 8741c407 Stavros Sachtouris
class image_compute_list(_init_cyclades):
429 f3e94e06 Stavros Sachtouris
    """List images"""
430 f3e94e06 Stavros Sachtouris
431 1ae79e60 Stavros Sachtouris
    arguments = dict(
432 f40f0cb7 Stavros Sachtouris
        detail=FlagArgument('show detailed output', ('-l', '--details')),
433 f40f0cb7 Stavros Sachtouris
        limit=IntArgument('limit number listed images', ('-n', '--number')),
434 15142309 Stavros Sachtouris
        more=FlagArgument(
435 15142309 Stavros Sachtouris
            'output results in pages (-n to set items per page, default 10)',
436 ed9af02c Stavros Sachtouris
            '--more'),
437 f5f35422 Stavros Sachtouris
        enum=FlagArgument('Enumerate results', '--enumerate'),
438 f5f35422 Stavros Sachtouris
        json_output=FlagArgument('Show results in json', ('-j', '--json'))
439 1ae79e60 Stavros Sachtouris
    )
440 f3e94e06 Stavros Sachtouris
441 15142309 Stavros Sachtouris
    def _make_results_pretty(self, images):
442 f3e94e06 Stavros Sachtouris
        for img in images:
443 15142309 Stavros Sachtouris
            if 'metadata' in img:
444 15142309 Stavros Sachtouris
                img['metadata'] = img['metadata']['values']
445 f3e94e06 Stavros Sachtouris
446 236e7d08 Stavros Sachtouris
    @errors.generic.all
447 236e7d08 Stavros Sachtouris
    @errors.cyclades.connection
448 236e7d08 Stavros Sachtouris
    def _run(self):
449 236e7d08 Stavros Sachtouris
        images = self.client.list_images(self['detail'])
450 f5f35422 Stavros Sachtouris
        if self['json_output']:
451 f5f35422 Stavros Sachtouris
            print_json(images)
452 f5f35422 Stavros Sachtouris
            return
453 236e7d08 Stavros Sachtouris
        if self['detail']:
454 236e7d08 Stavros Sachtouris
            self._make_results_pretty(images)
455 236e7d08 Stavros Sachtouris
        if self['more']:
456 ed9af02c Stavros Sachtouris
            print_items(
457 ed9af02c Stavros Sachtouris
                images,
458 ed9af02c Stavros Sachtouris
                page_size=self['limit'] or 10, with_enumeration=self['enum'])
459 236e7d08 Stavros Sachtouris
        else:
460 ed9af02c Stavros Sachtouris
            print_items(images[:self['limit']], with_enumeration=self['enum'])
461 236e7d08 Stavros Sachtouris
462 f3e94e06 Stavros Sachtouris
    def main(self):
463 236e7d08 Stavros Sachtouris
        super(self.__class__, self)._run()
464 236e7d08 Stavros Sachtouris
        self._run()
465 f3e94e06 Stavros Sachtouris
466 234954d1 Stavros Sachtouris
467 d486baec Stavros Sachtouris
@command(image_cmds)
468 8741c407 Stavros Sachtouris
class image_compute_info(_init_cyclades):
469 15142309 Stavros Sachtouris
    """Get detailed information on an image"""
470 f3e94e06 Stavros Sachtouris
471 f5f35422 Stavros Sachtouris
    arguments = dict(
472 f5f35422 Stavros Sachtouris
        json_output=FlagArgument('Show results in json', ('-j', '--json'))
473 f5f35422 Stavros Sachtouris
    )
474 f5f35422 Stavros Sachtouris
475 236e7d08 Stavros Sachtouris
    @errors.generic.all
476 236e7d08 Stavros Sachtouris
    @errors.cyclades.connection
477 236e7d08 Stavros Sachtouris
    @errors.plankton.id
478 236e7d08 Stavros Sachtouris
    def _run(self, image_id):
479 236e7d08 Stavros Sachtouris
        image = self.client.get_image_details(image_id)
480 f5f35422 Stavros Sachtouris
        if self['json_output']:
481 f5f35422 Stavros Sachtouris
            print_json(image)
482 f5f35422 Stavros Sachtouris
            return
483 234954d1 Stavros Sachtouris
        if 'metadata' in image:
484 f3e94e06 Stavros Sachtouris
            image['metadata'] = image['metadata']['values']
485 236e7d08 Stavros Sachtouris
        print_dict(image)
486 f3e94e06 Stavros Sachtouris
487 f3e94e06 Stavros Sachtouris
    def main(self, image_id):
488 236e7d08 Stavros Sachtouris
        super(self.__class__, self)._run()
489 b04288f7 Stavros Sachtouris
        self._run(image_id=image_id)
490 f3e94e06 Stavros Sachtouris
491 234954d1 Stavros Sachtouris
492 d486baec Stavros Sachtouris
@command(image_cmds)
493 f5f35422 Stavros Sachtouris
class image_compute_delete(_init_cyclades, _optional_output_cmd):
494 24ff0a35 Stavros Sachtouris
    """Delete an image (WARNING: image file is also removed)"""
495 f3e94e06 Stavros Sachtouris
496 236e7d08 Stavros Sachtouris
    @errors.generic.all
497 236e7d08 Stavros Sachtouris
    @errors.cyclades.connection
498 236e7d08 Stavros Sachtouris
    @errors.plankton.id
499 236e7d08 Stavros Sachtouris
    def _run(self, image_id):
500 f5f35422 Stavros Sachtouris
        self._optional_output(self.client.delete_image(image_id))
501 236e7d08 Stavros Sachtouris
502 f3e94e06 Stavros Sachtouris
    def main(self, image_id):
503 236e7d08 Stavros Sachtouris
        super(self.__class__, self)._run()
504 b04288f7 Stavros Sachtouris
        self._run(image_id=image_id)
505 f3e94e06 Stavros Sachtouris
506 234954d1 Stavros Sachtouris
507 d486baec Stavros Sachtouris
@command(image_cmds)
508 8741c407 Stavros Sachtouris
class image_compute_properties(_init_cyclades):
509 395fbf9e Stavros Sachtouris
    """Manage properties related to OS installation in an image"""
510 f5f35422 Stavros Sachtouris
511 f5f35422 Stavros Sachtouris
512 f5f35422 Stavros Sachtouris
@command(image_cmds)
513 f5f35422 Stavros Sachtouris
class image_compute_properties_list(_init_cyclades):
514 f5f35422 Stavros Sachtouris
    """List all image properties"""
515 f5f35422 Stavros Sachtouris
516 f5f35422 Stavros Sachtouris
    arguments = dict(
517 f5f35422 Stavros Sachtouris
        json_output=FlagArgument('Show results in json', ('-j', '--json'))
518 f5f35422 Stavros Sachtouris
    )
519 f5f35422 Stavros Sachtouris
520 f5f35422 Stavros Sachtouris
    @errors.generic.all
521 f5f35422 Stavros Sachtouris
    @errors.cyclades.connection
522 f5f35422 Stavros Sachtouris
    @errors.plankton.id
523 f5f35422 Stavros Sachtouris
    def _run(self, image_id):
524 f5f35422 Stavros Sachtouris
        printer = print_json if self['json_output'] else print_dict
525 f5f35422 Stavros Sachtouris
        printer(self.client.get_image_metadata(image_id))
526 f5f35422 Stavros Sachtouris
527 f5f35422 Stavros Sachtouris
    def main(self, image_id):
528 f5f35422 Stavros Sachtouris
        super(self.__class__, self)._run()
529 f5f35422 Stavros Sachtouris
        self._run(image_id=image_id)
530 f5f35422 Stavros Sachtouris
531 f5f35422 Stavros Sachtouris
532 f5f35422 Stavros Sachtouris
@command(image_cmds)
533 f5f35422 Stavros Sachtouris
class image_compute_properties_get(_init_cyclades):
534 f5f35422 Stavros Sachtouris
    """Get an image property"""
535 f5f35422 Stavros Sachtouris
536 f5f35422 Stavros Sachtouris
    arguments = dict(
537 f5f35422 Stavros Sachtouris
        json_output=FlagArgument('Show results in json', ('-j', '--json'))
538 f5f35422 Stavros Sachtouris
    )
539 f3e94e06 Stavros Sachtouris
540 236e7d08 Stavros Sachtouris
    @errors.generic.all
541 236e7d08 Stavros Sachtouris
    @errors.cyclades.connection
542 236e7d08 Stavros Sachtouris
    @errors.plankton.id
543 236e7d08 Stavros Sachtouris
    @errors.plankton.metadata
544 236e7d08 Stavros Sachtouris
    def _run(self, image_id, key):
545 f5f35422 Stavros Sachtouris
        printer = print_json if self['json_output'] else print_dict
546 f5f35422 Stavros Sachtouris
        printer(self.client.get_image_metadata(image_id, key))
547 236e7d08 Stavros Sachtouris
548 f5f35422 Stavros Sachtouris
    def main(self, image_id, key):
549 236e7d08 Stavros Sachtouris
        super(self.__class__, self)._run()
550 b04288f7 Stavros Sachtouris
        self._run(image_id=image_id, key=key)
551 f3e94e06 Stavros Sachtouris
552 234954d1 Stavros Sachtouris
553 d486baec Stavros Sachtouris
@command(image_cmds)
554 f5f35422 Stavros Sachtouris
class image_compute_properties_add(_init_cyclades):
555 f5f35422 Stavros Sachtouris
    """Add a property to an image"""
556 f5f35422 Stavros Sachtouris
557 f5f35422 Stavros Sachtouris
    arguments = dict(
558 f5f35422 Stavros Sachtouris
        json_output=FlagArgument('Show results in json', ('-j', '--json'))
559 f5f35422 Stavros Sachtouris
    )
560 f3e94e06 Stavros Sachtouris
561 236e7d08 Stavros Sachtouris
    @errors.generic.all
562 236e7d08 Stavros Sachtouris
    @errors.cyclades.connection
563 236e7d08 Stavros Sachtouris
    @errors.plankton.id
564 b04288f7 Stavros Sachtouris
    @errors.plankton.metadata
565 236e7d08 Stavros Sachtouris
    def _run(self, image_id, key, val):
566 f5f35422 Stavros Sachtouris
        printer = print_json if self['json_output'] else print_dict
567 f5f35422 Stavros Sachtouris
        printer(self.client.create_image_metadata(image_id, key, val))
568 236e7d08 Stavros Sachtouris
569 f3e94e06 Stavros Sachtouris
    def main(self, image_id, key, val):
570 236e7d08 Stavros Sachtouris
        super(self.__class__, self)._run()
571 b04288f7 Stavros Sachtouris
        self._run(image_id=image_id, key=key, val=val)
572 f3e94e06 Stavros Sachtouris
573 234954d1 Stavros Sachtouris
574 d486baec Stavros Sachtouris
@command(image_cmds)
575 f5f35422 Stavros Sachtouris
class image_compute_properties_set(_init_cyclades):
576 f5f35422 Stavros Sachtouris
    """Add / update a set of properties for an image
577 f5f35422 Stavros Sachtouris
    proeprties must be given in the form key=value, e.v.
578 f5f35422 Stavros Sachtouris
    /image compute properties set <image-id> key1=val1 key2=val2
579 f5f35422 Stavros Sachtouris
    """
580 f5f35422 Stavros Sachtouris
    arguments = dict(
581 f5f35422 Stavros Sachtouris
        json_output=FlagArgument('Show results in json', ('-j', '--json'))
582 f5f35422 Stavros Sachtouris
    )
583 f3e94e06 Stavros Sachtouris
584 236e7d08 Stavros Sachtouris
    @errors.generic.all
585 236e7d08 Stavros Sachtouris
    @errors.cyclades.connection
586 236e7d08 Stavros Sachtouris
    @errors.plankton.id
587 f5f35422 Stavros Sachtouris
    def _run(self, image_id, keyvals):
588 f5f35422 Stavros Sachtouris
        metadata = dict()
589 f5f35422 Stavros Sachtouris
        for keyval in keyvals:
590 f5f35422 Stavros Sachtouris
            key, val = keyval.split('=')
591 f5f35422 Stavros Sachtouris
            metadata[key] = val
592 f5f35422 Stavros Sachtouris
        printer = print_json if self['json_output'] else print_dict
593 f5f35422 Stavros Sachtouris
        printer(self.client.update_image_metadata(image_id, **metadata))
594 f5f35422 Stavros Sachtouris
595 f5f35422 Stavros Sachtouris
    def main(self, image_id, *key_equals_value):
596 236e7d08 Stavros Sachtouris
        super(self.__class__, self)._run()
597 f5f35422 Stavros Sachtouris
        self._run(image_id=image_id, keyvals=key_equals_value)
598 f3e94e06 Stavros Sachtouris
599 234954d1 Stavros Sachtouris
600 d486baec Stavros Sachtouris
@command(image_cmds)
601 f5f35422 Stavros Sachtouris
class image_compute_properties_delete(_init_cyclades, _optional_output_cmd):
602 f5f35422 Stavros Sachtouris
    """Delete a property from an image"""
603 f3e94e06 Stavros Sachtouris
604 236e7d08 Stavros Sachtouris
    @errors.generic.all
605 236e7d08 Stavros Sachtouris
    @errors.cyclades.connection
606 236e7d08 Stavros Sachtouris
    @errors.plankton.id
607 236e7d08 Stavros Sachtouris
    @errors.plankton.metadata
608 236e7d08 Stavros Sachtouris
    def _run(self, image_id, key):
609 f5f35422 Stavros Sachtouris
        self._optional_output(self.client.delete_image_metadata(image_id, key))
610 236e7d08 Stavros Sachtouris
611 f3e94e06 Stavros Sachtouris
    def main(self, image_id, key):
612 236e7d08 Stavros Sachtouris
        super(self.__class__, self)._run()
613 b04288f7 Stavros Sachtouris
        self._run(image_id=image_id, key=key)