From 6821d8234848a7e657434001cc9a904dc670db44 Mon Sep 17 00:00:00 2001 From: Adam Coldrick Date: Thu, 5 Feb 2015 13:51:23 +0000 Subject: Add support for unionfs-fuse Overlayfs is new in version 3.18 of the kernel, so add support for a different implementation of a union/overlay filesystem in order to allow morph to work on older kernels. Change-Id: I63f05265c645dfcc92f3987582bb3f06d853e740 --- morphlib/app.py | 7 +++++++ morphlib/builder.py | 14 +++++++------- morphlib/fsutils.py | 15 +++++++++++++++ morphlib/plugins/deploy_plugin.py | 19 ++++++++++--------- 4 files changed, 39 insertions(+), 16 deletions(-) diff --git a/morphlib/app.py b/morphlib/app.py index 1017ce9a..ac9d70e7 100644 --- a/morphlib/app.py +++ b/morphlib/app.py @@ -121,6 +121,13 @@ class Morph(cliapp.Application): metavar='URL', default=None, group=group_advanced) + self.settings.string(['union-filesystem'], + 'filesystem used to provide "union filesystem" ' + 'functionality when building and deploying. ' + 'Only "overlayfs" and "unionfs-fuse" are ' + 'supported at this time.', + default='overlayfs', + group=group_advanced) group_build = 'Build Options' self.settings.integer(['max-jobs'], diff --git a/morphlib/builder.py b/morphlib/builder.py index c1e409d0..524e85a3 100644 --- a/morphlib/builder.py +++ b/morphlib/builder.py @@ -536,19 +536,19 @@ class SystemBuilder(BuilderBase): # pragma: no cover try: fs_root = self.staging_area.destdir(self.source) self.unpack_strata(fs_root) - overlay_root = self.staging_area.overlay_upperdir( + upperdir = self.staging_area.overlay_upperdir( self.source) editable_root = self.staging_area.overlaydir(self.source) workdir = os.path.join(self.staging_area.dirname, 'overlayfs-workdir') if not os.path.exists(workdir): os.makedirs(workdir) - options = '-olowerdir=%s,upperdir=%s,workdir=%s' % \ - (fs_root, overlay_root, workdir) - morphlib.fsutils.mount(self.app.runcmd, - 'overlay-%s' % a_name, - editable_root, - 'overlay', options) + union_filesystem = self.app.settings['union-filesystem'] + morphlib.fsutils.overlay_mount(self.app.runcmd, + 'overlay-%s' % a_name, + editable_root, fs_root, + upperdir, workdir, + union_filesystem) self.write_metadata(editable_root, a_name) self.run_system_integration_commands(editable_root) unslashy_root = editable_root[1:] diff --git a/morphlib/fsutils.py b/morphlib/fsutils.py index 87b4cf3b..84bae8cb 100644 --- a/morphlib/fsutils.py +++ b/morphlib/fsutils.py @@ -59,6 +59,21 @@ def mount(runcmd, partition, mount_point, runcmd(['mount', partition, mount_point] + fstype + options) +def overlay_mount(runcmd, partition, mount_point, + lowerdir, upperdir, workdir, method): # pragma: no cover + if method == 'overlayfs': + options = '-olowerdir=%s,upperdir=%s,workdir=%s' % \ + (lowerdir, upperdir, workdir) + mount(runcmd, partition, mount_point, 'overlay', options) + elif method == 'unionfs-fuse': + if not os.path.exists(mount_point): + os.mkdir(mount_point) + dir_string = '%s=RW:%s=RO' % (upperdir, lowerdir) + runcmd(['unionfs', '-o', 'cow', dir_string, mount_point]) + else: + raise Exception('Union filesystem %s not supported' % method) + + def unmount(runcmd, mount_point): # pragma: no cover runcmd(['umount', mount_point]) diff --git a/morphlib/plugins/deploy_plugin.py b/morphlib/plugins/deploy_plugin.py index 35082e68..7bcf035a 100644 --- a/morphlib/plugins/deploy_plugin.py +++ b/morphlib/plugins/deploy_plugin.py @@ -571,12 +571,13 @@ class DeployPlugin(cliapp.Plugin): msg='System unpacked at %(system_tree)s', system_tree=system_tree) - options = '-olowerdir=%s,upperdir=%s,workdir=%s' % \ - (system_tree, overlay_dir, work_dir) - morphlib.fsutils.mount(self.app.runcmd, - 'overlay-deploy-%s' % artifact.name, - deploy_tree, fstype='overlay', - options=options) + union_filesystem = self.app.settings['union-filesystem'] + morphlib.fsutils.overlay_mount(self.app.runcmd, + 'overlay-deploy-%s' % + artifact.name, + deploy_tree, system_tree, + overlay_dir, work_dir, + union_filesystem) self.app.status( msg='Writing deployment metadata file') @@ -589,12 +590,12 @@ class DeployPlugin(cliapp.Plugin): sort_keys=True, encoding='unicode-escape') return deploy_tree except Exception: - shutil.rmtree(system_tree) - shutil.rmtree(overlay_dir) - shutil.rmtree(work_dir) if deploy_tree and os.path.exists(deploy_tree): morphlib.fsutils.unmount(self.app.runcmd, deploy_tree) shutil.rmtree(deploy_tree) + shutil.rmtree(system_tree) + shutil.rmtree(overlay_dir) + shutil.rmtree(work_dir) raise def run_deploy_commands(self, deploy_tempdir, env, artifact, root_repo_dir, -- cgit v1.2.1