Monkey-patch pythondialog to support form boxes
[snf-image-creator] / image_creator / kamaki_wrapper.py
1 # -*- coding: utf-8 -*-
2 #
3 # Copyright 2012 GRNET S.A. All rights reserved.
4 #
5 # Redistribution and use in source and binary forms, with or
6 # without modification, are permitted provided that the following
7 # conditions are met:
8 #
9 #   1. Redistributions of source code must retain the above
10 #      copyright notice, this list of conditions and the following
11 #      disclaimer.
12 #
13 #   2. Redistributions in binary form must reproduce the above
14 #      copyright notice, this list of conditions and the following
15 #      disclaimer in the documentation and/or other materials
16 #      provided with the distribution.
17 #
18 # THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
19 # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21 # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
22 # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
25 # USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26 # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
28 # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 # POSSIBILITY OF SUCH DAMAGE.
30 #
31 # The views and conclusions contained in the software and
32 # documentation are those of the authors and should not be
33 # interpreted as representing official policies, either expressed
34 # or implied, of GRNET S.A.
35
36 """This modules provides the interface for working with the ./kamaki library.
37 The library is used to upload images to and register them with a Synnefo
38 deployment.
39 """
40
41 from os.path import basename
42
43 from kamaki.cli.config import Config
44 from kamaki.clients import ClientError
45 from kamaki.clients.image import ImageClient
46 from kamaki.clients.pithos import PithosClient
47 from kamaki.clients.astakos import AstakosClient
48
49
50 class Kamaki(object):
51     """Wrapper class for the ./kamaki library"""
52     CONTAINER = "images"
53
54     @staticmethod
55     def get_token():
56         """Get the saved token"""
57         config = Config()
58         return config.get('global', 'token')
59
60     @staticmethod
61     def save_token(token):
62         """Save this token to the configuration file"""
63         config = Config()
64         config.set('global', 'token', token)
65         config.write()
66
67     @staticmethod
68     def get_account(token):
69         """Return the account corresponding to this token"""
70         config = Config()
71         astakos = AstakosClient(config.get('user', 'url'), token)
72         try:
73             account = astakos.info()
74         except ClientError as e:
75             if e.status == 401:  # Unauthorized: invalid token
76                 return None
77             else:
78                 raise
79         return account
80
81     def __init__(self, account, output):
82         """Create a Kamaki instance"""
83         self.account = account
84         self.out = output
85
86         config = Config()
87
88         pithos_url = config.get('file', 'url')
89         self.pithos_client = PithosClient(
90             pithos_url, self.account['auth_token'], self.account['uuid'],
91             self.CONTAINER)
92
93         image_url = config.get('image', 'url')
94         self.image_client = ImageClient(image_url, self.account['auth_token'])
95
96     def upload(self, file_obj, size=None, remote_path=None, hp=None, up=None):
97         """Upload a file to pithos"""
98
99         path = basename(file_obj.name) if remote_path is None else remote_path
100
101         try:
102             self.pithos_client.create_container(self.CONTAINER)
103         except ClientError as e:
104             if e.status != 202:  # Ignore container already exists errors
105                 raise e
106
107         hash_cb = self.out.progress_generator(hp) if hp is not None else None
108         upload_cb = self.out.progress_generator(up) if up is not None else None
109
110         self.pithos_client.upload_object(path, file_obj, size, hash_cb,
111                                          upload_cb)
112
113         return "pithos://%s/%s/%s" % (self.account['uuid'], self.CONTAINER,
114                                       path)
115
116     def register(self, name, location, metadata, public=False):
117         """Register an image to ~okeanos"""
118
119         # Convert all metadata to strings
120         str_metadata = {}
121         for (key, value) in metadata.iteritems():
122             str_metadata[str(key)] = str(value)
123         is_public = 'true' if public else 'false'
124         params = {'is_public': is_public, 'disk_format': 'diskdump'}
125         self.image_client.register(name, location, params, str_metadata)
126
127     def share(self, location):
128         """Share this file with all the users"""
129
130         self.pithos_client.set_object_sharing(location, "*")
131
132     def object_exists(self, location):
133         """Check if an object exists in pythos"""
134
135         try:
136             self.pithos_client.get_object_info(location)
137         except ClientError as e:
138             if e.status == 404:  # Object not found error
139                 return False
140             else:
141                 raise
142         return True
143
144 # vim: set sta sts=4 shiftwidth=4 sw=4 et ai :