27 from common.states
import image_states
28 from common.hardware
import disk_format_commands, disk_filesystems_reversed
30 from cm.utils
import log
33 from cm.utils
import message
41 threading.Thread.__init__(self)
46 if os.path.exists(self.image.path):
47 self.image.state = image_states[
'failed']
48 self.image.save(update_fields=[
'state'])
49 log.error(self.image.user.id,
"Destination image %d for user %d exists! Aborting creation" % (self.image.id, self.image.user.id))
51 self.image.progress = 0
53 if self.
format() ==
'failed':
54 self.image.state = image_states[
'failed']
55 self.image.save(update_fields=[
'state'])
57 self.image.progress = 100
58 self.image.state = image_states[
'ok']
59 self.image.save(update_fields=[
'state',
'progress'])
61 log.debug(self.image.user.id,
'stage [6/6] cleaning..')
63 os.remove(
'%s' % os.path.join(
'/var/lib/cc1/images-tmp/', os.path.split(self.image.path)[1]))
65 log.error(self.image.user.id,
'error remove file: %s' % str(e))
68 p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
69 retr_std = p.stdout.read()
72 retr_err = str(p.stderr.read())
73 log.error(self.image.user.id, retr_err)
74 log.error(self.image.user.id, retr_std)
78 self.image.progress = prg
79 self.image.save(update_fields=[
'progress'])
83 if not os.path.exists(os.path.dirname(self.image.path)):
84 os.makedirs(os.path.dirname(self.image.path))
85 format_cmd = disk_format_commands[disk_filesystems_reversed[self.
filesystem]].split()
87 tmp_path = os.path.join(
'/var/lib/cc1/images-tmp/', os.path.split(self.image.path)[1])
88 if not os.path.exists(os.path.dirname(
'/var/lib/cc1/images-tmp/')):
89 os.makedirs(os.path.dirname(
'/var/lib/cc1/images-tmp/'))
91 tmp_path = str(self.image.path)
93 log.debug(self.image.user.id,
'stage [1/6] truncate partition file')
94 if self.
exec_cmd([
'truncate',
'-s',
'%dM' % self.image.size,
'%s' % tmp_path]):
99 format_cmd.append(
'%s' % tmp_path)
100 log.debug(self.image.user.id,
'stage [2/6] creating partition filesystem')
105 log.debug(self.image.user.id,
'stage [3/6] creating disk')
106 if self.
exec_cmd([
'/usr/bin/ddrescue',
'-S',
'-o',
'1048576',
'%s' % tmp_path, str(self.image.path)]):
110 log.debug(self.image.user.id,
'stage [4/6] creating new partition table')
111 if self.
exec_cmd([
'/sbin/parted',
'-s', str(self.image.path),
'mklabel',
'msdos']):
115 log.debug(self.image.user.id,
'stage [5/6] adding partition')
116 if self.
exec_cmd([
'/sbin/parted',
'-s', str(self.image.path),
'mkpart',
'primary',
'1048576b',
'100%']):
120 log.info(self.image.user.id,
'disk succesfully formatted')
129 threading.Thread.__init__(self)
136 if self.url.startswith(
'/'):
137 src_image = open(self.
url,
'r')
139 src_image = urllib2.urlopen(self.
url)
141 log.exception(self.image.user.id,
"Cannot open url %s: %s" % (self.
url, str(e)))
142 self.image.state = image_states[
'failed']
145 if os.path.exists(self.image.path):
146 self.image.state = image_states[
'failed']
147 self.image.save(update_fields=[
'state'])
148 log.error(self.image.user.id,
"Destination image %d for user %d exists! Aborting download" % (self.image.id, self.image.user.id))
152 dirpath = os.path.dirname(self.image.path)
153 if not os.path.exists(dirpath):
155 dest_image = open(self.image.path,
'w')
157 md5sum = hashlib.md5()
158 while downloaded_size < self.
size:
159 buff = src_image.read(1024 * 1024)
161 downloaded_size += len(buff)
162 dest_image.write(buff)
164 progress = int(downloaded_size * 100 / self.
size)
165 if progress != self.image.progress:
166 self.image.progress = progress
167 self.image.save(update_fields=[
'progress'])
171 log.info(self.image.user.id,
'md5 hash of image %d is %s' % (self.image.id, md5sum.hexdigest()))
172 self.image.state = image_states[
'ok']
173 self.image.size = downloaded_size / (1024 * 1024)
174 self.image.save(update_fields=[
'progress',
'state',
'size'])
175 message.info(self.image.user.id,
'image_downloaded', {
'name': self.image.name,
'md5sum': md5sum.hexdigest()})
177 log.exception(self.image.user.id,
"Failed to download image: %s" % str(e))
178 self.image.state = image_states[
'failed']
179 self.image.save(update_fields=[
'state'])
184 threading.Thread.__init__(self)
192 size = os.path.getsize(self.src_image.path)
193 dirpath = os.path.dirname(self.dest_image.path)
194 if not os.path.exists(dirpath):
196 src = open(self.src_image.path,
"r")
197 dst = open(self.dest_image.path, "w")
199 buff = src.read(1024 * 1024)
200 if len(buff) > 0
and copied <= size:
202 copied = copied + len(buff)
206 progress = 100 * copied / size
207 if progress > prev_progress:
208 prev_progress = progress
209 self.dest_image.progress = progress
210 self.dest_image.save(update_fields=[
'progress'])
212 self.dest_image.state = image_states[
'ok']
213 self.dest_image.size = self.src_image.size
214 self.dest_image.save(update_fields=[
'progress',
'state',
'size'])
219 log.exception(self.dest_image.user.id,
"Failed to copy image: %s" % str(e))
220 self.dest_image.state = image_states[
'failed']
221 self.dest_image.save(update_fields=[
'state'])