blob: e26e95b9913bab255f96d15e8cad5e287dec0171 [file] [log] [blame]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001#
2# Copyright (c) 2014, Intel Corporation.
Patrick Williamsc124f4f2015-09-15 14:41:29 -05003#
Brad Bishopc342db32019-05-15 21:57:59 -04004# SPDX-License-Identifier: GPL-2.0-only
Patrick Williamsc124f4f2015-09-15 14:41:29 -05005#
6# DESCRIPTION
7# This implements the 'rootfs' source plugin class for 'wic'
8#
9# AUTHORS
10# Tom Zanussi <tom.zanussi (at] linux.intel.com>
11# Joao Henrique Ferreira de Freitas <joaohf (at] gmail.com>
12#
13
Brad Bishop6e60e8b2018-02-01 10:27:11 -050014import logging
Patrick Williamsc124f4f2015-09-15 14:41:29 -050015import os
Brad Bishop6e60e8b2018-02-01 10:27:11 -050016import shutil
Brad Bishopd7bf8c12018-02-25 22:55:05 -050017import sys
Patrick Williamsc124f4f2015-09-15 14:41:29 -050018
Brad Bishop6e60e8b2018-02-01 10:27:11 -050019from oe.path import copyhardlinktree
20
21from wic import WicError
Patrick Williamsc124f4f2015-09-15 14:41:29 -050022from wic.pluginbase import SourcePlugin
Brad Bishopd7bf8c12018-02-25 22:55:05 -050023from wic.misc import get_bitbake_var
Brad Bishop6e60e8b2018-02-01 10:27:11 -050024
25logger = logging.getLogger('wic')
Patrick Williamsc124f4f2015-09-15 14:41:29 -050026
27class RootfsPlugin(SourcePlugin):
28 """
29 Populate partition content from a rootfs directory.
30 """
31
32 name = 'rootfs'
33
34 @staticmethod
35 def __get_rootfs_dir(rootfs_dir):
36 if os.path.isdir(rootfs_dir):
Brad Bishopd7bf8c12018-02-25 22:55:05 -050037 return os.path.realpath(rootfs_dir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -050038
39 image_rootfs_dir = get_bitbake_var("IMAGE_ROOTFS", rootfs_dir)
40 if not os.path.isdir(image_rootfs_dir):
Brad Bishop6e60e8b2018-02-01 10:27:11 -050041 raise WicError("No valid artifact IMAGE_ROOTFS from image "
42 "named %s has been found at %s, exiting." %
43 (rootfs_dir, image_rootfs_dir))
Patrick Williamsc124f4f2015-09-15 14:41:29 -050044
Brad Bishopd7bf8c12018-02-25 22:55:05 -050045 return os.path.realpath(image_rootfs_dir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -050046
47 @classmethod
48 def do_prepare_partition(cls, part, source_params, cr, cr_workdir,
49 oe_builddir, bootimg_dir, kernel_dir,
50 krootfs_dir, native_sysroot):
51 """
52 Called to do the actual content population for a partition i.e. it
53 'prepares' the partition to be incorporated into the image.
54 In this case, prepare content for legacy bios boot partition.
55 """
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050056 if part.rootfs_dir is None:
Patrick Williamsc124f4f2015-09-15 14:41:29 -050057 if not 'ROOTFS_DIR' in krootfs_dir:
Brad Bishop6e60e8b2018-02-01 10:27:11 -050058 raise WicError("Couldn't find --rootfs-dir, exiting")
59
Patrick Williamsc124f4f2015-09-15 14:41:29 -050060 rootfs_dir = krootfs_dir['ROOTFS_DIR']
61 else:
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050062 if part.rootfs_dir in krootfs_dir:
63 rootfs_dir = krootfs_dir[part.rootfs_dir]
64 elif part.rootfs_dir:
65 rootfs_dir = part.rootfs_dir
Patrick Williamsc124f4f2015-09-15 14:41:29 -050066 else:
Brad Bishop6e60e8b2018-02-01 10:27:11 -050067 raise WicError("Couldn't find --rootfs-dir=%s connection or "
68 "it is not a valid path, exiting" % part.rootfs_dir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -050069
Brad Bishopd7bf8c12018-02-25 22:55:05 -050070 part.rootfs_dir = cls.__get_rootfs_dir(rootfs_dir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -050071
Brad Bishopd7bf8c12018-02-25 22:55:05 -050072 new_rootfs = None
Brad Bishop6e60e8b2018-02-01 10:27:11 -050073 # Handle excluded paths.
74 if part.exclude_path is not None:
75 # We need a new rootfs directory we can delete files from. Copy to
76 # workdir.
Brad Bishopd7bf8c12018-02-25 22:55:05 -050077 new_rootfs = os.path.realpath(os.path.join(cr_workdir, "rootfs%d" % part.lineno))
Patrick Williamsc124f4f2015-09-15 14:41:29 -050078
Brad Bishop6e60e8b2018-02-01 10:27:11 -050079 if os.path.lexists(new_rootfs):
80 shutil.rmtree(os.path.join(new_rootfs))
81
Brad Bishopd7bf8c12018-02-25 22:55:05 -050082 copyhardlinktree(part.rootfs_dir, new_rootfs)
Brad Bishop6e60e8b2018-02-01 10:27:11 -050083
84 for orig_path in part.exclude_path:
85 path = orig_path
86 if os.path.isabs(path):
Brad Bishopd7bf8c12018-02-25 22:55:05 -050087 logger.error("Must be relative: --exclude-path=%s" % orig_path)
88 sys.exit(1)
Brad Bishop6e60e8b2018-02-01 10:27:11 -050089
90 full_path = os.path.realpath(os.path.join(new_rootfs, path))
91
92 # Disallow climbing outside of parent directory using '..',
93 # because doing so could be quite disastrous (we will delete the
94 # directory).
95 if not full_path.startswith(new_rootfs):
Brad Bishopd7bf8c12018-02-25 22:55:05 -050096 logger.error("'%s' points to a path outside the rootfs" % orig_path)
97 sys.exit(1)
Brad Bishop6e60e8b2018-02-01 10:27:11 -050098
99 if path.endswith(os.sep):
100 # Delete content only.
101 for entry in os.listdir(full_path):
102 full_entry = os.path.join(full_path, entry)
103 if os.path.isdir(full_entry) and not os.path.islink(full_entry):
104 shutil.rmtree(full_entry)
105 else:
106 os.remove(full_entry)
107 else:
108 # Delete whole directory.
109 shutil.rmtree(full_path)
110
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500111 part.prepare_rootfs(cr_workdir, oe_builddir,
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500112 new_rootfs or part.rootfs_dir, native_sysroot)