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
, ks
, name
, fslabel
=None, releasever
=None):
42 """Initialise a LiveImageCreator instance.
44 This method takes the same arguments as LoopImageCreator.__init__().
47 LoopImageCreator
.__init
__(self
, ks
, name
, fslabel
=fslabel
, releasever
=releasever
)
49 self
.compress_type
= "gzip"
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",
74 "=mmc", "=pcmcia", "mptsas", "udf", "virtio_blk",
76 self
.__modules
.extend(kickstart
.get_modules(self
.ks
))
78 self
._isofstype
= "iso9660"
81 # Hooks for subclasses
83 def _configure_bootloader(self
, isodir
):
84 """Create the architecture specific booloader configuration.
86 This is the hook where subclasses must create the booloader
87 configuration in order to allow a bootable ISO to be built.
89 isodir -- the directory where the contents of the ISO are to be staged
92 raise CreatorError("Bootloader configuration is arch-specific, "
93 "but not implemented for this arch!")
95 def _get_kernel_options(self
):
96 """Return a kernel options string for bootloader configuration.
98 This is the hook where subclasses may specify a set of kernel options
99 which should be included in the images bootloader configuration.
101 A sensible default implementation is provided.
104 r
= kickstart
.get_kernel_args(self
.ks
)
105 if os
.path
.exists(self
._instroot
+ "/usr/bin/rhgb"):
107 if os
.path
.exists(self
._instroot
+ "/usr/bin/plymouth"):
111 def _get_mkisofs_options(self
, isodir
):
112 """Return the architecture specific mkisosfs options.
114 This is the hook where subclasses may specify additional arguments to
115 mkisofs, e.g. to enable a bootable ISO to be built.
117 By default, an empty list is returned.
123 # Helpers for subclasses
125 def _has_checkisomd5(self
):
126 """Check whether checkisomd5 is available in the install root."""
127 def exists(instroot
, path
):
128 return os
.path
.exists(instroot
+ path
)
130 if (exists(self
._instroot
, "/usr/lib/anaconda-runtime/checkisomd5") or
131 exists(self
._instroot
, "/usr/bin/checkisomd5")):
137 # Actual implementation
139 def _base_on(self
, base_on
):
140 """helper function to extract ext3 file system from a live CD ISO"""
141 isoloop
= DiskMount(LoopbackDisk(base_on
, 0), self
._mkdtemp
())
145 except MountError
, e
:
146 raise CreatorError("Failed to loopback mount '%s' : %s" %
149 # legacy LiveOS filesystem layout support, remove for F9 or F10
150 if os
.path
.exists(isoloop
.mountdir
+ "/squashfs.img"):
151 squashimg
= isoloop
.mountdir
+ "/squashfs.img"
153 squashimg
= isoloop
.mountdir
+ "/LiveOS/squashfs.img"
155 squashloop
= DiskMount(LoopbackDisk(squashimg
, 0), self
._mkdtemp
(), "squashfs")
158 if not squashloop
.disk
.exists():
159 raise CreatorError("'%s' is not a valid live CD ISO : "
160 "squashfs.img doesn't exist" % base_on
)
164 except MountError
, e
:
165 raise CreatorError("Failed to loopback mount squashfs.img "
166 "from '%s' : %s" % (base_on
, e
))
168 # legacy LiveOS filesystem layout support, remove for F9 or F10
169 if os
.path
.exists(squashloop
.mountdir
+ "/os.img"):
170 os_image
= squashloop
.mountdir
+ "/os.img"
172 os_image
= squashloop
.mountdir
+ "/LiveOS/ext3fs.img"
174 if not os
.path
.exists(os_image
):
175 raise CreatorError("'%s' is not a valid live CD ISO : neither "
176 "LiveOS/ext3fs.img nor os.img exist" %
180 shutil
.copyfile(os_image
, self
._image
)
182 raise CreatorError("Failed to copy base live image to %s for modification: %s" %(self
._image
, e
))
187 def _mount_instroot(self
, base_on
= None):
188 LoopImageCreator
._mount
_instroot
(self
, base_on
)
189 self
.__write
_initrd
_conf
(self
._instroot
+ "/etc/sysconfig/mkinitrd")
190 self
.__write
_dracut
_conf
(self
._instroot
+ "/etc/dracut.conf")
192 def _unmount_instroot(self
):
193 self
.__restore
_file
(self
._instroot
+ "/etc/sysconfig/mkinitrd")
194 self
.__restore
_file
(self
._instroot
+ "/etc/dracut.conf")
195 LoopImageCreator
._unmount
_instroot
(self
)
197 def __ensure_isodir(self
):
198 if self
.__isodir
is None:
199 self
.__isodir
= self
._mkdtemp
("iso-")
202 def _create_bootconfig(self
):
203 """Configure the image so that it's bootable."""
204 self
._configure
_bootloader
(self
.__ensure
_isodir
())
206 def _get_post_scripts_env(self
, in_chroot
):
207 env
= LoopImageCreator
._get
_post
_scripts
_env
(self
, in_chroot
)
210 env
["LIVE_ROOT"] = self
.__ensure
_isodir
()
214 def __extra_filesystems(self
):
215 return "squashfs ext4 ext3 ext2 vfat msdos ";
217 def __extra_drivers(self
):
218 retval
= "sr_mod sd_mod ide-cd cdrom "
219 for module
in self
.__modules
:
221 retval
= retval
+ "ehci_hcd uhci_hcd ohci_hcd "
222 retval
= retval
+ "usb_storage usbhid "
223 elif module
== "=firewire":
224 retval
= retval
+ "firewire-sbp2 firewire-ohci "
225 retval
= retval
+ "sbp2 ohci1394 ieee1394 "
226 elif module
== "=mmc":
227 retval
= retval
+ "mmc_block sdhci sdhci-pci "
228 elif module
== "=pcmcia":
229 retval
= retval
+ "pata_pcmcia "
231 retval
= retval
+ module
+ " "
234 def __restore_file(self
,path
):
239 if os
.path
.exists(path
+ '.rpmnew'):
240 os
.rename(path
+ '.rpmnew', path
)
242 def __write_initrd_conf(self
, path
):
243 if not os
.path
.exists(os
.path
.dirname(path
)):
244 makedirs(os
.path
.dirname(path
))
246 f
.write('LIVEOS="yes"\n')
247 f
.write('PROBE="no"\n')
248 f
.write('MODULES+="' + self
.__extra
_filesystems
() + '"\n')
249 f
.write('MODULES+="' + self
.__extra
_drivers
() + '"\n')
252 def __write_dracut_conf(self
, path
):
253 if not os
.path
.exists(os
.path
.dirname(path
)):
254 makedirs(os
.path
.dirname(path
))
256 f
.write('filesystems+="' + self
.__extra
_filesystems
() + ' "\n')
257 f
.write('drivers+="' + self
.__extra
_drivers
() + ' "\n')
260 def __create_iso(self
, isodir
):
261 iso
= self
._outdir
+ "/" + self
.name
+ ".iso"
263 args
= ["/usr/bin/mkisofs",
265 "-hide-rr-moved", "-hide-joliet-trans-tbl",
269 args
.extend(self
._get
_mkisofs
_options
(isodir
))
270 if self
._isofstype
== "udf":
271 args
.append("-allow-limited-size")
275 if subprocess
.call(args
) != 0:
276 raise CreatorError("ISO creation failed!")
278 if os
.path
.exists("/usr/bin/isohybrid"):
279 subprocess
.call(["/usr/bin/isohybrid", iso
])
281 self
.__implant
_md
5sum
(iso
)
283 def __implant_md5sum(self
, iso
):
284 """Implant an isomd5sum."""
285 if os
.path
.exists("/usr/bin/implantisomd5"):
286 implantisomd5
= "/usr/bin/implantisomd5"
287 elif os
.path
.exists("/usr/lib/anaconda-runtime/implantisomd5"):
288 implantisomd5
= "/usr/lib/anaconda-runtime/implantisomd5"
290 logging
.warn("isomd5sum not installed; not setting up mediacheck")
293 subprocess
.call([implantisomd5
, iso
])
295 def _stage_final_image(self
):
297 makedirs(self
.__ensure
_isodir
() + "/LiveOS")
301 if not self
.skip_minimize
:
302 create_image_minimizer(self
.__isodir
+ "/LiveOS/osmin.img", self
._image
, self
.compress_type
)
304 if self
.skip_compression
:
305 shutil
.move(self
._image
, self
.__isodir
+ "/LiveOS/ext3fs.img")
306 if os
.stat(self
.__isodir
+ "/LiveOS/ext3fs.img").st_size
>= 4*1024*1024*1024:
307 self
._isofstype
= "udf"
308 logging
.warn("Switching to UDF due to size of LiveOS/ext3fs.img")
310 makedirs(os
.path
.join(os
.path
.dirname(self
._image
), "LiveOS"))
311 shutil
.move(self
._image
,
312 os
.path
.join(os
.path
.dirname(self
._image
),
313 "LiveOS", "ext3fs.img"))
314 mksquashfs(os
.path
.dirname(self
._image
),
315 self
.__isodir
+ "/LiveOS/squashfs.img",
317 if os
.stat(self
.__isodir
+ "/LiveOS/squashfs.img").st_size
>= 4*1024*1024*1024:
318 self
._isofstype
= "udf"
319 logging
.warn("Switching to UDF due to size of LiveOS/squashfs.img")
322 self
.__create
_iso
(self
.__isodir
)
324 shutil
.rmtree(self
.__isodir
, ignore_errors
= True)
327 class x86LiveImageCreator(LiveImageCreatorBase
):
328 """ImageCreator for x86 machines"""
329 def _get_mkisofs_options(self
, isodir
):
330 return [ "-b", "isolinux/isolinux.bin",
331 "-c", "isolinux/boot.cat",
332 "-no-emul-boot", "-boot-info-table",
333 "-boot-load-size", "4" ]
335 def _get_required_packages(self
):
336 return ["syslinux"] + LiveImageCreatorBase
._get
_required
_packages
(self
)
338 def _get_isolinux_stanzas(self
, isodir
):
341 def __find_syslinux_menu(self
):
342 for menu
in ("vesamenu.c32", "menu.c32"):
343 for dir in ("/usr/lib/syslinux/", "/usr/share/syslinux/"):
344 if os
.path
.isfile(self
._instroot
+ dir + menu
):
347 raise CreatorError("syslinux not installed : "
348 "no suitable *menu.c32 found")
350 def __find_syslinux_mboot(self
):
352 # We only need the mboot module if we have any xen hypervisors
354 if not glob
.glob(self
._instroot
+ "/boot/xen.gz*"):
359 def __copy_syslinux_files(self
, isodir
, menu
, mboot
= None):
360 files
= ["isolinux.bin", menu
]
365 if os
.path
.exists(self
._instroot
+ "/usr/lib/syslinux/" + f
):
366 path
= self
._instroot
+ "/usr/lib/syslinux/" + f
367 elif os
.path
.exists(self
._instroot
+ "/usr/share/syslinux/" + f
):
368 path
= self
._instroot
+ "/usr/share/syslinux/" + f
369 if not os
.path
.isfile(path
):
370 raise CreatorError("syslinux not installed : "
371 "%s not found" % path
)
373 shutil
.copy(path
, isodir
+ "/isolinux/")
375 def __copy_syslinux_background(self
, isodest
):
376 background_path
= self
._instroot
+ \
377 "/usr/share/anaconda/boot/syslinux-vesa-splash.jpg"
379 if not os
.path
.exists(background_path
):
380 # fallback to F13 location
381 background_path
= self
._instroot
+ \
382 "/usr/lib/anaconda-runtime/syslinux-vesa-splash.jpg"
384 if not os
.path
.exists(background_path
):
387 shutil
.copyfile(background_path
, isodest
)
391 def __copy_kernel_and_initramfs(self
, isodir
, version
, index
):
392 bootdir
= self
._instroot
+ "/boot"
394 shutil
.copyfile(bootdir
+ "/vmlinuz-" + version
,
395 isodir
+ "/isolinux/vmlinuz" + index
)
398 if os
.path
.exists(bootdir
+ "/initramfs-" + version
+ ".img"):
399 shutil
.copyfile(bootdir
+ "/initramfs-" + version
+ ".img",
400 isodir
+ "/isolinux/initrd" + index
+ ".img")
403 shutil
.copyfile(bootdir
+ "/initrd-" + version
+ ".img",
404 isodir
+ "/isolinux/initrd" + index
+ ".img")
407 if os
.path
.exists(bootdir
+ "/xen.gz-" + version
[:-3]):
408 shutil
.copyfile(bootdir
+ "/xen.gz-" + version
[:-3],
409 isodir
+ "/isolinux/xen" + index
+ ".gz")
412 return (is_xen
, isDracut
)
414 def __is_default_kernel(self
, kernel
, kernels
):
415 if len(kernels
) == 1:
418 if kernel
== self
._default
_kernel
:
421 if kernel
.startswith("kernel-") and kernel
[7:] == self
._default
_kernel
:
426 def __get_basic_syslinux_config(self
, **args
):
432 menu title Welcome to %(name)s!
433 menu color border 0 #ffffffff #00000000
434 menu color sel 7 #ffffffff #ff000000
435 menu color title 0 #ffffffff #00000000
436 menu color tabmsg 0 #ffffffff #00000000
437 menu color unsel 0 #ffffffff #00000000
438 menu color hotsel 0 #ff000000 #ffffffff
439 menu color hotkey 7 #ffffffff #ff000000
440 menu color timeout_msg 0 #ffffffff #00000000
441 menu color timeout 0 #ffffffff #00000000
442 menu color cmdline 0 #ffffffff #00000000
447 def __get_image_stanza(self
, is_xen
, isDracut
, **args
):
449 args
["rootlabel"] = "live:CDLABEL=%(fslabel)s" % args
451 args
["rootlabel"] = "CDLABEL=%(fslabel)s" % args
454 template
= """label %(short)s
456 kernel vmlinuz%(index)s
457 append initrd=initrd%(index)s.img root=%(rootlabel)s rootfstype=%(isofstype)s %(liveargs)s %(xdriver)s %(extra)s
460 template
= """label %(short)s
463 append xen%(index)s.gz --- vmlinuz%(index)s root=%(rootlabel)s rootfstype=%(isofstype)s %(liveargs)s %(xdriver)s %(extra)s --- initrd%(index)s.img
465 return template
% args
467 def __get_image_stanzas(self
, isodir
):
469 kernels
= self
._get
_kernel
_versions
()
470 for kernel
in kernels
:
471 for version
in kernels
[kernel
]:
472 versions
.append(version
)
474 kernel_options
= self
._get
_kernel
_options
()
476 checkisomd5
= self
._has
_checkisomd
5()
481 for version
in versions
:
482 (is_xen
, isDracut
) = self
.__copy
_kernel
_and
_initramfs
(isodir
, version
, index
)
484 self
._isDracut
= isDracut
486 default
= self
.__is
_default
_kernel
(kernel
, kernels
)
490 elif kernel
.startswith("kernel-"):
491 long = "Boot %s(%s)" % (self
.name
, kernel
[7:])
493 long = "Boot %s(%s)" % (self
.name
, kernel
)
496 basic
= "system with basic video driver"
497 xdriver
= "xdriver=vesa nomodeset"
500 # tell dracut not to ask for LUKS passwords or activate mdraid sets
502 kern_opts
= kernel_options
+ " rd_NO_LUKS rd_NO_MD rd_NO_DM"
504 kern_opts
= kernel_options
506 cfg
+= self
.__get
_image
_stanza
(is_xen
, isDracut
,
507 fslabel
= self
.fslabel
,
509 liveargs
= kern_opts
,
511 short
= "linux" + index
,
518 cfg
+= "menu default\n"
520 cfg
+= self
.__get
_image
_stanza
(is_xen
, isDracut
,
521 fslabel
= self
.fslabel
,
523 liveargs
= kern_opts
,
524 long = long + " (Basic Video)",
525 short
= "linux" + index
,
532 cfg
+= self
.__get
_image
_stanza
(is_xen
, isDracut
,
533 fslabel
= self
.fslabel
,
535 liveargs
= kern_opts
,
536 long = "Verify and " + long,
537 short
= "check" + index
,
543 index
= str(int(index
) + 1)
547 def __get_memtest_stanza(self
, isodir
):
548 memtest
= glob
.glob(self
._instroot
+ "/boot/memtest86*")
552 shutil
.copyfile(memtest
[0], isodir
+ "/isolinux/memtest")
554 return """label memtest
555 menu label Memory Test
559 def __get_local_stanza(self
, isodir
):
560 return """label local
561 menu label Boot from local drive
565 def _configure_syslinux_bootloader(self
, isodir
):
566 """configure the boot loader"""
567 makedirs(isodir
+ "/isolinux")
569 menu
= self
.__find
_syslinux
_menu
()
571 self
.__copy
_syslinux
_files
(isodir
, menu
,
572 self
.__find
_syslinux
_mboot
())
575 if self
.__copy
_syslinux
_background
(isodir
+ "/isolinux/splash.jpg"):
576 background
= "menu background splash.jpg"
578 cfg
= self
.__get
_basic
_syslinux
_config
(menu
= menu
,
579 background
= background
,
581 timeout
= self
._timeout
* 10)
583 cfg
+= self
.__get
_image
_stanzas
(isodir
)
584 cfg
+= self
.__get
_memtest
_stanza
(isodir
)
585 cfg
+= self
.__get
_local
_stanza
(isodir
)
586 cfg
+= self
._get
_isolinux
_stanzas
(isodir
)
588 cfgf
= open(isodir
+ "/isolinux/isolinux.cfg", "w")
592 def __copy_efi_files(self
, isodir
):
593 if not os
.path
.exists(self
._instroot
+ "/boot/efi/EFI/redhat/grub.efi"):
595 shutil
.copy(self
._instroot
+ "/boot/efi/EFI/redhat/grub.efi",
596 isodir
+ "/EFI/boot/grub.efi")
597 shutil
.copy(self
._instroot
+ "/boot/grub/splash.xpm.gz",
598 isodir
+ "/EFI/boot/splash.xpm.gz")
602 def __get_basic_efi_config(self
, **args
):
605 splashimage=/EFI/boot/splash.xpm.gz
611 def __get_efi_image_stanza(self
, **args
):
613 args
["rootlabel"] = "live:LABEL=%(fslabel)s" % args
615 args
["rootlabel"] = "CDLABEL=%(fslabel)s" % args
616 return """title %(long)s
617 kernel /EFI/boot/vmlinuz%(index)s root=%(rootlabel)s rootfstype=%(isofstype)s %(liveargs)s %(extra)s
618 initrd /EFI/boot/initrd%(index)s.img
621 def __get_efi_image_stanzas(self
, isodir
, name
):
622 # FIXME: this only supports one kernel right now...
624 kernel_options
= self
._get
_kernel
_options
()
625 checkisomd5
= self
._has
_checkisomd
5()
629 for index
in range(0, 9):
630 # we don't support xen kernels
631 if os
.path
.exists("%s/EFI/boot/xen%d.gz" %(isodir
, index
)):
633 cfg
+= self
.__get
_efi
_image
_stanza
(fslabel
= self
.fslabel
,
635 liveargs
= kernel_options
,
637 extra
= "", index
= index
)
639 cfg
+= self
.__get
_efi
_image
_stanza
(fslabel
= self
.fslabel
,
641 liveargs
= kernel_options
,
642 long = "Verify and Boot " + name
,
649 def _configure_efi_bootloader(self
, isodir
):
650 """Set up the configuration for an EFI bootloader"""
651 makedirs(isodir
+ "/EFI/boot")
653 if not self
.__copy
_efi
_files
(isodir
):
654 shutil
.rmtree(isodir
+ "/EFI")
657 for f
in os
.listdir(isodir
+ "/isolinux"):
658 os
.link("%s/isolinux/%s" %(isodir
, f
),
659 "%s/EFI/boot/%s" %(isodir
, f
))
662 cfg
= self
.__get
_basic
_efi
_config
(name
= self
.name
,
663 timeout
= self
._timeout
)
664 cfg
+= self
.__get
_efi
_image
_stanzas
(isodir
, self
.name
)
666 cfgf
= open(isodir
+ "/EFI/boot/grub.conf", "w")
670 # first gen mactel machines get the bootloader name wrong apparently
671 if rpmUtils
.arch
.getBaseArch() == "i386":
672 os
.link(isodir
+ "/EFI/boot/grub.efi", isodir
+ "/EFI/boot/boot.efi")
673 os
.link(isodir
+ "/EFI/boot/grub.conf", isodir
+ "/EFI/boot/boot.conf")
675 # for most things, we want them named boot$efiarch
676 efiarch
= {"i386": "ia32", "x86_64": "x64"}
677 efiname
= efiarch
[rpmUtils
.arch
.getBaseArch()]
678 os
.rename(isodir
+ "/EFI/boot/grub.efi", isodir
+ "/EFI/boot/boot%s.efi" %(efiname
,))
679 os
.link(isodir
+ "/EFI/boot/grub.conf", isodir
+ "/EFI/boot/boot%s.conf" %(efiname
,))
682 def _configure_bootloader(self
, isodir
):
683 self
._configure
_syslinux
_bootloader
(isodir
)
684 self
._configure
_efi
_bootloader
(isodir
)
686 class ppcLiveImageCreator(LiveImageCreatorBase
):
687 def _get_mkisofs_options(self
, isodir
):
688 return [ "-hfs", "-no-desktop", "-part",
689 "-map", isodir
+ "/ppc/mapping",
690 "-hfs-bless", isodir
+ "/ppc/mac",
691 "-hfs-volid", self
.fslabel
]
693 def _get_required_packages(self
):
694 return ["yaboot"] + \
695 LiveImageCreatorBase
._get
_required
_packages
(self
)
697 def _get_excluded_packages(self
):
698 # kind of hacky, but exclude memtest86+ on ppc so it can stay in cfg
699 return ["memtest86+"] + \
700 LiveImageCreatorBase
._get
_excluded
_packages
(self
)
702 def __copy_boot_file(self
, destdir
, file):
703 for dir in ["/usr/share/ppc64-utils",
704 "/usr/lib/anaconda-runtime/boot"]:
705 path
= self
._instroot
+ dir + "/" + file
706 if not os
.path
.exists(path
):
710 shutil
.copy(path
, destdir
)
713 raise CreatorError("Unable to find boot file " + file)
715 def __kernel_bits(self
, kernel
):
716 testpath
= (self
._instroot
+ "/lib/modules/" +
717 kernel
+ "/kernel/arch/powerpc/platforms")
719 if not os
.path
.exists(testpath
):
720 return { "32" : True, "64" : False }
722 return { "32" : False, "64" : True }
724 def __copy_kernel_and_initramfs(self
, destdir
, version
):
726 bootdir
= self
._instroot
+ "/boot"
730 shutil
.copyfile(bootdir
+ "/vmlinuz-" + version
,
731 destdir
+ "/vmlinuz")
733 if os
.path
.exists(bootdir
+ "/initramfs-" + version
+ ".img"):
734 shutil
.copyfile(bootdir
+ "/initramfs-" + version
+ ".img",
735 destdir
+ "/initrd.img")
738 shutil
.copyfile(bootdir
+ "/initrd-" + version
+ ".img",
739 destdir
+ "/initrd.img")
743 def __get_basic_yaboot_config(self
, **args
):
745 init-message = "Welcome to %(name)s"
749 def __get_image_stanza(self
, **args
):
751 args
["rootlabel"] = "live:LABEL=%(fslabel)s" % args
753 args
["rootlabel"] = "CDLABEL=%(fslabel)s" % args
756 image=/ppc/ppc%(bit)s/vmlinuz
758 initrd=/ppc/ppc%(bit)s/initrd.img
760 append="root=%(rootlabel)s rootfstype=%(isofstype)s %(liveargs)s %(extra)s"
764 def __write_yaboot_config(self
, isodir
, bit
, isDracut
= False):
765 cfg
= self
.__get
_basic
_yaboot
_config
(name
= self
.name
,
766 timeout
= self
._timeout
* 100)
768 kernel_options
= self
._get
_kernel
_options
()
770 cfg
+= self
.__get
_image
_stanza
(fslabel
= self
.fslabel
,
773 long = "Run from image",
776 liveargs
= kernel_options
,
779 if self
._has
_checkisomd
5():
780 cfg
+= self
.__get
_image
_stanza
(fslabel
= self
.fslabel
,
783 long = "Verify and run from image",
786 liveargs
= kernel_options
,
789 f
= open(isodir
+ "/ppc/ppc" + bit
+ "/yaboot.conf", "w")
793 def __write_not_supported(self
, isodir
, bit
):
794 makedirs(isodir
+ "/ppc/ppc" + bit
)
796 message
= "Sorry, this LiveCD does not support your hardware"
798 f
= open(isodir
+ "/ppc/ppc" + bit
+ "/yaboot.conf", "w")
799 f
.write('init-message = "' + message
+ '"')
803 def __write_dualbits_yaboot_config(isodir
, **args
):
805 init-message = "\nWelcome to %(name)s!\nUse 'linux32' for 32-bit kernel.\n\n"
809 image=/ppc/ppc64/vmlinuz
812 initrd=/ppc/ppc64/initrd.img
815 image=/ppc/ppc32/vmlinuz
817 initrd=/ppc/ppc32/initrd.img
821 f
= open(isodir
+ "/etc/yaboot.conf", "w")
825 def _configure_bootloader(self
, isodir
):
826 """configure the boot loader"""
827 havekernel
= { 32: False, 64: False }
829 self
.__copy
_boot
_file
(isodir
+ "/ppc", "mapping")
830 self
.__copy
_boot
_file
(isodir
+ "/ppc", "bootinfo.txt")
831 self
.__copy
_boot
_file
(isodir
+ "/ppc/mac", "ofboot.b")
833 shutil
.copyfile(self
._instroot
+ "/usr/lib/yaboot/yaboot",
834 isodir
+ "/ppc/mac/yaboot")
836 makedirs(isodir
+ "/ppc/chrp")
837 shutil
.copyfile(self
._instroot
+ "/usr/lib/yaboot/yaboot",
838 isodir
+ "/ppc/chrp/yaboot")
840 subprocess
.call(["/usr/sbin/addnote", isodir
+ "/ppc/chrp/yaboot"])
843 # FIXME: ppc should support multiple kernels too...
845 kernel
= self
._get
_kernel
_versions
().values()[0][0]
847 kernel_bits
= self
.__kernel
_bits
(kernel
)
849 for (bit
, present
) in kernel_bits
.items():
851 self
.__write
_not
_supported
(isodir
, bit
)
854 isDracut
= self
.__copy
_kernel
_and
_initramfs
(isodir
+ "/ppc/ppc" + bit
, kernel
)
855 self
.__write
_yaboot
_config
(isodir
, bit
, isDracut
)
857 makedirs(isodir
+ "/etc")
858 if kernel_bits
["32"] and not kernel_bits
["64"]:
859 shutil
.copyfile(isodir
+ "/ppc/ppc32/yaboot.conf",
860 isodir
+ "/etc/yaboot.conf")
861 elif kernel_bits
["64"] and not kernel_bits
["32"]:
862 shutil
.copyfile(isodir
+ "/ppc/ppc64/yaboot.conf",
863 isodir
+ "/etc/yaboot.conf")
865 self
.__write
_dualbits
_yaboot
_config
(isodir
,
867 timeout
= self
._timeout
* 100)
870 # FIXME: build 'netboot' images with kernel+initrd, like mk-images.ppc
873 class ppc64LiveImageCreator(ppcLiveImageCreator
):
874 def _get_excluded_packages(self
):
876 # while kernel.ppc and kernel.ppc64 co-exist,
878 return ["kernel.ppc"] + \
879 ppcLiveImageCreator
._get
_excluded
_packages
(self
)
881 arch
= rpmUtils
.arch
.getBaseArch()
882 if arch
in ("i386", "x86_64"):
883 LiveImageCreator
= x86LiveImageCreator
884 elif arch
in ("ppc",):
885 LiveImageCreator
= ppcLiveImageCreator
886 elif arch
in ("ppc64",):
887 LiveImageCreator
= ppc64LiveImageCreator
889 raise CreatorError("Architecture not supported!")