Commit d97aa927 authored by Nikos Skalkotos's avatar Nikos Skalkotos

Make shrink a sysprep

Don't treat shrink as a seperated task. Add it in the syspreps menu.
parent 062dedef
......@@ -796,7 +796,7 @@ def sysprep(session):
image = session['image']
# Is the image already shrinked?
if 'shrinked' in session and session['shrinked']:
if image.os.shrinked:
msg = "It seems you have shrinked the image. Running system " \
"preparation tasks on a shrinked image is dangerous."
......@@ -872,6 +872,7 @@ def sysprep(session):
with MetadataMonitor(session, image.os.meta):
try:
image.os.do_sysprep()
update_background_title(session)
infobox.finalize()
except FatalError as error:
d.msgbox("System Preparation failed: %s" % error,
......@@ -885,43 +886,6 @@ def sysprep(session):
return True
def shrink(session):
"""Shrink the image"""
d = session['dialog']
image = session['image']
shrinked = 'shrinked' in session and session['shrinked']
if shrinked:
d.msgbox("The image is already shrinked!", title="Image Shrinking",
width=SMALL_WIDTH)
return True
msg = "This operation will shrink the last partition of the image to " \
"reduce the total image size. If the last partition is a swap " \
"partition, then this partition is removed and the partition " \
"before that is shrinked. The removed swap partition will be " \
"recreated during image deployment."
if not d.yesno("%s\n\nDo you want to continue?" % msg, width=WIDTH,
height=12, title="Image Shrinking"):
with MetadataMonitor(session, image.meta):
infobox = InfoBoxOutput(d, "Image Shrinking", height=4)
image.out.add(infobox)
try:
image.shrink()
infobox.finalize()
finally:
image.out.remove(infobox)
session['shrinked'] = True
update_background_title(session)
else:
return False
return True
def customization_menu(session):
"""Show image customization menu"""
d = session['dialog']
......@@ -932,7 +896,6 @@ def customization_menu(session):
choices.append(("Virtio", "Install or update the VirtIO drivers"))
choices.extend(
[("Sysprep", "Run various image preparation tasks"),
("Shrink", "Shrink image"),
("Properties", "View & Modify image properties"),
("Exclude", "Exclude various deployment tasks from running")])
......@@ -940,7 +903,6 @@ def customization_menu(session):
actions = {"Virtio": virtio,
"Sysprep": sysprep,
"Shrink": shrink,
"Properties": modify_properties,
"Exclude": exclude_tasks}
while 1:
......
......@@ -108,8 +108,7 @@ def update_background_title(session):
MB = 2 ** 20
size = (image.size + MB - 1) // MB
shrinked = 'shrinked' in session and session['shrinked']
postfix = " (shrinked)" if shrinked else ''
postfix = " (shrinked)" if image.os.shrinked else ''
title = "OS: %s, Distro: %s, Size: %dMB%s, Source: %s" % \
(image.ostype, image.distro, size, postfix,
......
......@@ -427,16 +427,13 @@ def create_image(session, answers):
image.os.do_sysprep()
metadata = image.os.meta
# Shrink
size = image.shrink()
session['shrinked'] = True
update_background_title(session)
metadata.update(image.meta)
metadata['DESCRIPTION'] = answers['ImageDescription']
# MD5
session['checksum'] = MD5(image.out).compute(image.device, size)
session['checksum'] = MD5(image.out).compute(image.device, image.size)
image.out.output()
try:
......@@ -448,7 +445,7 @@ def create_image(session, answers):
name = "%s-%s.diskdump" % (answers['ImageName'],
time.strftime("%Y%m%d%H%M"))
with open(image.device, 'rb') as device:
remote = kamaki.upload(device, size, name,
remote = kamaki.upload(device, image.size, name,
"(1/3) Calculating block hashes",
"(2/3) Uploading image blocks")
......
......@@ -245,7 +245,7 @@ class Image(object):
return last_partition
def shrink(self):
def shrink(self, silent=False):
"""Shrink the image.
This is accomplished by shrinking the last file system of the
......@@ -276,10 +276,9 @@ class Image(object):
MB = 2 ** 20
self.out.output("Shrinking image (this may take a while) ...", False)
if self.is_unsupported():
self.out.warn("Shrinking is disabled for unsupported images")
if not silent:
self.out.warn("Shrinking is disabled for unsupported images")
return self.size
sector_size = self.g.blockdev_getss(self.guestfs_device)
......@@ -307,7 +306,9 @@ class Image(object):
break
if not re.match("ext[234]", fstype):
self.out.warn("Don't know how to shrink %s partitions." % fstype)
if not silent:
self.out.warn(
"Don't know how to shrink %s partitions." % fstype)
return self.size
part_dev = "%s%d" % (self.guestfs_device, last_part['part_num'])
......@@ -376,7 +377,9 @@ class Image(object):
else:
self.size = min(new_size + 2048 * sector_size, self.size)
self.out.success("new size is %dMB" % ((self.size + MB - 1) // MB))
if not silent:
self.out.success("Image size is %dMB" %
((self.size + MB - 1) // MB))
return self.size
......
......@@ -120,9 +120,6 @@ def parse_options(input_args):
help="don't perform any system preparation operation",
action="store_false")
parser.add_option("--no-shrink", dest="shrink", default=True,
help="don't shrink any partition", action="store_false")
parser.add_option("--public", dest="public", default=False,
help="register image with the cloud as public",
action="store_true")
......@@ -304,8 +301,6 @@ def image_creator():
image.os.do_sysprep()
metadata = image.os.meta
size = options.shrink and image.shrink() or image.size
metadata.update(image.meta)
if image.is_unsupported():
......@@ -315,7 +310,7 @@ def image_creator():
metadata.update(options.metadata)
md5 = MD5(out)
checksum = md5.compute(image.device, size)
checksum = md5.compute(image.device, image.size)
metastring = unicode(json.dumps(
{'properties': metadata,
......@@ -345,7 +340,7 @@ def image_creator():
out.output("Uploading image to the storage service:")
with open(device, 'rb') as f:
uploaded_obj = kamaki.upload(
f, size, options.upload,
f, image.size, options.upload,
"(1/3) Calculating block hashes",
"(2/3) Uploading missing blocks")
out.output("(3/3) Uploading md5sum file ...", False)
......
......@@ -69,6 +69,7 @@ def sysprep(message, enabled=True, **kwargs):
method._sysprep = True
method._sysprep_enabled = enabled
method._sysprep_nomount = False
for key, val in kwargs.items():
setattr(method, "_sysprep_%s" % key, val)
......@@ -216,6 +217,7 @@ class OSBase(object):
"`%s'. Reason: %s" % (key, param.error))
self.meta = {}
self.shrinked = False
# This will host the error if mount fails
self._mount_error = ""
......@@ -400,16 +402,30 @@ class OSBase(object):
enabled = [s for s in self.list_syspreps() if self.sysprep_enabled(s)]
size = len(enabled)
cnt = 0
def exec_sysprep(cnt, size, task):
self.out.output(('(%d/%d)' % (cnt, size)).ljust(7), False)
task()
del self._sysprep_tasks[task.__name__]
with self.mount():
cnt = 0
for task in enabled:
for task in [t for t in enabled if t._sysprep_nomount is False]:
cnt += 1
self.out.output(('(%d/%d)' % (cnt, size)).ljust(7), False)
task()
del self._sysprep_tasks[task.__name__]
exec_sysprep(cnt, size, task)
for task in [t for t in enabled if t._sysprep_nomount]:
cnt += 1
exec_sysprep(cnt, size, task)
self.out.output()
@sysprep('Shrinking image', nomount=True)
def _shrink(self):
"""Shrink the last file system and update the partition table"""
self.image.shrink()
self.shrinked = True
@property
def ismounted(self):
return self._mounted
......
......@@ -423,8 +423,7 @@ class Windows(OSBase):
querymax = int(querymax)
if querymax == 0:
self.out.warn("Unable to reclaim any space. "
"Make sure the media is defragged")
self.out.warn("Unable to reclaim any space. The media is full.")
return
# Not sure if we should use 1000 or 1024 here
......@@ -470,6 +469,8 @@ class Windows(OSBase):
if line.find('shrunk') >= 0:
self.out.output(" %s" % line)
self.shrinked = True
def do_sysprep(self):
"""Prepare system for image creation."""
......@@ -586,6 +587,8 @@ class Windows(OSBase):
self._cleanup('sysprep')
self.out.success("done")
self.image.shrink(silent=True)
def _exec_sysprep_tasks(self):
"""This function hosts the actual code for executing the enabled
sysprep tasks. At the end of this method the VM is shut down if needed.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment