Statistics
| Branch: | Tag: | Revision:

root / image_creator / kamaki_wrapper.py @ ebe0f1e0

History | View | Annotate | Download (6.6 kB)

1 121f3bc0 Nikos Skalkotos
# -*- coding: utf-8 -*-
2 121f3bc0 Nikos Skalkotos
#
3 40e7a487 Nikos Skalkotos
# Copyright 2012 GRNET S.A. All rights reserved.
4 40e7a487 Nikos Skalkotos
#
5 40e7a487 Nikos Skalkotos
# Redistribution and use in source and binary forms, with or
6 40e7a487 Nikos Skalkotos
# without modification, are permitted provided that the following
7 40e7a487 Nikos Skalkotos
# conditions are met:
8 40e7a487 Nikos Skalkotos
#
9 40e7a487 Nikos Skalkotos
#   1. Redistributions of source code must retain the above
10 40e7a487 Nikos Skalkotos
#      copyright notice, this list of conditions and the following
11 40e7a487 Nikos Skalkotos
#      disclaimer.
12 40e7a487 Nikos Skalkotos
#
13 40e7a487 Nikos Skalkotos
#   2. Redistributions in binary form must reproduce the above
14 40e7a487 Nikos Skalkotos
#      copyright notice, this list of conditions and the following
15 40e7a487 Nikos Skalkotos
#      disclaimer in the documentation and/or other materials
16 40e7a487 Nikos Skalkotos
#      provided with the distribution.
17 40e7a487 Nikos Skalkotos
#
18 40e7a487 Nikos Skalkotos
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
19 40e7a487 Nikos Skalkotos
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 40e7a487 Nikos Skalkotos
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21 40e7a487 Nikos Skalkotos
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
22 40e7a487 Nikos Skalkotos
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 40e7a487 Nikos Skalkotos
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 40e7a487 Nikos Skalkotos
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
25 40e7a487 Nikos Skalkotos
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26 40e7a487 Nikos Skalkotos
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 40e7a487 Nikos Skalkotos
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
28 40e7a487 Nikos Skalkotos
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 40e7a487 Nikos Skalkotos
# POSSIBILITY OF SUCH DAMAGE.
30 40e7a487 Nikos Skalkotos
#
31 40e7a487 Nikos Skalkotos
# The views and conclusions contained in the software and
32 40e7a487 Nikos Skalkotos
# documentation are those of the authors and should not be
33 40e7a487 Nikos Skalkotos
# interpreted as representing official policies, either expressed
34 40e7a487 Nikos Skalkotos
# or implied, of GRNET S.A.
35 40e7a487 Nikos Skalkotos
36 121f3bc0 Nikos Skalkotos
"""This modules provides the interface for working with the ./kamaki library.
37 121f3bc0 Nikos Skalkotos
The library is used to upload images to and register them with a Synnefo
38 121f3bc0 Nikos Skalkotos
deployment.
39 121f3bc0 Nikos Skalkotos
"""
40 121f3bc0 Nikos Skalkotos
41 effda5db Nikos Skalkotos
import sys
42 effda5db Nikos Skalkotos
43 40e7a487 Nikos Skalkotos
from os.path import basename
44 40e7a487 Nikos Skalkotos
45 3dfe3651 Nikos Skalkotos
from kamaki.cli.config import Config
46 997ac76a Nikos Skalkotos
from kamaki.clients import ClientError
47 40e7a487 Nikos Skalkotos
from kamaki.clients.image import ImageClient
48 997ac76a Nikos Skalkotos
from kamaki.clients.pithos import PithosClient
49 31160dc8 Nikos Skalkotos
from kamaki.clients.astakos import AstakosClient
50 40e7a487 Nikos Skalkotos
51 effda5db Nikos Skalkotos
try:
52 effda5db Nikos Skalkotos
    config = Config()
53 effda5db Nikos Skalkotos
except Exception as e:
54 effda5db Nikos Skalkotos
    sys.stderr.write("Kamaki config error: %s\n" % str(e))
55 effda5db Nikos Skalkotos
    sys.exit(1)
56 49c07ce3 Nikos Skalkotos
57 49c07ce3 Nikos Skalkotos
58 e77e66a9 Nikos Skalkotos
class Kamaki(object):
59 121f3bc0 Nikos Skalkotos
    """Wrapper class for the ./kamaki library"""
60 31160dc8 Nikos Skalkotos
    CONTAINER = "images"
61 cf4f52b6 Nikos Skalkotos
62 24684bbb Nikos Skalkotos
    @staticmethod
63 49c07ce3 Nikos Skalkotos
    def get_default_cloud_name():
64 49c07ce3 Nikos Skalkotos
        """Returns the name of the default cloud"""
65 49c07ce3 Nikos Skalkotos
        clouds = config.keys('cloud')
66 49c07ce3 Nikos Skalkotos
        default = config.get('global', 'default_cloud')
67 49c07ce3 Nikos Skalkotos
        if not default:
68 49c07ce3 Nikos Skalkotos
            return clouds[0] if len(clouds) else ""
