diff --git a/scripts/lib/wic/help.py b/scripts/lib/wic/help.py index 1bd411deeb..63bbc23a83 100644 --- a/scripts/lib/wic/help.py +++ b/scripts/lib/wic/help.py @@ -721,6 +721,12 @@ DESCRIPTION partition table. It may be useful for bootloaders. + --exclude-path: This option is specific to wic. It excludes the given + absolute path from the resulting image. If the path + ends with a slash, only the content of the directory + is omitted, not the directory itself. This option only + has an effect with the rootfs source plugin. + --extra-space: This option is specific to wic. It adds extra space after the space filled by the content of the partition. The final size can go diff --git a/scripts/lib/wic/ksparser.py b/scripts/lib/wic/ksparser.py index 41d3cc667f..f0aa5d0389 100644 --- a/scripts/lib/wic/ksparser.py +++ b/scripts/lib/wic/ksparser.py @@ -130,6 +130,7 @@ class KickStart(): part.add_argument('mountpoint', nargs='?') part.add_argument('--active', action='store_true') part.add_argument('--align', type=int) + part.add_argument('--exclude-path', nargs='+') part.add_argument("--extra-space", type=sizetype) part.add_argument('--fsoptions', dest='fsopts') part.add_argument('--fstype') diff --git a/scripts/lib/wic/partition.py b/scripts/lib/wic/partition.py index 754ad757d0..1221f691dc 100644 --- a/scripts/lib/wic/partition.py +++ b/scripts/lib/wic/partition.py @@ -40,6 +40,7 @@ class Partition(): self.disk = args.disk self.device = None self.extra_space = args.extra_space + self.exclude_path = args.exclude_path self.fsopts = args.fsopts self.fstype = args.fstype self.label = args.label diff --git a/scripts/lib/wic/plugins/source/rootfs.py b/scripts/lib/wic/plugins/source/rootfs.py index 9d959fa7d7..c57a4341d1 100644 --- a/scripts/lib/wic/plugins/source/rootfs.py +++ b/scripts/lib/wic/plugins/source/rootfs.py @@ -26,10 +26,13 @@ # import os +import shutil + +from oe.path import copyhardlinktree from wic import msger from wic.pluginbase import SourcePlugin -from wic.utils.misc import get_bitbake_var +from wic.utils.misc import get_bitbake_var, exec_cmd class RootfsPlugin(SourcePlugin): """ @@ -78,6 +81,44 @@ class RootfsPlugin(SourcePlugin): real_rootfs_dir = cls.__get_rootfs_dir(rootfs_dir) + # Handle excluded paths. + if part.exclude_path is not None: + # We need a new rootfs directory we can delete files from. Copy to + # workdir. + new_rootfs = os.path.realpath(os.path.join(cr_workdir, "rootfs")) + + if os.path.lexists(new_rootfs): + shutil.rmtree(os.path.join(new_rootfs)) + + copyhardlinktree(real_rootfs_dir, new_rootfs) + + real_rootfs_dir = new_rootfs + + for orig_path in part.exclude_path: + path = orig_path + if os.path.isabs(path): + msger.error("Must be relative: --exclude-path=%s" % orig_path) + + full_path = os.path.realpath(os.path.join(new_rootfs, path)) + + # Disallow climbing outside of parent directory using '..', + # because doing so could be quite disastrous (we will delete the + # directory). + if not full_path.startswith(new_rootfs): + msger.error("'%s' points to a path outside the rootfs" % orig_path) + + if path.endswith(os.sep): + # Delete content only. + for entry in os.listdir(full_path): + full_entry = os.path.join(full_path, entry) + if os.path.isdir(full_entry) and not os.path.islink(full_entry): + shutil.rmtree(full_entry) + else: + os.remove(full_entry) + else: + # Delete whole directory. + shutil.rmtree(full_path) + part.rootfs_dir = real_rootfs_dir part.prepare_rootfs(cr_workdir, oe_builddir, real_rootfs_dir, native_sysroot) diff --git a/scripts/wic b/scripts/wic index 1b7d7dfa4e..10a03eeea6 100755 --- a/scripts/wic +++ b/scripts/wic @@ -41,6 +41,8 @@ from distutils import spawn scripts_path = os.path.abspath(os.path.dirname(__file__)) lib_path = scripts_path + '/lib' sys.path.insert(0, lib_path) +oe_lib_path = os.path.join(os.path.dirname(scripts_path), 'meta', 'lib') +sys.path.insert(0, oe_lib_path) bitbake_exe = spawn.find_executable('bitbake') if bitbake_exe: