blob: f2e2ca8a2be1a842033e820a01b98adbe0ec77a0 [file] [log] [blame]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001# ex:ts=4:sw=4:sts=4:et
2# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
3#
4# Copyright (c) 2014, Intel Corporation.
5# All rights reserved.
6#
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License version 2 as
9# published by the Free Software Foundation.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License along
17# with this program; if not, write to the Free Software Foundation, Inc.,
18# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19#
20# DESCRIPTION
21# This implements the 'rootfs' source plugin class for 'wic'
22#
23# AUTHORS
24# Tom Zanussi <tom.zanussi (at] linux.intel.com>
25# Joao Henrique Ferreira de Freitas <joaohf (at] gmail.com>
26#
27
Brad Bishop6e60e8b2018-02-01 10:27:11 -050028import logging
Patrick Williamsc124f4f2015-09-15 14:41:29 -050029import os
Brad Bishop6e60e8b2018-02-01 10:27:11 -050030import shutil
Patrick Williamsc124f4f2015-09-15 14:41:29 -050031
Brad Bishop6e60e8b2018-02-01 10:27:11 -050032from oe.path import copyhardlinktree
33
34from wic import WicError
Patrick Williamsc124f4f2015-09-15 14:41:29 -050035from wic.pluginbase import SourcePlugin
Brad Bishop6e60e8b2018-02-01 10:27:11 -050036from wic.utils.misc import get_bitbake_var, exec_cmd
37
38logger = logging.getLogger('wic')
Patrick Williamsc124f4f2015-09-15 14:41:29 -050039
40class RootfsPlugin(SourcePlugin):
41 """
42 Populate partition content from a rootfs directory.
43 """
44
45 name = 'rootfs'
46
47 @staticmethod
48 def __get_rootfs_dir(rootfs_dir):
49 if os.path.isdir(rootfs_dir):
50 return rootfs_dir
51
52 image_rootfs_dir = get_bitbake_var("IMAGE_ROOTFS", rootfs_dir)
53 if not os.path.isdir(image_rootfs_dir):
Brad Bishop6e60e8b2018-02-01 10:27:11 -050054 raise WicError("No valid artifact IMAGE_ROOTFS from image "
55 "named %s has been found at %s, exiting." %
56 (rootfs_dir, image_rootfs_dir))
Patrick Williamsc124f4f2015-09-15 14:41:29 -050057
58 return image_rootfs_dir
59
60 @classmethod
61 def do_prepare_partition(cls, part, source_params, cr, cr_workdir,
62 oe_builddir, bootimg_dir, kernel_dir,
63 krootfs_dir, native_sysroot):
64 """
65 Called to do the actual content population for a partition i.e. it
66 'prepares' the partition to be incorporated into the image.
67 In this case, prepare content for legacy bios boot partition.
68 """
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050069 if part.rootfs_dir is None:
Patrick Williamsc124f4f2015-09-15 14:41:29 -050070 if not 'ROOTFS_DIR' in krootfs_dir:
Brad Bishop6e60e8b2018-02-01 10:27:11 -050071 raise WicError("Couldn't find --rootfs-dir, exiting")
72
Patrick Williamsc124f4f2015-09-15 14:41:29 -050073 rootfs_dir = krootfs_dir['ROOTFS_DIR']
74 else:
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050075 if part.rootfs_dir in krootfs_dir:
76 rootfs_dir = krootfs_dir[part.rootfs_dir]
77 elif part.rootfs_dir:
78 rootfs_dir = part.rootfs_dir
Patrick Williamsc124f4f2015-09-15 14:41:29 -050079 else:
Brad Bishop6e60e8b2018-02-01 10:27:11 -050080 raise WicError("Couldn't find --rootfs-dir=%s connection or "
81 "it is not a valid path, exiting" % part.rootfs_dir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -050082
83 real_rootfs_dir = cls.__get_rootfs_dir(rootfs_dir)
84
Brad Bishop6e60e8b2018-02-01 10:27:11 -050085 # Handle excluded paths.
86 if part.exclude_path is not None:
87 # We need a new rootfs directory we can delete files from. Copy to
88 # workdir.
89 new_rootfs = os.path.realpath(os.path.join(cr_workdir, "rootfs"))
Patrick Williamsc124f4f2015-09-15 14:41:29 -050090
Brad Bishop6e60e8b2018-02-01 10:27:11 -050091 if os.path.lexists(new_rootfs):
92 shutil.rmtree(os.path.join(new_rootfs))
93
94 copyhardlinktree(real_rootfs_dir, new_rootfs)
95
96 real_rootfs_dir = new_rootfs
97
98 for orig_path in part.exclude_path:
99 path = orig_path
100 if os.path.isabs(path):
101 msger.error("Must be relative: --exclude-path=%s" % orig_path)
102
103 full_path = os.path.realpath(os.path.join(new_rootfs, path))
104
105 # Disallow climbing outside of parent directory using '..',
106 # because doing so could be quite disastrous (we will delete the
107 # directory).
108 if not full_path.startswith(new_rootfs):
109 msger.error("'%s' points to a path outside the rootfs" % orig_path)
110
111 if path.endswith(os.sep):
112 # Delete content only.
113 for entry in os.listdir(full_path):
114 full_entry = os.path.join(full_path, entry)
115 if os.path.isdir(full_entry) and not os.path.islink(full_entry):
116 shutil.rmtree(full_entry)
117 else:
118 os.remove(full_entry)
119 else:
120 # Delete whole directory.
121 shutil.rmtree(full_path)
122
123 part.rootfs_dir = real_rootfs_dir
124 part.prepare_rootfs(cr_workdir, oe_builddir,
125 real_rootfs_dir, native_sysroot)