69 49c07ce3 Nikos Skalkotos
        return default if default in clouds else ""
70 49c07ce3 Nikos Skalkotos
71 49c07ce3 Nikos Skalkotos
    @staticmethod
72 49c07ce3 Nikos Skalkotos
    def set_default_cloud(name):
73 49c07ce3 Nikos Skalkotos
        """Sets a cloud account as default"""
74 49c07ce3 Nikos Skalkotos
        config.set('global', 'default_cloud', name)
75 49c07ce3 Nikos Skalkotos
        config.write()
76 49c07ce3 Nikos Skalkotos
77 49c07ce3 Nikos Skalkotos
    @staticmethod
78 49c07ce3 Nikos Skalkotos
    def get_clouds():
79 49c07ce3 Nikos Skalkotos
        """Returns the list of available clouds"""
80 49c07ce3 Nikos Skalkotos
        names = config.keys('cloud')
81 49c07ce3 Nikos Skalkotos
82 49c07ce3 Nikos Skalkotos
        clouds = {}
83 49c07ce3 Nikos Skalkotos
        for name in names:
84 49c07ce3 Nikos Skalkotos
            clouds[name] = config.get('cloud', name)
85 49c07ce3 Nikos Skalkotos
86 49c07ce3 Nikos Skalkotos
        return clouds
87 49c07ce3 Nikos Skalkotos
88 49c07ce3 Nikos Skalkotos
    @staticmethod
89 49c07ce3 Nikos Skalkotos
    def get_cloud_by_name(name):
90 49c07ce3 Nikos Skalkotos
        """Returns a dict with cloud info"""
91 49c07ce3 Nikos Skalkotos
        return config.get('cloud', name)
92 cf4f52b6 Nikos Skalkotos
93 cf4f52b6 Nikos Skalkotos
    @staticmethod
94 49c07ce3 Nikos Skalkotos
    def save_cloud(name, url, token, description=""):
95 49c07ce3 Nikos Skalkotos
        """Save a new cloud account"""
96 49c07ce3 Nikos Skalkotos
        cloud = {'url': url, 'token': token}
97 49c07ce3 Nikos Skalkotos
        if len(description):
98 49c07ce3 Nikos Skalkotos
            cloud['description'] = description
99 49c07ce3 Nikos Skalkotos
        config.set('cloud', name, cloud)
100 49c07ce3 Nikos Skalkotos
101 49c07ce3 Nikos Skalkotos
        # Make the saved cloud the default one
102 49c07ce3 Nikos Skalkotos
        config.set('global', 'default_cloud', name)
103 cf4f52b6 Nikos Skalkotos
        config.write()
104 cf4f52b6 Nikos Skalkotos
105 cf4f52b6 Nikos Skalkotos
    @staticmethod
106 49c07ce3 Nikos Skalkotos
    def remove_cloud(name):
107 49c07ce3 Nikos Skalkotos
        """Deletes an existing cloud from the Kamaki configuration file"""
108 49c07ce3 Nikos Skalkotos
        config.remove_option('cloud', name)
109 49c07ce3 Nikos Skalkotos
        config.write()
110 49c07ce3 Nikos Skalkotos
111 49c07ce3 Nikos Skalkotos
    @staticmethod
112 49c07ce3 Nikos Skalkotos
    def create_account(url, token):
113 49c07ce3 Nikos Skalkotos
        """Given a valid (URL, tokens) pair this method returns an Astakos
114 49c07ce3 Nikos Skalkotos
        client instance
115 49c07ce3 Nikos Skalkotos
        """
116 49c07ce3 Nikos Skalkotos
        client = AstakosClient(url, token)
117 31160dc8 Nikos Skalkotos
        try:
118 49c07ce3 Nikos Skalkotos
            client.authenticate()
119 49c07ce3 Nikos Skalkotos
        except ClientError:
120 49c07ce3 Nikos Skalkotos
            return None
121 49c07ce3 Nikos Skalkotos
122 49c07ce3 Nikos Skalkotos
        return client
123 49c07ce3 Nikos Skalkotos
124 49c07ce3 Nikos Skalkotos
    @staticmethod
125 49c07ce3 Nikos Skalkotos
    def get_account(cloud_name):
126 49c07ce3 Nikos Skalkotos
        """Given a saved cloud name this method returns an Astakos client
127 49c07ce3 Nikos Skalkotos
        instance
128 49c07ce3 Nikos Skalkotos
        """
129 49c07ce3 Nikos Skalkotos
        cloud = config.get('cloud', cloud_name)
130 49c07ce3 Nikos Skalkotos
        assert cloud, "cloud: `%s' does not exist" % cloud_name
131 49c07ce3 Nikos Skalkotos
        assert 'url' in cloud, "url attr is missing in %s" % cloud_name
132 49c07ce3 Nikos Skalkotos
        assert 'token' in cloud, "token attr is missing in %s" % cloud_name
133 49c07ce3 Nikos Skalkotos
134 49c07ce3 Nikos Skalkotos
        return Kamaki.create_account(cloud['url'], cloud['token'])
