Statistics
| Branch: | Tag: | Revision:

root / kamaki / clients / image.py @ 961e6040

History | View | Annotate | Download (5.3 kB)

1 a1c50326 Giorgos Verigakis
# Copyright 2011 GRNET S.A. All rights reserved.
2 a1c50326 Giorgos Verigakis
#
3 a1c50326 Giorgos Verigakis
# Redistribution and use in source and binary forms, with or
4 a1c50326 Giorgos Verigakis
# without modification, are permitted provided that the following
5 a1c50326 Giorgos Verigakis
# conditions are met:
6 a1c50326 Giorgos Verigakis
#
7 a1c50326 Giorgos Verigakis
#   1. Redistributions of source code must retain the above
8 a1c50326 Giorgos Verigakis
#      copyright notice, this list of conditions and the following
9 a1c50326 Giorgos Verigakis
#      disclaimer.
10 a1c50326 Giorgos Verigakis
#
11 a1c50326 Giorgos Verigakis
#   2. Redistributions in binary form must reproduce the above
12 a1c50326 Giorgos Verigakis
#      copyright notice, this list of conditions and the following
13 a1c50326 Giorgos Verigakis
#      disclaimer in the documentation and/or other materials
14 a1c50326 Giorgos Verigakis
#      provided with the distribution.
15 a1c50326 Giorgos Verigakis
#
16 a1c50326 Giorgos Verigakis
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 a1c50326 Giorgos Verigakis
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 a1c50326 Giorgos Verigakis
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 a1c50326 Giorgos Verigakis
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 a1c50326 Giorgos Verigakis
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 a1c50326 Giorgos Verigakis
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 a1c50326 Giorgos Verigakis
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 a1c50326 Giorgos Verigakis
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 a1c50326 Giorgos Verigakis
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 a1c50326 Giorgos Verigakis
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 a1c50326 Giorgos Verigakis
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 a1c50326 Giorgos Verigakis
# POSSIBILITY OF SUCH DAMAGE.
28 a1c50326 Giorgos Verigakis
#
29 a1c50326 Giorgos Verigakis
# The views and conclusions contained in the software and
30 a1c50326 Giorgos Verigakis
# documentation are those of the authors and should not be
31 a1c50326 Giorgos Verigakis
# interpreted as representing official policies, either expressed
32 a1c50326 Giorgos Verigakis
# or implied, of GRNET S.A.
33 c270fe96 Stavros Sachtouris
from kamaki.clients import Client, ClientError
34 c270fe96 Stavros Sachtouris
from kamaki.clients.utils import path4url
35 a1c50326 Giorgos Verigakis
36 3dabe5d2 Stavros Sachtouris
37 cd75ff39 Giorgos Verigakis
class ImageClient(Client):
38 cd75ff39 Giorgos Verigakis
    """OpenStack Image Service API 1.0 and GRNET Plankton client"""
39 44b8928d Giorgos Verigakis
40 2f749e6e Stavros Sachtouris
    def __init__(self, base_url, token):
41 33dc6317 Stavros Sachtouris
        super(ImageClient, self).__init__(base_url, token)
42 2f749e6e Stavros Sachtouris
43 cd75ff39 Giorgos Verigakis
    def raise_for_status(self, r):
44 cd75ff39 Giorgos Verigakis
        if r.status_code == 404:
45 cd75ff39 Giorgos Verigakis
            raise ClientError("Image not found", r.status_code)
46 44b8928d Giorgos Verigakis
47 cd75ff39 Giorgos Verigakis
        # Fallback to the default
48 cd75ff39 Giorgos Verigakis
        super(ImageClient, self).raise_for_status(r)
49 44b8928d Giorgos Verigakis
50 a1c50326 Giorgos Verigakis
    def list_public(self, detail=False, filters={}, order=''):
51 3dabe5d2 Stavros Sachtouris
        path = path4url('images', 'detail') if detail else path4url('images/')
52 44b8928d Giorgos Verigakis
53 2f749e6e Stavros Sachtouris
        if isinstance(filters, dict):
54 2f749e6e Stavros Sachtouris
            self.http_client.params.update(filters)
55 a1c50326 Giorgos Verigakis
        if order.startswith('-'):
56 2f749e6e Stavros Sachtouris
            self.set_param('sort_dir', 'desc')
57 a1c50326 Giorgos Verigakis
            order = order[1:]
58 a1c50326 Giorgos Verigakis
        else:
59 2f749e6e Stavros Sachtouris
            self.set_param('sort_dir', 'asc')
60 2f749e6e Stavros Sachtouris
        self.set_param('sort_key', order, iff=order)
61 44b8928d Giorgos Verigakis
62 2f749e6e Stavros Sachtouris
        r = self.get(path, success=200)
63 cd75ff39 Giorgos Verigakis
        return r.json
64 44b8928d Giorgos Verigakis
65 a1c50326 Giorgos Verigakis
    def get_meta(self, image_id):
66 3dabe5d2 Stavros Sachtouris
        path = path4url('images', image_id)
67 cd75ff39 Giorgos Verigakis
        r = self.head(path, success=200)
68 44b8928d Giorgos Verigakis
69 a1c50326 Giorgos Verigakis
        reply = {}
70 cd75ff39 Giorgos Verigakis
        properties = {}
71 cd75ff39 Giorgos Verigakis
        meta_prefix = 'x-image-meta-'
72 cd75ff39 Giorgos Verigakis
        property_prefix = 'x-image-meta-property-'
