xref: /OK3568_Linux_fs/yocto/scripts/lib/wic/plugins/source/rawcopy.py (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun#
2*4882a593Smuzhiyun# SPDX-License-Identifier: GPL-2.0-only
3*4882a593Smuzhiyun#
4*4882a593Smuzhiyun
5*4882a593Smuzhiyunimport logging
6*4882a593Smuzhiyunimport os
7*4882a593Smuzhiyunimport signal
8*4882a593Smuzhiyunimport subprocess
9*4882a593Smuzhiyun
10*4882a593Smuzhiyunfrom wic import WicError
11*4882a593Smuzhiyunfrom wic.pluginbase import SourcePlugin
12*4882a593Smuzhiyunfrom wic.misc import exec_cmd, get_bitbake_var
13*4882a593Smuzhiyunfrom wic.filemap import sparse_copy
14*4882a593Smuzhiyun
15*4882a593Smuzhiyunlogger = logging.getLogger('wic')
16*4882a593Smuzhiyun
17*4882a593Smuzhiyunclass RawCopyPlugin(SourcePlugin):
18*4882a593Smuzhiyun    """
19*4882a593Smuzhiyun    Populate partition content from raw image file.
20*4882a593Smuzhiyun    """
21*4882a593Smuzhiyun
22*4882a593Smuzhiyun    name = 'rawcopy'
23*4882a593Smuzhiyun
24*4882a593Smuzhiyun    @staticmethod
25*4882a593Smuzhiyun    def do_image_label(fstype, dst, label):
26*4882a593Smuzhiyun        if fstype.startswith('ext'):
27*4882a593Smuzhiyun            cmd = 'tune2fs -L %s %s' % (label, dst)
28*4882a593Smuzhiyun        elif fstype in ('msdos', 'vfat'):
29*4882a593Smuzhiyun            cmd = 'dosfslabel %s %s' % (dst, label)
30*4882a593Smuzhiyun        elif fstype == 'btrfs':
31*4882a593Smuzhiyun            cmd = 'btrfs filesystem label %s %s' % (dst, label)
32*4882a593Smuzhiyun        elif fstype == 'swap':
33*4882a593Smuzhiyun            cmd = 'mkswap -L %s %s' % (label, dst)
34*4882a593Smuzhiyun        elif fstype in ('squashfs', 'erofs'):
35*4882a593Smuzhiyun            raise WicError("It's not possible to update a %s "
36*4882a593Smuzhiyun                           "filesystem label '%s'" % (fstype, label))
37*4882a593Smuzhiyun        else:
38*4882a593Smuzhiyun            raise WicError("Cannot update filesystem label: "
39*4882a593Smuzhiyun                           "Unknown fstype: '%s'" % (fstype))
40*4882a593Smuzhiyun
41*4882a593Smuzhiyun        exec_cmd(cmd)
42*4882a593Smuzhiyun
43*4882a593Smuzhiyun    @staticmethod
44*4882a593Smuzhiyun    def do_image_uncompression(src, dst, workdir):
45*4882a593Smuzhiyun        def subprocess_setup():
46*4882a593Smuzhiyun            # Python installs a SIGPIPE handler by default. This is usually not what
47*4882a593Smuzhiyun            # non-Python subprocesses expect.
48*4882a593Smuzhiyun            # SIGPIPE errors are known issues with gzip/bash
49*4882a593Smuzhiyun            signal.signal(signal.SIGPIPE, signal.SIG_DFL)
50*4882a593Smuzhiyun
51*4882a593Smuzhiyun        extension = os.path.splitext(src)[1]
52*4882a593Smuzhiyun        decompressor = {
53*4882a593Smuzhiyun            ".bz2": "bzip2",
54*4882a593Smuzhiyun            ".gz": "gzip",
55*4882a593Smuzhiyun            ".xz": "xz"
56*4882a593Smuzhiyun        }.get(extension)
57*4882a593Smuzhiyun        if not decompressor:
58*4882a593Smuzhiyun            raise WicError("Not supported compressor filename extension: %s" % extension)
59*4882a593Smuzhiyun        cmd = "%s -dc %s > %s" % (decompressor, src, dst)
60*4882a593Smuzhiyun        subprocess.call(cmd, preexec_fn=subprocess_setup, shell=True, cwd=workdir)
61*4882a593Smuzhiyun
62*4882a593Smuzhiyun    @classmethod
63*4882a593Smuzhiyun    def do_prepare_partition(cls, part, source_params, cr, cr_workdir,
64*4882a593Smuzhiyun                             oe_builddir, bootimg_dir, kernel_dir,
65*4882a593Smuzhiyun                             rootfs_dir, native_sysroot):
66*4882a593Smuzhiyun        """
67*4882a593Smuzhiyun        Called to do the actual content population for a partition i.e. it
68*4882a593Smuzhiyun        'prepares' the partition to be incorporated into the image.
69*4882a593Smuzhiyun        """
70*4882a593Smuzhiyun        if not kernel_dir:
71*4882a593Smuzhiyun            kernel_dir = get_bitbake_var("DEPLOY_DIR_IMAGE")
72*4882a593Smuzhiyun            if not kernel_dir:
73*4882a593Smuzhiyun                raise WicError("Couldn't find DEPLOY_DIR_IMAGE, exiting")
74*4882a593Smuzhiyun
75*4882a593Smuzhiyun        logger.debug('Kernel dir: %s', kernel_dir)
76*4882a593Smuzhiyun
77*4882a593Smuzhiyun        if 'file' not in source_params:
78*4882a593Smuzhiyun            raise WicError("No file specified")
79*4882a593Smuzhiyun
80*4882a593Smuzhiyun        if 'unpack' in source_params:
81*4882a593Smuzhiyun            img = os.path.join(kernel_dir, source_params['file'])
82*4882a593Smuzhiyun            src = os.path.join(cr_workdir, os.path.splitext(source_params['file'])[0])
83*4882a593Smuzhiyun            RawCopyPlugin.do_image_uncompression(img, src, cr_workdir)
84*4882a593Smuzhiyun        else:
85*4882a593Smuzhiyun            src = os.path.join(kernel_dir, source_params['file'])
86*4882a593Smuzhiyun
87*4882a593Smuzhiyun        dst = os.path.join(cr_workdir, "%s.%s" % (os.path.basename(source_params['file']), part.lineno))
88*4882a593Smuzhiyun
89*4882a593Smuzhiyun        if not os.path.exists(os.path.dirname(dst)):
90*4882a593Smuzhiyun            os.makedirs(os.path.dirname(dst))
91*4882a593Smuzhiyun
92*4882a593Smuzhiyun        if 'skip' in source_params:
93*4882a593Smuzhiyun            sparse_copy(src, dst, skip=int(source_params['skip']))
94*4882a593Smuzhiyun        else:
95*4882a593Smuzhiyun            sparse_copy(src, dst)
96*4882a593Smuzhiyun
97*4882a593Smuzhiyun        # get the size in the right units for kickstart (kB)
98*4882a593Smuzhiyun        du_cmd = "du -Lbks %s" % dst
99*4882a593Smuzhiyun        out = exec_cmd(du_cmd)
100*4882a593Smuzhiyun        filesize = int(out.split()[0])
101*4882a593Smuzhiyun
102*4882a593Smuzhiyun        if filesize > part.size:
103*4882a593Smuzhiyun            part.size = filesize
104*4882a593Smuzhiyun
105*4882a593Smuzhiyun        if part.label:
106*4882a593Smuzhiyun            RawCopyPlugin.do_image_label(part.fstype, dst, part.label)
107*4882a593Smuzhiyun
108*4882a593Smuzhiyun        part.source_file = dst
109