2 # livecd.py : LiveCDImageCreator class for creating Live CD images
4 # Copyright 2007, Red Hat Inc.
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; version 2 of the License.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU Library General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
28 import micng.utils.kickstart as kickstart
29 import micng.utils.fs_related as fs_related
30 import micng.utils.rpmmisc as rpmmisc
31 import micng.utils.misc as misc
32 from micng.utils.errors import *
33 from loop import LoopImageCreator
35 class LiveImageCreatorBase(LoopImageCreator):
36 """A base class for LiveCD image creators.
38 This class serves as a base class for the architecture-specific LiveCD
39 image creator subclass, LiveImageCreator.
41 LiveImageCreator creates a bootable ISO containing the system image,
42 bootloader, bootloader configuration, kernel and initramfs.
45 def __init__(self, creatoropts = None, pkgmgr = None):
46 """Initialise a LiveImageCreator instance.
48 This method takes the same arguments as ImageCreator.__init__().
50 LoopImageCreator.__init__(self, creatoropts, pkgmgr)
52 #Controls whether to use squashfs to compress the image.
53 self.skip_compression = False
55 #Controls whether an image minimizing snapshot should be created.
57 #This snapshot can be used when copying the system image from the ISO in
58 #order to minimize the amount of data that needs to be copied; simply,
59 #it makes it possible to create a version of the image's filesystem with
61 self.skip_minimize = False
63 #A flag which indicates i act as a convertor default false
64 self.actasconvertor = False
66 #The bootloader timeout from kickstart.
68 self._timeout = kickstart.get_timeout(self.ks, 10)
72 #The default kernel type from kickstart.
74 self._default_kernel = kickstart.get_default_kernel(self.ks, "kernel")
76 self._default_kernel = None
81 self.__modules = ["=ata", "sym53c8xx", "aic7xxx", "=usb", "=firewire", "=mmc", "=pcmcia", "mptsas"]
83 self.__modules.extend(kickstart.get_modules(self.ks))
85 self._dep_checks.extend(["isohybrid", "unsquashfs", "mksquashfs", "dd", "genisoimage"])
88 # Hooks for subclasses
90 def _configure_bootloader(self, isodir):
91 """Create the architecture specific booloader configuration.
93 This is the hook where subclasses must create the booloader
94 configuration in order to allow a bootable ISO to be built.
96 isodir -- the directory where the contents of the ISO are to be staged
98 raise CreatorError("Bootloader configuration is arch-specific, "
99 "but not implemented for this arch!")
100 def _get_menu_options(self):
101 """Return a menu options string for syslinux configuration.
104 return "bootinstall autoinst"
105 r = kickstart.get_menu_args(self.ks)
108 def _get_kernel_options(self):
109 """Return a kernel options string for bootloader configuration.
111 This is the hook where subclasses may specify a set of kernel options
112 which should be included in the images bootloader configuration.
114 A sensible default implementation is provided.
117 r = "ro liveimg quiet"
118 if os.path.exists(instroot + "/usr/bin/rhgb"):
120 if os.path.exists(instroot + "/usr/bin/plymouth"):
123 r = kickstart.get_kernel_args(self.ks)
124 if os.path.exists(self._instroot + "/usr/bin/rhgb") or \
125 os.path.exists(self._instroot + "/usr/bin/plymouth"):
129 def _get_mkisofs_options(self, isodir):
130 """Return the architecture specific mkisosfs options.
132 This is the hook where subclasses may specify additional arguments to
133 mkisofs, e.g. to enable a bootable ISO to be built.
135 By default, an empty list is returned.
140 # Helpers for subclasses
142 def _has_checkisomd5(self):
143 """Check whether checkisomd5 is available in the install root."""
144 def exists(instroot, path):
145 return os.path.exists(instroot + path)
147 if (exists(self._instroot, "/usr/lib/moblin-installer-runtime/checkisomd5") or
148 exists(self._instroot, "/usr/bin/checkisomd5")):
149 if (os.path.exists("/usr/bin/implantisomd5") or
150 os.path.exists("/usr/lib/anaconda-runtime/implantisomd5")):
155 def _uncompress_squashfs(self, squashfsimg, outdir):
156 """Uncompress file system from squshfs image"""
157 unsquashfs = fs_related.find_binary_path("unsquashfs")
158 args = [unsquashfs, "-d", outdir, squashfsimg ]
159 rc = subprocess.call(args)
161 raise CreatorError("Failed to uncompress %s." % squashfsimg)
163 # Actual implementation
165 def _base_on(self, base_on):
166 """Support Image Convertor"""
167 if self.actasconvertor:
168 if os.path.exists(base_on) and not os.path.isfile(base_on):
169 ddcmd = fs_related.find_binary_path("dd")
170 args = [ ddcmd, "if=%s" % base_on, "of=%s" % self._image ]
171 print "dd %s -> %s" % (base_on, self._image)
172 rc = subprocess.call(args)
174 raise CreatorError("Failed to dd from %s to %s" % (base_on, self._image))
175 self._set_image_size(misc.get_file_size(self._image) * 1024L * 1024L)
176 if os.path.isfile(base_on):
177 print "Copying file system..."
178 shutil.copyfile(base_on, self._image)
179 self._set_image_size(get_file_size(self._image) * 1024L * 1024L)
182 #helper function to extract ext3 file system from a live CD ISO
183 isoloop = fs_related.DiskMount(fs_related.LoopbackDisk(base_on, 0), self._mkdtemp())
187 except MountError, e:
188 raise CreatorError("Failed to loopback mount '%s' : %s" %
191 # legacy LiveOS filesystem layout support, remove for F9 or F10
192 if os.path.exists(isoloop.mountdir + "/squashfs.img"):
193 squashimg = isoloop.mountdir + "/squashfs.img"
195 squashimg = isoloop.mountdir + "/LiveOS/squashfs.img"
197 tmpoutdir = self._mkdtemp()
198 # unsquashfs requires outdir mustn't exist
199 shutil.rmtree(tmpoutdir, ignore_errors = True)
200 self._uncompress_squashfs(squashimg, tmpoutdir)
203 # legacy LiveOS filesystem layout support, remove for F9 or F10
204 if os.path.exists(tmpoutdir + "/os.img"):
205 os_image = tmpoutdir + "/os.img"
207 os_image = tmpoutdir + "/LiveOS/ext3fs.img"
209 if not os.path.exists(os_image):
210 raise CreatorError("'%s' is not a valid live CD ISO : neither "
211 "LiveOS/ext3fs.img nor os.img exist" %
214 print "Copying file system..."
215 shutil.copyfile(os_image, self._image)
216 self._set_image_size(get_file_size(self._image) * 1024L * 1024L)
218 shutil.rmtree(tmpoutdir, ignore_errors = True)
221 def _mount_instroot(self, base_on = None):
222 LoopImageCreator._mount_instroot(self, base_on)
223 self.__write_initrd_conf(self._instroot + "/etc/sysconfig/mkinitrd")
225 def _unmount_instroot(self):
227 os.unlink(self._instroot + "/etc/sysconfig/mkinitrd")
230 LoopImageCreator._unmount_instroot(self)
232 def __ensure_isodir(self):
233 if self.__isodir is None:
234 self.__isodir = self._mkdtemp("iso-")
237 def _get_isodir(self):
238 return self.__ensure_isodir()
240 def _set_isodir(self, isodir = None):
241 self.__isodir = isodir
243 def _create_bootconfig(self):
244 """Configure the image so that it's bootable."""
245 self._configure_bootloader(self.__ensure_isodir())
247 def _get_post_scripts_env(self, in_chroot):
248 env = LoopImageCreator._get_post_scripts_env(self, in_chroot)
251 env["LIVE_ROOT"] = self.__ensure_isodir()
255 def __write_initrd_conf(self, path):
257 if not os.path.exists(os.path.dirname(path)):
258 fs_related.makedirs(os.path.dirname(path))
261 content += 'LIVEOS="yes"\n'
262 content += 'PROBE="no"\n'
263 content += 'MODULES+="squashfs ext3 ext2 vfat msdos "\n'
264 content += 'MODULES+="sr_mod sd_mod ide-cd cdrom "\n'
266 for module in self.__modules:
268 content += 'MODULES+="ehci_hcd uhci_hcd ohci_hcd "\n'
269 content += 'MODULES+="usb_storage usbhid "\n'
270 elif module == "=firewire":
271 content += 'MODULES+="firewire-sbp2 firewire-ohci "\n'
272 content += 'MODULES+="sbp2 ohci1394 ieee1394 "\n'
273 elif module == "=mmc":
274 content += 'MODULES+="mmc_block sdhci sdhci-pci "\n'
275 elif module == "=pcmcia":
276 content += 'MODULES+="pata_pcmcia "\n'
278 content += 'MODULES+="' + module + ' "\n'
282 def __create_iso(self, isodir):
283 iso = self._outdir + "/" + self.name + ".iso"
284 genisoimage = fs_related.find_binary_path("genisoimage")
287 "-hide-rr-moved", "-hide-joliet-trans-tbl",
291 args.extend(self._get_mkisofs_options(isodir))
295 if subprocess.call(args) != 0:
296 raise CreatorError("ISO creation failed!")
298 """ It should be ok still even if you haven't isohybrid """
301 isohybrid = fs_related.find_binary_path("isohybrid")
306 args = [isohybrid, "-partok", iso ]
307 if subprocess.call(args) != 0:
308 raise CreatorError("Hybrid ISO creation failed!")
310 self.__implant_md5sum(iso)
312 def __implant_md5sum(self, iso):
313 """Implant an isomd5sum."""
314 if os.path.exists("/usr/bin/implantisomd5"):
315 implantisomd5 = "/usr/bin/implantisomd5"
316 elif os.path.exists("/usr/lib/anaconda-runtime/implantisomd5"):
317 implantisomd5 = "/usr/lib/anaconda-runtime/implantisomd5"
319 logging.warn("isomd5sum not installed; not setting up mediacheck")
323 subprocess.call([implantisomd5, iso], stdout=sys.stdout, stderr=sys.stderr)
325 def _stage_final_image(self):
327 fs_related.makedirs(self.__ensure_isodir() + "/LiveOS")
329 minimal_size = self._resparse()
331 if not self.skip_minimize:
332 fs_related.create_image_minimizer(self.__isodir + "/LiveOS/osmin.img",
333 self._image, minimal_size)
335 if self.skip_compression:
336 shutil.move(self._image, self.__isodir + "/LiveOS/ext3fs.img")
338 fs_related.makedirs(os.path.join(os.path.dirname(self._image), "LiveOS"))
339 shutil.move(self._image,
340 os.path.join(os.path.dirname(self._image),
341 "LiveOS", "ext3fs.img"))
342 fs_related.mksquashfs(os.path.dirname(self._image),
343 self.__isodir + "/LiveOS/squashfs.img")
345 self.__create_iso(self.__isodir)
347 shutil.rmtree(self.__isodir, ignore_errors = True)
350 class x86LiveImageCreator(LiveImageCreatorBase):
351 """ImageCreator for x86 machines"""
352 def _get_mkisofs_options(self, isodir):
353 return [ "-b", "isolinux/isolinux.bin",
354 "-c", "isolinux/boot.cat",
355 "-no-emul-boot", "-boot-info-table",
356 "-boot-load-size", "4" ]
358 def _get_required_packages(self):
359 return ["syslinux", "syslinux-extlinux"] + LiveImageCreatorBase._get_required_packages(self)
361 def _get_isolinux_stanzas(self, isodir):
364 def __find_syslinux_menu(self):
365 for menu in ["vesamenu.c32", "menu.c32"]:
366 if os.path.isfile(self._instroot + "/usr/share/syslinux/" + menu):
369 raise CreatorError("syslinux not installed : "
370 "no suitable /usr/share/syslinux/*menu.c32 found")
372 def __find_syslinux_mboot(self):
374 # We only need the mboot module if we have any xen hypervisors
376 if not glob.glob(self._instroot + "/boot/xen.gz*"):
381 def __copy_syslinux_files(self, isodir, menu, mboot = None):
382 files = ["isolinux.bin", menu]
387 path = self._instroot + "/usr/share/syslinux/" + f
389 if not os.path.isfile(path):
390 raise CreatorError("syslinux not installed : "
391 "%s not found" % path)
393 shutil.copy(path, isodir + "/isolinux/")
395 def __copy_syslinux_background(self, isodest):
396 background_path = self._instroot + \
397 "/usr/lib/anaconda-runtime/syslinux-vesa-splash.jpg"
399 if not os.path.exists(background_path):
402 shutil.copyfile(background_path, isodest)
406 def __copy_kernel_and_initramfs(self, isodir, version, index):
407 bootdir = self._instroot + "/boot"
409 if self._alt_initrd_name:
410 src_initrd_path = os.path.join(bootdir, self._alt_initrd_name)
412 src_initrd_path = os.path.join(bootdir, "initrd-" + version + ".img")
415 shutil.copyfile(bootdir + "/vmlinuz-" + version,
416 isodir + "/isolinux/vmlinuz" + index)
417 shutil.copyfile(src_initrd_path,
418 isodir + "/isolinux/initrd" + index + ".img")
420 raise CreatorError("Unable to copy valid kernels or initrds, please check the repo")
423 if os.path.exists(bootdir + "/xen.gz-" + version[:-3]):
424 shutil.copyfile(bootdir + "/xen.gz-" + version[:-3],
425 isodir + "/isolinux/xen" + index + ".gz")
430 def __is_default_kernel(self, kernel, kernels):
431 if len(kernels) == 1:
434 if kernel == self._default_kernel:
437 if kernel.startswith("kernel-") and kernel[7:] == self._default_kernel:
442 def __get_basic_syslinux_config(self, **args):
448 menu title Welcome to %(distroname)s!
449 menu color border 0 #ffffffff #00000000
450 menu color sel 7 #ffffffff #ff000000
451 menu color title 0 #ffffffff #00000000
452 menu color tabmsg 0 #ffffffff #00000000
453 menu color unsel 0 #ffffffff #00000000
454 menu color hotsel 0 #ff000000 #ffffffff
455 menu color hotkey 7 #ffffffff #ff000000
456 menu color timeout_msg 0 #ffffffff #00000000
457 menu color timeout 0 #ffffffff #00000000
458 menu color cmdline 0 #ffffffff #00000000
461 def __get_image_stanza(self, is_xen, **args):
463 template = """label %(short)s
465 kernel vmlinuz%(index)s
466 append initrd=initrd%(index)s.img root=CDLABEL=%(fslabel)s rootfstype=iso9660 %(liveargs)s %(extra)s
469 template = """label %(short)s
472 append xen%(index)s.gz --- vmlinuz%(index)s root=CDLABEL=%(fslabel)s rootfstype=iso9660 %(liveargs)s %(extra)s --- initrd%(index)s.img
474 return template % args
476 def __get_image_stanzas(self, isodir):
478 kernels = self._get_kernel_versions()
479 for kernel in kernels:
480 for version in kernels[kernel]:
481 versions.append(version)
484 raise CreatorError("Unable to find valid kernels, please check the repo")
486 kernel_options = self._get_kernel_options()
488 """ menu can be customized highly, the format is
490 short_name1:long_name1:extra_options1;short_name2:long_name2:extra_options2
492 for example: autoinst:Installation only:systemd.unit=installer-graphical.service
493 but in order to keep compatible with old format, these are still ok:
497 liveinst::;autoinst::
499 oldmenus = {"basic":{"short":"basic", "long":"Installation Only (Text based)", "extra":"basic nosplash 4"},
500 "liveinst":{"short":"liveinst", "long":"Installation Only", "extra":"liveinst nosplash 4"},
501 "autoinst":{"short":"autoinst", "long":"Autoinstall (Deletes all existing content)", "extra":"autoinst nosplash 4"},
502 "netinst":{"short":"netinst", "long":"Network Installation", "extra":"netinst 4"},
503 "verify":{"short":"check", "long":"Verify and", "extra":"check"}
505 menu_options = self._get_menu_options()
506 menus = menu_options.split(";")
507 for i in range(len(menus)):
508 menus[i] = menus[i].split(":")
509 if len(menus) == 1 and len(menus[0]) == 1:
510 """ Keep compatible with the old usage way """
511 menus = menu_options.split()
512 for i in range(len(menus)):
513 menus[i] = [menus[i]]
517 default_version = None
521 for version in versions:
522 is_xen = self.__copy_kernel_and_initramfs(isodir, version, index)
524 default = self.__is_default_kernel(kernel, kernels)
528 long = "Boot %s" % self.distro_name
529 elif kernel.startswith("kernel-"):
530 long = "Boot %s(%s)" % (self.name, kernel[7:])
532 long = "Boot %s(%s)" % (self.name, kernel)
533 oldmenus["verify"]["long"] = "%s %s" % (oldmenus["verify"]["long"], long)
535 cfg += self.__get_image_stanza(is_xen,
536 fslabel = self.fslabel,
537 liveargs = kernel_options,
539 short = "linux" + index,
544 cfg += "menu default\n"
545 default_version = version
546 default_index = index
551 short = menu[0] + index
556 if menu[0] in oldmenus.keys():
557 if menu[0] == "verify" and not self._has_checkisomd5():
559 if menu[0] == "netinst":
560 netinst = oldmenus[menu[0]]
562 long = oldmenus[menu[0]]["long"]
563 extra = oldmenus[menu[0]]["extra"]
565 long = short.upper() + " X" + index
571 cfg += self.__get_image_stanza(is_xen,
572 fslabel = self.fslabel,
573 liveargs = kernel_options,
579 index = str(int(index) + 1)
581 if not default_version:
582 default_version = versions[0]
583 if not default_index:
587 cfg += self.__get_image_stanza(is_xen,
588 fslabel = self.fslabel,
589 liveargs = kernel_options,
590 long = netinst["long"],
591 short = netinst["short"],
592 extra = netinst["extra"],
593 index = default_index)
597 def __get_memtest_stanza(self, isodir):
598 memtest = glob.glob(self._instroot + "/boot/memtest86*")
602 shutil.copyfile(memtest[0], isodir + "/isolinux/memtest")
604 return """label memtest
605 menu label Memory Test
609 def __get_local_stanza(self, isodir):
610 return """label local
611 menu label Boot from local drive
615 def _configure_syslinux_bootloader(self, isodir):
616 """configure the boot loader"""
617 fs_related.makedirs(isodir + "/isolinux")
619 menu = self.__find_syslinux_menu()
621 self.__copy_syslinux_files(isodir, menu,
622 self.__find_syslinux_mboot())
625 if self.__copy_syslinux_background(isodir + "/isolinux/splash.jpg"):
626 background = "menu background splash.jpg"
628 cfg = self.__get_basic_syslinux_config(menu = menu,
629 background = background,
631 timeout = self._timeout * 10,
632 distroname = self.distro_name)
634 cfg += self.__get_image_stanzas(isodir)
635 cfg += self.__get_memtest_stanza(isodir)
636 cfg += self.__get_local_stanza(isodir)
637 cfg += self._get_isolinux_stanzas(isodir)
639 cfgf = open(isodir + "/isolinux/isolinux.cfg", "w")
643 def __copy_efi_files(self, isodir):
644 if not os.path.exists(self._instroot + "/boot/efi/EFI/redhat/grub.efi"):
646 shutil.copy(self._instroot + "/boot/efi/EFI/redhat/grub.efi",
647 isodir + "/EFI/boot/grub.efi")
648 shutil.copy(self._instroot + "/boot/grub/splash.xpm.gz",
649 isodir + "/EFI/boot/splash.xpm.gz")
653 def __get_basic_efi_config(self, **args):
656 splashimage=/EFI/boot/splash.xpm.gz
662 def __get_efi_image_stanza(self, **args):
663 return """title %(long)s
664 kernel /EFI/boot/vmlinuz%(index)s root=CDLABEL=%(fslabel)s rootfstype=iso9660 %(liveargs)s %(extra)s
665 initrd /EFI/boot/initrd%(index)s.img
668 def __get_efi_image_stanzas(self, isodir, name):
669 # FIXME: this only supports one kernel right now...
671 kernel_options = self._get_kernel_options()
672 checkisomd5 = self._has_checkisomd5()
676 for index in range(0, 9):
677 # we don't support xen kernels
678 if os.path.exists("%s/EFI/boot/xen%d.gz" %(isodir, index)):
680 cfg += self.__get_efi_image_stanza(fslabel = self.fslabel,
681 liveargs = kernel_options,
683 extra = "", index = index)
685 cfg += self.__get_efi_image_stanza(fslabel = self.fslabel,
686 liveargs = kernel_options,
687 long = "Verify and Boot " + name,
694 def _configure_efi_bootloader(self, isodir):
695 """Set up the configuration for an EFI bootloader"""
696 fs_related.makedirs(isodir + "/EFI/boot")
698 if not self.__copy_efi_files(isodir):
699 shutil.rmtree(isodir + "/EFI")
702 for f in os.listdir(isodir + "/isolinux"):
703 os.link("%s/isolinux/%s" %(isodir, f),
704 "%s/EFI/boot/%s" %(isodir, f))
707 cfg = self.__get_basic_efi_config(name = self.name,
708 timeout = self._timeout)
709 cfg += self.__get_efi_image_stanzas(isodir, self.name)
711 cfgf = open(isodir + "/EFI/boot/grub.conf", "w")
715 # first gen mactel machines get the bootloader name wrong apparently
716 if rpmmisc.getBaseArch() == "i386":
717 os.link(isodir + "/EFI/boot/grub.efi", isodir + "/EFI/boot/boot.efi")
718 os.link(isodir + "/EFI/boot/grub.conf", isodir + "/EFI/boot/boot.conf")
720 # for most things, we want them named boot$efiarch
721 efiarch = {"i386": "ia32", "x86_64": "x64"}
722 efiname = efiarch[rpmmisc.getBaseArch()]
723 os.rename(isodir + "/EFI/boot/grub.efi", isodir + "/EFI/boot/boot%s.efi" %(efiname,))
724 os.link(isodir + "/EFI/boot/grub.conf", isodir + "/EFI/boot/boot%s.conf" %(efiname,))
727 def _configure_bootloader(self, isodir):
728 self._configure_syslinux_bootloader(isodir)
729 self._configure_efi_bootloader(isodir)
731 class ppcLiveImageCreator(LiveImageCreatorBase):
732 def _get_mkisofs_options(self, isodir):
733 return [ "-hfs", "-nodesktop", "-part"
734 "-map", isodir + "/ppc/mapping",
735 "-hfs-bless", isodir + "/ppc/mac",
736 "-hfs-volid", self.fslabel ]
738 def _get_required_packages(self):
739 return ["yaboot"] + \
740 LiveImageCreatorBase._get_required_packages(self)
742 def _get_excluded_packages(self):
743 # kind of hacky, but exclude memtest86+ on ppc so it can stay in cfg
744 return ["memtest86+"] + \
745 LiveImageCreatorBase._get_excluded_packages(self)
747 def __copy_boot_file(self, destdir, file):
748 for dir in ["/usr/share/ppc64-utils",
749 "/usr/lib/moblin-installer-runtime/boot"]:
750 path = self._instroot + dir + "/" + file
751 if not os.path.exists(path):
754 fs_related.makedirs(destdir)
755 shutil.copy(path, destdir)
758 raise CreatorError("Unable to find boot file " + file)
760 def __kernel_bits(self, kernel):
761 testpath = (self._instroot + "/lib/modules/" +
762 kernel + "/kernel/arch/powerpc/platforms")
764 if not os.path.exists(testpath):
765 return { "32" : True, "64" : False }
767 return { "32" : False, "64" : True }
769 def __copy_kernel_and_initramfs(self, destdir, version):
770 bootdir = self._instroot + "/boot"
772 fs_related.makedirs(destdir)
774 shutil.copyfile(bootdir + "/vmlinuz-" + version,
775 destdir + "/vmlinuz")
777 shutil.copyfile(bootdir + "/initrd-" + version + ".img",
778 destdir + "/initrd.img")
780 def __get_basic_yaboot_config(self, **args):
782 init-message = "Welcome to %(distroname)s!"
786 def __get_image_stanza(self, **args):
789 image=/ppc/ppc%(bit)s/vmlinuz
791 initrd=/ppc/ppc%(bit)s/initrd.img
793 append="root=CDLABEL=%(fslabel)s rootfstype=iso9660 %(liveargs)s %(extra)s"
797 def __write_yaboot_config(isodir, bit):
798 cfg = self.__get_basic_yaboot_config(name = self.name,
799 timeout = self._timeout * 100,
800 distroname = self.distro_name)
802 kernel_options = self._get_kernel_options()
804 cfg += self.__get_image_stanza(fslabel = self.fslabel,
806 long = "Run from image",
809 liveargs = kernel_options)
811 if self._has_checkisomd5():
812 cfg += self.__get_image_stanza(fslabel = self.fslabel,
814 long = "Verify and run from image",
817 liveargs = kernel_options)
819 f = open(isodir + "/ppc/ppc" + bit + "/yaboot.conf", "w")
823 def __write_not_supported(isodir, bit):
824 fs_related.makedirs(isodir + "/ppc/ppc" + bit)
826 message = "Sorry, this LiveCD does not support your hardware"
828 f = open(isodir + "/ppc/ppc" + bit + "/yaboot.conf", "w")
829 f.write('init-message = "' + message + '"')
833 def __write_dualbits_yaboot_config(isodir, **args):
835 init-message = "\nWelcome to %(name)s!\nUse 'linux32' for 32-bit kernel.\n\n"
839 image=/ppc/ppc64/vmlinuz
842 initrd=/ppc/ppc64/initrd.img
845 image=/ppc/ppc32/vmlinuz
847 initrd=/ppc/ppc32/initrd.img
851 f = open(isodir + "/etc/yaboot.conf", "w")
855 def _configure_bootloader(self, isodir):
856 """configure the boot loader"""
857 havekernel = { 32: False, 64: False }
859 self.__copy_boot_file("mapping", isodir + "/ppc")
860 self.__copy_boot_file("bootinfo.txt", isodir + "/ppc")
861 self.__copy_boot_file("ofboot.b", isodir + "/ppc/mac")
863 shutil.copyfile(self._instroot + "/usr/lib/yaboot/yaboot",
864 isodir + "/ppc/mac/yaboot")
866 fs_related.makedirs(isodir + "/ppc/chrp")
867 shutil.copyfile(self._instroot + "/usr/lib/yaboot/yaboot",
868 isodir + "/ppc/chrp/yaboot")
870 subprocess.call(["/usr/sbin/addnote", isodir + "/ppc/chrp/yaboot"])
873 # FIXME: ppc should support multiple kernels too...
875 kernel = self._get_kernel_versions().values()[0][0]
877 kernel_bits = self.__kernel_bits(kernel)
879 for (bit, present) in kernel_bits.items():
881 self.__write_not_supported(isodir, bit)
884 self.__copy_kernel_and_initramfs(isodir + "/ppc/ppc" + bit, kernel)
885 self.__write_yaboot_config(isodir, bit)
887 fs_related.makedirs(isodir + "/etc")
888 if kernel_bits["32"] and not kernel_bits["64"]:
889 shutil.copyfile(isodir + "/ppc/ppc32/yaboot.conf",
890 isodir + "/etc/yaboot.conf")
891 elif kernel_bits["64"] and not kernel_bits["32"]:
892 shutil.copyfile(isodir + "/ppc/ppc64/yaboot.conf",
893 isodir + "/etc/yaboot.conf")
895 self.__write_dualbits_yaboot_config(isodir,
897 timeout = self._timeout * 100)
900 # FIXME: build 'netboot' images with kernel+initrd, like mk-images.ppc
903 class ppc64LiveImageCreator(ppcLiveImageCreator):
904 def _get_excluded_packages(self):
906 # while kernel.ppc and kernel.ppc64 co-exist,
908 return ["kernel.ppc"] + \
909 ppcLiveImageCreator._get_excluded_packages(self)
911 arch = rpmmisc.getBaseArch()
912 if arch in ("i386", "x86_64"):
913 LiveCDImageCreator = x86LiveImageCreator
914 elif arch in ("ppc",):
915 LiveCDImageCreator = ppcLiveImageCreator
916 elif arch in ("ppc64",):
917 LiveCDImageCreator = ppc64LiveImageCreator
918 elif arch.startswith("arm"):
919 LiveCDImageCreator = LiveImageCreatorBase
921 raise CreatorError("Architecture not supported!")