From: Nikos Skalkotos Date: Fri, 11 Oct 2013 15:02:30 +0000 (+0300) Subject: Allow image creation from unsupported media X-Git-Tag: 0.6~1^2~15 X-Git-Url: https://code.grnet.gr/git/snf-image-creator/commitdiff_plain/e482b7f92115aab233908712e4a98204ae9de1c0 Allow image creation from unsupported media Add a new "Unsupported" os_type class. Images that get created from unsupported media have the EXCLUDE_ALL_TASKS property enabled. --- diff --git a/image_creator/dialog_main.py b/image_creator/dialog_main.py index 7895287..0586327 100644 --- a/image_creator/dialog_main.py +++ b/image_creator/dialog_main.py @@ -101,6 +101,25 @@ def create_image(d, media, out, tmp): "image": image, "metadata": metadata} + if hasattr(image, "unsupported"): + + session['excluded_tasks'] = [-1] + session['task_metadata'] = ["EXCLUDE_ALL_TASKS"] + + msg = "The system on the input media is not supported." \ + "\n\nReason: %s\n\n" \ + "We highly recommend not to create an image out of this, " \ + "since the image won't be cleaned up and you will not be " \ + "able to configure it during the deployment. Press if " \ + "you still want to continue with the image creation process." \ + % image.unsupported + + if not d.yesno(msg, width=WIDTH, defaultno=1, height=12): + main_menu(session) + + d.infobox("Thank you for using snf-image-creator. Bye", width=53) + return 0 + msg = "snf-image-creator detected a %s system on the input media. " \ "Would you like to run a wizard to assist you through the " \ "image creation process?\n\nChoose to run the wizard," \ diff --git a/image_creator/dialog_menu.py b/image_creator/dialog_menu.py index 25fcb6c..ba29ea1 100644 --- a/image_creator/dialog_menu.py +++ b/image_creator/dialog_menu.py @@ -583,6 +583,12 @@ def delete_properties(session): def exclude_tasks(session): """Exclude specific tasks from running during image deployment""" d = session['dialog'] + image = session['image'] + + if hasattr(image, "unsupported"): + d.msgbox("You cannot configure the deployment tasks for an unsupported" + " image.", width=SMALL_WIDTH) + return False index = 0 displayed_index = 1 diff --git a/image_creator/image.py b/image_creator/image.py index 7eb8ad8..2eb97dd 100644 --- a/image_creator/image.py +++ b/image_creator/image.py @@ -88,11 +88,25 @@ class Image(object): self.out.output('Inspecting Operating System ...', False) roots = self.g.inspect_os() - if len(roots) == 0: - raise FatalError("No operating system found") - if len(roots) > 1: - raise FatalError("Multiple operating systems found." - "We only support images with one OS.") + + if len(roots) == 0 or len(roots) > 1: + self.root = None + self.ostype = "unsupported" + self.distro = "unsupported" + self.guestfs_device = '/dev/sda' + self.size = self.g.blockdev_getsize64(self.guestfs_device) + if len(roots) > 1: + self.unsupported = "Multiple operating systems found on the " \ + "media. We only support images with one OS." + else: + self.unsupported = \ + "Unable to detect any operating system on the media" + + self.meta['UNSUPPORTED'] = "Reason: %s" % self.unsupported + self.out.warn('Media is not supported. %s' % + self.meta['UNSUPPORTED']) + return + self.root = roots[0] self.guestfs_device = self.g.part_to_dev(self.root) self.size = self.g.blockdev_getsize64(self.guestfs_device) @@ -264,6 +278,10 @@ class Image(object): self.out.output("Shrinking image (this may take a while) ...", False) + if hasattr(self, "unsupported"): + self.out.warn("Unable to shrink unsupported image") + return self.size + sector_size = self.g.blockdev_getss(self.guestfs_device) last_part = None diff --git a/image_creator/main.py b/image_creator/main.py index c328146..29ed068 100644 --- a/image_creator/main.py +++ b/image_creator/main.py @@ -140,6 +140,10 @@ def parse_options(input_args): help="register image with the cloud as public", action="store_true") + parser.add_option("--allow-unsupported", dest="allow_unsupported", + help="Proceed with the image creation even if the media " + "is not supported", default=False, action="store_true") + parser.add_option("--tmpdir", dest="tmp", type="string", default=None, help="create large temporary image files under DIR", metavar="DIR") @@ -273,6 +277,14 @@ def image_creator(): image = disk.get_image(snapshot, sysprep_params=options.sysprep_params) + if hasattr(image, 'unsupported') and not options.allow_unsupported: + raise FatalError( + "The media seems to be unsupported. If you insist on creating " + "an image out of it, use the `--allow-unsupported' option. " + "Using this is highly discouraged, since the resulting image " + "will not be cleaned up from sensitive data and will not get " + "configured during the deployment") + for sysprep in options.disabled_syspreps: image.os.disable_sysprep(image.os.get_sysprep_by_name(sysprep)) @@ -298,6 +310,9 @@ def image_creator(): size = options.shrink and image.shrink() or image.size metadata.update(image.meta) + if hasattr(image, 'unsupported'): + metadata['EXCLUDE_ALL_TASKS'] = "yes" + # Add command line metadata to the collected ones... metadata.update(options.metadata) diff --git a/image_creator/os_type/__init__.py b/image_creator/os_type/__init__.py index 5298569..ff51deb 100644 --- a/image_creator/os_type/__init__.py +++ b/image_creator/os_type/__init__.py @@ -247,12 +247,17 @@ class OSBase(object): def do_sysprep(self): """Prepare system for image creation.""" + self.out.output('Preparing system for image creation:') + + if hasattr(self.image, "unsupported"): + self.out.warn( + "System preparation is disabled for unsupported media") + return + try: if not self.mount(readonly=False): raise FatalError("Unable to mount the media read-write") - self.out.output('Preparing system for image creation:') - enabled = [task for task in self.list_syspreps() if task.enabled] size = len(enabled) diff --git a/image_creator/os_type/unsupported.py b/image_creator/os_type/unsupported.py new file mode 100644 index 0000000..9b27b7b --- /dev/null +++ b/image_creator/os_type/unsupported.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- +# +# Copyright 2013 GRNET S.A. All rights reserved. +# +# Redistribution and use in source and binary forms, with or +# without modification, are permitted provided that the following +# conditions are met: +# +# 1. Redistributions of source code must retain the above +# copyright notice, this list of conditions and the following +# disclaimer. +# +# 2. Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following +# disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS +# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +# The views and conclusions contained in the software and +# documentation are those of the authors and should not be +# interpreted as representing official policies, either expressed +# or implied, of GRNET S.A. + +"""This module hosts code to handle unknown OSs.""" + +from image_creator.os_type import OSBase + + +class Unsupported(OSBase): + """OS class for unsupported OSs""" + def __init__(self, image, **kargs): + super(Unsupported, self).__init__(image, **kargs) + + def collect_metadata(self): + """Collect metadata about the OS""" + self.out.warn("Unable to collect metadata for unsupported media") + + def _do_mount(self, readonly): + """Mount partitions in corrent order""" + self.out.warn('not supported on this media.') + return False + +# vim: set sta sts=4 shiftwidth=4 sw=4 et ai :