1eb8dc403SDave Cobbley#
2c342db35SBrad Bishop# SPDX-License-Identifier: GPL-2.0-only
3eb8dc403SDave Cobbley#
4eb8dc403SDave Cobbley# DESCRIPTION
5eb8dc403SDave Cobbley# This implements the 'isoimage-isohybrid' source plugin class for 'wic'
6eb8dc403SDave Cobbley#
7eb8dc403SDave Cobbley# AUTHORS
8eb8dc403SDave Cobbley# Mihaly Varga <mihaly.varga (at] ni.com>
9eb8dc403SDave Cobbley
10eb8dc403SDave Cobbleyimport glob
11eb8dc403SDave Cobbleyimport logging
12eb8dc403SDave Cobbleyimport os
13eb8dc403SDave Cobbleyimport re
14eb8dc403SDave Cobbleyimport shutil
15eb8dc403SDave Cobbley
16eb8dc403SDave Cobbleyfrom wic import WicError
17eb8dc403SDave Cobbleyfrom wic.engine import get_custom_config
18eb8dc403SDave Cobbleyfrom wic.pluginbase import SourcePlugin
19eb8dc403SDave Cobbleyfrom wic.misc import exec_cmd, exec_native_cmd, get_bitbake_var
20eb8dc403SDave Cobbley
21eb8dc403SDave Cobbleylogger = logging.getLogger('wic')
22eb8dc403SDave Cobbley
23eb8dc403SDave Cobbleyclass IsoImagePlugin(SourcePlugin):
24eb8dc403SDave Cobbley    """
25eb8dc403SDave Cobbley    Create a bootable ISO image
26eb8dc403SDave Cobbley
27eb8dc403SDave Cobbley    This plugin creates a hybrid, legacy and EFI bootable ISO image. The
28eb8dc403SDave Cobbley    generated image can be used on optical media as well as USB media.
29eb8dc403SDave Cobbley
30eb8dc403SDave Cobbley    Legacy boot uses syslinux and EFI boot uses grub or gummiboot (not
31eb8dc403SDave Cobbley    implemented yet) as bootloader. The plugin creates the directories required
32eb8dc403SDave Cobbley    by bootloaders and populates them by creating and configuring the
33eb8dc403SDave Cobbley    bootloader files.
34eb8dc403SDave Cobbley
35eb8dc403SDave Cobbley    Example kickstart file:
36eb8dc403SDave Cobbley    part /boot --source isoimage-isohybrid --sourceparams="loader=grub-efi, \\
371a4b7ee2SBrad Bishop    image_name= IsoImage" --ondisk cd --label LIVECD
38eb8dc403SDave Cobbley    bootloader  --timeout=10  --append=" "
39eb8dc403SDave Cobbley
40eb8dc403SDave Cobbley    In --sourceparams "loader" specifies the bootloader used for booting in EFI
41eb8dc403SDave Cobbley    mode, while "image_name" specifies the name of the generated image. In the
42eb8dc403SDave Cobbley    example above, wic creates an ISO image named IsoImage-cd.direct (default
43eb8dc403SDave Cobbley    extension added by direct imeger plugin) and a file named IsoImage-cd.iso
44eb8dc403SDave Cobbley    """
45eb8dc403SDave Cobbley
46eb8dc403SDave Cobbley    name = 'isoimage-isohybrid'
47eb8dc403SDave Cobbley
48eb8dc403SDave Cobbley    @classmethod
49eb8dc403SDave Cobbley    def do_configure_syslinux(cls, creator, cr_workdir):
50eb8dc403SDave Cobbley        """
51eb8dc403SDave Cobbley        Create loader-specific (syslinux) config
52eb8dc403SDave Cobbley        """
53eb8dc403SDave Cobbley        splash = os.path.join(cr_workdir, "ISO/boot/splash.jpg")
54eb8dc403SDave Cobbley        if os.path.exists(splash):
55eb8dc403SDave Cobbley            splashline = "menu background splash.jpg"
56eb8dc403SDave Cobbley        else:
57eb8dc403SDave Cobbley            splashline = ""
58eb8dc403SDave Cobbley
59eb8dc403SDave Cobbley        bootloader = creator.ks.bootloader
60eb8dc403SDave Cobbley
61eb8dc403SDave Cobbley        syslinux_conf = ""
62eb8dc403SDave Cobbley        syslinux_conf += "PROMPT 0\n"
63eb8dc403SDave Cobbley        syslinux_conf += "TIMEOUT %s \n" % (bootloader.timeout or 10)
64eb8dc403SDave Cobbley        syslinux_conf += "\n"
65eb8dc403SDave Cobbley        syslinux_conf += "ALLOWOPTIONS 1\n"
66eb8dc403SDave Cobbley        syslinux_conf += "SERIAL 0 115200\n"
67eb8dc403SDave Cobbley        syslinux_conf += "\n"
68eb8dc403SDave Cobbley        if splashline:
69eb8dc403SDave Cobbley            syslinux_conf += "%s\n" % splashline
70eb8dc403SDave Cobbley        syslinux_conf += "DEFAULT boot\n"
71eb8dc403SDave Cobbley        syslinux_conf += "LABEL boot\n"
72eb8dc403SDave Cobbley
7315ae2509SBrad Bishop        kernel = get_bitbake_var("KERNEL_IMAGETYPE")
7496ff1984SBrad Bishop        if get_bitbake_var("INITRAMFS_IMAGE_BUNDLE") == "1":
7596ff1984SBrad Bishop            if get_bitbake_var("INITRAMFS_IMAGE"):
7696ff1984SBrad Bishop                kernel = "%s-%s.bin" % \
7796ff1984SBrad Bishop                    (get_bitbake_var("KERNEL_IMAGETYPE"), get_bitbake_var("INITRAMFS_LINK_NAME"))
7896ff1984SBrad Bishop
7915ae2509SBrad Bishop        syslinux_conf += "KERNEL /" + kernel + "\n"
80eb8dc403SDave Cobbley        syslinux_conf += "APPEND initrd=/initrd LABEL=boot %s\n" \
81eb8dc403SDave Cobbley                             % bootloader.append
82eb8dc403SDave Cobbley
83eb8dc403SDave Cobbley        logger.debug("Writing syslinux config %s/ISO/isolinux/isolinux.cfg",
84eb8dc403SDave Cobbley                     cr_workdir)
85eb8dc403SDave Cobbley
86eb8dc403SDave Cobbley        with open("%s/ISO/isolinux/isolinux.cfg" % cr_workdir, "w") as cfg:
87eb8dc403SDave Cobbley            cfg.write(syslinux_conf)
88eb8dc403SDave Cobbley
89eb8dc403SDave Cobbley    @classmethod
90eb8dc403SDave Cobbley    def do_configure_grubefi(cls, part, creator, target_dir):
91eb8dc403SDave Cobbley        """
92eb8dc403SDave Cobbley        Create loader-specific (grub-efi) config
93eb8dc403SDave Cobbley        """
94eb8dc403SDave Cobbley        configfile = creator.ks.bootloader.configfile
95eb8dc403SDave Cobbley        if configfile:
96eb8dc403SDave Cobbley            grubefi_conf = get_custom_config(configfile)
97eb8dc403SDave Cobbley            if grubefi_conf:
98eb8dc403SDave Cobbley                logger.debug("Using custom configuration file %s for grub.cfg",
99eb8dc403SDave Cobbley                             configfile)
100eb8dc403SDave Cobbley            else:
101eb8dc403SDave Cobbley                raise WicError("configfile is specified "
102eb8dc403SDave Cobbley                               "but failed to get it from %s", configfile)
103eb8dc403SDave Cobbley        else:
104eb8dc403SDave Cobbley            splash = os.path.join(target_dir, "splash.jpg")
105eb8dc403SDave Cobbley            if os.path.exists(splash):
106eb8dc403SDave Cobbley                splashline = "menu background splash.jpg"
107eb8dc403SDave Cobbley            else:
108eb8dc403SDave Cobbley                splashline = ""
109eb8dc403SDave Cobbley
110eb8dc403SDave Cobbley            bootloader = creator.ks.bootloader
111eb8dc403SDave Cobbley
112eb8dc403SDave Cobbley            grubefi_conf = ""
113eb8dc403SDave Cobbley            grubefi_conf += "serial --unit=0 --speed=115200 --word=8 "
114eb8dc403SDave Cobbley            grubefi_conf += "--parity=no --stop=1\n"
115eb8dc403SDave Cobbley            grubefi_conf += "default=boot\n"
116eb8dc403SDave Cobbley            grubefi_conf += "timeout=%s\n" % (bootloader.timeout or 10)
117eb8dc403SDave Cobbley            grubefi_conf += "\n"
118eb8dc403SDave Cobbley            grubefi_conf += "search --set=root --label %s " % part.label
119eb8dc403SDave Cobbley            grubefi_conf += "\n"
120eb8dc403SDave Cobbley            grubefi_conf += "menuentry 'boot'{\n"
121eb8dc403SDave Cobbley
12215ae2509SBrad Bishop            kernel = get_bitbake_var("KERNEL_IMAGETYPE")
12396ff1984SBrad Bishop            if get_bitbake_var("INITRAMFS_IMAGE_BUNDLE") == "1":
12496ff1984SBrad Bishop                if get_bitbake_var("INITRAMFS_IMAGE"):
12596ff1984SBrad Bishop                    kernel = "%s-%s.bin" % \
12696ff1984SBrad Bishop                        (get_bitbake_var("KERNEL_IMAGETYPE"), get_bitbake_var("INITRAMFS_LINK_NAME"))
127eb8dc403SDave Cobbley
12815ae2509SBrad Bishop            grubefi_conf += "linux /%s rootwait %s\n" \
129eb8dc403SDave Cobbley                            % (kernel, bootloader.append)
130eb8dc403SDave Cobbley            grubefi_conf += "initrd /initrd \n"
131eb8dc403SDave Cobbley            grubefi_conf += "}\n"
132eb8dc403SDave Cobbley
133eb8dc403SDave Cobbley            if splashline:
134eb8dc403SDave Cobbley                grubefi_conf += "%s\n" % splashline
135eb8dc403SDave Cobbley
136eb8dc403SDave Cobbley        cfg_path = os.path.join(target_dir, "grub.cfg")
137eb8dc403SDave Cobbley        logger.debug("Writing grubefi config %s", cfg_path)
138eb8dc403SDave Cobbley
139eb8dc403SDave Cobbley        with open(cfg_path, "w") as cfg:
140eb8dc403SDave Cobbley            cfg.write(grubefi_conf)
141eb8dc403SDave Cobbley
142eb8dc403SDave Cobbley    @staticmethod
143eb8dc403SDave Cobbley    def _build_initramfs_path(rootfs_dir, cr_workdir):
144eb8dc403SDave Cobbley        """
145eb8dc403SDave Cobbley        Create path for initramfs image
146eb8dc403SDave Cobbley        """
147eb8dc403SDave Cobbley
148eb8dc403SDave Cobbley        initrd = get_bitbake_var("INITRD_LIVE") or get_bitbake_var("INITRD")
149eb8dc403SDave Cobbley        if not initrd:
150eb8dc403SDave Cobbley            initrd_dir = get_bitbake_var("DEPLOY_DIR_IMAGE")
151eb8dc403SDave Cobbley            if not initrd_dir:
152eb8dc403SDave Cobbley                raise WicError("Couldn't find DEPLOY_DIR_IMAGE, exiting.")
153eb8dc403SDave Cobbley
154eb8dc403SDave Cobbley            image_name = get_bitbake_var("IMAGE_BASENAME")
155eb8dc403SDave Cobbley            if not image_name:
156eb8dc403SDave Cobbley                raise WicError("Couldn't find IMAGE_BASENAME, exiting.")
157eb8dc403SDave Cobbley
158eb8dc403SDave Cobbley            image_type = get_bitbake_var("INITRAMFS_FSTYPES")
159eb8dc403SDave Cobbley            if not image_type:
160eb8dc403SDave Cobbley                raise WicError("Couldn't find INITRAMFS_FSTYPES, exiting.")
161eb8dc403SDave Cobbley
162eb8dc403SDave Cobbley            machine = os.path.basename(initrd_dir)
163eb8dc403SDave Cobbley
164eb8dc403SDave Cobbley            pattern = '%s/%s*%s.%s' % (initrd_dir, image_name, machine, image_type)
165eb8dc403SDave Cobbley            files = glob.glob(pattern)
166eb8dc403SDave Cobbley            if files:
167eb8dc403SDave Cobbley                initrd = files[0]
168eb8dc403SDave Cobbley
169eb8dc403SDave Cobbley        if not initrd or not os.path.exists(initrd):
170eb8dc403SDave Cobbley            # Create initrd from rootfs directory
171eb8dc403SDave Cobbley            initrd = "%s/initrd.cpio.gz" % cr_workdir
172eb8dc403SDave Cobbley            initrd_dir = "%s/INITRD" % cr_workdir
173eb8dc403SDave Cobbley            shutil.copytree("%s" % rootfs_dir, \
174eb8dc403SDave Cobbley                            "%s" % initrd_dir, symlinks=True)
175eb8dc403SDave Cobbley
176eb8dc403SDave Cobbley            if os.path.isfile("%s/init" % rootfs_dir):
177eb8dc403SDave Cobbley                shutil.copy2("%s/init" % rootfs_dir, "%s/init" % initrd_dir)
178eb8dc403SDave Cobbley            elif os.path.lexists("%s/init" % rootfs_dir):
179eb8dc403SDave Cobbley                os.symlink(os.readlink("%s/init" % rootfs_dir), \
180eb8dc403SDave Cobbley                            "%s/init" % initrd_dir)
181eb8dc403SDave Cobbley            elif os.path.isfile("%s/sbin/init" % rootfs_dir):
182eb8dc403SDave Cobbley                shutil.copy2("%s/sbin/init" % rootfs_dir, \
183eb8dc403SDave Cobbley                            "%s" % initrd_dir)
184eb8dc403SDave Cobbley            elif os.path.lexists("%s/sbin/init" % rootfs_dir):
185eb8dc403SDave Cobbley                os.symlink(os.readlink("%s/sbin/init" % rootfs_dir), \
186eb8dc403SDave Cobbley                            "%s/init" % initrd_dir)
187eb8dc403SDave Cobbley            else:
188eb8dc403SDave Cobbley                raise WicError("Couldn't find or build initrd, exiting.")
189eb8dc403SDave Cobbley
1901a4b7ee2SBrad Bishop            exec_cmd("cd %s && find . | cpio -o -H newc -R root:root >%s/initrd.cpio " \
1911a4b7ee2SBrad Bishop                     % (initrd_dir, cr_workdir), as_shell=True)
1921a4b7ee2SBrad Bishop            exec_cmd("gzip -f -9 %s/initrd.cpio" % cr_workdir, as_shell=True)
193eb8dc403SDave Cobbley            shutil.rmtree(initrd_dir)
194eb8dc403SDave Cobbley
195eb8dc403SDave Cobbley        return initrd
196eb8dc403SDave Cobbley
197eb8dc403SDave Cobbley    @classmethod
198eb8dc403SDave Cobbley    def do_configure_partition(cls, part, source_params, creator, cr_workdir,
199eb8dc403SDave Cobbley                               oe_builddir, bootimg_dir, kernel_dir,
200eb8dc403SDave Cobbley                               native_sysroot):
201eb8dc403SDave Cobbley        """
202eb8dc403SDave Cobbley        Called before do_prepare_partition(), creates loader-specific config
203eb8dc403SDave Cobbley        """
204eb8dc403SDave Cobbley        isodir = "%s/ISO/" % cr_workdir
205eb8dc403SDave Cobbley
206eb8dc403SDave Cobbley        if os.path.exists(isodir):
207eb8dc403SDave Cobbley            shutil.rmtree(isodir)
208eb8dc403SDave Cobbley
209eb8dc403SDave Cobbley        install_cmd = "install -d %s " % isodir
210eb8dc403SDave Cobbley        exec_cmd(install_cmd)
211eb8dc403SDave Cobbley
212eb8dc403SDave Cobbley        # Overwrite the name of the created image
213eb8dc403SDave Cobbley        logger.debug(source_params)
214eb8dc403SDave Cobbley        if 'image_name' in source_params and \
215eb8dc403SDave Cobbley                    source_params['image_name'].strip():
216eb8dc403SDave Cobbley            creator.name = source_params['image_name'].strip()
217eb8dc403SDave Cobbley            logger.debug("The name of the image is: %s", creator.name)
218eb8dc403SDave Cobbley
219*6ce62a20SAndrew Geissler    @staticmethod
220*6ce62a20SAndrew Geissler    def _install_payload(source_params, iso_dir):
221*6ce62a20SAndrew Geissler        """
222*6ce62a20SAndrew Geissler        Copies contents of payload directory (as specified in 'payload_dir' param) into iso_dir
223*6ce62a20SAndrew Geissler        """
224*6ce62a20SAndrew Geissler
225*6ce62a20SAndrew Geissler        if source_params.get('payload_dir'):
226*6ce62a20SAndrew Geissler            payload_dir = source_params['payload_dir']
227*6ce62a20SAndrew Geissler
228*6ce62a20SAndrew Geissler            logger.debug("Payload directory: %s", payload_dir)
229*6ce62a20SAndrew Geissler            shutil.copytree(payload_dir, iso_dir, symlinks=True, dirs_exist_ok=True)
230*6ce62a20SAndrew Geissler
231eb8dc403SDave Cobbley    @classmethod
232eb8dc403SDave Cobbley    def do_prepare_partition(cls, part, source_params, creator, cr_workdir,
233eb8dc403SDave Cobbley                             oe_builddir, bootimg_dir, kernel_dir,
234eb8dc403SDave Cobbley                             rootfs_dir, native_sysroot):
235eb8dc403SDave Cobbley        """
236eb8dc403SDave Cobbley        Called to do the actual content population for a partition i.e. it
237eb8dc403SDave Cobbley        'prepares' the partition to be incorporated into the image.
238eb8dc403SDave Cobbley        In this case, prepare content for a bootable ISO image.
239eb8dc403SDave Cobbley        """
240eb8dc403SDave Cobbley
241eb8dc403SDave Cobbley        isodir = "%s/ISO" % cr_workdir
242eb8dc403SDave Cobbley
243*6ce62a20SAndrew Geissler        cls._install_payload(source_params, isodir)
244*6ce62a20SAndrew Geissler
245eb8dc403SDave Cobbley        if part.rootfs_dir is None:
246eb8dc403SDave Cobbley            if not 'ROOTFS_DIR' in rootfs_dir:
247eb8dc403SDave Cobbley                raise WicError("Couldn't find --rootfs-dir, exiting.")
248eb8dc403SDave Cobbley            rootfs_dir = rootfs_dir['ROOTFS_DIR']
249eb8dc403SDave Cobbley        else:
250eb8dc403SDave Cobbley            if part.rootfs_dir in rootfs_dir:
251eb8dc403SDave Cobbley                rootfs_dir = rootfs_dir[part.rootfs_dir]
252eb8dc403SDave Cobbley            elif part.rootfs_dir:
253eb8dc403SDave Cobbley                rootfs_dir = part.rootfs_dir
254eb8dc403SDave Cobbley            else:
255eb8dc403SDave Cobbley                raise WicError("Couldn't find --rootfs-dir=%s connection "
256eb8dc403SDave Cobbley                               "or it is not a valid path, exiting." %
257eb8dc403SDave Cobbley                               part.rootfs_dir)
258eb8dc403SDave Cobbley
259eb8dc403SDave Cobbley        if not os.path.isdir(rootfs_dir):
260eb8dc403SDave Cobbley            rootfs_dir = get_bitbake_var("IMAGE_ROOTFS")
261eb8dc403SDave Cobbley        if not os.path.isdir(rootfs_dir):
262eb8dc403SDave Cobbley            raise WicError("Couldn't find IMAGE_ROOTFS, exiting.")
263eb8dc403SDave Cobbley
264eb8dc403SDave Cobbley        part.rootfs_dir = rootfs_dir
265eb8dc403SDave Cobbley        deploy_dir = get_bitbake_var("DEPLOY_DIR_IMAGE")
266eb8dc403SDave Cobbley        img_iso_dir = get_bitbake_var("ISODIR")
267eb8dc403SDave Cobbley
268eb8dc403SDave Cobbley        # Remove the temporary file created by part.prepare_rootfs()
269eb8dc403SDave Cobbley        if os.path.isfile(part.source_file):
270eb8dc403SDave Cobbley            os.remove(part.source_file)
271eb8dc403SDave Cobbley
272eb8dc403SDave Cobbley        # Support using a different initrd other than default
273eb8dc403SDave Cobbley        if source_params.get('initrd'):
274eb8dc403SDave Cobbley            initrd = source_params['initrd']
275eb8dc403SDave Cobbley            if not deploy_dir:
276eb8dc403SDave Cobbley                raise WicError("Couldn't find DEPLOY_DIR_IMAGE, exiting")
277eb8dc403SDave Cobbley            cp_cmd = "cp %s/%s %s" % (deploy_dir, initrd, cr_workdir)
278eb8dc403SDave Cobbley            exec_cmd(cp_cmd)
279eb8dc403SDave Cobbley        else:
280eb8dc403SDave Cobbley            # Prepare initial ramdisk
281eb8dc403SDave Cobbley            initrd = "%s/initrd" % deploy_dir
282eb8dc403SDave Cobbley            if not os.path.isfile(initrd):
283eb8dc403SDave Cobbley                initrd = "%s/initrd" % img_iso_dir
284eb8dc403SDave Cobbley            if not os.path.isfile(initrd):
285eb8dc403SDave Cobbley                initrd = cls._build_initramfs_path(rootfs_dir, cr_workdir)
286eb8dc403SDave Cobbley
287eb8dc403SDave Cobbley        install_cmd = "install -m 0644 %s %s/initrd" % (initrd, isodir)
288eb8dc403SDave Cobbley        exec_cmd(install_cmd)
289eb8dc403SDave Cobbley
290eb8dc403SDave Cobbley        # Remove the temporary file created by _build_initramfs_path function
291eb8dc403SDave Cobbley        if os.path.isfile("%s/initrd.cpio.gz" % cr_workdir):
292eb8dc403SDave Cobbley            os.remove("%s/initrd.cpio.gz" % cr_workdir)
293eb8dc403SDave Cobbley
29415ae2509SBrad Bishop        kernel = get_bitbake_var("KERNEL_IMAGETYPE")
29596ff1984SBrad Bishop        if get_bitbake_var("INITRAMFS_IMAGE_BUNDLE") == "1":
29696ff1984SBrad Bishop            if get_bitbake_var("INITRAMFS_IMAGE"):
29796ff1984SBrad Bishop                kernel = "%s-%s.bin" % \
29896ff1984SBrad Bishop                    (get_bitbake_var("KERNEL_IMAGETYPE"), get_bitbake_var("INITRAMFS_LINK_NAME"))
29915ae2509SBrad Bishop
30015ae2509SBrad Bishop        install_cmd = "install -m 0644 %s/%s %s/%s" % \
30115ae2509SBrad Bishop                      (kernel_dir, kernel, isodir, kernel)
302eb8dc403SDave Cobbley        exec_cmd(install_cmd)
303eb8dc403SDave Cobbley
304eb8dc403SDave Cobbley        #Create bootloader for efi boot
305eb8dc403SDave Cobbley        try:
306eb8dc403SDave Cobbley            target_dir = "%s/EFI/BOOT" % isodir
307eb8dc403SDave Cobbley            if os.path.exists(target_dir):
308eb8dc403SDave Cobbley                shutil.rmtree(target_dir)
309eb8dc403SDave Cobbley
310eb8dc403SDave Cobbley            os.makedirs(target_dir)
311eb8dc403SDave Cobbley
312eb8dc403SDave Cobbley            if source_params['loader'] == 'grub-efi':
313eb8dc403SDave Cobbley                # Builds bootx64.efi/bootia32.efi if ISODIR didn't exist or
314eb8dc403SDave Cobbley                # didn't contains it
315eb8dc403SDave Cobbley                target_arch = get_bitbake_var("TARGET_SYS")
316eb8dc403SDave Cobbley                if not target_arch:
317eb8dc403SDave Cobbley                    raise WicError("Coludn't find target architecture")
318eb8dc403SDave Cobbley
319eb8dc403SDave Cobbley                if re.match("x86_64", target_arch):
320c4ea075dSBrad Bishop                    grub_src_image = "grub-efi-bootx64.efi"
321c4ea075dSBrad Bishop                    grub_dest_image = "bootx64.efi"
322eb8dc403SDave Cobbley                elif re.match('i.86', target_arch):
323c4ea075dSBrad Bishop                    grub_src_image = "grub-efi-bootia32.efi"
324c4ea075dSBrad Bishop                    grub_dest_image = "bootia32.efi"
325eb8dc403SDave Cobbley                else:
326eb8dc403SDave Cobbley                    raise WicError("grub-efi is incompatible with target %s" %
327eb8dc403SDave Cobbley                                   target_arch)
328eb8dc403SDave Cobbley
329c4ea075dSBrad Bishop                grub_target = os.path.join(target_dir, grub_dest_image)
330eb8dc403SDave Cobbley                if not os.path.isfile(grub_target):
331c4ea075dSBrad Bishop                    grub_src = os.path.join(deploy_dir, grub_src_image)
332eb8dc403SDave Cobbley                    if not os.path.exists(grub_src):
333eb8dc403SDave Cobbley                        raise WicError("Grub loader %s is not found in %s. "
3341a4b7ee2SBrad Bishop                                       "Please build grub-efi first" % (grub_src_image, deploy_dir))
335eb8dc403SDave Cobbley                    shutil.copy(grub_src, grub_target)
336eb8dc403SDave Cobbley
337eb8dc403SDave Cobbley                if not os.path.isfile(os.path.join(target_dir, "boot.cfg")):
338eb8dc403SDave Cobbley                    cls.do_configure_grubefi(part, creator, target_dir)
339eb8dc403SDave Cobbley
340eb8dc403SDave Cobbley            else:
341eb8dc403SDave Cobbley                raise WicError("unrecognized bootimg-efi loader: %s" %
342eb8dc403SDave Cobbley                               source_params['loader'])
343eb8dc403SDave Cobbley        except KeyError:
344eb8dc403SDave Cobbley            raise WicError("bootimg-efi requires a loader, none specified")
345eb8dc403SDave Cobbley
346eb8dc403SDave Cobbley        # Create efi.img that contains bootloader files for EFI booting
347eb8dc403SDave Cobbley        # if ISODIR didn't exist or didn't contains it
348eb8dc403SDave Cobbley        if os.path.isfile("%s/efi.img" % img_iso_dir):
349eb8dc403SDave Cobbley            install_cmd = "install -m 0644 %s/efi.img %s/efi.img" % \
350eb8dc403SDave Cobbley                (img_iso_dir, isodir)
351eb8dc403SDave Cobbley            exec_cmd(install_cmd)
352eb8dc403SDave Cobbley        else:
3531d80a2eaSBrad Bishop            # Default to 100 blocks of extra space for file system overhead
3541d80a2eaSBrad Bishop            esp_extra_blocks = int(source_params.get('esp_extra_blocks', '100'))
3551d80a2eaSBrad Bishop
356eb8dc403SDave Cobbley            du_cmd = "du -bks %s/EFI" % isodir
357eb8dc403SDave Cobbley            out = exec_cmd(du_cmd)
358eb8dc403SDave Cobbley            blocks = int(out.split()[0])
3591d80a2eaSBrad Bishop            blocks += esp_extra_blocks
360eb8dc403SDave Cobbley            logger.debug("Added 100 extra blocks to %s to get to %d "
361eb8dc403SDave Cobbley                         "total blocks", part.mountpoint, blocks)
362eb8dc403SDave Cobbley
363eb8dc403SDave Cobbley            # dosfs image for EFI boot
364eb8dc403SDave Cobbley            bootimg = "%s/efi.img" % isodir
365eb8dc403SDave Cobbley
3661d80a2eaSBrad Bishop            esp_label = source_params.get('esp_label', 'EFIimg')
3671d80a2eaSBrad Bishop
3681d80a2eaSBrad Bishop            dosfs_cmd = 'mkfs.vfat -n \'%s\' -S 512 -C %s %d' \
3691d80a2eaSBrad Bishop                        % (esp_label, bootimg, blocks)
370eb8dc403SDave Cobbley            exec_native_cmd(dosfs_cmd, native_sysroot)
371eb8dc403SDave Cobbley
372eb8dc403SDave Cobbley            mmd_cmd = "mmd -i %s ::/EFI" % bootimg
373eb8dc403SDave Cobbley            exec_native_cmd(mmd_cmd, native_sysroot)
374eb8dc403SDave Cobbley
375eb8dc403SDave Cobbley            mcopy_cmd = "mcopy -i %s -s %s/EFI/* ::/EFI/" \
376eb8dc403SDave Cobbley                        % (bootimg, isodir)
377eb8dc403SDave Cobbley            exec_native_cmd(mcopy_cmd, native_sysroot)
378eb8dc403SDave Cobbley
379eb8dc403SDave Cobbley            chmod_cmd = "chmod 644 %s" % bootimg
380eb8dc403SDave Cobbley            exec_cmd(chmod_cmd)
381eb8dc403SDave Cobbley
382eb8dc403SDave Cobbley        # Prepare files for legacy boot
383eb8dc403SDave Cobbley        syslinux_dir = get_bitbake_var("STAGING_DATADIR")
384eb8dc403SDave Cobbley        if not syslinux_dir:
385eb8dc403SDave Cobbley            raise WicError("Couldn't find STAGING_DATADIR, exiting.")
386eb8dc403SDave Cobbley
387eb8dc403SDave Cobbley        if os.path.exists("%s/isolinux" % isodir):
388eb8dc403SDave Cobbley            shutil.rmtree("%s/isolinux" % isodir)
389eb8dc403SDave Cobbley
390eb8dc403SDave Cobbley        install_cmd = "install -d %s/isolinux" % isodir
391eb8dc403SDave Cobbley        exec_cmd(install_cmd)
392eb8dc403SDave Cobbley
393eb8dc403SDave Cobbley        cls.do_configure_syslinux(creator, cr_workdir)
394eb8dc403SDave Cobbley
395eb8dc403SDave Cobbley        install_cmd = "install -m 444 %s/syslinux/ldlinux.sys " % syslinux_dir
396eb8dc403SDave Cobbley        install_cmd += "%s/isolinux/ldlinux.sys" % isodir
397eb8dc403SDave Cobbley        exec_cmd(install_cmd)
398eb8dc403SDave Cobbley
399eb8dc403SDave Cobbley        install_cmd = "install -m 444 %s/syslinux/isohdpfx.bin " % syslinux_dir
400eb8dc403SDave Cobbley        install_cmd += "%s/isolinux/isohdpfx.bin" % isodir
401eb8dc403SDave Cobbley        exec_cmd(install_cmd)
402eb8dc403SDave Cobbley
403eb8dc403SDave Cobbley        install_cmd = "install -m 644 %s/syslinux/isolinux.bin " % syslinux_dir
404eb8dc403SDave Cobbley        install_cmd += "%s/isolinux/isolinux.bin" % isodir
405eb8dc403SDave Cobbley        exec_cmd(install_cmd)
406eb8dc403SDave Cobbley
407eb8dc403SDave Cobbley        install_cmd = "install -m 644 %s/syslinux/ldlinux.c32 " % syslinux_dir
408eb8dc403SDave Cobbley        install_cmd += "%s/isolinux/ldlinux.c32" % isodir
409eb8dc403SDave Cobbley        exec_cmd(install_cmd)
410eb8dc403SDave Cobbley
411eb8dc403SDave Cobbley        #create ISO image
412eb8dc403SDave Cobbley        iso_img = "%s/tempiso_img.iso" % cr_workdir
413eb8dc403SDave Cobbley        iso_bootimg = "isolinux/isolinux.bin"
414eb8dc403SDave Cobbley        iso_bootcat = "isolinux/boot.cat"
415eb8dc403SDave Cobbley        efi_img = "efi.img"
416eb8dc403SDave Cobbley
417eb8dc403SDave Cobbley        mkisofs_cmd = "mkisofs -V %s " % part.label
418eb8dc403SDave Cobbley        mkisofs_cmd += "-o %s -U " % iso_img
419eb8dc403SDave Cobbley        mkisofs_cmd += "-J -joliet-long -r -iso-level 2 -b %s " % iso_bootimg
420eb8dc403SDave Cobbley        mkisofs_cmd += "-c %s -no-emul-boot -boot-load-size 4 " % iso_bootcat
421eb8dc403SDave Cobbley        mkisofs_cmd += "-boot-info-table -eltorito-alt-boot "
422eb8dc403SDave Cobbley        mkisofs_cmd += "-eltorito-platform 0xEF -eltorito-boot %s " % efi_img
423eb8dc403SDave Cobbley        mkisofs_cmd += "-no-emul-boot %s " % isodir
424eb8dc403SDave Cobbley
425eb8dc403SDave Cobbley        logger.debug("running command: %s", mkisofs_cmd)
426eb8dc403SDave Cobbley        exec_native_cmd(mkisofs_cmd, native_sysroot)
427eb8dc403SDave Cobbley
428eb8dc403SDave Cobbley        shutil.rmtree(isodir)
429eb8dc403SDave Cobbley
430eb8dc403SDave Cobbley        du_cmd = "du -Lbks %s" % iso_img
431eb8dc403SDave Cobbley        out = exec_cmd(du_cmd)
432eb8dc403SDave Cobbley        isoimg_size = int(out.split()[0])
433eb8dc403SDave Cobbley
434eb8dc403SDave Cobbley        part.size = isoimg_size
435eb8dc403SDave Cobbley        part.source_file = iso_img
436eb8dc403SDave Cobbley
437eb8dc403SDave Cobbley    @classmethod
438eb8dc403SDave Cobbley    def do_install_disk(cls, disk, disk_name, creator, workdir, oe_builddir,
439eb8dc403SDave Cobbley                        bootimg_dir, kernel_dir, native_sysroot):
440eb8dc403SDave Cobbley        """
441eb8dc403SDave Cobbley        Called after all partitions have been prepared and assembled into a
442eb8dc403SDave Cobbley        disk image.  In this case, we insert/modify the MBR using isohybrid
443eb8dc403SDave Cobbley        utility for booting via BIOS from disk storage devices.
444eb8dc403SDave Cobbley        """
445eb8dc403SDave Cobbley
446eb8dc403SDave Cobbley        iso_img = "%s.p1" % disk.path
447eb8dc403SDave Cobbley        full_path = creator._full_path(workdir, disk_name, "direct")
448eb8dc403SDave Cobbley        full_path_iso = creator._full_path(workdir, disk_name, "iso")
449eb8dc403SDave Cobbley
450eb8dc403SDave Cobbley        isohybrid_cmd = "isohybrid -u %s" % iso_img
451eb8dc403SDave Cobbley        logger.debug("running command: %s", isohybrid_cmd)
452eb8dc403SDave Cobbley        exec_native_cmd(isohybrid_cmd, native_sysroot)
453eb8dc403SDave Cobbley
454eb8dc403SDave Cobbley        # Replace the image created by direct plugin with the one created by
455eb8dc403SDave Cobbley        # mkisofs command. This is necessary because the iso image created by
456eb8dc403SDave Cobbley        # mkisofs has a very specific MBR is system area of the ISO image, and
457eb8dc403SDave Cobbley        # direct plugin adds and configures an another MBR.
458eb8dc403SDave Cobbley        logger.debug("Replaceing the image created by direct plugin\n")
459eb8dc403SDave Cobbley        os.remove(disk.path)
460eb8dc403SDave Cobbley        shutil.copy2(iso_img, full_path_iso)
461eb8dc403SDave Cobbley        shutil.copy2(full_path_iso, full_path)
462