From e2a99f9bb762e61053cd3ee788390d0b2bb5e72d Mon Sep 17 00:00:00 2001 From: Jannis Pohlmann Date: Mon, 17 Dec 2012 14:51:19 +0000 Subject: Move MountableImage class into morphlib This class would be pretty useful in other cases where a system image needs to be mounted and inspected. Also updates the Trebuchet plugin to use this class. --- morphlib/__init__.py | 1 + morphlib/mountableimage.py | 81 ++++++++++++++++++++++++++++++++++++ morphlib/plugins/trebuchet_plugin.py | 60 ++------------------------ 3 files changed, 85 insertions(+), 57 deletions(-) create mode 100644 morphlib/mountableimage.py (limited to 'morphlib') diff --git a/morphlib/__init__.py b/morphlib/__init__.py index 271fa977..3cf60171 100644 --- a/morphlib/__init__.py +++ b/morphlib/__init__.py @@ -57,6 +57,7 @@ import fsutils import git import localartifactcache import localrepocache +import mountableimage import morph2 import morphologyfactory import remoteartifactcache diff --git a/morphlib/mountableimage.py b/morphlib/mountableimage.py new file mode 100644 index 00000000..3d29a516 --- /dev/null +++ b/morphlib/mountableimage.py @@ -0,0 +1,81 @@ +# Copyright (C) 2012-2013 Codethink Limited +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + +import cliapp +import os +import tempfile +import gzip + +import morphlib + + +class MountableImage(object): # pragma: no cover + + '''Mountable image (deals with decompression). + + Note, this is a read-only mount in the sense that the decompressed + image is not then recompressed after, instead any changes are discarded. + + ''' + def __init__(self, app, artifact_path): + self.app = app + self.artifact_path = artifact_path + + def setup(self, path): + self.app.status(msg='Preparing image %(path)s', path=path, chatty=True) + self.app.status(msg=' Decompressing...', chatty=True) + (tempfd, self.temp_path) = \ + tempfile.mkstemp(dir=self.app.settings['tempdir']) + + try: + with os.fdopen(tempfd, "wb") as outfh: + infh = gzip.open(path, "rb") + morphlib.util.copyfileobj(infh, outfh) + infh.close() + except: + os.unlink(self.temp_path) + raise + self.app.status(msg=' Mounting image at %(path)s', + path=self.temp_path, chatty=True) + part = morphlib.fsutils.setup_device_mapping(self.app.runcmd, + self.temp_path) + mount_point = tempfile.mkdtemp(dir=self.app.settings['tempdir']) + morphlib.fsutils.mount(self.app.runcmd, part, mount_point) + self.mount_point = mount_point + return mount_point + + def cleanup(self, path, mount_point): + self.app.status(msg='Clearing down image at %(path)s', path=path, + chatty=True) + try: + morphlib.fsutils.unmount(self.app.runcmd, mount_point) + except: + pass + try: + morphlib.fsutils.undo_device_mapping(self.app.runcmd, path) + except: + pass + try: + os.rmdir(mount_point) + os.unlink(path) + except: + pass + + def __enter__(self): + return self.setup(self.artifact_path) + + def __exit__(self, exctype, excvalue, exctraceback): + self.cleanup(self.temp_path, self.mount_point) diff --git a/morphlib/plugins/trebuchet_plugin.py b/morphlib/plugins/trebuchet_plugin.py index 2bdf4c3c..1ebffbf4 100644 --- a/morphlib/plugins/trebuchet_plugin.py +++ b/morphlib/plugins/trebuchet_plugin.py @@ -1,4 +1,4 @@ -# Copyright (C) 2012 Codethink Limited +# Copyright (C) 2012-2013 Codethink Limited # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -21,62 +21,8 @@ import gzip import morphlib -class MountableImage(object): - '''Mountable image (deals with decompression). - - Note, this is a read-only mount in the sense that the decompressed - image is not then recompressed after, instead any changes are discarded. - - ''' - def __init__(self, app, artifact_path): - self.app = app - self.artifact_path = artifact_path - - def setup(self, path): - self.app.status(msg='Preparing image %(path)s', path=path) - self.app.status(msg=' Decompressing...', chatty=True) - (tempfd, self.temp_path) = \ - tempfile.mkstemp(dir=self.app.settings['tempdir']) - - try: - with os.fdopen(tempfd, "wb") as outfh: - infh = gzip.open(path, "rb") - morphlib.util.copyfileobj(infh, outfh) - infh.close() - except: - os.unlink(self.temp_path) - raise - self.app.status(msg=' Mounting image at %(path)s', - path=self.temp_path, chatty=True) - part = morphlib.fsutils.setup_device_mapping(self.app.runcmd, - self.temp_path) - mount_point = tempfile.mkdtemp(dir=self.app.settings['tempdir']) - morphlib.fsutils.mount(self.app.runcmd, part, mount_point) - self.mount_point = mount_point - return mount_point - - def cleanup(self, path, mount_point): - self.app.status(msg='Clearing down image at %(path)s', path=path, - chatty=True) - try: - morphlib.fsutils.unmount(self.app.runcmd, mount_point) - except: - pass - try: - morphlib.fsutils.undo_device_mapping(self.app.runcmd, path) - except: - pass - try: - os.rmdir(mount_point) - os.unlink(path) - except: - pass - - def __enter__(self): - return self.setup(self.artifact_path) - - def __exit__(self, exctype, excvalue, exctraceback): - self.cleanup(self.temp_path, self.mount_point) +from morphlib.mountableimage import MountableImage + class TrebuchetPlugin(cliapp.Plugin): -- cgit v1.2.1