1eb8dc403SDave Cobbley#
292b42cb3SPatrick Williams# Copyright OpenEmbedded Contributors
392b42cb3SPatrick Williams#
4c342db35SBrad Bishop# SPDX-License-Identifier: GPL-2.0-only
5eb8dc403SDave Cobbley#
6eb8dc403SDave Cobbley
7eb8dc403SDave Cobbleyimport logging
8eb8dc403SDave Cobbleyimport os
97e0e3c0cSAndrew Geisslerimport signal
107e0e3c0cSAndrew Geisslerimport subprocess
11eb8dc403SDave Cobbley
12eb8dc403SDave Cobbleyfrom wic import WicError
13eb8dc403SDave Cobbleyfrom wic.pluginbase import SourcePlugin
14eb8dc403SDave Cobbleyfrom wic.misc import exec_cmd, get_bitbake_var
15eb8dc403SDave Cobbleyfrom wic.filemap import sparse_copy
16eb8dc403SDave Cobbley
17eb8dc403SDave Cobbleylogger = logging.getLogger('wic')
18eb8dc403SDave Cobbley
19eb8dc403SDave Cobbleyclass RawCopyPlugin(SourcePlugin):
20eb8dc403SDave Cobbley    """
21eb8dc403SDave Cobbley    Populate partition content from raw image file.
22eb8dc403SDave Cobbley    """
23eb8dc403SDave Cobbley
24eb8dc403SDave Cobbley    name = 'rawcopy'
25eb8dc403SDave Cobbley
26eb8dc403SDave Cobbley    @staticmethod
27eb8dc403SDave Cobbley    def do_image_label(fstype, dst, label):
2892b42cb3SPatrick Williams        # don't create label when fstype is none
2992b42cb3SPatrick Williams        if fstype == 'none':
3092b42cb3SPatrick Williams            return
3192b42cb3SPatrick Williams
32eb8dc403SDave Cobbley        if fstype.startswith('ext'):
33eb8dc403SDave Cobbley            cmd = 'tune2fs -L %s %s' % (label, dst)
34eb8dc403SDave Cobbley        elif fstype in ('msdos', 'vfat'):
35eb8dc403SDave Cobbley            cmd = 'dosfslabel %s %s' % (dst, label)
36eb8dc403SDave Cobbley        elif fstype == 'btrfs':
37eb8dc403SDave Cobbley            cmd = 'btrfs filesystem label %s %s' % (dst, label)
38eb8dc403SDave Cobbley        elif fstype == 'swap':
39eb8dc403SDave Cobbley            cmd = 'mkswap -L %s %s' % (label, dst)
40ac69b488SWilliam A. Kennington III        elif fstype in ('squashfs', 'erofs'):
41ac69b488SWilliam A. Kennington III            raise WicError("It's not possible to update a %s "
42ac69b488SWilliam A. Kennington III                           "filesystem label '%s'" % (fstype, label))
43eb8dc403SDave Cobbley        else:
44eb8dc403SDave Cobbley            raise WicError("Cannot update filesystem label: "
45eb8dc403SDave Cobbley                           "Unknown fstype: '%s'" % (fstype))
46eb8dc403SDave Cobbley
47eb8dc403SDave Cobbley        exec_cmd(cmd)
48eb8dc403SDave Cobbley
497e0e3c0cSAndrew Geissler    @staticmethod
507e0e3c0cSAndrew Geissler    def do_image_uncompression(src, dst, workdir):
517e0e3c0cSAndrew Geissler        def subprocess_setup():
527e0e3c0cSAndrew Geissler            # Python installs a SIGPIPE handler by default. This is usually not what
537e0e3c0cSAndrew Geissler            # non-Python subprocesses expect.
547e0e3c0cSAndrew Geissler            # SIGPIPE errors are known issues with gzip/bash
557e0e3c0cSAndrew Geissler            signal.signal(signal.SIGPIPE, signal.SIG_DFL)
567e0e3c0cSAndrew Geissler
577e0e3c0cSAndrew Geissler        extension = os.path.splitext(src)[1]
587e0e3c0cSAndrew Geissler        decompressor = {
597e0e3c0cSAndrew Geissler            ".bz2": "bzip2",
607e0e3c0cSAndrew Geissler            ".gz": "gzip",
61*da295319SPatrick Williams            ".xz": "xz",
62*da295319SPatrick Williams            ".zst": "zstd -f",
637e0e3c0cSAndrew Geissler        }.get(extension)
647e0e3c0cSAndrew Geissler        if not decompressor:
657e0e3c0cSAndrew Geissler            raise WicError("Not supported compressor filename extension: %s" % extension)
667e0e3c0cSAndrew Geissler        cmd = "%s -dc %s > %s" % (decompressor, src, dst)
677e0e3c0cSAndrew Geissler        subprocess.call(cmd, preexec_fn=subprocess_setup, shell=True, cwd=workdir)
687e0e3c0cSAndrew Geissler
69eb8dc403SDave Cobbley    @classmethod
70eb8dc403SDave Cobbley    def do_prepare_partition(cls, part, source_params, cr, cr_workdir,
71eb8dc403SDave Cobbley                             oe_builddir, bootimg_dir, kernel_dir,
72eb8dc403SDave Cobbley                             rootfs_dir, native_sysroot):
73eb8dc403SDave Cobbley        """
74eb8dc403SDave Cobbley        Called to do the actual content population for a partition i.e. it
75eb8dc403SDave Cobbley        'prepares' the partition to be incorporated into the image.
76eb8dc403SDave Cobbley        """
77eb8dc403SDave Cobbley        if not kernel_dir:
78eb8dc403SDave Cobbley            kernel_dir = get_bitbake_var("DEPLOY_DIR_IMAGE")
79eb8dc403SDave Cobbley            if not kernel_dir:
80eb8dc403SDave Cobbley                raise WicError("Couldn't find DEPLOY_DIR_IMAGE, exiting")
81eb8dc403SDave Cobbley
82eb8dc403SDave Cobbley        logger.debug('Kernel dir: %s', kernel_dir)
83eb8dc403SDave Cobbley
84eb8dc403SDave Cobbley        if 'file' not in source_params:
85eb8dc403SDave Cobbley            raise WicError("No file specified")
86eb8dc403SDave Cobbley
877e0e3c0cSAndrew Geissler        if 'unpack' in source_params:
887e0e3c0cSAndrew Geissler            img = os.path.join(kernel_dir, source_params['file'])
897e0e3c0cSAndrew Geissler            src = os.path.join(cr_workdir, os.path.splitext(source_params['file'])[0])
907e0e3c0cSAndrew Geissler            RawCopyPlugin.do_image_uncompression(img, src, cr_workdir)
917e0e3c0cSAndrew Geissler        else:
92eb8dc403SDave Cobbley            src = os.path.join(kernel_dir, source_params['file'])
937e0e3c0cSAndrew Geissler
9482c905dcSAndrew Geissler        dst = os.path.join(cr_workdir, "%s.%s" % (os.path.basename(source_params['file']), part.lineno))
95eb8dc403SDave Cobbley
9664c979e8SBrad Bishop        if not os.path.exists(os.path.dirname(dst)):
9764c979e8SBrad Bishop            os.makedirs(os.path.dirname(dst))
9864c979e8SBrad Bishop
99eb8dc403SDave Cobbley        if 'skip' in source_params:
100eb8dc403SDave Cobbley            sparse_copy(src, dst, skip=int(source_params['skip']))
101eb8dc403SDave Cobbley        else:
102eb8dc403SDave Cobbley            sparse_copy(src, dst)
103eb8dc403SDave Cobbley
104eb8dc403SDave Cobbley        # get the size in the right units for kickstart (kB)
105eb8dc403SDave Cobbley        du_cmd = "du -Lbks %s" % dst
106eb8dc403SDave Cobbley        out = exec_cmd(du_cmd)
107eb8dc403SDave Cobbley        filesize = int(out.split()[0])
108eb8dc403SDave Cobbley
109eb8dc403SDave Cobbley        if filesize > part.size:
110eb8dc403SDave Cobbley            part.size = filesize
111eb8dc403SDave Cobbley
112eb8dc403SDave Cobbley        if part.label:
113eb8dc403SDave Cobbley            RawCopyPlugin.do_image_label(part.fstype, dst, part.label)
114eb8dc403SDave Cobbley
115eb8dc403SDave Cobbley        part.source_file = dst
116