diff options
author | Sam Thursfield <sam.thursfield@codethink.co.uk> | 2015-05-27 16:42:53 +0000 |
---|---|---|
committer | Sam Thursfield <sam.thursfield@codethink.co.uk> | 2015-06-10 17:41:48 +0100 |
commit | 7a81a02b3a533a00740a3932b2e10d6377f45ede (patch) | |
tree | e59512e946a9275572c5e55bdcbc1e4d7a26f2b5 | |
parent | 117413f11e59c66071663a28d02b701e9c871236 (diff) | |
download | morph-7a81a02b3a533a00740a3932b2e10d6377f45ede.tar.gz |
Remove unneeded containerisation code
The 'sandboxlib' library can now handle this.
Change-Id: Ifd6c23b4eda8f96cca96ef21b237eabb02ea1bd6
-rw-r--r-- | morphlib/fsutils.py | 70 | ||||
-rw-r--r-- | morphlib/fsutils_tests.py | 113 | ||||
-rw-r--r-- | morphlib/util.py | 69 | ||||
-rw-r--r-- | without-test-modules | 2 |
4 files changed, 1 insertions, 253 deletions
diff --git a/morphlib/fsutils.py b/morphlib/fsutils.py index a3b73bf6..df6c8826 100644 --- a/morphlib/fsutils.py +++ b/morphlib/fsutils.py @@ -66,73 +66,3 @@ def undo_device_mapping(runcmd, image_name): # pragma: no cover i = line.find(':') device = line[:i] runcmd(['losetup', '-d', device]) - - -def invert_paths(tree_walker, paths): - '''List paths from `tree_walker` that are not in `paths`. - - Given a traversal of a tree and a set of paths separated by os.sep, - return the files and directories that are not part of the set of - paths, culling directories that do not need to be recursed into, - if the traversal supports this. - - `tree_walker` is expected to follow similar behaviour to `os.walk()`. - - This function will remove directores from the ones listed, to avoid - traversing into these subdirectories, if it doesn't need to. - - As such, if a directory is returned, it is implied that its contents - are also not in the set of paths. - - If the tree walker does not support culling the traversal this way, - such as `os.walk(root, topdown=False)`, then the contents will also - be returned. - - The purpose for this is to list the directories that can be made - read-only, such that it would leave everything in paths writable. - - Each path in `paths` is expected to begin with the same path as - yielded by the tree walker. - - ''' - - def normpath(path): - if path == '.': - return path - path = os.path.normpath(path) - if not os.path.isabs(path): - path = os.path.join('.', path) - return path - def any_paths_are_subpath_of(prefix): - prefix = normpath(prefix) - norm_paths = (normpath(path) for path in paths) - return any(path[:len(prefix)] == prefix - for path in norm_paths) - - def path_is_listed(path): - return any(normpath(path) == normpath(other) - for other in paths) - - for dirpath, dirnames, filenames in tree_walker: - - if path_is_listed(dirpath): - # No subpaths need to be considered - del dirnames[:] - del filenames[:] - elif any_paths_are_subpath_of(dirpath): - # Subpaths may be marked, or may not, need to leave this - # writable, so don't yield, but we don't cull. - pass - else: - # not listed as a parent or an exact match, needs to be - # yielded, but we don't need to consider subdirs, so can cull - yield dirpath - del dirnames[:] - del filenames[:] - - for filename in filenames: - fullpath = os.path.join(dirpath, filename) - if path_is_listed(fullpath): - pass - else: - yield fullpath diff --git a/morphlib/fsutils_tests.py b/morphlib/fsutils_tests.py deleted file mode 100644 index f2772fb7..00000000 --- a/morphlib/fsutils_tests.py +++ /dev/null @@ -1,113 +0,0 @@ -# Copyright (C) 2013, 2014-2015 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, see <http://www.gnu.org/licenses/>. - - -import os -import unittest - -import morphlib - - -def dummy_top_down_walker(root, treedict): - '''Something that imitates os.walk, but with a dict''' - - subdirs = [k for k in treedict if isinstance(treedict[k], dict)] - files = [k for k in treedict if not isinstance(treedict[k], dict)] - yield root, subdirs, files - for subdir in subdirs: - subwalker = dummy_top_down_walker(os.path.join(root, subdir), - treedict[subdir]) - for result in subwalker: - yield result - - -class InvertPathsTests(unittest.TestCase): - - def setUp(self): - self.flat_tree = {"foo": None, "bar": None, "baz": None} - self.nested_tree = { - "foo": { - "bar": None, - "baz": None, - }, - "fs": { - "btrfs": None, - "ext2": None, - "ext3": None, - "ext4": None, - "nfs": None, - }, - } - - def test_flat_lists_top_dir(self): - walker = dummy_top_down_walker('.', self.flat_tree) - self.assertEqual(["."], - sorted(morphlib.fsutils.invert_paths(walker, []))) - - def test_flat_skips_all_with_root_pased(self): - walker = dummy_top_down_walker('.', self.flat_tree) - self.assertEqual([], - list(morphlib.fsutils.invert_paths(walker, ['.']))) - - def test_flat_lists_top_dir(self): - walker = dummy_top_down_walker('.', self.nested_tree) - self.assertEqual(["."], - sorted(morphlib.fsutils.invert_paths(walker, []))) - - def test_flat_skips_all_with_root_pased(self): - walker = dummy_top_down_walker('.', self.nested_tree) - self.assertEqual([], - list(morphlib.fsutils.invert_paths(walker, ['.']))) - - def test_flat_excludes_listed_files(self): - walker = dummy_top_down_walker('.', self.flat_tree) - self.assertTrue( - "./bar" not in morphlib.fsutils.invert_paths(walker, ["./bar"])) - - def test_nested_excludes_listed_files(self): - walker = dummy_top_down_walker('.', self.nested_tree) - excludes = ["./foo/bar", "./fs/nfs"] - found = frozenset(morphlib.fsutils.invert_paths(walker, excludes)) - self.assertTrue(all(path not in found for path in excludes)) - - def test_nested_excludes_whole_dir(self): - walker = dummy_top_down_walker('.', self.nested_tree) - found = frozenset(morphlib.fsutils.invert_paths(walker, ["./foo"])) - unexpected = ("./foo", "./foo/bar", "./foo/baz") - self.assertTrue(all(path not in found for path in unexpected)) - - def test_lower_mount_precludes(self): - walker = dummy_top_down_walker('.', { - "tmp": { - "morph": { - "staging": { - "build": None, - "inst": None, - }, - }, - "ccache": { - "0": None - }, - }, - "bin": { - }, - }) - found = frozenset(morphlib.fsutils.invert_paths( - walker, [ - "./tmp/morph/staging/build", - "./tmp/morph/staging/inst", - "./tmp", - ])) - expected = ["./bin"] - self.assertEqual(sorted(found), expected) diff --git a/morphlib/util.py b/morphlib/util.py index 2bce6f31..fb9fba0a 100644 --- a/morphlib/util.py +++ b/morphlib/util.py @@ -15,7 +15,6 @@ import contextlib import itertools import os -import pipes import re import shutil import subprocess @@ -596,74 +595,6 @@ def unshared_cmdline(args, root='/', mounts=()): # pragma: no cover return cmdline -def containerised_cmdline(args, cwd='.', root='/', binds=(), - mount_proc=False, unshare_net=False, - writable_paths=None, **kwargs): # pragma: no cover - ''' - Describe how to run 'args' inside a linux-user-chroot container. - - The subprocess will only be permitted to write to the paths we - specifically allow it to write to, listed in 'writeable paths'. All - other locations in the file system will be read-only. - - The 'root' parameter allows running the command in a chroot, allowing - the host file system to be hidden completely except for the paths - below 'root'. - - The 'mount_proc' flag enables mounting of /proc inside 'root'. - Locations from the file system can be bind-mounted inside 'root' by - setting 'binds' to a list of (src, dest) pairs. The 'dest' - directory must be inside 'root'. - - The 'mounts' parameter allows mounting of arbitrary file-systems, - such as tmpfs, before running commands, by setting it to a list of - (mount_point, mount_type, source) triples. - - The subprocess will be run in a separate mount namespace. It can - optionally be run in a separate network namespace too by setting - 'unshare_net'. - - ''' - - if not root.endswith('/'): - root += '/' - if writable_paths is None: - writable_paths = (root,) - - cmdargs = ['linux-user-chroot', '--chdir', cwd] - if unshare_net: - cmdargs.append('--unshare-net') - for src, dst in binds: - # linux-user-chroot's mount target paths are relative to the chroot - cmdargs.extend(('--mount-bind', src, os.path.relpath(dst, root))) - for d in morphlib.fsutils.invert_paths(os.walk(root), writable_paths): - if not os.path.islink(d): - cmdargs.extend(('--mount-readonly', os.path.relpath(d, root))) - if mount_proc: - proc_target = os.path.join(root, 'proc') - if not os.path.exists(proc_target): - os.makedirs(proc_target) - cmdargs.extend(('--mount-proc', 'proc')) - cmdargs.append(root) - cmdargs.extend(args) - return unshared_cmdline(cmdargs, root=root, **kwargs) - - -def error_message_for_containerised_commandline( - argv, err, container_kwargs): # pragma: no cover - '''Return a semi-readable error message for a containerised command.''' - - # This function should do some formatting of the container_kwargs dict, - # rather than just dumping it in the error message, but that is better than - # nothing. - - argv_string = ' '.join(map(pipes.quote, argv)) - return 'Command failed: %s:\n' \ - 'Containerisation settings: %s\n' \ - 'Error output:\n%s' \ - % (argv_string, container_kwargs, err) - - def write_from_dict(filepath, d, validate=lambda x, y: True): #pragma: no cover '''Takes a dictionary and appends the contents to a file diff --git a/without-test-modules b/without-test-modules index df1aa2dd..edc050f2 100644 --- a/without-test-modules +++ b/without-test-modules @@ -2,7 +2,7 @@ morphlib/__init__.py morphlib/artifactcachereference.py morphlib/artifactsplitrule.py morphlib/builddependencygraph.py -morphlib/tester.py +morphlib/fsutils.py morphlib/git.py morphlib/app.py morphlib/mountableimage.py |