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 *
29 import imgcreate
.mayflower
as mayflower
31 class LiveImageCreatorBase(LoopImageCreator
):
32 """A base class for LiveCD image creators.
34 This class serves as a base class for the architecture-specific LiveCD
35 image creator subclass, LiveImageCreator.
37 LiveImageCreator creates a bootable ISO containing the system image,
38 bootloader, bootloader configuration, kernel and initramfs.
42 def __init__(self
, *args
):
43 """Initialise a LiveImageCreator instance.
45 This method takes the same arguments as ImageCreator.__init__().
48 LoopImageCreator
.__init
__(self
, *args
)
50 self
.skip_compression
= False
51 """Controls whether to use squashfs to compress the image."""
53 self
.skip_minimize
= False
54 """Controls whether an image minimizing snapshot should be created.
56 This snapshot can be used when copying the system image from the ISO in
57 order to minimize the amount of data that needs to be copied; simply,
58 it makes it possible to create a version of the image's filesystem with
63 self
._timeout
= kickstart
.get_timeout(self
.ks
, 10)
64 """The bootloader timeout from kickstart."""
66 self
._default
_kernel
= kickstart
.get_default_kernel(self
.ks
, "kernel")
67 """The default kernel type from kickstart."""
71 self
.__modules
= ["=ata", "sym53c8xx", "aic7xxx", "=usb", "=firewire", "=mmc", "=pcmcia", "mptsas", "udf"]
72 self
.__modules
.extend(kickstart
.get_modules(self
.ks
))
74 self
._isofstype
= "iso9660"
77 # Hooks for subclasses
79 def _configure_bootloader(self
, isodir
):
80 """Create the architecture specific booloader configuration.
82 This is the hook where subclasses must create the booloader
83 configuration in order to allow a bootable ISO to be built.
85 isodir -- the directory where the contents of the ISO are to be staged
88 raise CreatorError("Bootloader configuration is arch-specific, "
89 "but not implemented for this arch!")
91 def _get_kernel_options(self
):
92 """Return a kernel options string for bootloader configuration.
94 This is the hook where subclasses may specify a set of kernel options
95 which should be included in the images bootloader configuration.
97 A sensible default implementation is provided.
100 r
= kickstart
.get_kernel_args(self
.ks
)
101 if os
.path
.exists(self
._instroot
+ "/usr/bin/rhgb"):
103 if os
.path
.exists(self
._instroot
+ "/usr/bin/plymouth"):
107 def _get_mkisofs_options(self
, isodir
):
108 """Return the architecture specific mkisosfs options.
110 This is the hook where subclasses may specify additional arguments to
111 mkisofs, e.g. to enable a bootable ISO to be built.
113 By default, an empty list is returned.
119 # Helpers for subclasses
121 def _has_checkisomd5(self
):
122 """Check whether checkisomd5 is available in the install root."""
123 def exists(instroot
, path
):
124 return os
.path
.exists(instroot
+ path
)
126 if (exists(self
._instroot
, "/usr/lib/anaconda-runtime/checkisomd5") or
127 exists(self
._instroot
, "/usr/bin/checkisomd5")):
133 # Actual implementation
135 def _base_on(self
, base_on
):
136 """helper function to extract ext3 file system from a live CD ISO"""
137 isoloop
= DiskMount(LoopbackDisk(base_on
, 0), self
._mkdtemp
())
141 except MountError
, e
:
142 raise CreatorError("Failed to loopback mount '%s' : %s" %
145 # legacy LiveOS filesystem layout support, remove for F9 or F10
146 if os
.path
.exists(isoloop
.mountdir
+ "/squashfs.img"):
147 squashimg
= isoloop
.mountdir
+ "/squashfs.img"
149 squashimg
= isoloop
.mountdir
+ "/LiveOS/squashfs.img"
151 squashloop
= DiskMount(LoopbackDisk(squashimg
, 0), self
._mkdtemp
(), "squashfs")
154 if not squashloop
.disk
.exists():
155 raise CreatorError("'%s' is not a valid live CD ISO : "
156 "squashfs.img doesn't exist" % base_on
)
160 except MountError
, e
:
161 raise CreatorError("Failed to loopback mount squashfs.img "
162 "from '%s' : %s" % (base_on
, e
))
164 # legacy LiveOS filesystem layout support, remove for F9 or F10
165 if os
.path
.exists(squashloop
.mountdir
+ "/os.img"):
166 os_image
= squashloop
.mountdir
+ "/os.img"
168 os_image
= squashloop
.mountdir
+ "/LiveOS/ext3fs.img"
170 if not os
.path
.exists(os_image
):
171 raise CreatorError("'%s' is not a valid live CD ISO : neither "
172 "LiveOS/ext3fs.img nor os.img exist" %
175 shutil
.copyfile(os_image
, self
._image
)
180 def _mount_instroot(self
, base_on
= None):
181 LoopImageCreator
._mount
_instroot
(self
, base_on
)
182 self
.__write
_initrd
_conf
(self
._instroot
+ "/etc/mayflower.conf")
184 def _unmount_instroot(self
):
186 os
.unlink(self
._instroot
+ "/etc/mayflower.conf")
189 LoopImageCreator
._unmount
_instroot
(self
)
191 def __ensure_isodir(self
):
192 if self
.__isodir
is None:
193 self
.__isodir
= self
._mkdtemp
("iso-")
196 def _create_bootconfig(self
):
197 """Configure the image so that it's bootable."""
198 mayflower
.create_initramfs(self
._instroot
, self
._chroot
, self
._get
_kernel
_versions
())
199 self
._configure
_bootloader
(self
.__ensure
_isodir
())
201 def _get_post_scripts_env(self
, in_chroot
):
202 env
= LoopImageCreator
._get
_post
_scripts
_env
(self
, in_chroot
)
205 env
["LIVE_ROOT"] = self
.__ensure
_isodir
()
209 def __write_initrd_conf(self
, path
):
210 if not os
.path
.exists(os
.path
.dirname(path
)):
211 makedirs(os
.path
.dirname(path
))
214 f
.write('LIVEOS="yes"\n')
215 f
.write('PROBE="no"\n')
216 f
.write('MODULES+="squashfs ext3 ext2 vfat msdos "\n')
217 f
.write('MODULES+="sr_mod sd_mod ide-cd cdrom "\n')
218 # all scsi drivers included by anaconda
219 mods
= subprocess
.Popen(["/usr/lib/anaconda-runtime/modlist",
221 "/usr/lib/anaconda-runtime/loader/module-info",
222 "scsi"], stdout
=subprocess
.PIPE
).communicate()[0]
223 self
.__modules
.extend(mods
.split())
225 for module
in self
.__modules
:
227 f
.write('MODULES+="ehci_hcd uhci_hcd ohci_hcd "\n')
228 f
.write('MODULES+="usb_storage usbhid "\n')
229 elif module
== "=firewire":
230 f
.write('MODULES+="firewire-sbp2 firewire-ohci "\n')
231 f
.write('MODULES+="sbp2 ohci1394 ieee1394 "\n')
232 elif module
== "=mmc":
233 f
.write('MODULES+="mmc_block sdhci sdhci-pci "\n')
234 elif module
== "=pcmcia":
235 f
.write('MODULES+="pata_pcmcia "\n')
237 f
.write('MODULES+="' + module
+ ' "\n')
241 def __create_iso(self
, isodir
):
242 iso
= self
._outdir
+ "/" + self
.name
+ ".iso"
244 args
= ["/usr/bin/mkisofs",
246 "-hide-rr-moved", "-hide-joliet-trans-tbl",
250 args
.extend(self
._get
_mkisofs
_options
(isodir
))
251 if self
._isofstype
== "udf":
252 args
.append("-allow-limited-size")
256 if subprocess
.call(args
) != 0:
257 raise CreatorError("ISO creation failed!")
259 self
.__implant
_md
5sum
(iso
)
261 def __implant_md5sum(self
, iso
):
262 """Implant an isomd5sum."""
263 if os
.path
.exists("/usr/bin/implantisomd5"):
264 implantisomd5
= "/usr/bin/implantisomd5"
265 elif os
.path
.exists("/usr/lib/anaconda-runtime/implantisomd5"):
266 implantisomd5
= "/usr/lib/anaconda-runtime/implantisomd5"
268 logging
.warn("isomd5sum not installed; not setting up mediacheck")
270 subprocess
.call([implantisomd5
, iso
])
272 def _stage_final_image(self
):
274 makedirs(self
.__ensure
_isodir
() + "/LiveOS")
276 minimal_size
= self
._resparse
()
278 if not self
.skip_minimize
:
279 create_image_minimizer(self
.__isodir
+ "/LiveOS/osmin.img",
280 self
._image
, minimal_size
)
282 if self
.skip_compression
:
283 shutil
.move(self
._image
, self
.__isodir
+ "/LiveOS/ext3fs.img")
284 if os
.stat(self
.__isodir
+ "/LiveOS/ext3fs.img").st_size
>= 4*1024*1024*1024:
285 self
._isofstype
= "udf"
286 logging
.warn("Switching to UDF due to size of LiveOS/ext3fs.img")
288 makedirs(os
.path
.join(os
.path
.dirname(self
._image
), "LiveOS"))
289 shutil
.move(self
._image
,
290 os
.path
.join(os
.path
.dirname(self
._image
),
291 "LiveOS", "ext3fs.img"))
292 mksquashfs(os
.path
.dirname(self
._image
),
293 self
.__isodir
+ "/LiveOS/squashfs.img")
294 if os
.stat(self
.__isodir
+ "/LiveOS/squashfs.img").st_size
>= 4*1024*1024*1024:
295 self
._isofstype
= "udf"
296 logging
.warn("Switching to UDF due to size of LiveOS/squashfs.img")
299 self
.__create
_iso
(self
.__isodir
)
301 shutil
.rmtree(self
.__isodir
, ignore_errors
= True)
304 class x86LiveImageCreator(LiveImageCreatorBase
):
305 """ImageCreator for x86 machines"""
306 def _get_mkisofs_options(self
, isodir
):
307 return [ "-b", "isolinux/isolinux.bin",
308 "-c", "isolinux/boot.cat",
309 "-no-emul-boot", "-boot-info-table",
310 "-boot-load-size", "4" ]
312 def _get_required_packages(self
):
313 return ["syslinux"] + LiveImageCreatorBase
._get
_required
_packages
(self
)
315 def _get_isolinux_stanzas(self
, isodir
):
318 def __find_syslinux_menu(self
):
319 for menu
in ["vesamenu.c32", "menu.c32"]:
320 if os
.path
.isfile(self
._instroot
+ "/usr/lib/syslinux/" + menu
):
323 raise CreatorError("syslinux not installed : "
324 "no suitable /usr/lib/syslinux/*menu.c32 found")
326 def __find_syslinux_mboot(self
):
328 # We only need the mboot module if we have any xen hypervisors
330 if not glob
.glob(self
._instroot
+ "/boot/xen.gz*"):
335 def __copy_syslinux_files(self
, isodir
, menu
, mboot
= None):
336 files
= ["isolinux.bin", menu
]
341 path
= self
._instroot
+ "/usr/lib/syslinux/" + f
343 if not os
.path
.isfile(path
):
344 raise CreatorError("syslinux not installed : "
345 "%s not found" % path
)
347 shutil
.copy(path
, isodir
+ "/isolinux/")
349 def __copy_syslinux_background(self
, isodest
):
350 background_path
= self
._instroot
+ \
351 "/usr/lib/anaconda-runtime/syslinux-vesa-splash.jpg"
353 if not os
.path
.exists(background_path
):
356 shutil
.copyfile(background_path
, isodest
)
360 def __copy_kernel_and_initramfs(self
, isodir
, version
, index
):
361 bootdir
= self
._instroot
+ "/boot"
363 shutil
.copyfile(bootdir
+ "/vmlinuz-" + version
,
364 isodir
+ "/isolinux/vmlinuz" + index
)
366 shutil
.copyfile(bootdir
+ "/initrd-" + version
+ ".img",
367 isodir
+ "/isolinux/initrd" + index
+ ".img")
370 if os
.path
.exists(bootdir
+ "/xen.gz-" + version
[:-3]):
371 shutil
.copyfile(bootdir
+ "/xen.gz-" + version
[:-3],
372 isodir
+ "/isolinux/xen" + index
+ ".gz")
377 def __is_default_kernel(self
, kernel
, kernels
):
378 if len(kernels
) == 1:
381 if kernel
== self
._default
_kernel
:
384 if kernel
.startswith("kernel-") and kernel
[7:] == self
._default
_kernel
:
389 def __get_basic_syslinux_config(self
, **args
):
395 menu title Welcome to %(name)s!
396 menu color border 0 #ffffffff #00000000
397 menu color sel 7 #ffffffff #ff000000
398 menu color title 0 #ffffffff #00000000
399 menu color tabmsg 0 #ffffffff #00000000
400 menu color unsel 0 #ffffffff #00000000
401 menu color hotsel 0 #ff000000 #ffffffff
402 menu color hotkey 7 #ffffffff #ff000000
403 menu color timeout_msg 0 #ffffffff #00000000
404 menu color timeout 0 #ffffffff #00000000
405 menu color cmdline 0 #ffffffff #00000000
410 def __get_image_stanza(self
, is_xen
, **args
):
412 template
= """label %(short)s
414 kernel vmlinuz%(index)s
415 append initrd=initrd%(index)s.img root=CDLABEL=%(fslabel)s rootfstype=%(isofstype)s %(liveargs)s %(extra)s
418 template
= """label %(short)s
421 append xen%(index)s.gz --- vmlinuz%(index)s root=CDLABEL=%(fslabel)s rootfstype=%(isofstype)s %(liveargs)s %(extra)s --- initrd%(index)s.img
423 return template
% args
425 def __get_image_stanzas(self
, isodir
):
427 kernels
= self
._get
_kernel
_versions
()
428 for kernel
in kernels
:
429 for version
in kernels
[kernel
]:
430 versions
.append(version
)
432 kernel_options
= self
._get
_kernel
_options
()
434 checkisomd5
= self
._has
_checkisomd
5()
439 for version
in versions
:
440 is_xen
= self
.__copy
_kernel
_and
_initramfs
(isodir
, version
, index
)
442 default
= self
.__is
_default
_kernel
(kernel
, kernels
)
446 elif kernel
.startswith("kernel-"):
447 long = "Boot %s(%s)" % (self
.name
, kernel
[7:])
449 long = "Boot %s(%s)" % (self
.name
, kernel
)
451 cfg
+= self
.__get
_image
_stanza
(is_xen
,
452 fslabel
= self
.fslabel
,
454 liveargs
= kernel_options
,
456 short
= "linux" + index
,
461 cfg
+= "menu default\n"
464 cfg
+= self
.__get
_image
_stanza
(is_xen
,
465 fslabel
= self
.fslabel
,
467 liveargs
= kernel_options
,
468 long = "Verify and " + long,
469 short
= "check" + index
,
473 index
= str(int(index
) + 1)
477 def __get_memtest_stanza(self
, isodir
):
478 memtest
= glob
.glob(self
._instroot
+ "/boot/memtest86*")
482 shutil
.copyfile(memtest
[0], isodir
+ "/isolinux/memtest")
484 return """label memtest
485 menu label Memory Test
489 def __get_local_stanza(self
, isodir
):
490 return """label local
491 menu label Boot from local drive
495 def _configure_syslinux_bootloader(self
, isodir
):
496 """configure the boot loader"""
497 makedirs(isodir
+ "/isolinux")
499 menu
= self
.__find
_syslinux
_menu
()
501 self
.__copy
_syslinux
_files
(isodir
, menu
,
502 self
.__find
_syslinux
_mboot
())
505 if self
.__copy
_syslinux
_background
(isodir
+ "/isolinux/splash.jpg"):
506 background
= "menu background splash.jpg"
508 cfg
= self
.__get
_basic
_syslinux
_config
(menu
= menu
,
509 background
= background
,
511 timeout
= self
._timeout
* 10)
513 cfg
+= self
.__get
_image
_stanzas
(isodir
)
514 cfg
+= self
.__get
_memtest
_stanza
(isodir
)
515 cfg
+= self
.__get
_local
_stanza
(isodir
)
516 cfg
+= self
._get
_isolinux
_stanzas
(isodir
)
518 cfgf
= open(isodir
+ "/isolinux/isolinux.cfg", "w")
522 def __copy_efi_files(self
, isodir
):
523 if not os
.path
.exists(self
._instroot
+ "/boot/efi/EFI/redhat/grub.efi"):
525 shutil
.copy(self
._instroot
+ "/boot/efi/EFI/redhat/grub.efi",
526 isodir
+ "/EFI/boot/grub.efi")
527 shutil
.copy(self
._instroot
+ "/boot/grub/splash.xpm.gz",
528 isodir
+ "/EFI/boot/splash.xpm.gz")
532 def __get_basic_efi_config(self
, **args
):
535 splashimage=/EFI/boot/splash.xpm.gz
541 def __get_efi_image_stanza(self
, **args
):
542 return """title %(long)s
543 kernel /EFI/boot/vmlinuz%(index)s root=CDLABEL=%(fslabel)s rootfstype=%(isofstype)s %(liveargs)s %(extra)s
544 initrd /EFI/boot/initrd%(index)s.img
547 def __get_efi_image_stanzas(self
, isodir
, name
):
548 # FIXME: this only supports one kernel right now...
550 kernel_options
= self
._get
_kernel
_options
()
551 checkisomd5
= self
._has
_checkisomd
5()
555 for index
in range(0, 9):
556 # we don't support xen kernels
557 if os
.path
.exists("%s/EFI/boot/xen%d.gz" %(isodir
, index
)):
559 cfg
+= self
.__get
_efi
_image
_stanza
(fslabel
= self
.fslabel
,
561 liveargs
= kernel_options
,
563 extra
= "", index
= index
)
565 cfg
+= self
.__get
_efi
_image
_stanza
(fslabel
= self
.fslabel
,
567 liveargs
= kernel_options
,
568 long = "Verify and Boot " + name
,
575 def _configure_efi_bootloader(self
, isodir
):
576 """Set up the configuration for an EFI bootloader"""
577 makedirs(isodir
+ "/EFI/boot")
579 if not self
.__copy
_efi
_files
(isodir
):
580 shutil
.rmtree(isodir
+ "/EFI")
583 for f
in os
.listdir(isodir
+ "/isolinux"):
584 os
.link("%s/isolinux/%s" %(isodir
, f
),
585 "%s/EFI/boot/%s" %(isodir
, f
))
588 cfg
= self
.__get
_basic
_efi
_config
(name
= self
.name
,
589 timeout
= self
._timeout
)
590 cfg
+= self
.__get
_efi
_image
_stanzas
(isodir
, self
.name
)
592 cfgf
= open(isodir
+ "/EFI/boot/grub.conf", "w")
596 # first gen mactel machines get the bootloader name wrong apparently
597 if rpmUtils
.arch
.getBaseArch() == "i386":
598 os
.link(isodir
+ "/EFI/boot/grub.efi", isodir
+ "/EFI/boot/boot.efi")
599 os
.link(isodir
+ "/EFI/boot/grub.conf", isodir
+ "/EFI/boot/boot.conf")
601 # for most things, we want them named boot$efiarch
602 efiarch
= {"i386": "ia32", "x86_64": "x64"}
603 efiname
= efiarch
[rpmUtils
.arch
.getBaseArch()]
604 os
.rename(isodir
+ "/EFI/boot/grub.efi", isodir
+ "/EFI/boot/boot%s.efi" %(efiname
,))
605 os
.link(isodir
+ "/EFI/boot/grub.conf", isodir
+ "/EFI/boot/boot%s.conf" %(efiname
,))
608 def _configure_bootloader(self
, isodir
):
609 self
._configure
_syslinux
_bootloader
(isodir
)
610 self
._configure
_efi
_bootloader
(isodir
)
612 class ppcLiveImageCreator(LiveImageCreatorBase
):
613 def _get_mkisofs_options(self
, isodir
):
614 return [ "-hfs", "-nodesktop", "-part"
615 "-map", isodir
+ "/ppc/mapping",
616 "-hfs-bless", isodir
+ "/ppc/mac",
617 "-hfs-volid", self
.fslabel
]
619 def _get_required_packages(self
):
620 return ["yaboot"] + \
621 LiveImageCreatorBase
._get
_required
_packages
(self
)
623 def _get_excluded_packages(self
):
624 # kind of hacky, but exclude memtest86+ on ppc so it can stay in cfg
625 return ["memtest86+"] + \
626 LiveImageCreatorBase
._get
_excluded
_packages
(self
)
628 def __copy_boot_file(self
, destdir
, file):
629 for dir in ["/usr/share/ppc64-utils",
630 "/usr/lib/anaconda-runtime/boot"]:
631 path
= self
._instroot
+ dir + "/" + file
632 if not os
.path
.exists(path
):
636 shutil
.copy(path
, destdir
)
639 raise CreatorError("Unable to find boot file " + file)
641 def __kernel_bits(self
, kernel
):
642 testpath
= (self
._instroot
+ "/lib/modules/" +
643 kernel
+ "/kernel/arch/powerpc/platforms")
645 if not os
.path
.exists(testpath
):
646 return { "32" : True, "64" : False }
648 return { "32" : False, "64" : True }
650 def __copy_kernel_and_initramfs(self
, destdir
, version
):
651 bootdir
= self
._instroot
+ "/boot"
655 shutil
.copyfile(bootdir
+ "/vmlinuz-" + version
,
656 destdir
+ "/vmlinuz")
658 shutil
.copyfile(bootdir
+ "/initrd-" + version
+ ".img",
659 destdir
+ "/initrd.img")
661 def __get_basic_yaboot_config(self
, **args
):
663 init-message = "Welcome to %(name)s"
667 def __get_image_stanza(self
, **args
):
670 image=/ppc/ppc%(bit)s/vmlinuz
672 initrd=/ppc/ppc%(bit)s/initrd.img
674 append="root=CDLABEL=%(fslabel)s rootfstype=%(isofstype)s %(liveargs)s %(extra)s"
678 def __write_yaboot_config(isodir
, bit
):
679 cfg
= self
.__get
_basic
_yaboot
_config
(name
= self
.name
,
680 timeout
= self
._timeout
* 100)
682 kernel_options
= self
._get
_kernel
_options
()
684 cfg
+= self
.__get
_image
_stanza
(fslabel
= self
.fslabel
,
687 long = "Run from image",
690 liveargs
= kernel_options
)
692 if self
._has
_checkisomd
5():
693 cfg
+= self
.__get
_image
_stanza
(fslabel
= self
.fslabel
,
696 long = "Verify and run from image",
699 liveargs
= kernel_options
)
701 f
= open(isodir
+ "/ppc/ppc" + bit
+ "/yaboot.conf", "w")
705 def __write_not_supported(isodir
, bit
):
706 makedirs(isodir
+ "/ppc/ppc" + bit
)
708 message
= "Sorry, this LiveCD does not support your hardware"
710 f
= open(isodir
+ "/ppc/ppc" + bit
+ "/yaboot.conf", "w")
711 f
.write('init-message = "' + message
+ '"')
715 def __write_dualbits_yaboot_config(isodir
, **args
):
717 init-message = "\nWelcome to %(name)s!\nUse 'linux32' for 32-bit kernel.\n\n"
721 image=/ppc/ppc64/vmlinuz
724 initrd=/ppc/ppc64/initrd.img
727 image=/ppc/ppc32/vmlinuz
729 initrd=/ppc/ppc32/initrd.img
733 f
= open(isodir
+ "/etc/yaboot.conf", "w")
737 def _configure_bootloader(self
, isodir
):
738 """configure the boot loader"""
739 havekernel
= { 32: False, 64: False }
741 self
.__copy
_boot
_file
("mapping", isodir
+ "/ppc")
742 self
.__copy
_boot
_file
("bootinfo.txt", isodir
+ "/ppc")
743 self
.__copy
_boot
_file
("ofboot.b", isodir
+ "/ppc/mac")
745 shutil
.copyfile(self
._instroot
+ "/usr/lib/yaboot/yaboot",
746 isodir
+ "/ppc/mac/yaboot")
748 makedirs(isodir
+ "/ppc/chrp")
749 shutil
.copyfile(self
._instroot
+ "/usr/lib/yaboot/yaboot",
750 isodir
+ "/ppc/chrp/yaboot")
752 subprocess
.call(["/usr/sbin/addnote", isodir
+ "/ppc/chrp/yaboot"])
755 # FIXME: ppc should support multiple kernels too...
757 kernel
= self
._get
_kernel
_versions
().values()[0][0]
759 kernel_bits
= self
.__kernel
_bits
(kernel
)
761 for (bit
, present
) in kernel_bits
.items():
763 self
.__write
_not
_supported
(isodir
, bit
)
766 self
.__copy
_kernel
_and
_initramfs
(isodir
+ "/ppc/ppc" + bit
, kernel
)
767 self
.__write
_yaboot
_config
(isodir
, bit
)
769 makedirs(isodir
+ "/etc")
770 if kernel_bits
["32"] and not kernel_bits
["64"]:
771 shutil
.copyfile(isodir
+ "/ppc/ppc32/yaboot.conf",
772 isodir
+ "/etc/yaboot.conf")
773 elif kernel_bits
["64"] and not kernel_bits
["32"]:
774 shutil
.copyfile(isodir
+ "/ppc/ppc64/yaboot.conf",
775 isodir
+ "/etc/yaboot.conf")
777 self
.__write
_dualbits
_yaboot
_config
(isodir
,
779 timeout
= self
._timeout
* 100)
782 # FIXME: build 'netboot' images with kernel+initrd, like mk-images.ppc
785 class ppc64LiveImageCreator(ppcLiveImageCreator
):
786 def _get_excluded_packages(self
):
788 # while kernel.ppc and kernel.ppc64 co-exist,
790 return ["kernel.ppc"] + \
791 ppcLiveImageCreator
._get
_excluded
_packages
(self
)
793 arch
= rpmUtils
.arch
.getBaseArch()
794 if arch
in ("i386", "x86_64"):
795 LiveImageCreator
= x86LiveImageCreator
796 elif arch
in ("ppc",):
797 LiveImageCreator
= ppcLiveImageCreator
798 elif arch
in ("ppc64",):
799 LiveImageCreator
= ppc64LiveImageCreator
801 raise CreatorError("Architecture not supported!")