cc1  v2.1
CC1 source code docs
 All Classes Namespaces Files Functions Variables Pages
storage_image.py
Go to the documentation of this file.
1 # -*- coding: utf-8 -*-
2 # @COPYRIGHT_begin
3 #
4 # Copyright [2010-2014] Institute of Nuclear Physics PAN, Krakow, Poland
5 #
6 # Licensed under the Apache License, Version 2.0 (the "License");
7 # you may not use this file except in compliance with the License.
8 # You may obtain a copy of the License at
9 #
10 # http://www.apache.org/licenses/LICENSE-2.0
11 #
12 # Unless required by applicable law or agreed to in writing, software
13 # distributed under the License is distributed on an "AS IS" BASIS,
14 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 # See the License for the specific language governing permissions and
16 # limitations under the License.
17 #
18 # @COPYRIGHT_end
19 
20 ##
21 # @package src.cm.views.admin_cm.storage_image
22 # @alldecoratedby{src.cm.utils.decorators.user_log}
23 #
24 # @author Tomek Sośnicki <tom.sosnicki@gmail.com>
25 # @author Miłosz Zdybał <milosz.zdybal@ifj.edu.pl>
26 # @author Maciej Nabożny <mn@mnabozny.pl>
27 #
28 
29 import urllib
30 
31 from cm.utils.decorators import admin_cm_log
32 from cm.utils.exception import CMException
33 from cm.utils import log
34 from cm.utils.threads.image import DownloadImage
35 from cm.models.user import User
36 from cm.models.system_image import SystemImage
37 from cm.models.storage_image import StorageImage
38 from common.states import image_states
39 import os
40 from cm.utils.threads.image import CopyImage
41 
42 
43 @admin_cm_log(log=True)
44 ##
45 #
46 # Downloads specified StorateImage from remote path.
47 #
48 # @cmview_admin_cm
49 # @param_post{description,string}
50 # @param_post{name,string} how to name newly downloaded storage image
51 # @param_post{path,string} HTTP or FTP path to download StorageImage.
52 # @param_post{disk_dev}
53 # @param_post{disk_controller}
54 #
55 def download(caller_id, description, name, path, disk_dev, disk_controller):
56 
57  # size value is taken
58  try:
59  connection = urllib.urlopen(path)
60  size = int(connection.info()["Content-Length"])
61  except IOError:
62  log.exception('Cannot find image')
63  raise CMException('image_not_found')
64  except KeyError:
65  log.exception(caller_id, 'Cannot calculate size')
66  raise CMException('image_calculate_size')
67 
68  user = User.get(caller_id)
69 
70  image = StorageImage.create(name=name, description=description, user=user, disk_dev=disk_dev, disk_controller=disk_controller)
71 
72  try:
73  image.save()
74  except Exception, e:
75  log.error(caller_id, "Unable to save image to DB: %s" % str(e))
76  raise CMException('image_create')
77 
78  DownloadImage(image, path, size).start()
79 
80 
81 @admin_cm_log(log=False)
82 ##
83 #
84 # Fetch all StorageImages except those that are @val{locked}.
85 #
86 # @cmview_admin_cm
87 # @response{list(dict)} StorageImages.dict property for each StorageImages.
88 #
89 def get_list(caller_id):
90  images = StorageImage.objects.exclude(state=image_states['locked'])
91 
92  return [img.dict for img in images]
93 
94 
95 @admin_cm_log(log=True)
96 ##
97 #
98 # Fetch requested StorageImage.
99 #
100 # @cmview_admin_cm
101 # @param_post{storage_image_id,int} id of the requested StorageImage
102 #
103 # @response{dict} StorageImages.dict property for requested StorageImage
104 #
105 def get_by_id(caller_id, storage_image_id):
106  return StorageImage.admin_get(storage_image_id).dict
107 
108 
109 @admin_cm_log(log=True)
110 ##
111 #
112 # Sets StorageImage state as @val{locked}.
113 #
114 # @cmview_admin_cm
115 # @param_post{storage_image_id} id of the Image to delete
116 #
117 # @todo Should rather delete StorageImage and set its state to 'deleted'.
118 #
119 def delete(caller_id, storage_image_id):
120  image = StorageImage.admin_get(storage_image_id)
121 
122  image.check_attached()
123  image.state = image_states['locked']
124  image.save()
125 
126 
127 @admin_cm_log(log=True)
128 ##
129 #
130 # Updates Image's attributes.
131 #
132 # @cmview_admin_cm
133 # @param_post{storage_image_id,string}
134 # @param_post{name,string} new Image name
135 # @param_post{description,string} new Image description
136 # @param_post{disk_controller} new Image controller optional
137 #
138 def edit(caller_id, storage_image_id, name=None, description=None, disk_controller=None):
139 
140  image = StorageImage.admin_get(storage_image_id)
141 
142  if image.state != image_states['ok']:
143  raise CMException('image_edit')
144 
145  if name:
146  image.name = name
147  if description:
148  image.description = description
149  if disk_controller:
150  image.disk_controller = disk_controller
151 
152  try:
153  image.save()
154  except:
155  raise CMException('image_edit')
156 
157 
158 @admin_cm_log(log=True)
159 ##
160 #
161 # Converts specified StorageImage to SystemImage. After convertion it's not
162 # available as StorageImage anymore. File is moved and StorageImage entry is
163 # removed from database.
164 #
165 # @cmview_admin_cm
166 # @param_post{storage_image_id,int} ID of an StorageImage to convert
167 #
168 def convert_to_system_image(caller_id, storage_image_id):
169  image = StorageImage.admin_get(storage_image_id)
170 
171  system_image = SystemImage.create(name=image.name, description=image.description, user=image.user, disk_controller=image.disk_controller)
172  system_image.state = image_states['ok']
173  system_image.size = image.size
174 
175  try:
176  system_image.save()
177  os.rename(image.path, system_image.path)
178  image.delete()
179  except Exception:
180  raise CMException('image_change_type')
181 
182 
183 @admin_cm_log(log=True)
184 ##
185 #
186 # Copy selected StorageImage to user's StorageImages
187 #
188 # @cmview_admin_cm
189 # @param_post{src_image_id,int}
190 # @param_post{dest_user_id,int}
191 #
192 def copy(caller_id, src_image_id, dest_user_id):
193  src_image = StorageImage.admin_get(src_image_id)
194  dest_user = User.get(dest_user_id)
195  dest_image = StorageImage.create(name=src_image.name, description=src_image.description, user=dest_user,
196  disk_controller=src_image.disk_controller, size=src_image.size)
197 
198  try:
199  dest_image.save()
200  except Exception, e:
201  log.error(caller_id, "Unable to commit: %s" % str(e))
202  raise CMException('image_create')
203 
204  CopyImage(src_image, dest_image).start()
205 
206 
207 @admin_cm_log(log=True)
208 ##
209 #
210 # Revokes image from the virtual machine. For administrator use, works in "force" mode.
211 #
212 # @cmview_admin_cm
213 # @parameter{storage_image_id,int} ID of an StorageImage to revoke
214 #
215 def revoke(caller_id, storage_image_id):
216  image = StorageImage.admin_get(storage_image_id)
217  image.revoke()
218 
219