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