removed unnecessary selinux abort condition
[livecd.git] / imgcreate / live.py
blob0905dcc186da29b204e0d88947f76d6296fdd650
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.
19 import os
20 import os.path
21 import glob
22 import shutil
23 import subprocess
24 import logging
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.
39 """
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__().
46 """
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
61 no spare space.
63 """
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."""
71 self.__isodir = None
73 self.__modules = ["=ata", "sym53c8xx", "aic7xxx", "=usb", "=firewire",
74 "=mmc", "=pcmcia", "mptsas", "udf", "virtio_blk",
75 "virtio_pci"]
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
91 """
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"):
106 r += " rhgb"
107 if os.path.exists(self._instroot + "/usr/bin/plymouth"):
108 r += " rhgb"
109 return r
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.
120 return []
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")):
132 return True
134 return False
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())
143 try:
144 isoloop.mount()
145 except MountError, e:
146 raise CreatorError("Failed to loopback mount '%s' : %s" %
147 (base_on, e))
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"
152 else:
153 squashimg = isoloop.mountdir + "/LiveOS/squashfs.img"
155 squashloop = DiskMount(LoopbackDisk(squashimg, 0), self._mkdtemp(), "squashfs")
157 try:
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)
162 try:
163 squashloop.mount()
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"
171 else:
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" %
177 base_on)
179 try:
180 shutil.copyfile(os_image, self._image)
181 except IOError, e:
182 raise CreatorError("Failed to copy base live image to %s for modification: %s" %(self._image, e))
183 finally:
184 squashloop.cleanup()
185 isoloop.cleanup()
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-")
200 return self.__isodir
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)
209 if not in_chroot:
210 env["LIVE_ROOT"] = self.__ensure_isodir()
212 return env
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:
220 if module == "=usb":
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 "
230 else:
231 retval = retval + module + " "
232 return retval
234 def __restore_file(self,path):
235 try:
236 os.unlink(path)
237 except:
238 pass
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))
245 f = open(path, "a")
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')
250 f.close()
252 def __write_dracut_conf(self, path):
253 if not os.path.exists(os.path.dirname(path)):
254 makedirs(os.path.dirname(path))
255 f = open(path, "a")
256 f.write('filesystems+="' + self.__extra_filesystems() + ' "\n')
257 f.write('drivers+="' + self.__extra_drivers() + ' "\n')
258 f.close()
260 def __create_iso(self, isodir):
261 iso = self._outdir + "/" + self.name + ".iso"
263 args = ["/usr/bin/mkisofs",
264 "-J", "-r",
265 "-hide-rr-moved", "-hide-joliet-trans-tbl",
266 "-V", self.fslabel,
267 "-o", iso]
269 args.extend(self._get_mkisofs_options(isodir))
270 if self._isofstype == "udf":
271 args.append("-allow-limited-size")
273 args.append(isodir)
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_md5sum(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"
289 else:
290 logging.warn("isomd5sum not installed; not setting up mediacheck")
291 return
293 subprocess.call([implantisomd5, iso])
295 def _stage_final_image(self):
296 try:
297 makedirs(self.__ensure_isodir() + "/LiveOS")
299 self._resparse()
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")
309 else:
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",
316 self.compress_type)
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)
323 finally:
324 shutil.rmtree(self.__isodir, ignore_errors = True)
325 self.__isodir = None
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):
339 return ""
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):
345 return 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*"):
355 return None
357 return "mboot.c32"
359 def __copy_syslinux_files(self, isodir, menu, mboot = None):
360 files = ["isolinux.bin", menu]
361 if mboot:
362 files += [mboot]
364 for f in files:
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):
385 return False
387 shutil.copyfile(background_path, isodest)
389 return True
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)
397 isDracut = False
398 if os.path.exists(bootdir + "/initramfs-" + version + ".img"):
399 shutil.copyfile(bootdir + "/initramfs-" + version + ".img",
400 isodir + "/isolinux/initrd" + index + ".img")
401 isDracut = True
402 else:
403 shutil.copyfile(bootdir + "/initrd-" + version + ".img",
404 isodir + "/isolinux/initrd" + index + ".img")
406 is_xen = False
407 if os.path.exists(bootdir + "/xen.gz-" + version[:-3]):
408 shutil.copyfile(bootdir + "/xen.gz-" + version[:-3],
409 isodir + "/isolinux/xen" + index + ".gz")
410 is_xen = True
412 return (is_xen, isDracut)
414 def __is_default_kernel(self, kernel, kernels):
415 if len(kernels) == 1:
416 return True
418 if kernel == self._default_kernel:
419 return True
421 if kernel.startswith("kernel-") and kernel[7:] == self._default_kernel:
422 return True
424 return False
426 def __get_basic_syslinux_config(self, **args):
427 return """
428 default %(menu)s
429 timeout %(timeout)d
431 %(background)s
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
443 menu hidden
444 menu hiddenrow 5
445 """ % args
447 def __get_image_stanza(self, is_xen, isDracut, **args):
448 if isDracut:
449 args["rootlabel"] = "live:CDLABEL=%(fslabel)s" % args
450 else:
451 args["rootlabel"] = "CDLABEL=%(fslabel)s" % args
453 if not is_xen:
454 template = """label %(short)s
455 menu label %(long)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
459 else:
460 template = """label %(short)s
461 menu label %(long)s
462 kernel mboot.c32
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):
468 versions = []
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_checkisomd5()
478 cfg = ""
480 index = "0"
481 for version in versions:
482 (is_xen, isDracut) = self.__copy_kernel_and_initramfs(isodir, version, index)
483 if index == "0":
484 self._isDracut = isDracut
486 default = self.__is_default_kernel(kernel, kernels)
488 if default:
489 long = "Boot"
490 elif kernel.startswith("kernel-"):
491 long = "Boot %s(%s)" % (self.name, kernel[7:])
492 else:
493 long = "Boot %s(%s)" % (self.name, kernel)
495 # Basic video driver
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
501 if isDracut:
502 kern_opts = kernel_options + " rd_NO_LUKS rd_NO_MD rd_NO_DM"
503 else:
504 kern_opts = kernel_options
506 cfg += self.__get_image_stanza(is_xen, isDracut,
507 fslabel = self.fslabel,
508 isofstype = "auto",
509 liveargs = kern_opts,
510 long = long,
511 short = "linux" + index,
512 basicvideo = "",
513 xdriver = "",
514 extra = "",
515 index = index)
517 if default:
518 cfg += "menu default\n"
520 cfg += self.__get_image_stanza(is_xen, isDracut,
521 fslabel = self.fslabel,
522 isofstype = "auto",
523 liveargs = kern_opts,
524 long = long + " (Basic Video)",
525 short = "linux" + index,
526 basicvideo = basic,
527 xdriver = xdriver,
528 extra = "",
529 index = index)
531 if checkisomd5:
532 cfg += self.__get_image_stanza(is_xen, isDracut,
533 fslabel = self.fslabel,
534 isofstype = "auto",
535 liveargs = kern_opts,
536 long = "Verify and " + long,
537 short = "check" + index,
538 basicvideo = "",
539 xdriver = "",
540 extra = "check",
541 index = index)
543 index = str(int(index) + 1)
545 return cfg
547 def __get_memtest_stanza(self, isodir):
548 memtest = glob.glob(self._instroot + "/boot/memtest86*")
549 if not memtest:
550 return ""
552 shutil.copyfile(memtest[0], isodir + "/isolinux/memtest")
554 return """label memtest
555 menu label Memory Test
556 kernel memtest
559 def __get_local_stanza(self, isodir):
560 return """label local
561 menu label Boot from local drive
562 localboot 0xffff
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())
574 background = ""
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,
580 name = self.name,
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")
589 cfgf.write(cfg)
590 cfgf.close()
592 def __copy_efi_files(self, isodir):
593 if not os.path.exists(self._instroot + "/boot/efi/EFI/redhat/grub.efi"):
594 return False
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")
600 return True
602 def __get_basic_efi_config(self, **args):
603 return """
604 default=0
605 splashimage=/EFI/boot/splash.xpm.gz
606 timeout %(timeout)d
607 hiddenmenu
609 """ %args
611 def __get_efi_image_stanza(self, **args):
612 if self._isDracut:
613 args["rootlabel"] = "live:LABEL=%(fslabel)s" % args
614 else:
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
619 """ %args
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_checkisomd5()
627 cfg = ""
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)):
632 continue
633 cfg += self.__get_efi_image_stanza(fslabel = self.fslabel,
634 isofstype = "auto",
635 liveargs = kernel_options,
636 long = name,
637 extra = "", index = index)
638 if checkisomd5:
639 cfg += self.__get_efi_image_stanza(fslabel = self.fslabel,
640 isofstype = "auto",
641 liveargs = kernel_options,
642 long = "Verify and Boot " + name,
643 extra = "check",
644 index = index)
645 break
647 return cfg
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")
655 return
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")
667 cfgf.write(cfg)
668 cfgf.close()
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):
707 continue
709 makedirs(destdir)
710 shutil.copy(path, destdir)
711 return
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 }
721 else:
722 return { "32" : False, "64" : True }
724 def __copy_kernel_and_initramfs(self, destdir, version):
725 isDracut = False
726 bootdir = self._instroot + "/boot"
728 makedirs(destdir)
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")
736 isDracut = True
737 else:
738 shutil.copyfile(bootdir + "/initrd-" + version + ".img",
739 destdir + "/initrd.img")
741 return isDracut
743 def __get_basic_yaboot_config(self, **args):
744 return """
745 init-message = "Welcome to %(name)s"
746 timeout=%(timeout)d
747 """ % args
749 def __get_image_stanza(self, **args):
750 if args["isDracut"]:
751 args["rootlabel"] = "live:LABEL=%(fslabel)s" % args
752 else:
753 args["rootlabel"] = "CDLABEL=%(fslabel)s" % args
754 return """
756 image=/ppc/ppc%(bit)s/vmlinuz
757 label=%(short)s
758 initrd=/ppc/ppc%(bit)s/initrd.img
759 read-only
760 append="root=%(rootlabel)s rootfstype=%(isofstype)s %(liveargs)s %(extra)s"
761 """ % args
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,
771 isofstype = "auto",
772 short = "linux",
773 long = "Run from image",
774 extra = "",
775 bit = bit,
776 liveargs = kernel_options,
777 isDracut = isDracut)
779 if self._has_checkisomd5():
780 cfg += self.__get_image_stanza(fslabel = self.fslabel,
781 isofstype = "auto",
782 short = "check",
783 long = "Verify and run from image",
784 extra = "check",
785 bit = bit,
786 liveargs = kernel_options,
787 isDracut = isDracut)
789 f = open(isodir + "/ppc/ppc" + bit + "/yaboot.conf", "w")
790 f.write(cfg)
791 f.close()
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 + '"')
800 f.close()
803 def __write_dualbits_yaboot_config(isodir, **args):
804 cfg = """
805 init-message = "\nWelcome to %(name)s!\nUse 'linux32' for 32-bit kernel.\n\n"
806 timeout=%(timeout)d
807 default=linux
809 image=/ppc/ppc64/vmlinuz
810 label=linux64
811 alias=linux
812 initrd=/ppc/ppc64/initrd.img
813 read-only
815 image=/ppc/ppc32/vmlinuz
816 label=linux32
817 initrd=/ppc/ppc32/initrd.img
818 read-only
819 """ % args
821 f = open(isodir + "/etc/yaboot.conf", "w")
822 f.write(cfg)
823 f.close()
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():
850 if not present:
851 self.__write_not_supported(isodir, bit)
852 continue
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")
864 else:
865 self.__write_dualbits_yaboot_config(isodir,
866 name = self.name,
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):
875 # FIXME:
876 # while kernel.ppc and kernel.ppc64 co-exist,
877 # we can't have both
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
888 else:
889 raise CreatorError("Architecture not supported!")