2 # live.py : LiveImageCreator 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.
26 from imgcreate
.errors
import *
27 from imgcreate
.fs
import *
28 from imgcreate
.creator
import *
30 class LiveImageCreatorBase(LoopImageCreator
):
31 """A base class for LiveCD image creators.
33 This class serves as a base class for the architecture-specific LiveCD
34 image creator subclass, LiveImageCreator.
36 LiveImageCreator creates a bootable ISO containing the system image,
37 bootloader, bootloader configuration, kernel and initramfs.
41 def __init__(self
, *args
):
42 """Initialise a LiveImageCreator instance.
44 This method takes the same arguments as ImageCreator.__init__().
47 LoopImageCreator
.__init
__(self
, *args
)
49 self
.compress_type
= "zlib"
50 """mksquashfs compressor to use."""
52 self
.skip_compression
= False
53 """Controls whether to use squashfs to compress the image."""
55 self
.skip_minimize
= False
56 """Controls whether an image minimizing snapshot should be created.
58 This snapshot can be used when copying the system image from the ISO in
59 order to minimize the amount of data that needs to be copied; simply,
60 it makes it possible to create a version of the image's filesystem with
65 self
._timeout
= kickstart
.get_timeout(self
.ks
, 10)
66 """The bootloader timeout from kickstart."""
68 self
._default
_kernel
= kickstart
.get_default_kernel(self
.ks
, "kernel")
69 """The default kernel type from kickstart."""
73 self
.__modules
= ["=ata", "sym53c8xx", "aic7xxx", "=usb", "=firewire", "=mmc", "=pcmcia", "mptsas", "udf"]
74 self
.__modules
.extend(kickstart
.get_modules(self
.ks
))
76 self
._isofstype
= "iso9660"
79 # Hooks for subclasses
81 def _configure_bootloader(self
, isodir
):
82 """Create the architecture specific booloader configuration.
84 This is the hook where subclasses must create the booloader
85 configuration in order to allow a bootable ISO to be built.
87 isodir -- the directory where the contents of the ISO are to be staged
90 raise CreatorError("Bootloader configuration is arch-specific, "
91 "but not implemented for this arch!")
93 def _get_kernel_options(self
):
94 """Return a kernel options string for bootloader configuration.
96 This is the hook where subclasses may specify a set of kernel options
97 which should be included in the images bootloader configuration.
99 A sensible default implementation is provided.
102 r
= kickstart
.get_kernel_args(self
.ks
)
103 if os
.path
.exists(self
._instroot
+ "/usr/bin/rhgb"):
105 if os
.path
.exists(self
._instroot
+ "/usr/bin/plymouth"):
109 def _get_mkisofs_options(self
, isodir
):
110 """Return the architecture specific mkisosfs options.
112 This is the hook where subclasses may specify additional arguments to
113 mkisofs, e.g. to enable a bootable ISO to be built.
115 By default, an empty list is returned.
121 # Helpers for subclasses
123 def _has_checkisomd5(self
):
124 """Check whether checkisomd5 is available in the install root."""
125 def exists(instroot
, path
):
126 return os
.path
.exists(instroot
+ path
)
128 if (exists(self
._instroot
, "/usr/lib/anaconda-runtime/checkisomd5") or
129 exists(self
._instroot
, "/usr/bin/checkisomd5")):
135 # Actual implementation
137 def _base_on(self
, base_on
):
138 """helper function to extract ext3 file system from a live CD ISO"""
139 isoloop
= DiskMount(LoopbackDisk(base_on
, 0), self
._mkdtemp
())
143 except MountError
, e
:
144 raise CreatorError("Failed to loopback mount '%s' : %s" %
147 # legacy LiveOS filesystem layout support, remove for F9 or F10
148 if os
.path
.exists(isoloop
.mountdir
+ "/squashfs.img"):
149 squashimg
= isoloop
.mountdir
+ "/squashfs.img"
151 squashimg
= isoloop
.mountdir
+ "/LiveOS/squashfs.img"
153 squashloop
= DiskMount(LoopbackDisk(squashimg
, 0), self
._mkdtemp
(), "squashfs")
156 if not squashloop
.disk
.exists():
157 raise CreatorError("'%s' is not a valid live CD ISO : "
158 "squashfs.img doesn't exist" % base_on
)
162 except MountError
, e
:
163 raise CreatorError("Failed to loopback mount squashfs.img "
164 "from '%s' : %s" % (base_on
, e
))
166 # legacy LiveOS filesystem layout support, remove for F9 or F10
167 if os
.path
.exists(squashloop
.mountdir
+ "/os.img"):
168 os_image
= squashloop
.mountdir
+ "/os.img"
170 os_image
= squashloop
.mountdir
+ "/LiveOS/ext3fs.img"
172 if not os
.path
.exists(os_image
):
173 raise CreatorError("'%s' is not a valid live CD ISO : neither "
174 "LiveOS/ext3fs.img nor os.img exist" %
178 shutil
.copyfile(os_image
, self
._image
)
180 raise CreatorError("Failed to copy base live image to %s for modification: %s" %(self
._image
, e
))
185 def _mount_instroot(self
, base_on
= None):
186 LoopImageCreator
._mount
_instroot
(self
, base_on
)
187 self
.__write
_initrd
_conf
(self
._instroot
+ "/etc/sysconfig/mkinitrd")
188 self
.__write
_dracut
_conf
(self
._instroot
+ "/etc/dracut.conf")
190 def _unmount_instroot(self
):
191 self
.__restore
_file
(self
._instroot
+ "/etc/sysconfig/mkinitrd")
192 self
.__restore
_file
(self
._instroot
+ "/etc/dracut.conf")
193 LoopImageCreator
._unmount
_instroot
(self
)
195 def __ensure_isodir(self
):
196 if self
.__isodir
is None:
197 self
.__isodir
= self
._mkdtemp
("iso-")
200 def _create_bootconfig(self
):
201 """Configure the image so that it's bootable."""
202 self
._configure
_bootloader
(self
.__ensure
_isodir
())
204 def _get_post_scripts_env(self
, in_chroot
):
205 env
= LoopImageCreator
._get
_post
_scripts
_env
(self
, in_chroot
)
208 env
["LIVE_ROOT"] = self
.__ensure
_isodir
()
212 def __extra_filesystems(self
):
213 return "squashfs ext4 ext3 ext2 vfat msdos ";
215 def __extra_drivers(self
):
216 retval
= "sr_mod sd_mod ide-cd cdrom "
217 for module
in self
.__modules
:
219 retval
= retval
+ "ehci_hcd uhci_hcd ohci_hcd "
220 retval
= retval
+ "usb_storage usbhid "
221 elif module
== "=firewire":
222 retval
= retval
+ "firewire-sbp2 firewire-ohci "
223 retval
= retval
+ "sbp2 ohci1394 ieee1394 "
224 elif module
== "=mmc":
225 retval
= retval
+ "mmc_block sdhci sdhci-pci "
226 elif module
== "=pcmcia":
227 retval
= retval
+ "pata_pcmcia "
229 retval
= retval
+ module
+ " "
232 def __restore_file(self
,path
):
237 if os
.path
.exists(path
+ '.rpmnew'):
238 os
.rename(path
+ '.rpmnew', path
)
240 def __write_initrd_conf(self
, path
):
241 if not os
.path
.exists(os
.path
.dirname(path
)):
242 makedirs(os
.path
.dirname(path
))
244 f
.write('LIVEOS="yes"\n')
245 f
.write('PROBE="no"\n')
246 f
.write('MODULES+="' + self
.__extra
_filesystems
() + '"\n')
247 f
.write('MODULES+="' + self
.__extra
_drivers
() + '"\n')
250 def __write_dracut_conf(self
, path
):
251 if not os
.path
.exists(os
.path
.dirname(path
)):
252 makedirs(os
.path
.dirname(path
))
254 f
.write('filesystems+="' + self
.__extra
_filesystems
() + ' "\n')
255 f
.write('drivers+="' + self
.__extra
_drivers
() + ' "\n')
258 def __create_iso(self
, isodir
):
259 iso
= self
._outdir
+ "/" + self
.name
+ ".iso"
261 args
= ["/usr/bin/mkisofs",
263 "-hide-rr-moved", "-hide-joliet-trans-tbl",
267 args
.extend(self
._get
_mkisofs
_options
(isodir
))
268 if self
._isofstype
== "udf":
269 args
.append("-allow-limited-size")
273 if subprocess
.call(args
) != 0:
274 raise CreatorError("ISO creation failed!")
276 if os
.path
.exists("/usr/bin/isohybrid"):
277 subprocess
.call(["/usr/bin/isohybrid", iso
])
279 self
.__implant
_md
5sum
(iso
)
281 def __implant_md5sum(self
, iso
):
282 """Implant an isomd5sum."""
283 if os
.path
.exists("/usr/bin/implantisomd5"):
284 implantisomd5
= "/usr/bin/implantisomd5"
285 elif os
.path
.exists("/usr/lib/anaconda-runtime/implantisomd5"):
286 implantisomd5
= "/usr/lib/anaconda-runtime/implantisomd5"
288 logging
.warn("isomd5sum not installed; not setting up mediacheck")
291 subprocess
.call([implantisomd5
, iso
])
293 def _stage_final_image(self
):
295 makedirs(self
.__ensure
_isodir
() + "/LiveOS")
299 if not self
.skip_minimize
:
300 create_image_minimizer(self
.__isodir
+ "/LiveOS/osmin.img", self
._image
, self
.compress_type
)
302 if self
.skip_compression
:
303 shutil
.move(self
._image
, self
.__isodir
+ "/LiveOS/ext3fs.img")
304 if os
.stat(self
.__isodir
+ "/LiveOS/ext3fs.img").st_size
>= 4*1024*1024*1024:
305 self
._isofstype
= "udf"
306 logging
.warn("Switching to UDF due to size of LiveOS/ext3fs.img")
308 makedirs(os
.path
.join(os
.path
.dirname(self
._image
), "LiveOS"))
309 shutil
.move(self
._image
,
310 os
.path
.join(os
.path
.dirname(self
._image
),
311 "LiveOS", "ext3fs.img"))
312 mksquashfs(os
.path
.dirname(self
._image
),
313 self
.__isodir
+ "/LiveOS/squashfs.img",
315 if os
.stat(self
.__isodir
+ "/LiveOS/squashfs.img").st_size
>= 4*1024*1024*1024:
316 self
._isofstype
= "udf"
317 logging
.warn("Switching to UDF due to size of LiveOS/squashfs.img")
320 self
.__create
_iso
(self
.__isodir
)
322 shutil
.rmtree(self
.__isodir
, ignore_errors
= True)
325 class x86LiveImageCreator(LiveImageCreatorBase
):
326 """ImageCreator for x86 machines"""
327 def _get_mkisofs_options(self
, isodir
):
328 return [ "-b", "isolinux/isolinux.bin",
329 "-c", "isolinux/boot.cat",
330 "-no-emul-boot", "-boot-info-table",
331 "-boot-load-size", "4" ]
333 def _get_required_packages(self
):
334 return ["syslinux"] + LiveImageCreatorBase
._get
_required
_packages
(self
)
336 def _get_isolinux_stanzas(self
, isodir
):
339 def __find_syslinux_menu(self
):
340 for menu
in ("vesamenu.c32", "menu.c32"):
341 for dir in ("/usr/lib/syslinux/", "/usr/share/syslinux/"):
342 if os
.path
.isfile(self
._instroot
+ dir + menu
):
345 raise CreatorError("syslinux not installed : "
346 "no suitable *menu.c32 found")
348 def __find_syslinux_mboot(self
):
350 # We only need the mboot module if we have any xen hypervisors
352 if not glob
.glob(self
._instroot
+ "/boot/xen.gz*"):
357 def __copy_syslinux_files(self
, isodir
, menu
, mboot
= None):
358 files
= ["isolinux.bin", menu
]
363 if os
.path
.exists(self
._instroot
+ "/usr/lib/syslinux/" + f
):
364 path
= self
._instroot
+ "/usr/lib/syslinux/" + f
365 elif os
.path
.exists(self
._instroot
+ "/usr/share/syslinux/" + f
):
366 path
= self
._instroot
+ "/usr/share/syslinux/" + f
367 if not os
.path
.isfile(path
):
368 raise CreatorError("syslinux not installed : "
369 "%s not found" % path
)
371 shutil
.copy(path
, isodir
+ "/isolinux/")
373 def __copy_syslinux_background(self
, isodest
):
374 background_path
= self
._instroot
+ \
375 "/usr/share/anaconda/syslinux-vesa-splash.jpg"
377 if not os
.path
.exists(background_path
):
378 # fallback to F13 location
379 background_path
= self
._instroot
+ \
380 "/usr/lib/anaconda-runtime/syslinux-vesa-splash.jpg"
382 if not os
.path
.exists(background_path
):
385 shutil
.copyfile(background_path
, isodest
)
389 def __copy_kernel_and_initramfs(self
, isodir
, version
, index
):
390 bootdir
= self
._instroot
+ "/boot"
392 shutil
.copyfile(bootdir
+ "/vmlinuz-" + version
,
393 isodir
+ "/isolinux/vmlinuz" + index
)
396 if os
.path
.exists(bootdir
+ "/initramfs-" + version
+ ".img"):
397 shutil
.copyfile(bootdir
+ "/initramfs-" + version
+ ".img",
398 isodir
+ "/isolinux/initrd" + index
+ ".img")
401 shutil
.copyfile(bootdir
+ "/initrd-" + version
+ ".img",
402 isodir
+ "/isolinux/initrd" + index
+ ".img")
405 if os
.path
.exists(bootdir
+ "/xen.gz-" + version
[:-3]):
406 shutil
.copyfile(bootdir
+ "/xen.gz-" + version
[:-3],
407 isodir
+ "/isolinux/xen" + index
+ ".gz")
410 return (is_xen
, isDracut
)
412 def __is_default_kernel(self
, kernel
, kernels
):
413 if len(kernels
) == 1:
416 if kernel
== self
._default
_kernel
:
419 if kernel
.startswith("kernel-") and kernel
[7:] == self
._default
_kernel
:
424 def __get_basic_syslinux_config(self
, **args
):
430 menu title Welcome to %(name)s!
431 menu color border 0 #ffffffff #00000000
432 menu color sel 7 #ffffffff #ff000000
433 menu color title 0 #ffffffff #00000000
434 menu color tabmsg 0 #ffffffff #00000000
435 menu color unsel 0 #ffffffff #00000000
436 menu color hotsel 0 #ff000000 #ffffffff
437 menu color hotkey 7 #ffffffff #ff000000
438 menu color timeout_msg 0 #ffffffff #00000000
439 menu color timeout 0 #ffffffff #00000000
440 menu color cmdline 0 #ffffffff #00000000
445 def __get_image_stanza(self
, is_xen
, isDracut
, **args
):
447 args
["rootlabel"] = "live:CDLABEL=%(fslabel)s" % args
449 args
["rootlabel"] = "CDLABEL=%(fslabel)s" % args
452 template
= """label %(short)s
454 kernel vmlinuz%(index)s
455 append initrd=initrd%(index)s.img root=%(rootlabel)s rootfstype=%(isofstype)s %(liveargs)s %(extra)s
458 template
= """label %(short)s
461 append xen%(index)s.gz --- vmlinuz%(index)s root=%(rootlabel)s rootfstype=%(isofstype)s %(liveargs)s %(extra)s --- initrd%(index)s.img
463 return template
% args
465 def __get_image_stanzas(self
, isodir
):
467 kernels
= self
._get
_kernel
_versions
()
468 for kernel
in kernels
:
469 for version
in kernels
[kernel
]:
470 versions
.append(version
)
472 kernel_options
= self
._get
_kernel
_options
()
474 checkisomd5
= self
._has
_checkisomd
5()
479 for version
in versions
:
480 (is_xen
, isDracut
) = self
.__copy
_kernel
_and
_initramfs
(isodir
, version
, index
)
482 self
._isDracut
= isDracut
484 default
= self
.__is
_default
_kernel
(kernel
, kernels
)
488 elif kernel
.startswith("kernel-"):
489 long = "Boot %s(%s)" % (self
.name
, kernel
[7:])
491 long = "Boot %s(%s)" % (self
.name
, kernel
)
494 # tell dracut not to ask for LUKS passwords or activate mdraid sets
496 kern_opts
= kernel_options
+ " rd_NO_LUKS rd_NO_MD rd_NO_DM"
498 kern_opts
= kernel_options
500 cfg
+= self
.__get
_image
_stanza
(is_xen
, isDracut
,
501 fslabel
= self
.fslabel
,
503 liveargs
= kern_opts
,
505 short
= "linux" + index
,
510 cfg
+= "menu default\n"
513 cfg
+= self
.__get
_image
_stanza
(is_xen
, isDracut
,
514 fslabel
= self
.fslabel
,
516 liveargs
= kernel_options
,
517 long = "Verify and " + long,
518 short
= "check" + index
,
522 index
= str(int(index
) + 1)
526 def __get_memtest_stanza(self
, isodir
):
527 memtest
= glob
.glob(self
._instroot
+ "/boot/memtest86*")
531 shutil
.copyfile(memtest
[0], isodir
+ "/isolinux/memtest")
533 return """label memtest
534 menu label Memory Test
538 def __get_local_stanza(self
, isodir
):
539 return """label local
540 menu label Boot from local drive
544 def _configure_syslinux_bootloader(self
, isodir
):
545 """configure the boot loader"""
546 makedirs(isodir
+ "/isolinux")
548 menu
= self
.__find
_syslinux
_menu
()
550 self
.__copy
_syslinux
_files
(isodir
, menu
,
551 self
.__find
_syslinux
_mboot
())
554 if self
.__copy
_syslinux
_background
(isodir
+ "/isolinux/splash.jpg"):
555 background
= "menu background splash.jpg"
557 cfg
= self
.__get
_basic
_syslinux
_config
(menu
= menu
,
558 background
= background
,
560 timeout
= self
._timeout
* 10)
562 cfg
+= self
.__get
_image
_stanzas
(isodir
)
563 cfg
+= self
.__get
_memtest
_stanza
(isodir
)
564 cfg
+= self
.__get
_local
_stanza
(isodir
)
565 cfg
+= self
._get
_isolinux
_stanzas
(isodir
)
567 cfgf
= open(isodir
+ "/isolinux/isolinux.cfg", "w")
571 def __copy_efi_files(self
, isodir
):
572 if not os
.path
.exists(self
._instroot
+ "/boot/efi/EFI/redhat/grub.efi"):
574 shutil
.copy(self
._instroot
+ "/boot/efi/EFI/redhat/grub.efi",
575 isodir
+ "/EFI/boot/grub.efi")
576 shutil
.copy(self
._instroot
+ "/boot/grub/splash.xpm.gz",
577 isodir
+ "/EFI/boot/splash.xpm.gz")
581 def __get_basic_efi_config(self
, **args
):
584 splashimage=/EFI/boot/splash.xpm.gz
590 def __get_efi_image_stanza(self
, **args
):
592 args
["rootlabel"] = "live:LABEL=%(fslabel)s" % args
594 args
["rootlabel"] = "CDLABEL=%(fslabel)s" % args
595 return """title %(long)s
596 kernel /EFI/boot/vmlinuz%(index)s root=%(rootlabel)s rootfstype=%(isofstype)s %(liveargs)s %(extra)s
597 initrd /EFI/boot/initrd%(index)s.img
600 def __get_efi_image_stanzas(self
, isodir
, name
):
601 # FIXME: this only supports one kernel right now...
603 kernel_options
= self
._get
_kernel
_options
()
604 checkisomd5
= self
._has
_checkisomd
5()
608 for index
in range(0, 9):
609 # we don't support xen kernels
610 if os
.path
.exists("%s/EFI/boot/xen%d.gz" %(isodir
, index
)):
612 cfg
+= self
.__get
_efi
_image
_stanza
(fslabel
= self
.fslabel
,
614 liveargs
= kernel_options
,
616 extra
= "", index
= index
)
618 cfg
+= self
.__get
_efi
_image
_stanza
(fslabel
= self
.fslabel
,
620 liveargs
= kernel_options
,
621 long = "Verify and Boot " + name
,
628 def _configure_efi_bootloader(self
, isodir
):
629 """Set up the configuration for an EFI bootloader"""
630 makedirs(isodir
+ "/EFI/boot")
632 if not self
.__copy
_efi
_files
(isodir
):
633 shutil
.rmtree(isodir
+ "/EFI")
636 for f
in os
.listdir(isodir
+ "/isolinux"):
637 os
.link("%s/isolinux/%s" %(isodir
, f
),
638 "%s/EFI/boot/%s" %(isodir
, f
))
641 cfg
= self
.__get
_basic
_efi
_config
(name
= self
.name
,
642 timeout
= self
._timeout
)
643 cfg
+= self
.__get
_efi
_image
_stanzas
(isodir
, self
.name
)
645 cfgf
= open(isodir
+ "/EFI/boot/grub.conf", "w")
649 # first gen mactel machines get the bootloader name wrong apparently
650 if rpmUtils
.arch
.getBaseArch() == "i386":
651 os
.link(isodir
+ "/EFI/boot/grub.efi", isodir
+ "/EFI/boot/boot.efi")
652 os
.link(isodir
+ "/EFI/boot/grub.conf", isodir
+ "/EFI/boot/boot.conf")
654 # for most things, we want them named boot$efiarch
655 efiarch
= {"i386": "ia32", "x86_64": "x64"}
656 efiname
= efiarch
[rpmUtils
.arch
.getBaseArch()]
657 os
.rename(isodir
+ "/EFI/boot/grub.efi", isodir
+ "/EFI/boot/boot%s.efi" %(efiname
,))
658 os
.link(isodir
+ "/EFI/boot/grub.conf", isodir
+ "/EFI/boot/boot%s.conf" %(efiname
,))
661 def _configure_bootloader(self
, isodir
):
662 self
._configure
_syslinux
_bootloader
(isodir
)
663 self
._configure
_efi
_bootloader
(isodir
)
665 class ppcLiveImageCreator(LiveImageCreatorBase
):
666 def _get_mkisofs_options(self
, isodir
):
667 return [ "-hfs", "-no-desktop", "-part",
668 "-map", isodir
+ "/ppc/mapping",
669 "-hfs-bless", isodir
+ "/ppc/mac",
670 "-hfs-volid", self
.fslabel
]
672 def _get_required_packages(self
):
673 return ["yaboot"] + \
674 LiveImageCreatorBase
._get
_required
_packages
(self
)
676 def _get_excluded_packages(self
):
677 # kind of hacky, but exclude memtest86+ on ppc so it can stay in cfg
678 return ["memtest86+"] + \
679 LiveImageCreatorBase
._get
_excluded
_packages
(self
)
681 def __copy_boot_file(self
, destdir
, file):
682 for dir in ["/usr/share/ppc64-utils",
683 "/usr/lib/anaconda-runtime/boot"]:
684 path
= self
._instroot
+ dir + "/" + file
685 if not os
.path
.exists(path
):
689 shutil
.copy(path
, destdir
)
692 raise CreatorError("Unable to find boot file " + file)
694 def __kernel_bits(self
, kernel
):
695 testpath
= (self
._instroot
+ "/lib/modules/" +
696 kernel
+ "/kernel/arch/powerpc/platforms")
698 if not os
.path
.exists(testpath
):
699 return { "32" : True, "64" : False }
701 return { "32" : False, "64" : True }
703 def __copy_kernel_and_initramfs(self
, destdir
, version
):
705 bootdir
= self
._instroot
+ "/boot"
709 shutil
.copyfile(bootdir
+ "/vmlinuz-" + version
,
710 destdir
+ "/vmlinuz")
712 if os
.path
.exists(bootdir
+ "/initramfs-" + version
+ ".img"):
713 shutil
.copyfile(bootdir
+ "/initramfs-" + version
+ ".img",
714 destdir
+ "/initrd.img")
717 shutil
.copyfile(bootdir
+ "/initrd-" + version
+ ".img",
718 destdir
+ "/initrd.img")
722 def __get_basic_yaboot_config(self
, **args
):
724 init-message = "Welcome to %(name)s"
728 def __get_image_stanza(self
, **args
):
730 args
["rootlabel"] = "live:LABEL=%(fslabel)s" % args
732 args
["rootlabel"] = "CDLABEL=%(fslabel)s" % args
735 image=/ppc/ppc%(bit)s/vmlinuz
737 initrd=/ppc/ppc%(bit)s/initrd.img
739 append="root=%(rootlabel)s rootfstype=%(isofstype)s %(liveargs)s %(extra)s"
743 def __write_yaboot_config(self
, isodir
, bit
, isDracut
= False):
744 cfg
= self
.__get
_basic
_yaboot
_config
(name
= self
.name
,
745 timeout
= self
._timeout
* 100)
747 kernel_options
= self
._get
_kernel
_options
()
749 cfg
+= self
.__get
_image
_stanza
(fslabel
= self
.fslabel
,
752 long = "Run from image",
755 liveargs
= kernel_options
,
758 if self
._has
_checkisomd
5():
759 cfg
+= self
.__get
_image
_stanza
(fslabel
= self
.fslabel
,
762 long = "Verify and run from image",
765 liveargs
= kernel_options
,
768 f
= open(isodir
+ "/ppc/ppc" + bit
+ "/yaboot.conf", "w")
772 def __write_not_supported(self
, isodir
, bit
):
773 makedirs(isodir
+ "/ppc/ppc" + bit
)
775 message
= "Sorry, this LiveCD does not support your hardware"
777 f
= open(isodir
+ "/ppc/ppc" + bit
+ "/yaboot.conf", "w")
778 f
.write('init-message = "' + message
+ '"')
782 def __write_dualbits_yaboot_config(isodir
, **args
):
784 init-message = "\nWelcome to %(name)s!\nUse 'linux32' for 32-bit kernel.\n\n"
788 image=/ppc/ppc64/vmlinuz
791 initrd=/ppc/ppc64/initrd.img
794 image=/ppc/ppc32/vmlinuz
796 initrd=/ppc/ppc32/initrd.img
800 f
= open(isodir
+ "/etc/yaboot.conf", "w")
804 def _configure_bootloader(self
, isodir
):
805 """configure the boot loader"""
806 havekernel
= { 32: False, 64: False }
808 self
.__copy
_boot
_file
(isodir
+ "/ppc", "mapping")
809 self
.__copy
_boot
_file
(isodir
+ "/ppc", "bootinfo.txt")
810 self
.__copy
_boot
_file
(isodir
+ "/ppc/mac", "ofboot.b")
812 shutil
.copyfile(self
._instroot
+ "/usr/lib/yaboot/yaboot",
813 isodir
+ "/ppc/mac/yaboot")
815 makedirs(isodir
+ "/ppc/chrp")
816 shutil
.copyfile(self
._instroot
+ "/usr/lib/yaboot/yaboot",
817 isodir
+ "/ppc/chrp/yaboot")
819 subprocess
.call(["/usr/sbin/addnote", isodir
+ "/ppc/chrp/yaboot"])
822 # FIXME: ppc should support multiple kernels too...
824 kernel
= self
._get
_kernel
_versions
().values()[0][0]
826 kernel_bits
= self
.__kernel
_bits
(kernel
)
828 for (bit
, present
) in kernel_bits
.items():
830 self
.__write
_not
_supported
(isodir
, bit
)
833 isDracut
= self
.__copy
_kernel
_and
_initramfs
(isodir
+ "/ppc/ppc" + bit
, kernel
)
834 self
.__write
_yaboot
_config
(isodir
, bit
, isDracut
)
836 makedirs(isodir
+ "/etc")
837 if kernel_bits
["32"] and not kernel_bits
["64"]:
838 shutil
.copyfile(isodir
+ "/ppc/ppc32/yaboot.conf",
839 isodir
+ "/etc/yaboot.conf")
840 elif kernel_bits
["64"] and not kernel_bits
["32"]:
841 shutil
.copyfile(isodir
+ "/ppc/ppc64/yaboot.conf",
842 isodir
+ "/etc/yaboot.conf")
844 self
.__write
_dualbits
_yaboot
_config
(isodir
,
846 timeout
= self
._timeout
* 100)
849 # FIXME: build 'netboot' images with kernel+initrd, like mk-images.ppc
852 class ppc64LiveImageCreator(ppcLiveImageCreator
):
853 def _get_excluded_packages(self
):
855 # while kernel.ppc and kernel.ppc64 co-exist,
857 return ["kernel.ppc"] + \
858 ppcLiveImageCreator
._get
_excluded
_packages
(self
)
860 arch
= rpmUtils
.arch
.getBaseArch()
861 if arch
in ("i386", "x86_64"):
862 LiveImageCreator
= x86LiveImageCreator
863 elif arch
in ("ppc",):
864 LiveImageCreator
= ppcLiveImageCreator
865 elif arch
in ("ppc64",):
866 LiveImageCreator
= ppc64LiveImageCreator
868 raise CreatorError("Architecture not supported!")