Statistics
| Branch: | Tag: | Revision:

root / image_creator / kamaki_wrapper.py @ 121f3bc0

History | View | Annotate | Download (5 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 40e7a487 Nikos Skalkotos
from os.path import basename
42 40e7a487 Nikos Skalkotos
43 3dfe3651 Nikos Skalkotos
from kamaki.cli.config import Config
44 997ac76a Nikos Skalkotos
from kamaki.clients import ClientError
45 40e7a487 Nikos Skalkotos
from kamaki.clients.image import ImageClient
46 997ac76a Nikos Skalkotos
from kamaki.clients.pithos import PithosClient
47 31160dc8 Nikos Skalkotos
from kamaki.clients.astakos import AstakosClient
48 40e7a487 Nikos Skalkotos
49 40e7a487 Nikos Skalkotos
50 e77e66a9 Nikos Skalkotos
class Kamaki(object):
51 121f3bc0 Nikos Skalkotos
    """Wrapper class for the ./kamaki library"""
52 31160dc8 Nikos Skalkotos
    CONTAINER = "images"
53 cf4f52b6 Nikos Skalkotos
54 24684bbb Nikos Skalkotos
    @staticmethod
55 24684bbb Nikos Skalkotos
    def get_token():
56 88f83027 Nikos Skalkotos
        """Get the saved token"""
57 24684bbb Nikos Skalkotos
        config = Config()
58 24684bbb Nikos Skalkotos
        return config.get('global', 'token')
59 cf4f52b6 Nikos Skalkotos
60 cf4f52b6 Nikos Skalkotos
    @staticmethod
61 31160dc8 Nikos Skalkotos
    def save_token(token):
62 88f83027 Nikos Skalkotos
        """Save this token to the configuration file"""
63 cf4f52b6 Nikos Skalkotos
        config = Config()
64 31160dc8 Nikos Skalkotos
        config.set('global', 'token', token)
65 cf4f52b6 Nikos Skalkotos
        config.write()
66 cf4f52b6 Nikos Skalkotos
67 cf4f52b6 Nikos Skalkotos
    @staticmethod
68 31160dc8 Nikos Skalkotos
    def get_account(token):
69 88f83027 Nikos Skalkotos
        """Return the account corresponding to this token"""
70 cf4f52b6 Nikos Skalkotos
        config = Config()
71 ee0719db Nikos Skalkotos
        astakos = AstakosClient(config.get('user', 'url'), token)
72 31160dc8 Nikos Skalkotos
        try:
73 31160dc8 Nikos Skalkotos
            account = astakos.info()
74 31160dc8 Nikos Skalkotos
        except ClientError as e:
75 31160dc8 Nikos Skalkotos
            if e.status == 401:  # Unauthorized: invalid token
76 31160dc8 Nikos Skalkotos
                return None
77 31160dc8 Nikos Skalkotos
            else:
78 31160dc8 Nikos Skalkotos
                raise
79 31160dc8 Nikos Skalkotos
        return account
80 cf4f52b6 Nikos Skalkotos
81 31160dc8 Nikos Skalkotos
    def __init__(self, account, output):
82 88f83027 Nikos Skalkotos
        """Create a Kamaki instance"""
83 997ac76a Nikos Skalkotos
        self.account = account
84 e77e66a9 Nikos Skalkotos
        self.out = output
85 40e7a487 Nikos Skalkotos
86 40e7a487 Nikos Skalkotos
        config = Config()
87 40e7a487 Nikos Skalkotos
88 ee0719db Nikos Skalkotos
        pithos_url = config.get('file', 'url')
89 37d581b8 Nikos Skalkotos
        self.pithos_client = PithosClient(
90 37d581b8 Nikos Skalkotos
            pithos_url, self.account['auth_token'], self.account['uuid'],
91 37d581b8 Nikos Skalkotos
            self.CONTAINER)
92 40e7a487 Nikos Skalkotos
93 40e7a487 Nikos Skalkotos
        image_url = config.get('image', 'url')
94 31160dc8 Nikos Skalkotos
        self.image_client = ImageClient(image_url, self.account['auth_token'])
95 40e7a487 Nikos Skalkotos
96 b1395967 Nikos Skalkotos
    def upload(self, file_obj, size=None, remote_path=None, hp=None, up=None):
97 b1aea98e Nikos Skalkotos
        """Upload a file to pithos"""
98 3b7d3fc7 Nikos Skalkotos
99 3b7d3fc7 Nikos Skalkotos
        path = basename(file_obj.name) if remote_path is None else remote_path
100 40e7a487 Nikos Skalkotos
101 b1395967 Nikos Skalkotos
        try:
102 31160dc8 Nikos Skalkotos
            self.pithos_client.create_container(self.CONTAINER)
103 b1395967 Nikos Skalkotos
        except ClientError as e:
104 b1395967 Nikos Skalkotos
            if e.status != 202:  # Ignore container already exists errors
105 3b7d3fc7 Nikos Skalkotos
                raise e
106 3b7d3fc7 Nikos Skalkotos
107 3b7d3fc7 Nikos Skalkotos
        hash_cb = self.out.progress_generator(hp) if hp is not None else None
108 3b7d3fc7 Nikos Skalkotos
        upload_cb = self.out.progress_generator(up) if up is not None else None
109 3b7d3fc7 Nikos Skalkotos
110 55fd2858 Nikos Skalkotos
        self.pithos_client.upload_object(path, file_obj, size, hash_cb,
111 3b7d3fc7 Nikos Skalkotos
                                         upload_cb)
112 3b7d3fc7 Nikos Skalkotos
113 31160dc8 Nikos Skalkotos
        return "pithos://%s/%s/%s" % (self.account['uuid'], self.CONTAINER,
114 31160dc8 Nikos Skalkotos
                                      path)
115 997ac76a Nikos Skalkotos
116 37d581b8 Nikos Skalkotos
    def register(self, name, location, metadata, public=False):
117 b1aea98e Nikos Skalkotos
        """Register an image to ~okeanos"""
118 3b7d3fc7 Nikos Skalkotos
119 d3445122 Nikos Skalkotos
        # Convert all metadata to strings
120 d3445122 Nikos Skalkotos
        str_metadata = {}
121 d3445122 Nikos Skalkotos
        for (key, value) in metadata.iteritems():
122 f99fe99d Nikos Skalkotos
            str_metadata[str(key)] = str(value)
123 37d581b8 Nikos Skalkotos
        is_public = 'true' if public else 'false'
124 37d581b8 Nikos Skalkotos
        params = {'is_public': is_public, 'disk_format': 'diskdump'}
125 d3445122 Nikos Skalkotos
        self.image_client.register(name, location, params, str_metadata)
126 40e7a487 Nikos Skalkotos
127 3afe6b44 Nikos Skalkotos
    def share(self, location):
128 3afe6b44 Nikos Skalkotos
        """Share this file with all the users"""
129 3afe6b44 Nikos Skalkotos
130 3afe6b44 Nikos Skalkotos
        self.pithos_client.set_object_sharing(location, "*")
131 3afe6b44 Nikos Skalkotos
132 03eb7dc8 Nikos Skalkotos
    def object_exists(self, location):
133 03eb7dc8 Nikos Skalkotos
        """Check if an object exists in pythos"""
134 03eb7dc8 Nikos Skalkotos
135 03eb7dc8 Nikos Skalkotos
        try:
136 03eb7dc8 Nikos Skalkotos
            self.pithos_client.get_object_info(location)
137 03eb7dc8 Nikos Skalkotos
        except ClientError as e:
138 03eb7dc8 Nikos Skalkotos
            if e.status == 404:  # Object not found error
139 03eb7dc8 Nikos Skalkotos
                return False
140 03eb7dc8 Nikos Skalkotos
            else:
141 03eb7dc8 Nikos Skalkotos
                raise
142 03eb7dc8 Nikos Skalkotos
        return True
143 03eb7dc8 Nikos Skalkotos
144 6152a559 Nikos Skalkotos
# vim: set sta sts=4 shiftwidth=4 sw=4 et ai :