blob: aec720fb22771f0e7cbbb8a0cf644f09fd931b08 [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
Brad Bishopd7bf8c12018-02-25 22:55:05 -050031import sys
Patrick Williamsc124f4f2015-09-15 14:41:29 -050032
Brad Bishop6e60e8b2018-02-01 10:27:11 -050033from oe.path import copyhardlinktree
34
35from wic import WicError
Patrick Williamsc124f4f2015-09-15 14:41:29 -050036from wic.pluginbase import SourcePlugin
Brad Bishopd7bf8c12018-02-25 22:55:05 -050037from wic.misc import get_bitbake_var
Brad Bishop6e60e8b2018-02-01 10:27:11 -050038
39logger = logging.getLogger('wic')
Patrick Williamsc124f4f2015-09-15 14:41:29 -050040
41class RootfsPlugin(SourcePlugin):
42 """
43 Populate partition content from a rootfs directory.
44 """
45
46 name = 'rootfs'
47
48 @staticmethod
49 def __get_rootfs_dir(rootfs_dir):
50 if os.path.isdir(rootfs_dir):
Brad Bishopd7bf8c12018-02-25 22:55:05 -050051 return os.path.realpath(rootfs_dir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -050052
53 image_rootfs_dir = get_bitbake_var("IMAGE_ROOTFS", rootfs_dir)
54 if not os.path.isdir(image_rootfs_dir):
Brad Bishop6e60e8b2018-02-01 10:27:11 -050055 raise WicError("No valid artifact IMAGE_ROOTFS from image "
56 "named %s has been found at %s, exiting." %
57 (rootfs_dir, image_rootfs_dir))
Patrick Williamsc124f4f2015-09-15 14:41:29 -050058
Brad Bishopd7bf8c12018-02-25 22:55:05 -050059 return os.path.realpath(image_rootfs_dir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -050060
61 @classmethod
62 def do_prepare_partition(cls, part, source_params, cr, cr_workdir,
63 oe_builddir, bootimg_dir, kernel_dir,
64 krootfs_dir, native_sysroot):
65 """
66 Called to do the actual content population for a partition i.e. it
67 'prepares' the partition to be incorporated into the image.
68 In this case, prepare content for legacy bios boot partition.
69 """
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050070 if part.rootfs_dir is None:
Patrick Williamsc124f4f2015-09-15 14:41:29 -050071 if not 'ROOTFS_DIR' in krootfs_dir:
Brad Bishop6e60e8b2018-02-01 10:27:11 -050072 raise WicError("Couldn't find --rootfs-dir, exiting")
73
Patrick Williamsc124f4f2015-09-15 14:41:29 -050074 rootfs_dir = krootfs_dir['ROOTFS_DIR']
75 else:
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050076 if part.rootfs_dir in krootfs_dir:
77 rootfs_dir = krootfs_dir[part.rootfs_dir]
78 elif part.rootfs_dir:
79 rootfs_dir = part.rootfs_dir
Patrick Williamsc124f4f2015-09-15 14:41:29 -050080 else:
Brad Bishop6e60e8b2018-02-01 10:27:11 -050081 raise WicError("Couldn't find --rootfs-dir=%s connection or "
82 "it is not a valid path, exiting" % part.rootfs_dir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -050083
Brad Bishopd7bf8c12018-02-25 22:55:05 -050084 part.rootfs_dir = cls.__get_rootfs_dir(rootfs_dir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -050085
Brad Bishopd7bf8c12018-02-25 22:55:05 -050086 new_rootfs = None
Brad Bishop6e60e8b2018-02-01 10:27:11 -050087 # Handle excluded paths.
88 if part.exclude_path is not None:
89 # We need a new rootfs directory we can delete files from. Copy to
90 # workdir.
Brad Bishopd7bf8c12018-02-25 22:55:05 -050091 new_rootfs = os.path.realpath(os.path.join(cr_workdir, "rootfs%d" % part.lineno))
Patrick Williamsc124f4f2015-09-15 14:41:29 -050092
Brad Bishop6e60e8b2018-02-01 10:27:11 -050093 if os.path.lexists(new_rootfs):
94 shutil.rmtree(os.path.join(new_rootfs))
95
Brad Bishopd7bf8c12018-02-25 22:55:05 -050096 copyhardlinktree(part.rootfs_dir, new_rootfs)
Brad Bishop6e60e8b2018-02-01 10:27:11 -050097
98 for orig_path in part.exclude_path:
99 path = orig_path
100 if os.path.isabs(path):
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500101 logger.error("Must be relative: --exclude-path=%s" % orig_path)
102 sys.exit(1)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500103
104 full_path = os.path.realpath(os.path.join(new_rootfs, path))
105
106 # Disallow climbing outside of parent directory using '..',
107 # because doing so could be quite disastrous (we will delete the
108 # directory).
109 if not full_path.startswith(new_rootfs):
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500110 logger.error("'%s' points to a path outside the rootfs" % orig_path)
111 sys.exit(1)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500112
113 if path.endswith(os.sep):
114 # Delete content only.
115 for entry in os.listdir(full_path):
116 full_entry = os.path.join(full_path, entry)
117 if os.path.isdir(full_entry) and not os.path.islink(full_entry):
118 shutil.rmtree(full_entry)
119 else:
120 os.remove(full_entry)
121 else:
122 # Delete whole directory.
123 shutil.rmtree(full_path)
124
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500125 part.prepare_rootfs(cr_workdir, oe_builddir,
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500126 new_rootfs or part.rootfs_dir, native_sysroot)