73 44b8928d Giorgos Verigakis
74 cd75ff39 Giorgos Verigakis
        for key, val in r.headers.items():
75 a1c50326 Giorgos Verigakis
            key = key.lower()
76 cd75ff39 Giorgos Verigakis
            if key.startswith(property_prefix):
77 cd75ff39 Giorgos Verigakis
                key = key[len(property_prefix):]
78 cd75ff39 Giorgos Verigakis
                properties[key] = val
79 cd75ff39 Giorgos Verigakis
            elif key.startswith(meta_prefix):
80 cd75ff39 Giorgos Verigakis
                key = key[len(meta_prefix):]
81 cd75ff39 Giorgos Verigakis
                reply[key] = val
82 44b8928d Giorgos Verigakis
83 cd75ff39 Giorgos Verigakis
        if properties:
84 cd75ff39 Giorgos Verigakis
            reply['properties'] = properties
85 a1c50326 Giorgos Verigakis
        return reply
86 44b8928d Giorgos Verigakis
87 a1c50326 Giorgos Verigakis
    def register(self, name, location, params={}, properties={}):
88 edbee9c8 Stavros Sachtouris
        path = path4url('images/')
89 edbee9c8 Stavros Sachtouris
        self.set_header('X-Image-Meta-Name', name)
90 edbee9c8 Stavros Sachtouris
        self.set_header('X-Image-Meta-Location', location)
91 44b8928d Giorgos Verigakis
92 a1c50326 Giorgos Verigakis
        for key, val in params.items():
93 a1c50326 Giorgos Verigakis
            if key in ('id', 'store', 'disk_format', 'container_format',
94 a1c50326 Giorgos Verigakis
                       'size', 'checksum', 'is_public', 'owner'):
95 a1c50326 Giorgos Verigakis
                key = 'x-image-meta-' + key.replace('_', '-')
96 edbee9c8 Stavros Sachtouris
                self.set_header(key, val)
97 44b8928d Giorgos Verigakis
98 a1c50326 Giorgos Verigakis
        for key, val in properties.items():
99 3dabe5d2 Stavros Sachtouris
            self.set_header('X-Image-Meta-Property-%s' % key, val)
100 44b8928d Giorgos Verigakis
101 0a0b9fb6 Stavros Sachtouris
        r = self.post(path, success=200)
102 adb1dde9 Stavros Sachtouris
        r.release()
103 44b8928d Giorgos Verigakis
104 bcebdfef Stavros Sachtouris
    def reregister(self, location, name=None, params={}, properties={}):
105 bcebdfef Stavros Sachtouris
        path = path4url('images', 'detail')
106 bcebdfef Stavros Sachtouris
        r = self.get(path, success=200)
107 bcebdfef Stavros Sachtouris
        imgs = [img for img in r.json if img['location'] == location]
108 bcebdfef Stavros Sachtouris
        for img in imgs:
109 bcebdfef Stavros Sachtouris
            img_name = name if name else img['name']
110 bcebdfef Stavros Sachtouris
            img_properties = img['properties']
111 bcebdfef Stavros Sachtouris
            for k, v in properties.items():
112 bcebdfef Stavros Sachtouris
                img_properties[k] = v
113 bcebdfef Stavros Sachtouris
            self.register(img_name, location, params, img_properties)
114 bcebdfef Stavros Sachtouris
115 a1c50326 Giorgos Verigakis
    def list_members(self, image_id):
116 3dabe5d2 Stavros Sachtouris
        path = path4url('images', image_id, 'members')
117 cd75ff39 Giorgos Verigakis
        r = self.get(path, success=200)
118 cd75ff39 Giorgos Verigakis
        return r.json['members']
119 a1c50326 Giorgos Verigakis
120 a1c50326 Giorgos Verigakis
    def list_shared(self, member):
121 edbee9c8 Stavros Sachtouris
        path = path4url('shared-images', member)
122 1bb4d14d Stavros Sachtouris
        #self.set_param('format', 'json')
123 cd75ff39 Giorgos Verigakis
        r = self.get(path, success=200)
124 cd75ff39 Giorgos Verigakis
        return r.json['shared_images']
125 a1c50326 Giorgos Verigakis
126 a1c50326 Giorgos Verigakis
    def add_member(self, image_id, member):
127 edbee9c8 Stavros Sachtouris
        path = path4url('images', image_id, 'members', member)
128 6ce9fc72 Stavros Sachtouris
        r = self.put(path, success=204)
129 6ce9fc72 Stavros Sachtouris
        r.release()
130 986b53f8 Giorgos Verigakis
131 a1c50326 Giorgos Verigakis
    def remove_member(self, image_id, member):
132 edbee9c8 Stavros Sachtouris
        path = path4url('images', image_id, 'members', member)
133 6ce9fc72 Stavros Sachtouris
        r = self.delete(path, success=204)
134 6ce9fc72 Stavros Sachtouris
        r.release()
135 44b8928d Giorgos Verigakis
136 a1c50326 Giorgos Verigakis
    def set_members(self, image_id, members):
137 edbee9c8 Stavros Sachtouris
        path = path4url('images', image_id, 'members')
138 a1c50326 Giorgos Verigakis
        req = {'memberships': [{'member_id': member} for member in members]}
139 6ce9fc72 Stavros Sachtouris
        r = self.put(path, json=req, success=204)
140 6ce9fc72 Stavros Sachtouris
        r.release()