135 cf4f52b6 Nikos Skalkotos
136 31160dc8 Nikos Skalkotos
    def __init__(self, account, output):
137 88f83027 Nikos Skalkotos
        """Create a Kamaki instance"""
138 997ac76a Nikos Skalkotos
        self.account = account
139 e77e66a9 Nikos Skalkotos
        self.out = output
140 40e7a487 Nikos Skalkotos
141 49c07ce3 Nikos Skalkotos
        self.pithos = PithosClient(
142 49c07ce3 Nikos Skalkotos
            self.account.get_service_endpoints('object-store')['publicURL'],
143 49c07ce3 Nikos Skalkotos
            self.account.token,
144 49c07ce3 Nikos Skalkotos
            self.account.user_info()['id'],
145 37d581b8 Nikos Skalkotos
            self.CONTAINER)
146 40e7a487 Nikos Skalkotos
147 49c07ce3 Nikos Skalkotos
        self.image = ImageClient(
148 49c07ce3 Nikos Skalkotos
            self.account.get_service_endpoints('image')['publicURL'],
149 49c07ce3 Nikos Skalkotos
            self.account.token)
150 40e7a487 Nikos Skalkotos
151 b1395967 Nikos Skalkotos
    def upload(self, file_obj, size=None, remote_path=None, hp=None, up=None):
152 b1aea98e Nikos Skalkotos
        """Upload a file to pithos"""
153 3b7d3fc7 Nikos Skalkotos
154 3b7d3fc7 Nikos Skalkotos
        path = basename(file_obj.name) if remote_path is None else remote_path
155 40e7a487 Nikos Skalkotos
156 b1395967 Nikos Skalkotos
        try:
157 49c07ce3 Nikos Skalkotos
            self.pithos.create_container(self.CONTAINER)
158 b1395967 Nikos Skalkotos
        except ClientError as e:
159 b1395967 Nikos Skalkotos
            if e.status != 202:  # Ignore container already exists errors
160 3b7d3fc7 Nikos Skalkotos
                raise e
161 3b7d3fc7 Nikos Skalkotos
162 3b7d3fc7 Nikos Skalkotos
        hash_cb = self.out.progress_generator(hp) if hp is not None else None
163 3b7d3fc7 Nikos Skalkotos
        upload_cb = self.out.progress_generator(up) if up is not None else None
164 3b7d3fc7 Nikos Skalkotos
165 49c07ce3 Nikos Skalkotos
        self.pithos.upload_object(path, file_obj, size, hash_cb, upload_cb)
166 3b7d3fc7 Nikos Skalkotos
167 49c07ce3 Nikos Skalkotos
        return "pithos://%s/%s/%s" % (self.account.user_info()['id'],
168 49c07ce3 Nikos Skalkotos
                                      self.CONTAINER, path)
169 997ac76a Nikos Skalkotos
170 37d581b8 Nikos Skalkotos
    def register(self, name, location, metadata, public=False):
171 ffc64d7c Nikos Skalkotos
        """Register an image with cyclades"""
172 3b7d3fc7 Nikos Skalkotos
173 d3445122 Nikos Skalkotos
        # Convert all metadata to strings
174 d3445122 Nikos Skalkotos
        str_metadata = {}
175 d3445122 Nikos Skalkotos
        for (key, value) in metadata.iteritems():
176 f99fe99d Nikos Skalkotos
            str_metadata[str(key)] = str(value)
177 37d581b8 Nikos Skalkotos
        is_public = 'true' if public else 'false'
178 37d581b8 Nikos Skalkotos
        params = {'is_public': is_public, 'disk_format': 'diskdump'}
179 49c07ce3 Nikos Skalkotos
        return self.image.register(name, location, params, str_metadata)
180 40e7a487 Nikos Skalkotos
181 3afe6b44 Nikos Skalkotos
    def share(self, location):
182 3afe6b44 Nikos Skalkotos
        """Share this file with all the users"""
183 3afe6b44 Nikos Skalkotos
184 49c07ce3 Nikos Skalkotos
        self.pithos.set_object_sharing(location, "*")
185 3afe6b44 Nikos Skalkotos
186 03eb7dc8 Nikos Skalkotos
    def object_exists(self, location):
187 03eb7dc8 Nikos Skalkotos
        """Check if an object exists in pythos"""
188 03eb7dc8 Nikos Skalkotos
189 03eb7dc8 Nikos Skalkotos
        try:
190 49c07ce3 Nikos Skalkotos
            self.pithos.get_object_info(location)
191 03eb7dc8 Nikos Skalkotos
        except ClientError as e:
192 03eb7dc8 Nikos Skalkotos
            if e.status == 404:  # Object not found error
193 03eb7dc8 Nikos Skalkotos
                return False
194 03eb7dc8 Nikos Skalkotos
            else:
195 03eb7dc8 Nikos Skalkotos
                raise
196 03eb7dc8 Nikos Skalkotos
        return True
197 03eb7dc8 Nikos Skalkotos
198 6152a559 Nikos Skalkotos
# vim: set sta sts=4 shiftwidth=4 sw=4 et ai :