New version

Added support for Mako templates.
Changed the Lorax class to require an yumbase object as a parameter.
Changed a lot of unnecessary system calls to native python code.
Moved most of the file paths into a separate object.
The output and config objects are now singletons.
Also done a lot of code cleanup.
This commit is contained in:
Martin Gracik 2009-12-15 15:26:01 +01:00
parent 2c6d450c58
commit b672d9936e
81 changed files with 3371 additions and 4050 deletions

View File

@ -1,222 +0,0 @@
# initrd template
# create required directories
makedir @initrd@/lib
makedir @initrd@/modules
makedir @initrd@/firmware
link @initrd@/lib/modules to ../modules
link @initrd@/lib/firmware to ../firmware
makedir @initrd@/sbin
makedir @initrd@/dev
makedir @initrd@/etc
makedir @initrd@/etc/udev/rules.d
makedir @initrd@/lib/udev/rules.d
makedir @initrd@/proc
makedir @initrd@/selinux
makedir @initrd@/sys
makedir @initrd@/etc/terminfo/a
makedir @initrd@/etc/terminfo/d
makedir @initrd@/etc/terminfo/l
makedir @initrd@/etc/terminfo/s
makedir @initrd@/etc/terminfo/v
makedir @initrd@/etc/terminfo/x
makedir @initrd@/etc/terminfo/g
makedir @initrd@/tmp
makedir @initrd@/usr/libexec
makedir @initrd@/usr/@libdir@/NetworkManager
makedir @initrd@/usr/share/dbus-1/system-services
makedir @initrd@/var/cache/hald
makedir @initrd@/var/lib/dbus
makedir @initrd@/var/lib/dhclient
makedir @initrd@/var/lock/rpm
makedir @initrd@/var/run
makedir @initrd@/var/run/dbus
makedir @initrd@/var/run/hald
makedir @initrd@/var/run/NetworkManager
makedir @initrd@/etc/dbus-1/system.d
makedir @initrd@/etc/modprobe.d
makedir @initrd@/etc/NetworkManager/dispatcher.d
makedir @initrd@/@libdir@/dbus-1
makedir @initrd@/etc/sysconfig/network-scripts
makedir @initrd@/usr/share/PolicyKit/policy
makedir @initrd@/etc/PolicyKit
makedir @initrd@/var/lib/misc
makedir @initrd@/etc/hal/fdi
makedir @initrd@/usr/share/hal/fdi
makedir @initrd@/usr/share/hwdata
makedir @initrd@/etc/rc.d/init.d
makedir @initrd@/usr/sbin
makedir @initrd@/var/run/wpa_supplicant
# set the buildarch
edit @initrd@/etc/arch text "@buildarch@"
# copy etc stuff
copy @instroot@ etc/passwd to @initrd@ etc
chmod @initrd@/etc/passwd mode 0644
copy @instroot@ etc/group to @initrd@ etc
chmod @initrd@/etc/group mode 0644
copy @instroot@ etc/nsswitch.conf to @initrd@ etc
chmod @initrd@/etc/nsswitch.conf mode 0644
copy @instroot@ etc/hosts to @initrd@ etc
chmod @initrd@/etc/hosts mode 0644
# copy mount/umount
copy @instroot@ bin/mount to @initrd@ sbin
copy @instroot@ bin/umount to @initrd@ sbin
copy @instroot@ sbin/mount.* to @initrd@ sbin
copy @instroot@ sbin/umount.* to @initrd@ sbin
# copy udev
copy @instroot@ sbin/udevd to @initrd@ sbin
copy @instroot@ sbin/udevadm to @initrd@ sbin
link @initrd@/sbin/udevinfo to udevadm
link @initrd@/sbin/udevsettle to udevadm
# udev rules
copy @instroot@ etc/udev/udev.conf to @initrd@ etc/udev
chmod @initrd@/etc/udev/udev.conf mode 0644
copy @instroot@ lib/udev/* to @initrd@ lib/udev
#chmod @initrd@/lib/udev/* mode 0644
remove @initrd@/lib/udev/rules.d/*persistent*
remove @initrd@/lib/udev/rules.d/*generator*
copy @instroot@ etc/udev/rules.d/*.rules to @initrd@ etc/udev/rules.d
chmod @initrd@/etc/udev/rules.d/*.rules mode 0644
# copy bash
copy @instroot@ bin/bash to @initrd@ sbin
link @initrd@/sbin/sh to bash
copy @instroot@ sbin/consoletype to @initrd@ sbin
copy @instroot@ usr/bin/logger to @initrd@ sbin
copy @instroot@ etc/rc.d/init.d/functions to @initrd@ etc/rc.d/init.d
copy @instroot@ etc/sysconfig/network-scripts/network-functions* to @initrd@ etc/sysconfig/network-scripts
link @initrd@/etc/init.d to /etc/rc.d/init.d
# dhcp and dhcpv6 client daemons and support programs
copy @instroot@ sbin/dhclient to @initrd@ sbin
copy @instroot@ sbin/dhclient-script to @initrd@ sbin
copy @instroot@ sbin/dhcp6c to @initrd@ sbin
copy @instroot@ sbin/arping to @initrd@ sbin
copy @instroot@ sbin/ifconfig to @initrd@ sbin
copy @instroot@ sbin/ip to @initrd@ sbin
copy @instroot@ bin/ipcalc to @initrd@ sbin
copy @instroot@ bin/hostname to @initrd@ sbin
copy @instroot@ sbin/ethtool to @initrd@ sbin
copy @instroot@ sbin/route to @initrd@ sbin
touch @initrd@/etc/resolv.conf
# hwdata
copy @instroot@ usr/share/hwdata/pci.ids to @initrd@ usr/share/hwdata
copy @instroot@ usr/share/hwdata/usb.ids to @initrd@ usr/share/hwdata
# hal
copy @instroot@ usr/sbin/hald to @initrd@ sbin
copy @instroot@ usr/libexec/hald-runner to @initrd@ usr/libexec
copy @instroot@ usr/libexec/hald-generate-fdi-cache to @initrd@ usr/libexec
copy @instroot@ usr/libexec/hal*storage* to @initrd@ usr/libexec
touch @initrd@/var/run/hald.acl-list
copy @instroot@ usr/share/hal/fdi/* to @initrd@ usr/share/hal/fdi
copy @instroot@ etc/hal/fdi/* to @initrd@ etc/hal/fdi
copy @instroot@ etc/dbus-1/system.d/hal.conf to @initrd@ etc/dbus-1/system.d
# policykit
copy @instroot@ etc/PolicyKit/PolicyKit.conf to @initrd@ etc/PolicyKit
copy @instroot@ usr/share/dbus-1/system-services/org.freedesktop.PolicyKit.service to @initrd@ usr/share/dbus-1/system-services
copy @instroot@ usr/share/PolicyKit/policy/org.freedesktop.policykit.policy to @initrd@ usr/share/PolicyKit/policy
copy @instroot@ var/lib/misc/PolicyKit.reload to @initrd@ var/lib/misc
# dbus
copy @instroot@ bin/dbus-uuidgen to @initrd@ sbin
copy @instroot@ bin/dbus-daemon to @initrd@ sbin
copy @instroot@ etc/dbus-1/system.conf to @initrd@ etc/dbus-1
copy @instroot@ @libdir@/dbus-1/dbus-daemon-launch-helper to @initrd@ @libdir@/dbus-1
chown @initrd@/@libdir@/dbus-1/dbus-daemon-launch-helper user root group dbus
chmod @initrd@/@libdir@/dbus-1/dbus-daemon-launch-helper mode 04750
# wpa_supplicant
copy @instroot@ usr/sbin/wpa_passphrase to @initrd@ usr/sbin
copy @instroot@ usr/sbin/wpa_supplicant to @initrd@ usr/sbin
copy @instroot@ etc/dbus-1/system.d/wpa_supplicant.conf to @initrd@ etc/dbus-1/system.d
copy @instroot@ etc/wpa_supplicant/wpa_supplicant.conf to @initrd@ etc/wpa_supplicant
copy @instroot@ usr/share/dbus-1/system-services/fi.epitest.hostap.WPASupplicant.service to @initrd@ usr/share/dbus-1/system-services
# networkmanager
copy @instroot@ usr/sbin/NetworkManager to @initrd@ usr/sbin
copy @instroot@ usr/sbin/nm-system-settings to @initrd@ usr/sbin
copy @instroot@ etc/dbus-1/system.d/nm-*.conf to @initrd@ etc/dbus-1/system.d
copy @instroot@ etc/dbus-1/system.d/NetworkManager.conf to @initrd@ etc/dbus-1/system.d
copy @instroot@ etc/NetworkManager/nm-system-settings.conf to @initrd@ etc/NetworkManager
copy @instroot@ usr/@libdir@/NetworkManager/libnm-settings-plugin-ifcfg-fedora.so to @initrd@ usr/@libdir@/NetworkManager
copy @instroot@ usr/libexec/nm-* to @initrd@ usr/libexec
copy @instroot@ usr/share/dbus-1/system-services/org.freedesktop.NetworkManagerSystemSettings.service to @initrd@ usr/share/dbus-1/system-services
copy @instroot@ usr/share/dbus-1/system-services/org.freedesktop.nm_dispatcher.service to @initrd@ usr/share/dbus-1/system-services
# modprobe
copy @instroot@ sbin/modprobe to @initrd@ sbin
copy @instroot@ sbin/insmod to @initrd@ sbin
copy @instroot@ sbin/rmmod to @initrd@ sbin
# profile
edit @initrd@/.profile text "PATH=/bin:/usr/bin:/usr/sbin:/mnt/sysimage/sbin:/mnt/sysimage/usr/sbin:/mnt/sysimage/bin:/mnt/sysimage/usr/bin\nexport PATH"
# terminfos
copy @instroot@ usr/share/terminfo/a/ansi to @initrd@ etc/terminfo/a nolinks
copy @instroot@ usr/share/terminfo/d/dumb to @initrd@ etc/terminfo/d nolinks
copy @instroot@ usr/share/terminfo/l/linux to @initrd@ etc/terminfo/l nolinks
copy @instroot@ usr/share/terminfo/s/screen to @initrd@ etc/terminfo/s nolinks
copy @instroot@ usr/share/terminfo/v/vt100 to @initrd@ etc/terminfo/v nolinks
copy @instroot@ usr/share/terminfo/v/vt100-nav to @initrd@ etc/terminfo/v nolinks
copy @instroot@ usr/share/terminfo/v/vt102 to @initrd@ etc/terminfo/v nolinks
copy @instroot@ usr/share/terminfo/x/xterm to @initrd@ etc/terminfo/x nolinks
copy @instroot@ usr/share/terminfo/x/xterm-color to @initrd@ etc/terminfo/x nolinks
copy @instroot@ usr/share/terminfo/g/gnome to @initrd@ etc/terminfo/g nolinks
chmod @initrd@/etc/terminfo/*/* mode 0644
# misc
copy @instroot@ bin/awk to @initrd@ sbin
copy @instroot@ bin/gawk to @initrd@ sbin
copy @instroot@ bin/egrep to @initrd@ sbin
copy @instroot@ bin/fgrep to @initrd@ sbin
copy @instroot@ bin/grep to @initrd@ sbin
copy @instroot@ bin/kill to @initrd@ sbin
copy @instroot@ bin/ln to @initrd@ sbin
copy @instroot@ bin/readlink to @initrd@ sbin
copy @instroot@ bin/rm to @initrd@ sbin
copy @instroot@ bin/rmdir to @initrd@ sbin
copy @instroot@ bin/sed to @initrd@ sbin
copy @instroot@ bin/sleep to @initrd@ sbin
copy @instroot@ bin/touch to @initrd@ sbin
link @initrd@/init to /sbin/init
link @initrd@/etc/mtab to /proc/mounts
link @initrd@/bin to sbin
link @initrd@/var/lib/xkb to ../../tmp
# loader
copy @instroot@ usr/lib/anaconda-runtime/loader/loader to @initrd@ sbin
copy @instroot@ usr/lib/anaconda-runtime/loader/loader.tr to @initrd@ etc
chmod @initrd/etc/loader.tr mode 0644
# indirect dependencies
copy @instroot@ @libdir@/ld-linux.so.2 to @initrd@ @libdir@
#copy @instroot@ @libdir@/libcom_err.so.2 to @initrd@ @libdir@
#copy @instroot@ @libdir@/libdbus-glib-1.so.2 to @initrd@ @libdir@
#copy @instroot@ @libdir@/libfreebl3.so to @initrd@ @libdir@
copy @instroot@ @libdir@/libgcc_s.so.1 to @initrd@ @libdir@
copy @instroot@ @libdir@/libnss_dns.so.2 to @initrd@ @libdir@
copy @instroot@ @libdir@/libnss_files.so.2 to @initrd@ @libdir@
copy @instroot@ @libdir@/libsoftokn3.so to @initrd@ @libdir@
copy @instroot@ usr/@libdir@/libsqlite3.so.0 to @initrd@ usr/@libdir@
# langtable
copy @instroot@ usr/lib/anaconda/lang-table to @initrd@ etc

View File

@ -1 +0,0 @@
initrd.i386

View File

@ -1,12 +0,0 @@
# initrd template
#include includes/initrd.common
# loader
copy @instroot@ usr/lib/anaconda-runtime/loader/init to @initrd@ sbin/init
link @initrd@/sbin/reboot to init
link @initrd@/sbin/halt to init
link @initrd@/sbin/poweroff to init
# screenfont
copy @instroot@ usr/lib/anaconda-runtime/screenfont-@buildarch@.gz to @initrd@ etc/screenfont.gz

View File

@ -1 +0,0 @@
initrd.i386

View File

@ -1 +0,0 @@
initrd.i386

View File

@ -1 +0,0 @@
initrd.ppc

View File

@ -1,54 +0,0 @@
# initrd template
#include includes/initrd.common
# create required directories
makedir @initrd@/var/empty/sshd mode 0111
makedir @initrd@/etc/pam.d
makedir @initrd@/etc/security
makedir @initrd@/@libdir@/security
# copy some files
copy @instroot@ usr/bin/xauth to @initrd@ sbin
copy @instroot@ usr/sbin/cmsfs* to @initrd@ sbin
copy @instroot@ @libdir@/libpam_misc.so.0.* to @initrd@ @libdir@/libpam_misc.so.0
copy @instroot@ @libdir@/libwrap*.so* to @initrd@ @libdir@
link @initrd@/var/state/xkb to /tmp
# loader
copy @instroot@ usr/lib/anaconda-runtime/loader/shutdown to @initrd@ sbin
copy @instroot@ usr/lib/anaconda-runtime/loader/linuxrc.s390 to @initrd@ sbin/init
copy @instroot@ usr/lib/anaconda-runtime/loader/lsznet.raw to @initrd@ sbin/lsznet
copy @instroot@ usr/lib/anaconda-runtime/loader/controlunits.sh @initrd@ sbin/controlunits
copy @instroot@ usr/sbin/dasdfmt to @initrd@ sbin
# setup shell environment
edit @initrd@/etc/protocols text "tcp\t6\tTCP\n"
copy @instroot@ @libdir@/security/pam_limits.so to @initrd@ @libdir@/security
copy @instroot@ @libdir@/security/pam_env.so to @initrd@ @libdir@/security
copy @instroot@ @libdir@/security/pam_unix.so to @initrd@ @libdir@/security
copy @instroot@ @libdir@/security/pam_deny.so to @initrd@ @libdir@/security
copy @instroot@ etc/pam.d/other to @initrd@ etc/pam.d
copy @datadir@ pam.d/login to @initrd@ etc/pam.d/login
copy @datadir@ pam.d/login to @initrd@ etc/pam.d/sshd
copy @datadir@ pam.d/login to @initrd@ etc/pam.d/remote
copy @instroot@ etc/security/limits.conf to @initrd@ etc/security
copy @Instroot@ etc/security/pam_env.conf to @initrd@ etc/security
# generate keys
makedir @initrd@/etc/ssh mode 0700
genkey @initrd@/etc/ssh/ssh_host_key type rsa1
genkey @initrd@/etc/ssh/ssh_host_rsa_key type rsa
genkey @initrd@/etc/ssh/ssh_host_dsa_key type dsa
copy @datadir@ sshd/sshd_config to @initrd@ etc/ssh/sshd_config
chmod @initrd@/etc/ssh/sshd_config mode 0600
# copy in the binaries
copy @instroot@ bin/login to @initrd@ sbin/login
copy @instroot@ usr/sbin/sshd to @initrd@ sbin/sshd

View File

@ -1 +0,0 @@
initrd.s390

View File

@ -1 +0,0 @@
initrd.i386

View File

@ -1 +0,0 @@
initrd.i386

8
etc/lorax/config.i386 Normal file
View File

@ -0,0 +1,8 @@
[lorax]
packages:
grub gpart syslinux memtest86+ efibootmgr dmidecode pcmciautils
kernel-PAE
initrd_template=templates/initrd/initrd.i386
scrubs_template=templates/scrubs/scrubs.i386

1
etc/lorax/config.i586 Symbolic link
View File

@ -0,0 +1 @@
config.i386

23
etc/lorax/config.noarch Normal file
View File

@ -0,0 +1,23 @@
[lorax]
packages:
anaconda kernel *firmware* joe gnome-icon-theme fedora-icon-theme
xorg-x11-server-Xorg firstaidkit bzip2 busybox selinux-policy-targeted
python-imaging hal specspo xorg-x11-fonts-misc xorg-x11-drivers rhpxl
ntfs-3g ntfsprogs xfsprogs xfsdump reiserfs-utils gfs2-utils jfsutils
nfs-utils btrfs-progs mesa-dri-drivers dogtail rsh rsync prelink
smartmontools iscsi-initiator-utils samba-client mtr gtk-nodoka-engine
ftp openssh-clients gtk+ gdk-pixbuf madan-fonts lklug-fonts
xorg-x11-fonts-ethiopic un-core-fonts-dotum man yum-fedorakmod
/etc/gtk-2.0/gtkrc
modules:
sunrpc lockd floppy cramfs loop edd pcspkr squashfs
ipv6 virtio_pci ohci-hcd uhci-hcd ehci-hcd usbhid mousedev usb-storage
sd_mod sr_mod ub appletouch ohci1394 sbp2 fw-ohci fw-sbp2 firewire-sbp2
firewire-ohci mmc-block sdhci sdhci-pci ide-cd ide-cd_mod sr_mod sg st
sd_mod scsi_mod iscsi_tcp iscsi_ibft fat msdos vfat ext2 ext3 ext4 reiserfs
jfs xfs gfs2 cifs nfs fuse btrfs dm-mod dm-zero dm-snapshot dm-mirror
dm-multipath dm-round-robin dm-crypt raid0 raid1 raid5 raid6 raid456 raid10
linear sha256_generic cbc xts lrw aes_generic crypto_blkcipher crc32c ecb
arc4 yenta_socket i82365 tcic pcmcia =scsi =net =drm

11
etc/lorax/config.s390 Normal file
View File

@ -0,0 +1,11 @@
[lorax]
packages: s390utils binutils libgcc tcp_wrappers sed net-tools openssh
openssh-server coreutils login initscripts portmap pam mount modutils
s390utils-cmsfs strace xorg-x11-xauth xorg-x11-libs
modules: zfcp tape390 dasd_diag_mod dasd_eckd_mod dasd_fba_mod dasd_mod
ctc netiucv smsgiucv lcs qdio qeth ccwgroup crypto_api xfrm_nalgo
initrd_template=templates/initrd/initrd.s390
scrubs_template=templates/scrubs/scrubs.s390

1
etc/lorax/config.s390x Symbolic link
View File

@ -0,0 +1 @@
config.s390

1
etc/lorax/config.x86_64 Symbolic link
View File

@ -0,0 +1 @@
config.i386

View File

@ -0,0 +1,242 @@
## create required directories
makedirs ${initrd}/lib
makedirs ${initrd}/modules
makedirs ${initrd}/firmware
symlink name ${initrd}/lib/modules target ../modules
symlink name ${initrd}/lib/firmware target ../firmware
makedirs ${initrd}/sbin
makedirs ${initrd}/dev
makedirs ${initrd}/etc
makedirs ${initrd}/etc/udev/rules.d
makedirs ${initrd}/lib/udev/rules.d
makedirs ${initrd}/proc
makedirs ${initrd}/selinux
makedirs ${initrd}/sys
makedirs ${initrd}/etc/terminfo/{a,d,l,s,v,x,g}
makedirs ${initrd}/tmp
makedirs ${initrd}/usr/libexec
makedirs ${initrd}/usr/${libdir}/NetworkManager
makedirs ${initrd}/usr/share/dbus-1/system-services
makedirs ${initrd}/var/cache/hald
makedirs ${initrd}/var/lib/dbus
makedirs ${initrd}/var/lib/dhclient
makedirs ${initrd}/var/lock/rpm
makedirs ${initrd}/var/run
makedirs ${initrd}/var/run/dbus
makedirs ${initrd}/var/run/hald
makedirs ${initrd}/var/run/NetworkManager
makedirs ${initrd}/etc/dbus-1/system.d
makedirs ${initrd}/etc/modprobe.d
makedirs ${initrd}/etc/NetworkManager/dispatcher.d
makedirs ${initrd}/${libdir}/dbus-1
makedirs ${initrd}/etc/sysconfig/network-scripts
makedirs ${initrd}/usr/share/PolicyKit/policy
makedirs ${initrd}/etc/PolicyKit
makedirs ${initrd}/var/lib/misc
makedirs ${initrd}/etc/hal/fdi
makedirs ${initrd}/usr/share/hal/fdi
makedirs ${initrd}/usr/share/hwdata
makedirs ${initrd}/etc/rc.d/init.d
makedirs ${initrd}/usr/sbin
makedirs ${initrd}/var/run/wpa_supplicant
## set the buildarch
edit ${initrd}/etc/arch text "${arch}"
## copy etc stuff
copy ${instroot} etc/passwd to ${initrd} etc
chmod ${initrd}/etc/passwd mode 0644
copy ${instroot} etc/group to ${initrd} etc
chmod ${initrd}/etc/group mode 0644
copy ${instroot} etc/nsswitch.conf to ${initrd} etc
chmod ${initrd}/etc/nsswitch.conf mode 0644
copy ${instroot} etc/hosts to ${initrd} etc
chmod ${initrd}/etc/hosts mode 0644
## copy mount/umount
copy ${instroot} bin/mount to ${initrd} sbin
copy ${instroot} bin/umount to ${initrd} sbin
copy ${instroot} sbin/mount.* to ${initrd} sbin
copy ${instroot} sbin/umount.* to ${initrd} sbin
## copy udev
copy ${instroot} sbin/udevd to ${initrd} sbin
copy ${instroot} sbin/udevadm to ${initrd} sbin
symlink name ${initrd}/sbin/udevinfo target udevadm
symlink name ${initrd}/sbin/udevsettle target udevadm
## udev rules
copy ${instroot} etc/udev/udev.conf to ${initrd} etc/udev
chmod ${initrd}/etc/udev/udev.conf mode 0644
copy ${instroot} lib/udev/* to ${initrd} lib/udev
##chmod ${initrd}/lib/udev/* mode 0644
remove ${initrd}/lib/udev/rules.d/*persistent*
remove ${initrd}/lib/udev/rules.d/*generator*
copy ${instroot} etc/udev/rules.d/*.rules to ${initrd} etc/udev/rules.d
chmod ${initrd}/etc/udev/rules.d/*.rules mode 0644
## copy bash
copy ${instroot} bin/bash to ${initrd} sbin
symlink name ${initrd}/sbin/sh target bash
copy ${instroot} sbin/consoletype to ${initrd} sbin
copy ${instroot} usr/bin/logger to ${initrd} sbin
copy ${instroot} etc/rc.d/init.d/functions to ${initrd} etc/rc.d/init.d
copy ${instroot} etc/sysconfig/network-scripts/network-functions* to \
${initrd} etc/sysconfig/network-scripts
symlink name ${initrd}/etc/init.d target /etc/rc.d/init.d
## dhcp and dhcpv6 client daemons and support programs
copy ${instroot} sbin/dhclient to ${initrd} sbin
copy ${instroot} sbin/dhclient-script to ${initrd} sbin
copy ${instroot} sbin/dhcp6c to ${initrd} sbin
copy ${instroot} sbin/arping to ${initrd} sbin
copy ${instroot} sbin/ifconfig to ${initrd} sbin
copy ${instroot} sbin/ip to ${initrd} sbin
copy ${instroot} bin/ipcalc to ${initrd} sbin
copy ${instroot} bin/hostname to ${initrd} sbin
copy ${instroot} sbin/ethtool to ${initrd} sbin
copy ${instroot} sbin/route to ${initrd} sbin
touch ${initrd}/etc/resolv.conf
## hwdata
copy ${instroot} usr/share/hwdata/pci.ids to ${initrd} usr/share/hwdata
copy ${instroot} usr/share/hwdata/usb.ids to ${initrd} usr/share/hwdata
## hal
copy ${instroot} usr/sbin/hald to ${initrd} sbin
copy ${instroot} usr/libexec/hald-runner to ${initrd} usr/libexec
copy ${instroot} usr/libexec/hald-generate-fdi-cache to ${initrd} usr/libexec
copy ${instroot} usr/libexec/hal*storage* to ${initrd} usr/libexec
touch ${initrd}/var/run/hald.acl-list
copy ${instroot} usr/share/hal/fdi/* to ${initrd} usr/share/hal/fdi
copy ${instroot} etc/hal/fdi/* to ${initrd} etc/hal/fdi
copy ${instroot} etc/dbus-1/system.d/hal.conf to ${initrd} etc/dbus-1/system.d
## policykit
copy ${instroot} etc/PolicyKit/PolicyKit.conf to ${initrd} etc/PolicyKit
copy ${instroot} \
usr/share/dbus-1/system-services/org.freedesktop.PolicyKit.service to \
${initrd} usr/share/dbus-1/system-services
copy ${instroot} usr/share/PolicyKit/policy/org.freedesktop.policykit.policy \
to ${initrd} usr/share/PolicyKit/policy
copy ${instroot} var/lib/misc/PolicyKit.reload to ${initrd} var/lib/misc
## dbus
copy ${instroot} bin/dbus-uuidgen to ${initrd} sbin
copy ${instroot} bin/dbus-daemon to ${initrd} sbin
copy ${instroot} etc/dbus-1/system.conf to ${initrd} etc/dbus-1
copy ${instroot} ${libdir}/dbus-1/dbus-daemon-launch-helper to \
${initrd} ${libdir}/dbus-1
chown ${initrd}/${libdir}/dbus-1/dbus-daemon-launch-helper user root group dbus
chmod ${initrd}/${libdir}/dbus-1/dbus-daemon-launch-helper mode 04750
## wpa_supplicant
copy ${instroot} usr/sbin/wpa_passphrase to ${initrd} usr/sbin
copy ${instroot} usr/sbin/wpa_supplicant to ${initrd} usr/sbin
copy ${instroot} etc/dbus-1/system.d/wpa_supplicant.conf to \
${initrd} etc/dbus-1/system.d
copy ${instroot} etc/wpa_supplicant/wpa_supplicant.conf to \
${initrd} etc/wpa_supplicant
copy ${instroot} \
usr/share/dbus-1/system-services/fi.epitest.hostap.WPASupplicant.service \
to ${initrd} usr/share/dbus-1/system-services
## networkmanager
copy ${instroot} usr/sbin/NetworkManager to ${initrd} usr/sbin
copy ${instroot} usr/sbin/nm-system-settings to ${initrd} usr/sbin
copy ${instroot} etc/dbus-1/system.d/nm-*.conf to ${initrd} etc/dbus-1/system.d
copy ${instroot} etc/dbus-1/system.d/NetworkManager.conf to \
${initrd} etc/dbus-1/system.d
copy ${instroot} etc/NetworkManager/nm-system-settings.conf to \
${initrd} etc/NetworkManager
copy ${instroot} \
usr/${libdir}/NetworkManager/libnm-settings-plugin-ifcfg-fedora.so to \
${initrd} usr/${libdir}/NetworkManager
copy ${instroot} usr/libexec/nm-* to ${initrd} usr/libexec
copy ${instroot} usr/share/dbus-1/system-services/org.freedesktop.NetworkManagerSystemSettings.service to ${initrd} usr/share/dbus-1/system-services
copy ${instroot} usr/share/dbus-1/system-services/org.freedesktop.nm_dispatcher.service to ${initrd} usr/share/dbus-1/system-services
## modprobe
copy ${instroot} sbin/modprobe to ${initrd} sbin
copy ${instroot} sbin/insmod to ${initrd} sbin
copy ${instroot} sbin/rmmod to ${initrd} sbin
## profile
edit ${initrd}/.profile text "PATH=/bin:/usr/bin:/usr/sbin:/mnt/sysimage/sbin:/mnt/sysimage/usr/sbin:/mnt/sysimage/bin:/mnt/sysimage/usr/bin\nexport PATH"
## terminfos
copy ${instroot} usr/share/terminfo/a/ansi to ${initrd} etc/terminfo/a \
nosymlinks
copy ${instroot} usr/share/terminfo/d/dumb to ${initrd} etc/terminfo/d \
nosymlinks
copy ${instroot} usr/share/terminfo/l/linux to ${initrd} etc/terminfo/l \
nosymlinks
copy ${instroot} usr/share/terminfo/s/screen to ${initrd} etc/terminfo/s \
nosymlinks
copy ${instroot} usr/share/terminfo/v/vt100 to ${initrd} etc/terminfo/v \
nosymlinks
copy ${instroot} usr/share/terminfo/v/vt100-nav to ${initrd} etc/terminfo/v \
nosymlinks
copy ${instroot} usr/share/terminfo/v/vt102 to ${initrd} etc/terminfo/v \
nosymlinks
copy ${instroot} usr/share/terminfo/x/xterm to ${initrd} etc/terminfo/x \
nosymlinks
copy ${instroot} usr/share/terminfo/x/xterm-color to ${initrd} etc/terminfo/x \
nosymlinks
copy ${instroot} usr/share/terminfo/g/gnome to ${initrd} etc/terminfo/g \
nosymlinks
chmod ${initrd}/etc/terminfo/*/* mode 0644
## misc
copy ${instroot} bin/awk to ${initrd} sbin
copy ${instroot} bin/gawk to ${initrd} sbin
copy ${instroot} bin/egrep to ${initrd} sbin
copy ${instroot} bin/fgrep to ${initrd} sbin
copy ${instroot} bin/grep to ${initrd} sbin
copy ${instroot} bin/kill to ${initrd} sbin
copy ${instroot} bin/ln to ${initrd} sbin
copy ${instroot} bin/readlink to ${initrd} sbin
copy ${instroot} bin/rm to ${initrd} sbin
copy ${instroot} bin/rmdir to ${initrd} sbin
copy ${instroot} bin/sed to ${initrd} sbin
copy ${instroot} bin/sleep to ${initrd} sbin
copy ${instroot} bin/touch to ${initrd} sbin
symlink name ${initrd}/init target /sbin/init
symlink name ${initrd}/etc/mtab target /proc/mounts
symlink name ${initrd}/bin target sbin
symlink name ${initrd}/var/lib/xkb target ../../tmp
## loader
copy ${instroot} usr/lib/anaconda-runtime/loader/loader to ${initrd} sbin
copy ${instroot} usr/lib/anaconda-runtime/loader/loader.tr to ${initrd} etc
chmod ${initrd}/etc/loader.tr mode 0644
## indirect dependencies
##copy ${instroot} ${libdir}/ld-linux.so.2 to ${initrd} ${libdir}
copy ${instroot} ${libdir}/libcom_err.so.2 to ${initrd} ${libdir}
copy ${instroot} ${libdir}/libdbus-glib-1.so.2 to ${initrd} ${libdir}
copy ${instroot} ${libdir}/libfreebl3.so to ${initrd} ${libdir}
copy ${instroot} ${libdir}/libgcc_s.so.1 to ${initrd} ${libdir}
copy ${instroot} ${libdir}/libnss_dns.so.2 to ${initrd} ${libdir}
copy ${instroot} ${libdir}/libnss_files.so.2 to ${initrd} ${libdir}
copy ${instroot} ${libdir}/libsoftokn3.so to ${initrd} ${libdir}
copy ${instroot} usr/${libdir}/libsqlite3.so.0 to ${initrd} usr/${libdir}
## langtable
copy ${instroot} usr/lib/anaconda/lang-table to ${initrd} etc

View File

@ -0,0 +1,11 @@
<%include file="includes/initrd" />
## loader
copy ${instroot} usr/lib/anaconda-runtime/loader/init to ${initrd} sbin/init
symlink name ${initrd}/sbin/reboot target init
symlink name ${initrd}/sbin/halt target init
symlink name ${initrd}/sbin/poweroff target init
## screenfont
copy ${instroot} usr/lib/anaconda-runtime/screenfont-${arch}.gz to \
${initrd} etc/screenfont.gz

View File

@ -0,0 +1,51 @@
<%include file="includes/initrd" />
## create required directories
makedirs ${initrd}/var/empty/sshd mode 0111
makedirs ${initrd}/etc/security
makedirs ${initrd}/${libdir}/security
## copy some files
copy ${instroot} usr/bin/xauth to ${initrd} sbin
copy ${instroot} usr/sbin/cmsfs* to ${initrd} sbin
copy ${instroot} ${libdir}/libpam_misc.so.0.* to ${initrd} ${libdir}/libpam_misc.so.0
copy ${instroot} ${libdir}/libwrap*.so* to ${initrd} ${libdir}
symlink name ${initrd}/var/state/xkb target /tmp
## loader
copy ${instroot} usr/lib/anaconda-runtime/loader/shutdown to ${initrd} sbin
copy ${instroot} usr/lib/anaconda-runtime/loader/linuxrc.s390 to \
${initrd} sbin/init
copy ${instroot} usr/lib/anaconda-runtime/loader/lsznet.raw to \
${initrd} sbin/lsznet
copy ${instroot} usr/lib/anaconda-runtime/loader/controlunits.sh to \
${initrd} sbin/controlunits
copy ${instroot} usr/sbin/dasdfmt to ${initrd} sbin
## setup shell environment
edit ${initrd}/etc/protocols text "tcp\t6\tTCP\n"
copy ${instroot} ${libdir}/security/pam_limits.so to \
${initrd} ${libdir}/security
copy ${instroot} ${libdir}/security/pam_env.so to ${initrd} ${libdir}/security
copy ${instroot} ${libdir}/security/pam_unix.so to ${initrd} ${libdir}/security
copy ${instroot} ${libdir}/security/pam_deny.so to ${initrd} ${libdir}/security
copy ${instroot} etc/pam.d/other to ${initrd} etc/pam.d
copy ${instroot} etc/security/limits.conf to ${initrd} etc/security
copy ${instroot} etc/security/pam_env.conf to ${initrd} etc/security
## generate ssh keys
makedirs ${initrd}/etc/ssh mode 0700
gensshkey ${initrd}/etc/ssh/ssh_host_key type rsa1
gensshkey ${initrd}/etc/ssh/ssh_host_rsa_key type rsa
gensshkey ${initrd}/etc/ssh/ssh_host_dsa_key type dsa
chmod ${initrd}/etc/ssh/sshd_config mode 0600
## copy in the binaries
copy ${instroot} bin/login to ${initrd} sbin/login
copy ${instroot} usr/sbin/sshd to ${initrd} sbin/sshd

View File

@ -0,0 +1,103 @@
## remove unnecessary directories from /
remove ${instroot}/boot
remove ${instroot}/dev
remove ${instroot}/home
remove ${instroot}/media
remove ${instroot}/mnt
remove ${instroot}/opt
remove ${instroot}/root
remove ${instroot}/selinux
remove ${instroot}/srv
remove ${instroot}/sys
remove ${instroot}/tmp
## remove directories from /usr
remove ${instroot}/usr/etc
remove ${instroot}/usr/games
remove ${instroot}/usr/include
remove ${instroot}/usr/kerberos
remove ${instroot}/usr/local
remove ${instroot}/usr/tmp
## remove modules and firmware directories
remove ${instroot}/lib/modules
remove ${instroot}/lib/firmware
## remove directories from /var
remove ${instroot}/var/db
remove ${instroot}/var/empty
remove ${instroot}/var/games
remove ${instroot}/var/local
remove ${instroot}/var/lock
remove ${instroot}/var/log
remove ${instroot}/var/mail
remove ${instroot}/var/nis
remove ${instroot}/var/opt
remove ${instroot}/var/preserve
remove ${instroot}/var/spool
remove ${instroot}/var/tmp
remove ${instroot}/var/yp
## remove directories from /lib
remove ${instroot}/lib/i686
remove ${instroot}/lib/kbd
remove ${instroot}/lib/rtkaio
remove ${instroot}/lib/security
remove ${instroot}/lib/tls
remove ${instroot}/lib/xtables
## remove directories from /etc
remove ${instroot}/etc/ConsoleKit
remove ${instroot}/etc/X11
remove ${instroot}/etc/alternatives
remove ${instroot}/etc/asterisk
remove ${instroot}/etc/avahi
remove ${instroot}/etc/blkid
remove ${instroot}/etc/bonobo*
remove ${instroot}/etc/chkconfig*
remove ${instroot}/etc/cron.*
remove ${instroot}/etc/default
remove ${instroot}/etc/depmod.d
remove ${instroot}/etc/dirmngr
remove ${instroot}/etc/dnsmasq.d
remove ${instroot}/etc/event.d
remove ${instroot}/etc/firmware
remove ${instroot}/etc/firstaidkit
remove ${instroot}/etc/gconf
remove ${instroot}/etc/gcrypt
remove ${instroot}/etc/gnome-vfs*
remove ${instroot}/etc/gnupg
remove ${instroot}/etc/gtk
remove ${instroot}/etc/hotplug
remove ${instroot}/etc/init.d
remove ${instroot}/etc/iproute2
remove ${instroot}/etc/iscsi
remove ${instroot}/etc/kernel
remove ${instroot}/etc/ld.so.conf.d
remove ${instroot}/etc/logrotate.d
remove ${instroot}/etc/lvm
remove ${instroot}/etc/makedev.d
remove ${instroot}/etc/modprobe.d
remove ${instroot}/etc/netplug*
remove ${instroot}/etc/ntp
remove ${instroot}/etc/openldap
remove ${instroot}/etc/opt
remove ${instroot}/etc/pam.d
remove ${instroot}/etc/pki
remove ${instroot}/etc/pm
remove ${instroot}/etc/popt.d
remove ${instroot}/etc/ppp
remove ${instroot}/etc/prelink.conf.d
remove ${instroot}/etc/profile.d
remove ${instroot}/etc/rc?.d
remove ${instroot}/etc/rwtab.d
remove ${instroot}/etc/samba
remove ${instroot}/etc/sasl2
remove ${instroot}/etc/security
remove ${instroot}/etc/setuptool.d
remove ${instroot}/etc/skel
remove ${instroot}/etc/ssh
remove ${instroot}/etc/statetab.d
remove ${instroot}/etc/terminfo
remove ${instroot}/etc/xdg
remove ${instroot}/etc/xinetd.d

View File

@ -1,84 +0,0 @@
fat
vfat
nfs
sunrpc
lockd
floppy
cramfs
loop
edd
pcspkr
squashfs
ipv6
virtio_pci
ohci-hcd
uhci-hcd
ehci-hcd
usbhid
mousedev
usb-storage
sd_mod
sr_mod
ub
appletouch
ohci1394
sbp2
fw-ohci
fw-sbp2
firewire-sbp2
firewire-ohci
mmc-block
sdhci
sdhci-pci
ide-cd
ide-cd_mod
sr_mod
sg
st
sd_mod
scsi_mod
iscsi_tcp
iscsi_ibft
fat
msdos
vfat
ext2
ext3
ext4
reiserfs
jfs
xfs
gfs2
cifs
fuse
btrfs
dm-mod
dm-zero
dm-snapshot
dm-mirror
dm-multipath
dm-round-robin
dm-crypt
raid0
raid1
raid5
raid6
raid456
raid10
linear
sha256_generic
cbc
xts
lrw
aes_generic
crypto_blkcipher
crc32c
ecb
arc4
yenta_socket
i82365
tcic
pcmcia
=scsi
=net
=drm

View File

@ -1,2 +0,0 @@
tgafb
crc32

View File

@ -1,15 +0,0 @@
zfcp
tape390
dasd_diag_mod
dasd_eckd_mod
dasd_fba_mod
dasd_mod
ctc
netiucv
smsgiucv
lcs
qdio
qeth
ccwgroup
crypto_api
xfrm_nalgo

View File

@ -1 +0,0 @@
modules.s390

View File

@ -1,43 +0,0 @@
joe
gnome-icon-theme
fedora-icon-theme
xorg-x11-server-Xorg
firstaidkit
bzip2
busybox
selinux-policy-targeted
python-imaging
hal
specspo
xorg-x11-fonts-misc
xorg-x11-drivers
rhpxl
ntfs-3g
ntfsprogs
xfsprogs
xfsdump
reiserfs-utils
gfs2-utils
jfsutils
nfs-utils
btrfs-progs
mesa-dri-drivers
dogtail
rsh
rsync
prelink
smartmontools
iscsi-initiator-utils
samba-client
mtr
gtk-nodoka-engine
ftp
openssh-clients
gtk+
gdk-pixbuf
madan-fonts
lklug-fonts
xorg-x11-fonts-ethiopic
un-core-fonts-dotum
man
yum-fedorakmod

View File

@ -1 +0,0 @@
aboot

View File

@ -1,7 +0,0 @@
pcmciautils
grub
dmidecode
efibootmgr
gpart
syslinux
memtest86+

View File

@ -1 +0,0 @@
packages.i386

View File

@ -1,3 +0,0 @@
dmidecode
efibootmgr
elilo

View File

@ -1,6 +0,0 @@
pcmciautils
pdisk
yaboot
hfsutils
fbset
ppc64-utils

View File

@ -1 +0,0 @@
packages.ppc

View File

@ -1,19 +0,0 @@
s390utils
binutils
libgcc
tcp_wrappers
sed
net-tools
openssh
openssh-server
coreutils
login
initscripts
portmap
pam
mount
modutils
s390utils-cmsfs
strace
xorg-x11-xauth
xorg-x11-libs

View File

@ -1 +0,0 @@
packages.s390

View File

@ -1,2 +0,0 @@
tilo
silo

View File

@ -1 +0,0 @@
packages.i386

View File

@ -1 +0,0 @@
scrubs.i386

View File

@ -1,103 +0,0 @@
# remove unnecessary directories from /
remove @instroot@/boot
remove @instroot@/dev
remove @instroot@/home
remove @instroot@/media
remove @instroot@/mnt
remove @instroot@/opt
remove @instroot@/root
remove @instroot@/selinux
remove @instroot@/srv
remove @instroot@/sys
remove @instroot@/tmp
# remove directories from /usr
remove @instroot@/usr/etc
remove @instroot@/usr/games
remove @instroot@/usr/include
remove @instroot@/usr/kerberos
remove @instroot@/usr/local
remove @instroot@/usr/tmp
# remove modules and firmware directories
remove @instroot@/lib/modules
remove @instroot@/lib/firmware
# remove directories from /var
remove @instroot@/var/db
remove @instroot@/var/empty
remove @instroot@/var/games
remove @instroot@/var/local
remove @instroot@/var/lock
remove @instroot@/var/log
remove @instroot@/var/mail
remove @instroot@/var/nis
remove @instroot@/var/opt
remove @instroot@/var/preserve
remove @instroot@/var/spool
remove @instroot@/var/tmp
remove @instroot@/var/yp
# remove directories from /lib
remove @instroot@/lib/i686
remove @instroot@/lib/kbd
remove @instroot@/lib/rtkaio
remove @instroot@/lib/security
remove @instroot@/lib/tls
remove @instroot@/lib/xtables
# remove directories from /etc
remove @instroot@/etc/ConsoleKit
remove @instroot@/etc/X11
remove @instroot@/etc/alternatives
remove @instroot@/etc/asterisk
remove @instroot@/etc/avahi
remove @instroot@/etc/blkid
remove @instroot@/etc/bonobo*
remove @instroot@/etc/chkconfig*
remove @instroot@/etc/cron.*
remove @instroot@/etc/default
remove @instroot@/etc/depmod.d
remove @instroot@/etc/dirmngr
remove @instroot@/etc/dnsmasq.d
remove @instroot@/etc/event.d
remove @instroot@/etc/firmware
remove @instroot@/etc/firstaidkit
remove @instroot@/etc/gconf
remove @instroot@/etc/gcrypt
remove @instroot@/etc/gnome-vfs*
remove @instroot@/etc/gnupg
remove @instroot@/etc/gtk
remove @instroot@/etc/hotplug
remove @instroot@/etc/init.d
remove @instroot@/etc/iproute2
remove @instroot@/etc/iscsi
remove @instroot@/etc/kernel
remove @instroot@/etc/ld.so.conf.d
remove @instroot@/etc/logrotate.d
remove @instroot@/etc/lvm
remove @instroot@/etc/makedev.d
remove @instroot@/etc/modprobe.d
remove @instroot@/etc/netplug*
remove @instroot@/etc/ntp
remove @instroot@/etc/openldap
remove @instroot@/etc/opt
remove @instroot@/etc/pam.d
remove @instroot@/etc/pki
remove @instroot@/etc/pm
remove @instroot@/etc/popt.d
remove @instroot@/etc/ppp
remove @instroot@/etc/prelink.conf.d
remove @instroot@/etc/profile.d
remove @instroot@/etc/rc?.d
remove @instroot@/etc/rwtab.d
remove @instroot@/etc/samba
remove @instroot@/etc/sasl2
remove @instroot@/etc/security
remove @instroot@/etc/setuptool.d
remove @instroot@/etc/skel
remove @instroot@/etc/ssh
remove @instroot@/etc/statetab.d
remove @instroot@/etc/terminfo
remove @instroot@/etc/xdg
remove @instroot@/etc/xinetd.d

View File

@ -1 +0,0 @@
scrubs.i386

View File

@ -1 +0,0 @@
scrubs.i386

View File

@ -1 +0,0 @@
scrubs.ppc

View File

@ -1 +0,0 @@
scrubs.s390

View File

@ -1 +0,0 @@
scrubs.i386

View File

@ -1 +0,0 @@
scrubs.i386

View File

@ -2,119 +2,11 @@
#
# lorax
# lorax executable script
#
# Copyright (C) 2009 Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# Red Hat Author(s): David Cantrell <dcantrell@redhat.com>
# Martin Gracik <mgracik@redhat.com>
#
import sys
import os
from optparse import OptionParser, OptionGroup
import pylorax
import pylorax.launcher
if __name__ == "__main__":
version = "%s 0.1" % (os.path.basename(sys.argv[0]),)
usage = "%prog -p PRODUCT -v VERSION -r RELEASE -o OUTPUTDIR REPOSITORY"
parser = OptionParser(usage=usage)
def check_dir(option, opt_str, value, parser):
if os.path.isdir(value):
setattr(parser.values, option.dest, value)
else:
parser.error("'%s' is not a directory" % (value,))
# required
# XXX "options" should not be required
group = OptionGroup(parser, "Required")
group.add_option("-p", "--product", help="Product name",
metavar="STRING")
group.add_option("-v", "--version", help="Version identifier",
metavar="STRING")
group.add_option("-r", "--release", help="Release information or comment",
metavar="STRING")
group.add_option("-o", "--output", help="Destination directory",
metavar="PATHSPEC")
parser.add_option_group(group)
# optional
# XXX are all of these used?
group = OptionGroup(parser, "Optional")
group.add_option("-d", "--debug", help="Enable debugging messages",
action="store_true", default=False)
group.add_option("-t", "--variant", help="Variant name",
metavar="STRING")
group.add_option("-b", "--bugurl", help="Bug reporting URL for the product",
metavar="URL",
default="your distribution provided bug reporting tool")
group.add_option("-u", "--updates", help="Directory containing updates",
metavar="PATHSPEC")
group.add_option("-m", "--mirrorlist",
help="Mirror list repository (may be listed multiple times)",
metavar="REPOSITORY", action="append", default=[])
group.add_option("-c", "--confdir", help="Path to config files (default: /etc/lorax)",
metavar="PATHSPEC", action="callback", callback=check_dir,
type="string", default="/etc/lorax")
group.add_option("-C", "--cleanup", help="Clean up on exit",
action="store_true", default=False)
group.add_option("-V", help="Print version and exit",
action="store_true", default=False, dest="printver")
parser.add_option_group(group)
# additional information
group = OptionGroup(parser, "Additional information",
"A 'REPOSITORY' specification is a valid yum repository path.\n"
"See the man page lorax(8) for more information.")
parser.add_option_group(group)
(opts, args) = parser.parse_args()
if opts.printver:
print(version)
sys.exit(0)
if not opts.product or not opts.version or not opts.release or not opts.output:
parser.error("Missing required argument")
if not args:
parser.error("Missing repository")
config = pylorax.Config()
config.set(confdir=opts.confdir,
debug=opts.debug,
cleanup=opts.cleanup)
# required
config.set(product=opts.product,
version=opts.version,
release=opts.release,
outdir=opts.output,
repos=args)
# optional
config.set(variant=opts.variant,
bugurl=opts.bugurl,
updates=opts.updates,
mirrorlist=opts.mirrorlist)
lorax = pylorax.Lorax(config=config)
lorax.run()
pylorax.launcher.main(sys.argv)

File diff suppressed because it is too large Load Diff

View File

@ -1,126 +0,0 @@
import stat
import commands
import pwd
import grp
class Install(object):
def scrub(self):
# change tree permissions
root_uid = pwd.getpwnam('root')[2]
root_gid = grp.getgrnam('root')[2]
for root, files, dirs in os.walk(self.conf.treedir):
os.chown(root, root_uid, root_gid)
os.chmod(root, 0755)
for file in files:
path = os.path.join(root, file)
os.chown(path, root_uid, root_gid)
mode = os.stat(path).st_mode
if (mode & stat.S_IXUSR) or (mode & stat.S_IXGRP) or (mode & stat.S_IXOTH):
os.chmod(path, 0555)
else:
os.chmod(path, 0444)
# create ld.so.conf
ldsoconf = os.path.join(self.conf.treedir, 'etc', 'ld.so.conf')
touch(ldsoconf)
procdir = os.path.join(self.conf.treedir, 'proc')
if not os.path.isdir(procdir):
os.makedirs(procdir)
os.system('mount -t proc proc %s' % procdir)
f = open(ldsoconf, 'w')
f.write('/usr/kerberos/%s\n' % self.conf.libdir)
f.close()
cwd = os.getcwd()
os.chdir(self.conf.treedir)
os.system('/usr/sbin/chroot %s /sbin/ldconfig' % self.conf.treedir)
os.chdir(cwd)
if self.conf.buildarch not in ('s390', 's390x'):
# XXX this is not in usr
rm(os.path.join(self.conf.treedir, 'usr', 'sbin', 'ldconfig'))
# XXX why are we removing this?
#rm(os.path.join(self.conf.treedir, 'etc', 'ld.so.conf'))
os.system('umount %s' % procdir)
# make bash link
# XXX already exists
#if os.path.isfile(os.path.join(self.conf.treedir, 'bin', 'bash')):
# rm(os.path.join(self.conf.treedir, 'bin', 'ash'))
# os.symlink('bash', os.path.join(self.conf.treedir, 'bin', 'sh'))
# make awk link
# XXX already exists
#if os.path.isfile(os.path.join(self.conf.treedir, 'bin', 'gawk')):
# os.symlink('awk', os.path.join(self.conf.treedir, 'bin', 'gawk'))
# remove dirs from usr/lib
dirs = ('ConsoleKit', 'X11', 'alsa-lib', 'asterisk', 'avahi', 'booty', 'db4.5*', 'enchant', 'games', 'gio', 'gnome-keyring', 'gnome-vfs-2.0',
'krb5', 'libglade', 'libxslt-plugins', 'lua', 'notification-daemon*', 'nss', 'openssl', 'orbit-2.0', 'perl5', 'pkgconfig', 'plymouth',
'pm-utils', 'pppd', 'pygtk', 'rsyslog', 'samba', 'sasl2', 'sse2', 'syslinux', 'tc', 'tls', 'udev', 'window-manager-settings')
for dir in dirs:
rm(os.path.join(self.conf.treedir, 'usr', 'lib', dir))
# remove dirs from usr/share
dirs = ('GConf', 'NetworkManager', 'aclocal', 'alsa', 'application-registry', 'applications', 'asterisk', 'augeas', 'authconfig', 'avahi',
'awk', 'createrepo', 'desktop-directories', 'dict', 'doc', 'dogtail', 'emacs', 'empty', 'enchant', 'file', 'firmware', 'firmware-tools',
'firstboot', 'games', 'gnome*', 'gnupg', 'groff', 'gtk-*', 'help', 'i18n', 'info', 'kde*', 'librarian', 'libthai', 'lua',
'makebootfat', 'man', 'metacity', 'mime*', 'misc', 'myspell', 'octave', 'omf', 'pkgconfig', 'plymouth', 'pygtk', 'selinux',
'setuptool', 'sgml', 'system-config-firewall', 'system-config-network', 'system-config-users', 'tabset', 'tc', 'usermode', 'xml',
'xsessions', 'yum-cli', 'magic')
for dir in dirs:
rm(os.path.join(self.conf.treedir, 'usr', 'share', dir))
# remove dirs from usr/share/themes
dirs = ('AgingGorilla', 'Atlanta', 'Bright', 'Clearlooks', 'ClearlooksClassic', 'Crux', 'Default', 'Emacs', 'Esco', 'Glider', 'Glossy',
'HighContrast*', 'Industrial', 'Inverted', 'LargePrint', 'LowContrast*', 'Metabox', 'Mist', 'Raleigh', 'Simple', 'ThinIce')
for dir in dirs:
rm(os.path.join(self.conf.treedir, 'usr', 'share', 'themes', dir))
# remove dirs from usr/libexec
dirs = ('awk', 'gcc', 'getconf', 'openssh', 'plymouth')
for dir in dirs:
rm(os.path.join(self.conf.treedir, 'usr', 'libexec', dir))
# remove dirs from usr/share/locale
dirs = ('af_ZA', 'ca_ES', 'cs_CZ', 'de_DE', 'el_GR', 'en', 'en_US', 'es_ES', 'et_EE', 'fa_IR', 'fr_FR', 'he_IL', 'hr_HR', 'it_IT', 'ja_JP',
'ko_KR', 'nb_NO', 'nl_NL', 'nso', 'pl_PL', 'pt_PT', 'ru_RU', 'sr', 'sv_SE', 'uk_UA')
for dir in dirs:
rm(os.path.join(self.conf.treedir, 'usr', 'share', 'locale'))
# remove dirs from var/cache
dirs = ('dirmngr', 'fontconfig', 'man', 'yum')
map(lambda dir: rm(os.path.join(self.conf.treedir, 'var', 'cache', dir)), dirs)
# remove dirs from var/lib
dirs = ('alternatives', 'asterisk', 'authconfig', 'dhclient', 'dhcpv6', 'dirmngr', 'dnsmasq', 'games', 'iscsi', 'nfs', 'ntp', 'plymouth',
'rpcbind', 'rpm', 'samba', 'selinux', 'sepolgen', 'stateless', 'udev', 'yum', 'logrotate.status')
map(lambda dir: rm(os.path.join(self.conf.treedir, 'var', 'lib', dir)), dirs)
# remove dirs from var/run
dirs = ('ConsoleKit', 'NetworkManager', 'asterisk', 'avahi-daemon', 'console', 'dirmngr', 'hald', 'mdadm', 'netreport', 'plymouth',
'pm-utils', 'ppp', 'sepermit', 'setrans', 'winbindd', 'wpa_supplicant', 'utmp')
map(lambda dir: rm(os.path.join(self.conf.treedir, 'var', 'run', dir)), dirs)
# remove dirs from usr/share/terminfo
dirs = ('A', 'E', 'a', 'c', 'd', 'g', 'h', 'j', 'k', 'm', 'n', 'p', 'r', 's', 't', 'w')
map(lambda dir: rm(os.path.join(self.conf.treedir, 'usr', 'share', 'terminfo', dir)), dirs)
# remove dirs from usr/share/pixmaps
dirs = ('redhat', 'splash')
map(lambda dir: rm(os.path.join(self.conf.treedir, 'usr', 'share', 'pixmaps', dir)), dirs)
# remove dirs form usr/share/X11/fonts
dirs = ('OTF', 'encodings', 'util')
map(lambda dir: rm(os.path.join(self.conf.treedir, 'usr', 'share', 'X11', 'fonts', dir)), dirs)
# remove dirs from usr/lib/python2.5/site-packages
dirs = ('firmware_addon_dell', 'firmwaretools')
map(lambda dir: rm(os.path.join(self.conf.treedir, 'usr', 'lib', 'python2.5', 'site-packages', dir)), dirs)

View File

@ -1,58 +0,0 @@
#
# __init__.py
# actions parser
#
# Copyright (C) 2009 Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# Red Hat Author(s): Martin Gracik <mgracik@redhat.com>
#
import sys
import os
def getActions(verbose=False):
actions = {}
root, actions_dir = os.path.split(os.path.dirname(__file__))
sys.path.insert(0, root)
modules = set()
for filename in os.listdir(os.path.join(root, actions_dir)):
if filename.endswith(".py") and filename != "__init__.py":
basename, extension = os.path.splitext(filename)
modules.add(os.path.join(actions_dir, basename).replace("/", "."))
for module in modules:
if verbose:
print("Loading actions from module '%s'" % (module,))
imported = __import__(module, globals(), locals(), [module], -1)
try:
commands = getattr(imported, "COMMANDS")
except AttributeError:
if verbose:
print("No actions found")
continue
else:
for command, classname in commands.items():
if verbose:
print("Loaded: %s" % classname)
actions[command] = getattr(imported, classname)
sys.path.pop(0)
return actions

View File

@ -1,404 +0,0 @@
#
# base.py
# base actions
#
# Copyright (C) 2009 Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# Red Hat Author(s): Martin Gracik <mgracik@redhat.com>
#
import os
import re
import pwd
import grp
import glob
from pylorax.utils.fileutils import copy, move, remove, touch, edit, replace, chmod
# command:action mapping
# maps a template command to an action class
# if you want your new action to be supported, you have to include it in this mapping
COMMANDS = { 'copy': 'Copy',
'move': 'Move',
'remove': 'Remove',
'link': 'Link',
'touch': 'Touch',
'edit': 'Edit',
'replace': 'Replace',
'makedir': 'MakeDir',
'chmod': 'Chmod',
'chown': 'Chown',
'genkey': 'GenerateSSHKey' }
class LoraxAction(object):
"""Actions base class.
To create your own custom action, subclass this class and override the methods you need.
A valid action has to have a REGEX class variable, which specifies the format of the action
command line, so the needed parameters can be properly extracted from it.
All the work should be done in the execute method, which will be called from Lorax.
At the end, set the success to False, or True depending on the success or failure of your action.
If you need to install some package prior to executing the action, return an install pattern
with the "install" property. Lorax will get this first, and will try to install the needed
package.
Don't forget to include a command:action map for your new action in the COMMANDS dictionary.
Action classes which are not in the COMMANDS dictionary will not be loaded.
You can take a look at some of the builtin actions to get an idea of how to create your
own actions."""
REGEX = r'' # regular expression for extracting the parameters from the command line
def __init__(self):
if self.__class__ is LoraxAction:
raise TypeError, 'LoraxAction is an abstract class, cannot be used this way'
self._attrs = {}
self._attrs['success'] = None # success is None, if the action wasn't executed yet
def __str__(self):
return '%s: %s' % (self.__class__.__name__, self._attrs)
def execute(self, verbose=False):
"""This method is the main body of the action. Put all the "work" stuff in here."""
raise NotImplementedError, 'execute method not implemented for LoraxAction class'
@property
def success(self):
"""Returns if the action's execution was successful or not."""
return self._attrs['success']
@property
def install(self):
"""Returns a pattern that needs to be installed, prior to calling the execute method."""
return None
@property
def getDeps(self):
return None
##### builtin actions
class Copy(LoraxAction):
REGEX = r'^(?P<src_root>.*?)\s(?P<src_path>.*?)\sto\s(?P<dst_root>.*?)\s(?P<dst_path>.*?)(\s(?P<install>install))?(\s(?P<nolinks>nolinks))?$'
def __init__(self, **kwargs):
LoraxAction.__init__(self)
self._attrs['src_root'] = kwargs.get('src_root')
self._attrs['src_path'] = kwargs.get('src_path')
self._attrs['dst_root'] = kwargs.get('dst_root')
self._attrs['dst_path'] = kwargs.get('dst_path')
install = kwargs.get('install', False)
if install:
self._attrs['install'] = True
else:
self._attrs['install'] = False
nolinks = kwargs.get('nolinks', False)
if nolinks:
self._attrs['nolinks'] = True
else:
self._attrs['nolinks'] = False
def execute(self, verbose=False):
copy(src_root=self.src_root, src_path=self.src_path,
dst_root=self.dst_root, dst_path=self.dst_path,
nolinks=self.nolinks, ignore_errors=False, verbose=verbose)
self._attrs['success'] = True
@property
def src(self):
path = os.path.join(self._attrs['src_root'], self._attrs['src_path'])
return os.path.normpath(path)
@property
def src_root(self):
return self._attrs['src_root']
@property
def src_path(self):
return self._attrs['src_path']
@property
def dst(self):
path = os.path.join(self._attrs['dst_root'], self._attrs['dst_path'])
return os.path.normpath(path)
@property
def dst_root(self):
return self._attrs['dst_root']
@property
def dst_path(self):
return self._attrs['dst_path']
@property
def mode(self):
return self._attrs['mode']
@property
def install(self):
if self._attrs['install']:
return self._attrs['src']
else:
return None
@property
def getDeps(self):
return self.src
@property
def nolinks(self):
return self._attrs['nolinks']
class Move(Copy):
def execute(self, verbose=False):
move(src_root=self.src_root, src_path=self.src_path,
dst_root=self.dst_root, dst_path=self.dst_path,
nolinks=self.nolinks, ignore_errors=False, verbose=verbose)
self._attrs['success'] = True
class Remove(LoraxAction):
REGEX = r'^(?P<filename>.*?)$'
def __init__(self, **kwargs):
LoraxAction.__init__(self)
self._attrs['filename'] = kwargs.get('filename')
def execute(self, verbose=False):
remove(self.filename, verbose=verbose)
self._attrs['success'] = True
@property
def filename(self):
return self._attrs['filename']
class Link(LoraxAction):
REGEX = r'^(?P<name>.*?)\sto\s(?P<target>.*?)$'
def __init__(self, **kwargs):
LoraxAction.__init__(self)
self._attrs['name'] = kwargs.get('name')
self._attrs['target'] = kwargs.get('target')
def execute(self, verbose=False):
os.symlink(self.target, self.name)
self._attrs['success'] = True
@property
def name(self):
return self._attrs['name']
@property
def target(self):
return self._attrs['target']
@property
def install(self):
return self._attrs['target']
class Touch(LoraxAction):
REGEX = r'^(?P<filename>.*?)$'
def __init__(self, **kwargs):
LoraxAction.__init__(self)
self._attrs['filename'] = kwargs.get('filename')
def execute(self, verbose=False):
touch(filename=self.filename, verbose=verbose)
self._attrs['success'] = True
@property
def filename(self):
return self._attrs['filename']
class Edit(Touch):
REGEX = r'^(?P<filename>.*?)\stext\s"(?P<text>.*?)"(\s(?P<append>append))?$'
def __init__(self, **kwargs):
Touch.__init__(self, **kwargs)
self._attrs['text'] = kwargs.get('text')
append = kwargs.get('append', False)
if append:
self._attrs['append'] = True
else:
self._attrs['append'] = False
def execute(self, verbose=False):
edit(filename=self.filename, text=self.text, append=self.append, verbose=verbose)
self._attrs['success'] = True
@property
def text(self):
return self._attrs['text']
@property
def append(self):
return self._attrs['append']
@property
def install(self):
return self._attrs['filename']
class Replace(Touch):
REGEX = r'^(?P<filename>.*?)\sfind\s"(?P<find>.*?)"\sreplace\s"(?P<replace>.*?)"$'
def __init__(self, **kwargs):
Touch.__init__(self, **kwargs)
self._attrs['find'] = kwargs.get('find')
self._attrs['replace'] = kwargs.get('replace')
def execute(self, verbose=False):
replace(filename=self.filename, find=self.find, replace=self.replace, verbose=verbose)
self._attrs['success'] = True
@property
def find(self):
return self._attrs['find']
@property
def replace(self):
return self._attrs['replace']
@property
def install(self):
return self._attrs['filename']
class MakeDir(LoraxAction):
REGEX = r'^(?P<dir>.*?)(\smode\s(?P<mode>.*?))?$'
def __init__(self, **kwargs):
LoraxAction.__init__(self)
self._attrs['dir'] = kwargs.get('dir')
self._attrs['mode'] = kwargs.get('mode')
def execute(self, verbose=False):
if not os.path.isdir(self.dir):
if self.mode:
os.makedirs(self.dir, mode=int(self.mode))
else:
os.makedirs(self.dir)
self._attrs['success'] = True
@property
def dir(self):
return self._attrs['dir']
@property
def mode(self):
return self._attrs['mode']
class Chmod(LoraxAction):
REGEX = r'^(?P<filename>.*?)\smode\s(?P<mode>[0-9]*?)$'
def __init__(self, **kwargs):
LoraxAction.__init__(self)
self._attrs['filename'] = kwargs.get('filename')
self._attrs['mode'] = kwargs.get('mode')
def execute(self, verbose=False):
chmod(self.filename, self.mode)
self._attrs['success'] = True
@property
def filename(self):
return self._attrs['filename']
@property
def mode(self):
return self._attrs['mode']
class Chown(LoraxAction):
REGEX = r'^(?P<filename>.*?)\suser\s(?P<user>.*?)\sgroup\s(?P<group>.*?)$'
def __init__(self, **kwargs):
LoraxAction.__init__(self)
self._attrs['filename'] = kwargs.get('filename')
self._attrs['user'] = kwargs.get('user')
self._attrs['group'] = kwargs.get('group')
def execute(self, verbose=False):
uid = pwd.getpwnam(self.user)[2]
gid = grp.getgrnam(self.group)[2]
os.chown(self.filename, uid, gid)
self._attrs['success'] = True
@property
def filename(self):
return self._attrs['filename']
@property
def user(self):
return self._attrs['user']
@property
def group(self):
return self._attrs['group']
class GenerateSSHKey(LoraxAction):
REGEX = r'^(?P<file>.*?)\stype\s(?P<type>.*?)$'
def __init__(self, **kwargs):
LoraxAction.__init__(self)
self._attrs['file'] = kwargs.get('file')
self._attrs['type'] = kwargs.get('type')
def execute(self, verbose=False):
cmd = "/usr/bin/ssh-keygen -q -t %s -f %s -C '' -N ''" % (self.type, self.file)
err, output = commands.getstatusoutput(cmd)
if not err:
os.chmod(self.file, 0600)
os.chmod(self.file + '.pub', 0644)
self._attrs['success'] = True
@property
def file(self):
return self._attrs['file']
@property
def type(self):
return self._attrs['type']

View File

@ -1,90 +1,191 @@
#
# config.py
# lorax configuration
#
# Copyright (C) 2009 Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# Red Hat Author(s): Martin Gracik <mgracik@redhat.com>
#
from misc import seq
import os
import singleton
import output
class Container(object):
class LoraxConfig(singleton.Singleton):
def __init__(self, attrs=None):
self.__dict__["__internal"] = {}
self.__dict__["__internal"]["attrs"] = set()
def __init__(self):
self.confdir = "/etc/lorax"
self.datadir = "/usr/share/lorax"
if attrs:
self.addAttr(attrs)
def __str__(self):
return str(self.__makeDict())
def __iter__(self):
return iter(self.__makeDict())
def __getitem__(self, attr):
self.__checkInternal(attr)
if attr not in self.__dict__:
raise AttributeError, "object has no attribute '%s'" % attr
return self.__dict__[attr]
self.colors = True
self.encoding = "utf-8"
self.debug = False
self.cleanup = False
def __setattr__(self, attr, value):
raise AttributeError, "you can't do that, use addAttr() and/or set() instead"
output.Terminal.get().debug("[%s = %s]" % (attr, value))
singleton.Singleton.__setattr__(self, attr, value)
def __delattr__(self, attr):
raise AttributeError, "you can't do that, use delAttr() instead"
def addAttr(self, attrs):
for attr in filter(lambda attr: attr not in self.__dict__, seq(attrs)):
self.__checkInternal(attr)
class LoraxPaths(singleton.Singleton):
self.__dict__[attr] = None
self.__dict__["__internal"]["attrs"].add(attr)
def __init__(self):
self.datadir = LoraxConfig.get().datadir
self.installtree = LoraxConfig.get().installtree
def delAttr(self, attrs):
for attr in filter(lambda attr: attr in self.__dict__, seq(attrs)):
self.__checkInternal(attr)
@property
def ANACONDA_PACKAGE(self): return "anaconda"
del self.__dict__[attr]
self.__dict__["__internal"]["attrs"].discard(attr)
@property
def INITRD_DATADIR(self):
return os.path.join(self.datadir, "initrd")
def set(self, **kwargs):
unknown = set()
for attr, value in kwargs.items():
self.__checkInternal(attr)
@property
def INSTALLTREE_DATADIR(self):
return os.path.join(self.datadir, "installtree")
if attr in self.__dict__:
self.__dict__[attr] = value
else:
unknown.add(attr)
@property
def OUTPUTDIR_DATADIR(self):
return os.path.join(self.datadir, "outputdir")
return unknown
@property
def BOOTDIR(self):
return os.path.join(self.installtree, "boot")
def __makeDict(self):
d = {}
for attr in self.__dict__["__internal"]["attrs"]:
d[attr] = self.__dict__[attr]
@property
def BOOTDIR_IA64(self):
return os.path.join(self.BOOTDIR, "efi", "EFI", "redhat")
return d
@property
def ANACONDA_RUNTIME(self):
return os.path.join(self.installtree, "usr", "lib", "anaconda-runtime")
def __checkInternal(self, attr):
if attr.startswith("__"):
raise AttributeError, "do not mess with internal objects"
@property
def ANACONDA_BOOT(self):
return os.path.join(self.ANACONDA_RUNTIME, "boot")
@property
def SYSLINUXDIR(self):
return os.path.join(self.installtree, "usr", "lib", "syslinux")
@property
def ISOLINUXBIN(self):
return os.path.join(self.SYSLINUXDIR, "isolinux.bin")
@property
def SYSLINUXCFG(self):
return os.path.join(self.ANACONDA_BOOT, "syslinux.cfg")
@property
def GRUBCONF(self):
return os.path.join(self.ANACONDA_BOOT, "grub.conf")
@property
def GRUBEFI(self):
return os.path.join(self.BOOTDIR, "efi", "EFI", "redhat", "grub.efi")
@property
def VESASPLASH(self):
return os.path.join(self.ANACONDA_RUNTIME, "syslinux-vesa-splash.jpg")
@property
def VESAMENU(self):
return os.path.join(self.SYSLINUXDIR, "vesamenu.c32")
@property
def SPLASHTOOLS(self):
return os.path.join(self.ANACONDA_RUNTIME, "splashtools.sh")
@property
def SPLASHLSS(self):
return os.path.join(self.ANACONDA_BOOT, "splash.lss")
@property
def SYSLINUXSPLASH(self):
return os.path.join(self.ANACONDA_BOOT, "syslinux-splash.jpg")
@property
def SPLASHXPM(self):
return os.path.join(self.BOOTDIR, "grub", "splash.xpm.gz")
@property
def MODULES_DIR(self):
return os.path.join(self.installtree, "lib", "modules",
LoraxConfig.get().kernelver)
@property
def MODULES_DEP(self):
return os.path.join(self.MODULES_DIR, "modules.dep")
@property
def MODINFO(self): return "/sbin/modinfo"
@property
def MODLIST(self):
return os.path.join(self.ANACONDA_RUNTIME, "modlist")
@property
def DEPMOD(self): return "/sbin/depmod"
@property
def GETKEYMAPS(self):
return os.path.join(self.ANACONDA_RUNTIME, "getkeymaps")
@property
def LOCALEDEF(self): return "/usr/bin/localedef"
@property
def GENINITRDSZ(self):
return os.path.join(self.ANACONDA_RUNTIME, "geninitrdsz")
@property
def REDHAT_EXEC(self):
return os.path.join(self.ANACONDA_BOOT, "redhat.exec")
@property
def GENERIC_PRM(self):
return os.path.join(self.ANACONDA_BOOT, "generic.prm")
@property
def MKS390CD(self):
return os.path.join(self.ANACONDA_RUNTIME, "mk-s390-cdboot")
@property
def MKSQUASHFS(self): return "/sbin/mksquashfs"
@property
def MKCRAMFS(self): return "/sbin/mkfs.cramfs"
@property
def MKISOFS(self): return "/usr/bin/mkisofs"
@property
def MKDOSFS(self): return "/sbin/mkdosfs"
@property
def ISOHYBRID(self): return "/usr/bin/isohybrid"
@property
def SYSTEM_MAP(self):
return os.path.join(self.BOOTDIR,
"System.map-%s" % LoraxConfig.get().kernelver)
@property
def KEYMAPS_OVERRIDE(self):
return os.path.join(self.ANACONDA_RUNTIME,
"keymaps-override-%s" % LoraxConfig.get().arch)
@property
def LANGTABLE(self):
return os.path.join(self.installtree, "usr", "lib", "anaconda",
"lang-table")
@property
def LOCALEPATH(self):
return os.path.join(self.installtree, "usr", "share", "locale")
@property
def MANCONFIG(self):
return os.path.join(self.installtree, "etc", "man.config")
@property
def FEDORAKMODCONF(self):
return os.path.join(self.installtree, "etc", "yum", "pluginconf.d",
"fedorakmod.conf")

213
src/pylorax/efi.py Normal file
View File

@ -0,0 +1,213 @@
#
# efi.py
#
import sys
import os
import shutil
import tempfile
import commands
import config
import output
import utils
class EFI(object):
def __init__(self):
self.conf = config.LoraxConfig.get()
self.paths = config.LoraxPaths.get()
self.output = output.Terminal.get()
def create_efiboot(self, kernel=None, initrd=None,
kernelpath=None, initrdpath=None):
# create the temporary efi tree directory
efitreedir = tempfile.mkdtemp(prefix="efitree.", dir=self.conf.tempdir)
# copy kernel and initrd files to efi tree directory
if kernel and initrd:
shutil.copy2(kernel, os.path.join(efitreedir, "vmlinuz"))
shutil.copy2(initrd, os.path.join(efitreedir, "initrd.img"))
efikernelpath = "/EFI/BOOT/vmlinuz"
efiinitrdpath = "/EFI/BOOT/initrd.img"
else:
efikernelpath = kernelpath
efiinitrdpath = initrdpath
# copy conf files to efi tree directory
utils.scopy(src_root=self.conf.anaconda_boot, src_path="*.conf",
dst_root=efitreedir, dst_path="")
# edit the grub.conf file
grubconf = os.path.join(efitreedir, "grub.conf")
utils.replace(grubconf, "@PRODUCT@", self.conf.product)
utils.replace(grubconf, "@VERSION@", self.conf.version)
utils.replace(grubconf, "@KERNELPATH@", efikernelpath)
utils.replace(grubconf, "@INITRDPATH@", efiinitrdpath)
utils.replace(grubconf, "@SPLASHPATH@", "/EFI/BOOT/splash.xpm.gz")
# copy grub.efi
shutil.copy2(self.paths.GRUBEFI, efitreedir)
# the first generation mactel machines get the bootloader name wrong
if self.conf.efiarch == "IA32":
src = os.path.join(efitreedir, "grub.efi")
dst = os.path.join(efitreedir, "BOOT.efi")
shutil.copy2(src, dst)
src = os.path.join(efitreedir, "grub.conf")
dst = os.path.join(efitreedir, "BOOT.conf")
shutil.copy2(src, dst)
src = os.path.join(efitreedir, "grub.efi")
dst = os.path.join(efitreedir, "BOOT%s.efi" % self.conf.efiarch)
shutil.move(src, dst)
src = os.path.join(efitreedir, "grub.conf")
dst = os.path.join(efitreedir, "BOOT%s.conf" % self.conf.efiarch)
shutil.move(src, dst)
# copy splash.xpm.gz
shutil.copy2(self.paths.SPLASHXPM, efitreedir)
efiboot = os.path.join(self.conf.tempdir, "efiboot.img")
if os.path.isfile(efiboot):
os.unlink(efiboot)
# calculate the size of the efitree directory
sizeinbytes = 0
for root, dirs, files in os.walk(efitreedir):
for file in files:
filepath = os.path.join(root, file)
sizeinbytes += os.path.getsize(filepath)
# mkdosfs needs the size in blocks of 1024 bytes
size = int(round(sizeinbytes / 1024.0))
# add 100 blocks for the filesystem overhead
size += 100
cmd = "%s -n ANACONDA -C %s %s > /dev/null" % (self.paths.MKDOSFS,
efiboot, size)
err, output = commands.getstatusoutput(cmd)
if err:
self.output.error(output)
return None
# mount the efiboot image
efibootdir = tempfile.mkdtemp(prefix="efiboot.", dir=self.conf.tempdir)
cmd = "mount -o loop,shortname=winnt,umask=0777 -t vfat %s %s" % \
(efiboot, efibootdir)
err, output = commands.getstatusoutput(cmd)
if err:
self.output.error(output)
return None
# copy the files to the efiboot image
utils.scopy(src_root=efitreedir, src_path="*",
dst_root=efibootdir, dst_path="")
# unmount the efiboot image
cmd = "umount %s" % efibootdir
err, output = commands.getstatusoutput(cmd)
if err:
self.output.warning(output)
pass
# copy the conf files to the output directory
if not kernel and not initrd:
utils.scopy(src_root=efitreedir, src_path="*.conf",
dst_root=self.conf.efibootdir, dst_path="")
return efiboot
def create_efidisk(self, efiboot):
efidisk = os.path.join(self.conf.tempdir, "efidisk.img")
if os.path.isfile(efidisk):
os.unlink(efidisk)
partsize = os.path.getsize(efiboot)
disksize = 17408 + partsize + 17408
disksize = disksize + (disksize % 512)
with open(efidisk, "wb") as f:
f.truncate(disksize)
cmd = "losetup -v -f %s | awk '{print $4}'" % efidisk
err, loop = commands.getstatusoutput(cmd)
if err:
self.output.error(loop)
os.unlink(efidisk)
return None
cmd = 'dmsetup create efiboot --table "0 %s linear %s 0"' % \
(disksize / 512, loop)
err, output = commands.getstatusoutput(cmd)
if err:
self.output.error(output)
self.remove_loop_dev(loop)
os.unlink(efidisk)
return None
cmd = "parted --script /dev/mapper/efiboot " \
"mklabel gpt unit b mkpart '\"EFI System Partition\"' " \
"fat32 17408 %s set 1 boot on" % (partsize + 17408)
err, output = commands.getstatusoutput(cmd)
if err:
self.output.error(output)
self.remove_dm_dev("efiboot")
self.remove_loop_dev(loop)
os.unlink(efidisk)
return None
with open(efiboot, "rb") as f_from:
with open("/dev/mapper/efibootp1", "wb") as f_to:
efidata = f_from.read(1024)
while efidata:
f_to.write(efidata)
efidata = f_from.read(1024)
self.remove_dm_dev("efibootp1")
self.remove_dm_dev("efiboot")
self.remove_loop_dev(loop)
return efidisk
def remove_loop_dev(self, dev):
cmd = "losetup -d %s" % dev
err, output = commands.getstatusoutput(cmd)
if err:
self.output.warning(output)
def remove_dm_dev(self, dev):
cmd = "dmsetup remove /dev/mapper/%s" % dev
err, output = commands.getstatusoutput(cmd)
if err:
self.output.warning(output)
def create(self, kernel=None, initrd=None,
kernelpath=None, initrdpath=None):
# create the efiboot image
efiboot = self.create_efiboot(kernel, initrd)
if efiboot is None:
self.output.critical("unable to create the efiboot image")
sys.exit(1)
# create the efidisk image
efidisk = self.create_efidisk(efiboot)
if efidisk is None:
self.output.critical("unable to create the efidisk image")
sys.exit(1)
# create the efiboot image again
efiboot = self.create_efiboot(kernelpath=kernelpath,
initrdpath=initrdpath)
if efiboot is None:
self.output.critical("unable to create the efiboot image")
sys.exit(1)
return efiboot, efidisk

View File

@ -1,867 +0,0 @@
#
# images.py
# lorax images manipulation
#
# Copyright (C) 2009 Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# Red Hat Author(s): Martin Gracik <mgracik@redhat.com>
#
import sys
import os
import glob
import shutil
import commands
import re
import actions
import actions.base
from template import Template
from utils.fileutils import copy, remove, touch, edit, replace
from utils.ldd import LDD
class InitRD(object):
def __init__(self, config, yum, output):
self.conf = config
self.yum = yum
self.so, self.se = output
def read_template(self):
# get supported actions
supported_actions = actions.getActions(verbose=self.conf.debug)
# variables supported in templates
vars = { "instroot": self.conf.treedir,
"initrd": self.conf.initrddir,
"libdir": self.conf.libdir,
"buildarch": self.conf.buildarch,
"basearch": self.conf.basearch,
"confdir" : self.conf.confdir,
"datadir": self.conf.datadir }
# parse the template file
initrd_template = os.path.join(self.conf.confdir, "initrd",
"initrd.%s" % self.conf.buildarch)
self.template = Template()
self.template.preparse(initrd_template)
self.template.parse(supported_actions, vars)
def install_required_packages(self):
packages = set()
for action in filter(lambda action: action.install, self.template.actions):
m = re.match(r"%s(.*)" % (self.conf.treedir,), action.install)
if m:
packages.add(m.group(1))
for package in packages:
ok = self.yum.add_package(package)
if not ok:
self.se.error("No package '%s' found" % (package,))
self.yum.install()
def get_file_dependencies(self):
libroots = []
libroots.append(os.path.join(self.conf.treedir, self.conf.libdir))
libroots.append(os.path.join(self.conf.treedir, "usr", self.conf.libdir))
# on 64 bit systems, add also normal lib directories
if self.conf.libdir.endswith("64"):
libdir = self.conf.libdir[:-2]
libroots.append(os.path.join(self.conf.treedir, libdir))
libroots.append(os.path.join(self.conf.treedir, "usr", libdir))
ldd = LDD(libroots)
for action in self.template.actions:
if action.getDeps:
[ldd.getDeps(fname) for fname in glob.glob(action.getDeps)]
if ldd.errors:
# XXX ldd didn't get all the dependencies, what now?
for filename, error in ldd.errors:
self.se.error(filename)
self.se.error(error)
# additional actions that need to be processed
self._actions = []
# add dependencies to actions, so they are copied too
for dep in ldd.deps:
kwargs = {}
kwargs["src_root"] = self.conf.treedir
kwargs["src_path"] = dep.replace(self.conf.treedir + "/", "", 1)
kwargs["dst_root"] = self.conf.initrddir
kwargs["dst_path"] = os.path.dirname(kwargs["src_path"])
if kwargs["dst_path"].startswith("/"):
kwargs["dst_path"] = kwargs["dst_path"][1:]
new_action = actions.base.Copy(**kwargs)
self._actions.append(new_action)
def process_actions(self):
for action in self.template.actions:
action.execute()
# process dependencies
for action in self._actions:
action.execute()
def create_modinfo(self, moddir, target):
# XXX why do we need this thing?
mods = {}
for root, dirs, files in os.walk(moddir):
for file in files:
mods[file] = os.path.join(root, file)
modules = { "scsi_hostadapter" : ["block"],
"eth" : ["networking"] }
blacklist = ("floppy", "scsi_mod", "libiscsi")
list = {}
for modtype in modules:
list[modtype] = {}
for file in modules[modtype]:
try:
filename = os.path.join(moddir, "modules.%s" % file)
f = open(filename, "r")
except IOError as why:
self.se.error("Unable to open file '%s'" % (filename,))
continue
else:
lines = f.readlines()
f.close()
for line in lines:
line = line.strip()
if line in mods:
modname, ext = os.path.splitext(line)
if modname in blacklist:
continue
cmd = "modinfo -F description %s" % (mods[line],)
outtext = commands.getoutput(cmd)
desc = outtext.split("\n")[0]
desc = desc.strip()
desc = desc[:65]
if not desc:
desc = "%s driver" % modname
modinfo = '%s\n\t%s\n\t"%s"\n' % (modname, modtype, desc)
list[modtype][modname] = modinfo
f = open(target, "a")
f.write("Version 0\n")
for type in list:
modlist = list[type].keys()
modlist.sort()
for m in modlist:
f.write("%s\n" % (list[type][m],))
f.close()
def get_kernel_modules(self):
kernelver = self.conf.kernelver
modfiles = []
modfiles.append(os.path.join(self.conf.confdir, "modules",
"modules.all"))
modfiles.append(os.path.join(self.conf.confdir, "modules",
"modules.%s" % (self.conf.buildarch,)))
src_moddir = os.path.join(self.conf.treedir, "lib", "modules", kernelver)
dst_moddir = os.path.join(self.conf.initrddir, "lib", "modules", kernelver)
# get the modules from configuration files
modules = set()
for file in modfiles:
if os.path.isfile(file):
f = open(file, "r")
lines = f.readlines()
f.close()
for line in lines:
line, sep, comment = line.partition("#")
line = line.strip()
if not line:
continue
if line.startswith("-"):
modules.discard(line[1:])
elif line.startswith("="):
# expand modules
group = line[1:]
if group in ("scsi", "ata"):
path = os.path.join(src_moddir, "modules.block")
elif group == "net":
path = os.path.join(src_moddir, "modules.networking")
else:
path = os.path.join(src_moddir, "modules.%s" % (group,))
if os.path.isfile(path):
f = open(path, "r")
for module in f.readlines():
module = module.strip()
module = module.replace(".ko", "")
modules.add(module)
f.close()
else:
modules.add(line)
# resolve modules dependencies
depfile = os.path.join(src_moddir, "modules.dep")
f = open(depfile, "r")
lines = f.readlines()
f.close()
changed = True
while changed:
for line in lines:
changed = False
line = line.strip()
m = re.match(r"^.*/(?P<name>.*)\.ko:(?P<deps>.*)$", line)
modname = m.group("name")
if modname in modules:
for dep in m.group("deps").split():
m = re.match(r"^.*/(?P<name>.*)\.ko$", dep)
depname = m.group("name")
if depname not in modules:
changed = True
modules.add(depname)
# copy the modules directory
copy(src_root=self.conf.treedir,
src_path=os.path.join("lib", "modules", kernelver),
dst_root=self.conf.initrddir,
dst_path=os.path.join("lib", "modules"))
# remove not needed modules
for root, dirs, files in os.walk(dst_moddir):
for file in files:
full_path = os.path.join(root, file)
name, ext = os.path.splitext(file)
if ext == ".ko":
if name not in modules:
remove(full_path)
else:
# copy the required firmware
cmd = "modinfo -F firmware %s" % (full_path,)
err, output = commands.getstatusoutput(cmd)
for fw in output.split():
dst = os.path.join(self.conf.initrddir,
"lib", "firmware", fw)
dir = os.path.dirname(dst)
if not os.path.exists(dir):
os.makedirs(dir)
copy(src_root = self.conf.treedir,
src_path = os.path.join("lib", "firmware", fw),
dst_root = self.conf.initrddir,
dst_path = os.path.join("lib", "firmware", fw))
# copy additional firmware
srcdir = os.path.join(self.conf.treedir, "lib", "firmware")
dstdir = os.path.join(self.conf.initrddir, "lib", "firmware")
fw = ( ("ipw2100", "ipw2100*"),
("ipw2200", "ipw2200*"),
("iwl3945", "iwlwifi-3945*"),
("iwl4965", "iwlwifi-4965*"),
("atmel", "atmel_*.bin"),
("zd1211rw", "zd1211"),
("qla2xxx", "ql*") )
for module, file in fw:
if module in modules:
copy(src_root=self.conf.treedir,
src_path=os.path.join("lib", "firmware", file),
dst_root=self.conf.initrddir,
dst_path=os.path.join("lib", "firmware"))
# compress modules
cmd = "find -H %s -type f -name *.ko -exec gzip -9 {} \\;" % (dst_moddir,)
err, output = commands.getstatusoutput(cmd)
if err:
self.se.debug(output)
# create modinfo
modinfo = os.path.join(self.conf.tempdir, "modinfo")
self.create_modinfo(src_moddir, modinfo)
modlist = os.path.join(self.conf.treedir,
"usr", "lib", "anaconda-runtime", "modlist")
target = os.path.join(self.conf.initrddir, "lib", "modules", "module-info")
cmd = "%s --modinfo-file %s --ignore-missing --modinfo %s > %s" % \
(modlist, modinfo, " ".join(list(modules)), target)
err, output = commands.getstatusoutput(cmd)
if err:
self.se.debug(output)
# run depmod
systemmap = os.path.join(self.conf.treedir, "boot", "System.map-%s" \
% (kernelver,))
cmd = "/sbin/depmod -a -F %s -b %s %s" % (systemmap,
self.conf.initrddir, kernelver)
err, output = commands.getstatusoutput(cmd)
if err:
self.se.debug(output)
# remove leftovers
remove(os.path.join(dst_moddir, "modules.*map"))
def trim_pci_ids(self):
# FIXME remove this function, just copy the original pci.ids file
kernelver = self.conf.kernelver
vendors = set()
devices = set()
modulesalias = os.path.join(self.conf.treedir,
"lib", "modules", kernelver, "modules.alias")
f = open(modulesalias)
pcitable = f.readlines()
f.close()
for line in pcitable:
if not line.startswith("alias pci:"):
continue
vend = "0x%s" % (line[15:19],)
vend = vend.upper()
dev = "0x%s" % (line[24:28],)
dev = dev.upper()
vendors.add(vend)
devices.add((vend, dev))
videoaliases = os.path.join(self.conf.treedir,
"usr", "share", "hwdata", "videoaliases", "*")
for file in glob.iglob(videoaliases):
f = open(file)
pcitable = f.readlines()
f.close()
for line in pcitable:
if not line.startswith("alias pcivideo:"):
continue
vend = "0x%s" % (line[20:24],)
vend = vend.upper()
dev = "0x%s" % (line[29:33],)
dev = dev.upper()
vendors.add(vend)
devices.add((vend, dev))
# create the pci.ids file
src = os.path.join(self.conf.treedir, "usr", "share", "hwdata", "pci.ids")
dst = os.path.join(self.conf.initrddir, "usr", "share", "hwdata", "pci.ids")
input = open(src, "r")
pcitable = input.readlines()
input.close()
output = open(dst, "w")
current_vend = 0
for line in pcitable:
# skip lines that start with 2 tabs or #
if line.startswith("\t\t") or line.startswith("#"):
continue
# skip empty lines
if line == "\n":
continue
# end of file
if line == "ffff Illegal Vendor ID":
break
if not line.startswith("\t"):
current_vend = "0x%s" % (line.split()[0],)
current_vend = current_vend.upper()
if current_vend in vendors:
output.write(line)
continue
dev = "0x%s" % (line.split()[0],)
dev = dev.upper()
if (current_vend, dev) in devices:
output.write(line)
output.close()
def get_keymaps(self):
anadir = os.path.join(self.conf.treedir, "usr", "lib", "anaconda-runtime")
override = os.path.join(anadir,
"keymaps-override-%s" % (self.conf.buildarch,))
if os.path.isfile(override):
self.so.debug("Found keymap override, using it")
shutil.copy2(override,
os.path.join(self.conf.initrddir, "etc", "keymaps.gz"))
else:
cmd = "%s %s %s %s" % (os.path.join(anadir, "getkeymaps"),
self.conf.buildarch,
os.path.join(self.conf.initrddir, "etc", "keymaps.gz"),
self.conf.treedir)
err, output = commands.getstatusoutput(cmd)
if err:
return False
return True
def create_locales(self):
os.makedirs(os.path.join(self.conf.initrddir, "usr", "lib", "locale"))
err, output = commands.getstatusoutput("localedef -c -i en_US -f UTF-8"
" --prefix %s en_US" % (self.conf.initrddir,))
def create(self, target):
# copy the .buildstamp file
shutil.copy2(self.conf.buildstamp, self.conf.initrddir)
cwd = os.getcwd()
os.chdir(self.conf.initrddir)
cmd = "find . | cpio --quiet -c -o | gzip -9 > %s" % (target,)
output = commands.getoutput(cmd)
os.chdir(cwd)
def run(self):
# create the temporary directory for initrd
initrddir = os.path.join(self.conf.tempdir, "initrddir",
self.conf.kernelver)
self.so.info("Creating the temporary initrd directory")
os.makedirs(initrddir)
self.conf.addAttr("initrddir")
self.conf.set(initrddir=initrddir)
self.so.info("Reading the initrd template file")
self.read_template()
self.so.info("Installing additional packages")
self.install_required_packages()
self.so.info("Getting required dependencies")
self.get_file_dependencies()
self.so.info("Copying required files to initrd directory")
self.process_actions()
self.so.info("Getting required kernel modules")
self.get_kernel_modules()
self.so.info("Getting the pci.ids file")
self.trim_pci_ids()
ok = self.get_keymaps()
if not ok:
self.se.error("Unable to create the keymaps")
sys.exit(1)
self.so.info("Creating locales")
self.create_locales()
f = getattr(self, "run_%s" % (self.conf.buildarch,), None)
if f:
f()
def run_i386(self):
initrd_filename = "initrd.img"
kernel_filename = "vmlinuz"
if self.conf.kernelfile.endswith("PAE"):
initrd_filename = "initrd-PAE.img"
kernel_filename = "vmlinuz-PAE"
text = "[images-xen]\n"
text += "kernel = images/pxeboot/vmlinuz-PAE\n"
text += "initrd = images/pxeboot/initrd-PAE.img\n"
edit(os.path.join(self.conf.outdir, ".treeinfo"),
append=True, text=text)
self.so.info("Compressing the image file '%s'" % (initrd_filename,))
self.create(os.path.join(self.conf.pxebootdir, initrd_filename))
self.so.info("Copying the kernel file")
shutil.copy2(self.conf.kernelfile,
os.path.join(self.conf.pxebootdir, kernel_filename))
if not self.conf.kernelfile.endswith("PAE"):
# copy the kernel and initrd to the isolinux directory
shutil.copy2(self.conf.kernelfile,
os.path.join(self.conf.isolinuxdir, kernel_filename))
shutil.copy2(os.path.join(self.conf.pxebootdir, initrd_filename),
os.path.join(self.conf.isolinuxdir, initrd_filename))
# create the efi images
efi = EFI(self.conf, (self.so, self.se))
efi.run(kernelfile=self.conf.kernelfile,
initrd=os.path.join(self.conf.pxebootdir, initrd_filename),
kernelpath="/images/pxeboot/vmlinuz",
initrdpath="/images/pxeboot/initrd.img")
def run_x86_64(self):
self.run_i386()
def run_s390(self):
initrd_filename = "initrd.img"
kernel_filename = "kernel.img"
self.so.info("Compressing the image file '%s'" % (initrd_filename,))
self.create(os.path.join(self.conf.imagesdir, initrd_filename))
cmd = "ls -l %s | awk '{print $5}'" % \
(os.path.join(self.conf.imagesdir, initrd_filename),)
self.so.debug(cmd)
err, size = commands.getstatusoutput(cmd)
if err:
self.se.debug(size)
geninitrdsz = os.path.join(self.conf.treedir, "usr", "lib",
"anaconda-runtime", "geninitrdsz")
cmd = "%s %s %s" % (geninitrdsz, size,
os.path.join(self.conf.imagesdir, "initrd.size"))
self.so.debug(cmd)
err, output = commands.getstatusoutput(cmd)
if err:
self.se.debug(output)
# copy the kernel file
shutil.copy2(self.conf.kernelfile,
os.path.join(self.conf.imagesdir, kernel_filename))
for filename in ("redhat.exec", "generic.prm"):
shutil.copy2(os.path.join(self.conf.bootdiskdir, filename),
self.conf.imagesdir)
shutil.copy2(os.path.join(self.conf.bootdiskdir, filename),
self.conf.outdir)
mks390cdboot = os.path.join(self.conf.treedir, "usr", "lib",
"anaconda-runtime", "mk-s390-cdboot")
cmd = "%s -i %s -r %s -p %s -o %s" % (mks390cdboot,
os.path.join(self.conf.imagesdir, kernel_filename),
os.path.join(self.conf.imagesdir, initrd_filename),
os.path.join(self.conf.imagesdir, "generic.prm"),
os.path.join(self.conf.imagesdir, "cdboot.img"))
err, output = commands.getstatusoutput(cmd)
if err:
self.se.debug(output)
text = "[images-%s" % (self.conf.buildarch,)
text += "kernel = images/kernel.img"
text += "initrd = images/initrd.img"
text += "initrd.size = images/initrd.size"
text += "generic.prm = images/generic.prm"
text += "generic.ins = generic.ins"
text += "cdboot.img = images/cdboot.img"
edit(os.path.join(self.conf.outdir, ".treeinfo"),
append=True, text=text)
def run_s390x(self):
self.run_s390()
def run_alpha(self):
kerneldir = os.path.join(self.conf.outdir, "kernels")
if not os.path.isdir(kerneldir):
os.makedirs(kerneldir)
# XXX check for the jensen kernel file, how can we differentiate it?
# i don't know the filename...
if self.conf.kernelfile.endswith("jensen"):
copy(self.conf.kernelfile,
os.path.join(kerneldir, "vmlinux.j"))
else:
copy(self.conf.kernelfile,
os.path.join(kerneldir, "vmlinux.gz"))
os.makedirs(os.path.join(self.conf.outdir, "boot"))
copy(os.path.join(self.conf.bootdiskdir, "bootlx"),
os.path.join(self.conf.outdir, "boot"))
os.makedirs(os.path.join(self.conf.outdir, "etc"))
abootconf = os.path.join(self.conf.outdir, "etc", "aboot.conf")
touch(abootconf)
text = "0:/kernels/vmlinux.gz initrd=/images/initrd.img\n"
text += "1:/kernels/vmlinux.gz initrd=/images/initrd.img "
text += "console=ttyS0\n"
text += "2:/kernels/vmlinux.gz initrd=/images/initrd.img text\n"
text += "3:/kernels/vmlinux.gz initrd=/images/initrd.img rescue\n"
edit(abootconf, text=text)
initrd_filename = "initrd.img"
self.so.info("Compressing the image file '%s'" % (initrd_filename,))
self.create(os.path.join(self.conf.imagesdir, initrd_filename))
def run_ia64(self):
raise NotImplementedError
def run_ppc(self):
raise NotImplementedError
def run_ppc64(self):
self.run_ppc()
class EFI(object):
def __init__(self, config, output):
self.conf = config
self.so, self.se = output
# create the temporary efi directory
tempdir = os.path.join(self.conf.tempdir, "efi")
if os.path.exists(tempdir):
remove(tempdir)
os.makedirs(tempdir)
self.tempdir = tempdir
def create(self, kernelfile=None, initrd=None, kernelpath=None, initrdpath=None):
# create the temporary efi tree directory
efitreedir = os.path.join(self.tempdir, "tree")
if os.path.exists(efitreedir):
remove(efitreedir)
os.makedirs(efitreedir)
# copy kernel and initrd files to efi tree directory
if kernelfile and initrd:
shutil.copy2(kernelfile, os.path.join(efitreedir, "vmlinuz"))
shutil.copy2(initrd, os.path.join(efitreedir, "initrd.img"))
efikernelpath = os.path.join("/", "EFI", "BOOT", "vmlinuz")
efiinitrdpath = os.path.join("/", "EFI", "BOOT", "initrd.img")
else:
efikernelpath = kernelpath
efiinitrdpath = initrdpath
# copy conf files to efi tree directory
copy(src_root=self.conf.bootdiskdir, src_path="*.conf",
dst_root=efitreedir, dst_path="")
# edit the grub.conf file
grubconf = os.path.join(efitreedir, "grub.conf")
replace(grubconf, "@PRODUCT@", self.conf.product)
replace(grubconf, "@VERSION@", self.conf.version)
replace(grubconf, "@KERNELPATH@", efikernelpath)
replace(grubconf, "@INITRDPATH@", efiinitrdpath)
replace(grubconf, "@SPLASHPATH@", "/EFI/BOOT/splash.xpm.gz")
# copy grub.efi
src = os.path.join(self.conf.treedir,
"boot", "efi", "EFI", "redhat", "grub.efi")
shutil.copy2(src, efitreedir)
# the first generation mactel machines get the bootloader name wrong
if self.conf.efiarch == "ia32":
src = os.path.join(efitreedir, "grub.efi")
dst = os.path.join(efitreedir, "BOOT.efi")
shutil.copy2(src, dst)
src = os.path.join(efitreedir, "grub.conf")
dst = os.path.join(efitreedir, "BOOT.conf")
shutil.copy2(src, dst)
efiarch = self.conf.efiarch
if efiarch == "x64":
efiarch = efiarch.upper()
elif efiarch == "ia32":
efiarch = efiarch.upper()
src = os.path.join(efitreedir, "grub.efi")
dst = os.path.join(efitreedir, "BOOT%s.efi" % (efiarch,))
shutil.move(src, dst)
src = os.path.join(efitreedir, "grub.conf")
dst = os.path.join(efitreedir, "BOOT%s.conf" % (efiarch,))
shutil.move(src, dst)
# copy splash
src = os.path.join(self.conf.treedir, "boot", "grub", "splash.xpm.gz")
shutil.copy2(src, efitreedir)
# calculate the size of the efi image
cmd = "du -kcs %s | tail -n1 | awk '{print $1}'" % (efitreedir,)
self.so.debug(cmd)
err, out = commands.getstatusoutput(cmd)
if err:
self.se.info(out)
return False
size = int(out) + 100
efiimage = os.path.join(self.tempdir, "efiboot.img")
if os.path.exists(efiimage):
remove(efiimage)
cmd = "mkdosfs -n ANACONDA -C %s %s > /dev/null" % (efiimage, size)
self.so.debug(cmd)
err, out = commands.getstatusoutput(cmd)
if err:
self.se.info(out)
return False
# mount the efi image
efiimagedir = os.path.join(self.tempdir, "efiboot.img.d")
if os.path.exists(efiimagedir):
remove(efiimagedir)
os.makedirs(efiimagedir)
cmd = "mount -o loop,shortname=winnt,umask=0777 -t vfat %s %s" % \
(efiimage, efiimagedir)
self.so.debug(cmd)
err, out = commands.getstatusoutput(cmd)
if err:
self.se.info(out)
return False
# copy the files to the efi image
copy(src_root=efitreedir, src_path="*",
dst_root=efiimagedir, dst_path="")
# unmount the efi image
cmd = "umount %s" % (efiimagedir,)
self.so.debug(cmd)
err, out = commands.getstatusoutput(cmd)
if err:
self.se.info(out)
# copy the conf files to the output directory
if not kernelfile and not initrd:
copy(src_root=efitreedir, src_path="*.conf",
dst_root=self.conf.efibootdir, dst_path="")
return efiimage
def create_bootdisk(self, efiimage):
cmd = "ls -l %s | awk '{print $5}'" % (efiimage,)
self.so.debug(cmd)
err, out = commands.getstatusoutput(cmd)
if err:
self.se.info(out)
return False
partsize = int(out)
disksize = 17408 + partsize + 17408
disksize = disksize + (disksize % 512)
efidiskimg = os.path.join(self.tempdir, "efidisk.img")
if os.path.exists(efidiskimg):
remove(efidiskimg)
touch(efidiskimg)
cmd = "dd if=/dev/zero of=%s count=1 bs=%s" % (efidiskimg, disksize)
self.so.debug(cmd)
err, out = commands.getstatusoutput(cmd)
if err:
self.se.info(out)
return False
cmd = "losetup -v -f %s | awk '{print $4}'" % (efidiskimg,)
self.so.debug(cmd)
err, loop = commands.getstatusoutput(cmd)
if err:
self.se.info(loop)
return False
cmd = "dmsetup create efiboot --table \"0 %s linear %s 0\"" \
% (disksize / 512, loop)
self.so.debug(cmd)
err, out = commands.getstatusoutput(cmd)
if err:
self.se.info(out)
return False
cmd = "parted --script /dev/mapper/efiboot" \
" mklabel gpt unit b mkpart '\"EFI System Partition\"'" \
" fat32 17408 %s set 1 boot on" % (partsize + 17408,)
self.so.debug(cmd)
err, out = commands.getstatusoutput(cmd)
if err:
self.se.info(out)
return False
cmd = "dd if=%s of=/dev/mapper/efibootp1" % (efiimage,)
self.so.debug(cmd)
err, out = commands.getstatusoutput(cmd)
if err:
self.se.info(out)
return False
cmd = "dmsetup remove /dev/mapper/efibootp1"
self.so.debug(cmd)
err, out = commands.getstatusoutput(cmd)
if err:
self.se.info(out)
return False
cmd = "dmsetup remove /dev/mapper/efiboot"
self.so.debug(cmd)
err, out = commands.getstatusoutput(cmd)
if err:
self.se.info(out)
return False
cmd = "losetup -d %s" % loop
self.so.debug(cmd)
err, out = commands.getstatusoutput(cmd)
if err:
self.se.info(out)
return False
return efidiskimg
def run(self, kernelfile=None, initrd=None, kernelpath=None, initrdpath=None):
self.so.info("Creating the EFI image file")
efiimage = self.create(kernelfile, initrd)
if not efiimage:
sys.exit(1)
self.so.info("Creating the boot disk")
bootdisk = self.create_bootdisk(efiimage)
if not bootdisk:
sys.exit(1)
# copy the boot disk file to the output directory
dst = os.path.join(self.conf.imagesdir, "efidisk.img")
shutil.copy2(bootdisk, dst)
self.so.info("Creating the second EFI image file")
efiimage = self.create(kernelpath=kernelpath, initrdpath=initrdpath)
# copy the efi image to the output directory
dst = os.path.join(self.conf.imagesdir, "efiboot.img")
shutil.copy2(efiimage, dst)

479
src/pylorax/install.py Normal file
View File

@ -0,0 +1,479 @@
#
# install.py
#
import os
import shutil
import glob
import fnmatch
import re
import commands
import pwd
import grp
import stat
import config
import output
import lcs
import utils
class InstallImage(object):
def __init__(self):
self.conf = config.LoraxConfig.get()
self.paths = config.LoraxPaths.get()
self.output = output.Terminal.get()
self.actions = self.get_actions_from_template()
def get_actions_from_template(self):
variables = { "instroot" : self.conf.installtree }
if self.conf.scrubs_template is not None:
template = lcs.TemplateParser(variables)
return template.get_actions(self.conf.scrubs_template)
return []
def move_shared_files(self):
dirs = [os.path.join(self.paths.INSTALLTREE_DATADIR, "noarch"),
os.path.join(self.paths.INSTALLTREE_DATADIR, self.conf.arch)]
self.output.info(":: copying the custom install tree files")
for dir in [dir for dir in dirs if os.path.isdir(dir)]:
utils.scopy(src_root=dir, src_path="*",
dst_root=self.conf.installtree, dst_path="")
def process_actions(self):
for action in self.actions:
action.execute()
# XXX why do we need this?
def copy_stubs(self):
for file in ("raidstart", "raidstop", "losetup", "list-harddrives",
"loadkeys", "mknod", "syslogd"):
src = os.path.join(self.conf.installtree, "usr", "lib", "anaconda",
"%s-stub" % file)
dst = os.path.join(self.conf.installtree, "usr", "bin", file)
shutil.copy2(src, dst)
def configure_fedorakmod(self):
utils.replace(self.paths.FEDORAKMODCONF,
r"installforallkernels = 0", r"installforallkernels = 1")
# XXX why do we need this?
def copy_bootloaders(self):
if self.conf.arch in ("i386", "i586", "x86_64"):
for f in glob.glob(os.path.join(self.paths.BOOTDIR, "memtest*")):
shutil.copy2(f, self.paths.ANACONDA_BOOT)
elif self.conf.arch == "sparc":
for f in glob.glob(os.path.join(self.paths.BOOTDIR, "*.b")):
shutil.copy2(f, self.paths.ANACONDA_BOOT)
elif self.conf.arch in ("ppc", "ppc64"):
f = os.path.join(self.paths.BOOTDIR, "efika.forth")
shutil.copy2(f, self.paths.ANACONDA_BOOT)
# XXX alpha stuff should not be needed anymore
#elif self.conf.arch == "alpha":
# f = os.path.join(self.paths.BOOTDIR, "bootlx")
# shutil.copy2(f, self.paths.ANACONDA_BOOT)
elif self.conf.arch == "ia64":
utils.scopy(src_root=self.paths.BOOTDIR_IA64, src_path="*",
dst_root=self.paths.ANACONDA_BOOT, dst_dir="")
# XXX why do we need this?
def move_repos(self):
src = os.path.join(self.conf.installtree, "etc", "yum.repos.d")
dst = os.path.join(self.conf.installtree, "etc", "anaconda.repos.d")
shutil.move(src, dst)
# XXX why do we need this?
def move_anaconda_files(self):
# move anaconda executable
src = os.path.join(self.conf.installtree, "usr", "sbin", "anaconda")
dst = os.path.join(self.conf.installtree, "usr", "bin", "anaconda")
shutil.move(src, dst)
# move anaconda libraries
dstdir = os.path.join(self.conf.installtree, "usr", self.conf.libdir)
utils.scopy(src_root=self.paths.ANACONDA_RUNTIME, src_path="lib*",
dst_root=dstdir, dst_path="")
utils.remove(os.path.join(self.paths.ANACONDA_RUNTIME, "lib*"))
# XXX this saves 40 MB
def create_modules_symlinks(self):
utils.mkdir(os.path.join(self.conf.installtree, "modules"))
utils.mkdir(os.path.join(self.conf.installtree, "firmware"))
utils.remove(os.path.join(self.conf.installtree, "lib", "modules"))
utils.remove(os.path.join(self.conf.installtree, "lib", "firmware"))
utils.symlink("/modules",
os.path.join(self.conf.installtree, "lib", "modules"))
utils.symlink("/firmware",
os.path.join(self.conf.installtree, "lib", "firmware"))
# XXX why do we need this?
def fix_man_pages(self):
# fix up some links for man page related stuff
for file in ("nroff", "groff", "iconv", "geqn", "gtbl", "gpic",
"grefer"):
target = os.path.join("/mnt/sysimage/usr/bin", file)
name = os.path.join(self.conf.installtree, "usr", "bin", file)
if not os.path.isfile(name):
utils.symlink(target, name)
# fix /etc/man.config to point into /mnt/sysimage
utils.replace(self.paths.MANCONFIG, r"^MANPATH\s+(\S+)",
"MANPATH\t/mnt/sysimage\g<1>")
utils.replace(self.paths.MANCONFIG, r"^MANPATH_MAP\s+(\S+)\s+(\S+)",
"MANPATH_MAP\t\g<1>\t/mnt/sysimage\g<2>")
# XXX this saves 2 MB
def remove_gtk_stuff(self):
# figure out the gtk+ theme to keep
gtkrc = os.path.join(self.conf.installtree, "etc", "gtk-2.0", "gtkrc")
gtk_theme_name = None
gtk_engine = None
gtk_icon_themes = []
if os.path.isfile(gtkrc):
f = open(gtkrc, "r")
lines = f.readlines()
f.close()
for line in lines:
line = line.strip()
if line.startswith("gtk-theme-name"):
gtk_theme_name = line[line.find("=") + 1:]
gtk_theme_name = gtk_theme_name.replace('"', "").strip()
# find the engine for this theme
gtkrc = os.path.join(self.conf.installtree, "usr", "share",
"themes", gtk_theme_name, "gtk-2.0", "gtkrc")
if os.path.isfile(gtkrc):
f = open(gtkrc, "r")
engine_lines = f.readlines()
f.close()
for engine_l in engine_lines:
engine_l = engine_l.strip()
if engine_l.find("engine") != -1:
gtk_engine = engine_l[engine_l.find('"') + 1:]
gtk_engine = gtk_engine.replace('"', "").strip()
break
elif line.startswith("gtk-icon-theme-name"):
icon_theme = line[line.find("=") + 1:]
icon_theme = icon_theme.replace('"', "").strip()
gtk_icon_themes.append(icon_theme)
# bring in all inherited themes
while True:
icon_theme_index = os.path.join(self.conf.installtree,
"usr", "share", "icons", icon_theme,
"index.theme")
if os.path.isfile(icon_theme_index):
inherits = False
f = open(icon_theme_index, "r")
icon_lines = f.readlines()
f.close()
for icon_l in icon_lines:
icon_l = icon_l.strip()
if icon_l.startswith("Inherits="):
inherits = True
icon_theme = icon_l[icon_l.find("=") + 1:]
icon_theme = \
icon_theme.replace('"', "").strip()
gtk_icon_themes.append(icon_theme)
break
if not inherits:
break
else:
break
# remove themes we don't need
theme_path = os.path.join(self.conf.installtree, "usr", "share",
"themes")
if os.path.isdir(theme_path):
for theme in filter(lambda theme: theme != gtk_theme_name,
os.listdir(theme_path)):
theme = os.path.join(theme_path, theme)
shutil.rmtree(theme, ignore_errors=True)
# remove icons we don't need
icon_path = os.path.join(self.conf.installtree, "usr", "share",
"icons")
if os.path.isdir(icon_path):
for icon in filter(lambda icon: icon not in gtk_icon_themes,
os.listdir(icon_path)):
icon = os.path.join(icon_path, icon)
shutil.rmtree(icon, ignore_errors=True)
# remove engines we don't need
tmp_path = os.path.join(self.conf.installtree, "usr",
self.conf.libdir, "gtk-2.0")
if os.path.isdir(tmp_path):
fnames = map(lambda fname: os.path.join(tmp_path, fname,
"engines"), os.listdir(tmp_path))
dnames = filter(lambda fname: os.path.isdir(fname), fnames)
for dir in dnames:
engines = filter(lambda e: e.find(gtk_engine) == -1,
os.listdir(dir))
for engine in engines:
engine = os.path.join(dir, engine)
os.unlink(engine)
# XXX this saves 5 MB
def remove_locales(self):
if os.path.isfile(self.paths.LANGTABLE):
keep = set()
with open(self.paths.LANGTABLE, "r") as f:
lines = f.readlines()
for line in lines:
line = line.strip()
if not line or line.startswith("#"):
continue
fields = line.split("\t")
dir = os.path.join(self.paths.LOCALEPATH, fields[1])
if os.path.isdir(dir):
keep.add(fields[1])
locale = fields[3].split(".")[0]
dir = os.path.join(self.paths.LOCALEPATH, locale)
if os.path.isdir(dir):
keep.add(locale)
for locale in os.listdir(self.paths.LOCALEPATH):
if locale not in keep:
path = os.path.join(self.paths.LOCALEPATH, locale)
utils.remove(path)
# XXX this saves 5 MB
def remove_unnecessary_files(self):
for root, dirs, files in os.walk(self.conf.installtree):
for file in files:
path = os.path.join(root, file)
if fnmatch.fnmatch(path, "*.a"):
if path.find("kernel-wrapper/wrapper.a") == -1:
os.unlink(path)
if fnmatch.fnmatch(path, "lib*.la"):
if path.find("usr/" + self.conf.libdir + "/gtk-2.0") == -1:
os.unlink(path)
if fnmatch.fnmatch(path, "*.py"):
if os.path.isfile(path + "o"):
os.unlink(path + "o")
if os.path.isfile(path + "c"):
os.unlink(path + "c")
utils.symlink("/dev/null", path + "c")
# remove libunicode-lite
utils.remove(os.path.join(self.conf.installtree, "usr",
self.conf.libdir, "libunicode-lite*"))
# XXX this saves 1 MB
def remove_python_stuff(self):
for fname in ("bsddb", "compiler", "curses", "distutils", "email",
"encodings", "hotshot", "idlelib", "test",
"doctest.py", "pydoc.py"):
utils.remove(os.path.join(self.conf.installtree, "usr",
self.conf.libdir, "python?.?", fname))
# XXX the udev package should get fixed,
# but for now, we have to fix it ourselves, otherwise we get an error
def fix_udev_links(self):
# these links are broken by default (at least on i386)
for filename in ("udevcontrol", "udevsettle", "udevtrigger"):
filename = os.path.join(self.conf.installtree, "sbin", filename)
if os.path.islink(filename):
os.unlink(filename)
os.symlink("udevadm", filename)
def move_bins(self):
# move bin to usr/bin
utils.scopy(src_root=self.conf.installtree,
src_path=os.path.join("bin", "*"),
dst_root=self.conf.installtree,
dst_path=os.path.join("usr", "bin"))
utils.remove(os.path.join(self.conf.installtree, "bin"))
# move sbin to /usr/sbin
utils.scopy(src_root=self.conf.installtree,
src_path=os.path.join("sbin", "*"),
dst_root=self.conf.installtree,
dst_path=os.path.join("usr", "sbin"))
utils.remove(os.path.join(self.conf.installtree, "sbin"))
# fix broken links
brokenlinks = []
for dir in ("bin", "sbin"):
dir = os.path.join(self.conf.installtree, "usr", dir)
for root, dnames, fnames in os.walk(dir):
for fname in fnames:
fname = os.path.join(root, fname)
if os.path.islink(fname) and not os.path.exists(fname):
brokenlinks.append(fname)
for link in brokenlinks:
target = os.readlink(link)
newtarget = re.sub(r"^\.\./\.\./(bin|sbin)/(.*)$",
r"../\g<1>/\g<2>", target)
if newtarget != target:
os.unlink(link)
utils.symlink(newtarget, link)
def create_ld_so_conf(self):
ldsoconf = os.path.join(self.conf.installtree, "etc", "ld.so.conf")
utils.touch(ldsoconf)
procdir = os.path.join(self.conf.installtree, "proc")
if not os.path.isdir(procdir):
utils.mkdir(procdir)
cmd = "mount -t proc proc %s" % procdir
err, output = commands.getstatusoutput(cmd)
with open(ldsoconf, "w") as f:
f.write("/usr/kerberos/%s\n" % self.conf.libdir)
cwd = os.getcwd()
os.chdir(self.conf.installtree)
# XXX os.chroot does not support exiting from the root
cmd = "/usr/sbin/chroot %s /sbin/ldconfig" % self.conf.installtree
err, output = commands.getstatusoutput(cmd)
os.chdir(cwd)
cmd = "umount %s" % procdir
err, output = commands.getstatusoutput(cmd)
os.unlink(ldsoconf)
def change_tree_permissions(self):
root_uid = pwd.getpwnam("root")[2]
root_gid = grp.getgrnam("root")[2]
for root, dirs, files in os.walk(self.conf.installtree):
os.chown(root, root_uid, root_gid)
os.chmod(root, 0755)
for file in files:
# skip broken symlinks
if not os.path.exists(file):
continue
path = os.path.join(root, file)
os.chown(path, root_uid, root_gid)
mode = os.stat(path).st_mode
if (mode & stat.S_IXUSR) or (mode & stat.S_IXGRP) \
or (mode & stat.S_IXOTH):
os.chmod(path, 0555)
else:
os.chmod(path, 0444)
def prepare(self):
# copy the .buildstamp
shutil.copy2(self.conf.buildstamp, self.conf.installtree)
self.move_shared_files()
self.process_actions()
self.copy_stubs()
self.configure_fedorakmod()
self.copy_bootloaders()
self.move_repos()
self.move_anaconda_files()
self.create_modules_symlinks()
self.fix_man_pages()
self.remove_gtk_stuff()
self.remove_locales()
self.remove_unnecessary_files()
self.remove_python_stuff()
self.fix_udev_links()
self.move_bins()
self.create_ld_so_conf()
self.change_tree_permissions()
def create(self, type="squashfs"):
self.prepare()
installimg = os.path.join(self.conf.tempdir, "install.img")
if os.path.exists(installimg):
os.unlink(installimg)
self.output.info(":: compressing the image file")
if type == "squashfs":
if not os.path.exists(self.paths.MKSQUASHFS):
self.output.error("'%s' does not exist" % self.paths.MKSQUASHFS)
return None
cmd = "%s %s %s -all-root -no-fragments -no-progress" % \
(self.paths.MKSQUASHFS, self.conf.installtree, installimg)
err, output = commands.getstatusoutput(cmd)
if err:
self.output.error(output)
return None
elif type == "cramfs":
if not os.path.exists(self.paths.MKCRAMFS):
self.output.error("'%s' does not exist" % self.paths.MKCRAMFS)
return None
crambs = ""
if self.conf.arch == "sparc64":
crambs = "--blocksize 8192"
elif self.conf.arch == "sparc":
crambs = "--blocksize 4096"
cmd = "%s %s %s %s" % (self.paths.MKCRAMFS, crambs,
self.conf.installtree, installimg)
err, output = commands.getstatusoutput(cmd)
if err:
self.output.error(output)
return None
elif type == "ext2":
# TODO
raise NotImplementedError
# edit the .treeinfo
text = "[stage2]\nmainimage = images/install.img\n"
utils.edit(self.conf.treeinfo, append=True, text=text)
return installimg

View File

@ -1,551 +0,0 @@
#
# instroot.py
# install root class
#
# Copyright (C) 2009 Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# Red Hat Author(s): Martin Gracik <mgracik@redhat.com>
#
import os
import glob
import fnmatch
import shutil
import re
from utils.fileutils import copy, move, remove, replace, touch
import actions
import actions.base
from template import Template
class InstallTree(object):
def __init__(self, config, yum, output):
self.conf = config
self.yum = yum
self.so, self.se = output
def get_packages(self):
required = ["anaconda", "anaconda-runtime", "/etc/gtk-2.0/gtkrc"]
# kernel packages
required.extend(["kernel", "*firmware*"])
# add the XEN kernel package
if self.conf.buildarch == "i386":
required.append("kernel-PAE")
# add the jensen kernel package
if self.conf.buildarch == "alpha":
required.append("kernel-jensen")
# get additional packages from the configuration files
packages_files = []
packages_files.append(os.path.join(self.conf.confdir, "packages",
"packages.all")),
packages_files.append(os.path.join(self.conf.confdir, "packages",
"packages.%s" % (self.conf.buildarch,)))
packages = set()
for file in packages_files:
if os.path.isfile(file):
try:
f = open(file, "r")
except IOError as why:
self.se.error("Unable to read packages configuration:"
" %s" % (why,))
else:
for line in f.readlines():
line, sep, comment = line.partition("#")
line = line.strip()
if not line:
continue
if line.startswith("-"):
packages.discard(line[1:])
else:
packages.add(line)
f.close()
required.extend(list(packages))
# logos
required.extend(["%s-logos" % (self.conf.product.lower(),),
"%s-release" % (self.conf.product.lower(),)])
return required
def add_packages(self, packages):
for package in packages:
ok = self.yum.add_package(package)
if not ok:
self.se.warning("No package '%s' available" (package,))
def install_packages(self):
# XXX why do we need this?
os.symlink(os.path.join("/", "tmp"),
os.path.join(self.conf.treedir, "var", "lib", "xkb"))
self.yum.install()
def copy_updates(self):
if self.conf.updates and os.path.isdir(self.conf.updates):
copy(src_root=self.conf.updates, src_path="*",
dst_root=self.conf.treedir, dst_path="")
self.conf.delAttr("updates")
def fix_udev_links(self):
# these links are broken by default (at least on i386)
for filename in ("udevcontrol", "udevsettle", "udevtrigger"):
filename = os.path.join(self.conf.treedir, "sbin", filename)
if os.path.islink(filename):
os.unlink(filename)
os.symlink("udevadm", filename)
def remove_modules_broken_links(self):
# remove build and source links from modules directories
build = os.path.join(self.conf.treedir, "lib", "modules", "*", "build")
build_files = glob.glob(build)
source = os.path.join(self.conf.treedir, "lib", "modules", "*", "source")
source_files = glob.glob(source)
[os.unlink(filename) for filename in build_files + source_files
if os.path.islink(filename)]
def get_kernelfiles(self):
kerneldir = os.path.join(self.conf.treedir, "boot")
if self.conf.buildarch == "ia64":
kerneldir = os.path.join(kerneldir, "efi", "EFI", "redhat")
return glob.glob(os.path.join(kerneldir, "vmlinuz-*"))
def run(self):
self.so.info("Getting the list of packages")
packages = self.get_packages()
self.so.info("Running yum")
self.add_packages(packages)
self.install_packages()
self.so.info("Copying the updates")
self.copy_updates()
self.so.info("Fixing udev links")
self.fix_udev_links()
self.so.info("Removing build and source links in modules directories")
self.remove_modules_broken_links()
return self.get_kernelfiles()
####################
### tree scrubs
def copy_stubs(self):
for file in ("raidstart", "raidstop", "losetup", "list-harddrives",
"loadkeys", "mknod", "syslogd"):
src = os.path.join(self.conf.treedir, "usr", "lib", "anaconda",
"%s-stub" % (file,))
dst = os.path.join(self.conf.treedir, "usr", "bin", file)
shutil.copy2(src, dst)
def create_dogtail_conf(self):
dogtailconf = os.path.join(self.conf.datadir, "dogtail", "%gconf.xml")
if os.path.isfile(dogtailconf):
dst = os.path.join(self.conf.treedir, ".gconf", "desktop", "gnome",
"interface")
os.makedirs(dst)
shutil.copy2(dogtailconf, dst)
touch(os.path.join(self.conf.treedir, ".gconf", "desktop",
"%gconf.xml"))
touch(os.path.join(self.conf.treedir, ".gconf", "desktop", "gnome",
"%gconf.xml"))
def create_libuser_conf(self):
src = os.path.join(self.conf.datadir, "libuser", "libuser.conf")
dst = os.path.join(self.conf.treedir, "etc", "libuser.conf")
shutil.copy2(src, dst)
def create_selinux_conf(self):
if os.path.exists(os.path.join(self.conf.treedir, "etc", "selinux",
"targeted")):
src = os.path.join(self.conf.datadir, "selinux", "config")
dst = os.path.join(self.conf.treedir, "etc", "selinux", "config")
shutil.copy2(src, dst)
def configure_fedorakmod(self):
fedorakmodconf = os.path.join(self.conf.treedir, "etc", "yum",
"pluginconf.d", "fedorakmod.conf")
replace(fedorakmodconf, r"\(installforallkernels\) = 0", r"\1 = 1")
def copy_bootloaders(self):
bootpath = os.path.join(self.conf.treedir, "usr", "lib",
"anaconda-runtime", "boot")
if not os.path.isdir(bootpath):
os.makedirs(bootpath)
if self.conf.buildarch in ("i386", "i586", "x86_64"):
for file in os.listdir(os.path.join(self.conf.treedir, "boot")):
if file.startswith("memtest"):
src = os.path.join(self.conf.treedir, "boot", file)
dst = os.path.join(bootpath, file)
shutil.copy2(src, dst)
elif self.conf.buildarch == "sparc":
for file in os.listdir(os.path.join(self.conf.treedir, "boot")):
if file.endswith(".b"):
src = os.path.join(self.conf.treedir, "boot", file)
dst = os.path.join(bootpath, file)
shutil.copy2(src, dst)
elif self.conf.buildarch in ("ppc", "ppc64"):
src = os.path.join(self.conf.treedir, "boot", "efika.forth")
shutil.copy2(src, bootpath)
elif self.conf.buildarch == "alpha":
src = os.path.join(self.conf.treedir, "boot", "bootlx")
shutil.copy2(src, bootpath)
elif self.conf.buildarch == "ia64":
srcdir = os.path.join(self.conf.treedir, "boot", "efi", "EFI", "redhat")
copy(src_root=srcdir, src_path="*",
dst_root=bootpath, dst_dir="")
def move_repos(self):
src = os.path.join(self.conf.treedir, "etc", "yum.repos.d")
dst = os.path.join(self.conf.treedir, "etc", "anaconda.repos.d")
shutil.move(src, dst)
def move_anaconda_files(self):
# move anaconda executable
src = os.path.join(self.conf.treedir, "usr", "sbin", "anaconda")
dst = os.path.join(self.conf.treedir, "usr", "bin", "anaconda")
shutil.move(src, dst)
# move anaconda libraries
srcdir = os.path.join(self.conf.treedir, "usr", "lib", "anaconda-runtime")
dst = os.path.join(self.conf.treedir, "usr", self.conf.libdir)
move(src_root=srcdir, src_path="lib*",
dst_root=dst, dst_path="")
def create_debug_directories(self):
os.makedirs(os.path.join(self.conf.treedir, "usr", "lib", "debug"))
os.makedirs(os.path.join(self.conf.treedir, "usr", "src", "debug"))
def create_modules_symlinks(self):
os.makedirs(os.path.join(self.conf.treedir, "modules"))
os.makedirs(os.path.join(self.conf.treedir, "firmware"))
# XXX are we sure we want to do this?
remove(os.path.join(self.conf.treedir, "lib", "modules"))
remove(os.path.join(self.conf.treedir, "lib", "firmware"))
os.symlink("/modules", os.path.join(self.conf.treedir, "lib", "modules"))
os.symlink("/firmware", os.path.join(self.conf.treedir, "lib", "firmware"))
def fix_joe_links(self):
joedir = os.path.join(self.conf.treedir, "etc", "joe")
if os.path.isdir(joedir):
os.symlink("jpicorc", os.path.join(joedir, "picorc"))
os.symlink("jpicorc", os.path.join(joedir, "jnanorc"))
os.symlink("jpicorc", os.path.join(joedir, "nanorc"))
os.symlink("jmacsrc", os.path.join(joedir, "emacsrc"))
os.symlink("jmacs", os.path.join(self.conf.treedir, "usr", "bin",
"emacs"))
os.symlink("jpico", os.path.join(self.conf.treedir, "usr", "bin",
"pico"))
os.symlink("jpico", os.path.join(self.conf.treedir, "usr", "bin",
"nano"))
def fix_man_pages(self):
# fix up some links for man page related stuff
for file in ["nroff", "groff", "iconv", "geqn", "gtbl", "gpic", "grefer"]:
src = os.path.join("mnt", "sysimage", "usr", "bin", file)
dst = os.path.join(self.conf.treedir, "usr", "bin", file)
if not os.path.isfile(dst):
os.symlink(src, dst)
# fix /etc/man.config to point into /mnt/sysimage
manconfig = os.path.join(self.conf.treedir, "etc", "man.config")
# don't change MANPATH_MAP lines now
replace(manconfig, r"^MANPATH[^_MAP][ \t]*", r"&/mnt/sysimage")
# change MANPATH_MAP lines now
replace(manconfig, r"^MANPATH_MAP[ \t]*[a-zA-Z0-9/]*[ \t]*",
r"&/mnt/sysimage")
def remove_gtk_stuff(self):
# figure out the gtk+ theme to keep
gtkrc = os.path.join(self.conf.treedir, "etc", "gtk-2.0", "gtkrc")
gtk_theme_name = None
gtk_engine = None
gtk_icon_themes = []
if os.path.isfile(gtkrc):
f = open(gtkrc, "r")
lines = f.readlines()
f.close()
for line in lines:
line = line.strip()
if line.startswith("gtk-theme-name"):
gtk_theme_name = line[line.find("=") + 1:]
gtk_theme_name = gtk_theme_name.replace('"', "").strip()
# find the engine for this theme
gtkrc = os.path.join(self.conf.treedir, "usr", "share",
"themes", gtk_theme_name, "gtk-2.0", "gtkrc")
if os.path.isfile(gtkrc):
f = open(gtkrc, "r")
engine_lines = f.readlines()
f.close()
for engine_line in engine_lines:
engine_line = engine_line.strip()
if engine_line.find("engine") != -1:
gtk_engine = engine_line[engine_line.find('"') + 1:]
gtk_engine = gtk_engine.replace('"', "").strip()
break
elif line.startswith("gtk-icon-theme-name"):
icon_theme = line[line.find("=") + 1:]
icon_theme = icon_theme.replace('"', "").strip()
gtk_icon_themes.append(icon_theme)
# bring in all inherited themes
while True:
icon_theme_index = os.path.join(self.conf.treedir, "usr",
"share", "icons", icon_theme, "index.theme")
if os.path.isfile(icon_theme_index):
inherits = False
f = open(icon_theme_index, "r")
icon_lines = f.readlines()
f.close()
for icon_line in icon_lines:
icon_line = icon_line.strip()
if icon_line.startswith("Inherits="):
inherits = True
icon_theme = icon_line[icon_line.find("=") + 1:]
icon_theme = icon_theme.replace('"', "").strip()
gtk_icon_themes.append(icon_theme)
break
if not inherits:
break
else:
break
# remove themes we don't need
theme_path = os.path.join(self.conf.treedir, "usr", "share", "themes")
if os.path.isdir(theme_path):
for theme in filter(lambda theme: theme != gtk_theme_name,
os.listdir(theme_path)):
theme = os.path.join(theme_path, theme)
shutil.rmtree(theme, ignore_errors=True)
# remove icons we don't need
icon_path = os.path.join(self.conf.treedir, "usr", "share", "icons")
if os.path.isdir(icon_path):
for icon in filter(lambda icon: icon not in gtk_icon_themes,
os.listdir(icon_path)):
icon = os.path.join(icon_path, icon)
shutil.rmtree(icon, ignore_errors=True)
# remove engines we don't need
tmp_path = os.path.join(self.conf.treedir, "usr", self.conf.libdir,
"gtk-2.0")
if os.path.isdir(tmp_path):
fnames = map(lambda fname: os.path.join(tmp_path, fname, "engines"),
os.listdir(tmp_path))
dnames = filter(lambda fname: os.path.isdir(fname), fnames)
for dir in dnames:
engines = filter(lambda engine: engine.find(gtk_engine) == -1,
os.listdir(dir))
for engine in engines:
engine = os.path.join(dir, engine)
os.unlink(engine)
def remove_locales(self):
langtable = os.path.join(self.conf.treedir, "usr", "lib", "anaconda",
"lang-table")
localepath = os.path.join(self.conf.treedir, "usr", "share", "locale")
if os.path.isfile(langtable):
locales = set()
all_locales = set()
f = open(langtable, "r")
lines = f.readlines()
f.close()
for line in lines:
line = line.strip()
if not line or line.startswith("#"):
continue
fields = line.split("\t")
if os.path.isdir(os.path.join(localepath, fields[1])):
locales.add(fields[1])
locale = fields[3].split(".")[0]
if os.path.isdir(os.path.join(localepath, locale)):
locales.add(locale)
for locale in os.listdir(localepath):
all_locales.add(locale)
locales_to_remove = list(all_locales.difference(locales))
for locale in locales_to_remove:
rmpath = os.path.join(localepath, locale)
shutil.rmtree(rmpath, ignore_errors=True)
def remove_unnecessary_files(self):
to_remove = set()
for root, dirs, files in os.walk(self.conf.treedir):
for file in files:
path = os.path.join(root, file)
if fnmatch.fnmatch(path, "*.a"):
if path.find("kernel-wrapper/wrapper.a") == -1:
to_remove.add(path)
elif fnmatch.fnmatch(path, "lib*.la"):
if path.find("usr/" + self.conf.libdir + "/gtk-2.0") == -1:
to_remove.add(path)
elif fnmatch.fnmatch(path, "*.py"):
to_remove.add(path + "o")
try:
os.unlink(path + "c")
except OSError:
pass
os.symlink("/dev/null", path + "c")
for file in to_remove:
try:
os.unlink(file)
except OSError:
pass
# remove libunicode-lite
remove(os.path.join(self.conf.treedir, "usr", self.conf.libdir,
"libunicode-lite*"))
def remove_python_stuff(self):
for fname in ["bsddb", "compiler", "curses", "distutils", "email",
"encodings", "hotshot", "idlelib", "test",
"doctest.py", "pydoc.py"]:
remove(os.path.join(self.conf.treedir, "usr", self.conf.libdir,
"python?.?", fname))
def move_bins(self):
# move bin to usr/bin
move(src_root=self.conf.treedir,
src_path=os.path.join("bin", "*"),
dst_root=self.conf.treedir,
dst_path=os.path.join("usr", "bin"))
remove(os.path.join(self.conf.treedir, "bin"))
# move sbin to /usr/sbin
copy(src_root=self.conf.treedir,
src_path=os.path.join("sbin", "*"),
dst_root=self.conf.treedir,
dst_path=os.path.join("usr", "sbin"))
remove(os.path.join(self.conf.treedir, "sbin"))
# fix broken links
brokenlinks = []
for dir in ("bin", "sbin"):
dir = os.path.join(self.conf.treedir, "usr", dir)
for root, dnames, fnames in os.walk(dir):
for fname in fnames:
fname = os.path.join(root, fname)
if os.path.islink(fname) and not os.path.exists(fname):
brokenlinks.append(fname)
for link in brokenlinks:
target = os.readlink(link)
newtarget = re.sub(r"^\.\./\.\./(bin|sbin)/(.*)$", "../\g<1>/\g<2>",
target)
if newtarget != target:
os.unlink(link)
os.symlink(newtarget, link)
def process_scrubs_from_template(self):
# get supported actions
supported_actions = actions.getActions(verbose=self.conf.debug)
# variables supported in templates
vars = { "instroot": self.conf.treedir }
# parse the template file
scrubs = os.path.join(self.conf.confdir, "tree",
"scrubs.%s" % (self.conf.buildarch,))
if os.path.exists(scrubs):
self.template = Template()
self.template.preparse(scrubs)
self.template.parse(supported_actions, vars)
for action in self.template.actions:
action.execute()
def scrub(self):
self.copy_stubs()
self.create_dogtail_conf()
self.create_libuser_conf()
self.create_selinux_conf()
self.configure_fedorakmod()
self.copy_bootloaders()
self.move_repos()
self.move_anaconda_files()
self.create_debug_directories()
self.create_modules_symlinks()
self.fix_joe_links()
self.fix_man_pages()
self.remove_gtk_stuff()
self.remove_locales()
self.remove_unnecessary_files()
self.remove_python_stuff()
self.move_bins()
self.process_scrubs_from_template()

205
src/pylorax/launcher.py Normal file
View File

@ -0,0 +1,205 @@
#
# launcher.py
#
from __future__ import print_function
import sys
import os
from optparse import OptionParser, OptionGroup
import tempfile
import shutil
import ConfigParser
import yum
import pylorax
def main(args):
version = "%s %s" % (os.path.basename(args[0]), pylorax.__VERSION__)
usage = "%prog -p PRODUCT -v VERSION -r RELEASE -o OUTPUTDIR REPOSITORY"
parser = OptionParser(usage=usage)
# required arguments for image creation
required = OptionGroup(parser, "required arguments")
required.add_option("-p", "--product", help="product name",
metavar="STRING")
required.add_option("-v", "--version", help="version identifier",
metavar="STRING")
required.add_option("-r", "--release", help="release information",
metavar="STRING")
required.add_option("-o", "--outputdir", help="output directory",
metavar="PATHSPEC")
# optional arguments
optional = OptionGroup(parser, "optional arguments")
optional.add_option("-m", "--mirrorlist",
help="mirrorlist repository (may be listed multiple times)",
metavar="REPOSITORY", action="append", default=[])
optional.add_option("-t", "--variant",
help="variant name", metavar="STRING")
optional.add_option("-b", "--bugurl",
help="bug reporting URL for the product", metavar="URL",
default="your distribution provided bug reporting tool")
optional.add_option("-u", "--updates",
help="directory containing updates", metavar="PATHSPEC")
# output settings
output = OptionGroup(parser, "output settings")
output.add_option("--no-colors", help="disable color output",
action="store_false", default=True, dest="colors")
output.add_option("--encoding", help="set encoding",
metavar="STRING", default="utf-8")
output.add_option("-d", "--debug", help="enable debugging messages",
action="store_true", default=False)
# lorax settings
settings = OptionGroup(parser, "lorax settings")
settings.add_option("-c", "--cleanup", help="clean up on exit",
action="store_true", default=False)
# add the option groups to the parser
parser.add_option_group(required)
parser.add_option_group(optional)
parser.add_option_group(output)
parser.add_option_group(settings)
# add the show version option
parser.add_option("-V", help="show program's version number and exit",
action="store_true", default=False, dest="showver")
# parse the arguments
opts, args = parser.parse_args()
repositories = args
if opts.showver:
print(version)
sys.exit(0)
# check for the required arguments
if not opts.product or not opts.version or not opts.release \
or not opts.outputdir or not repositories:
parser.error("missing one or more required arguments")
# create the temporary directory for lorax
tempdir = tempfile.mkdtemp(prefix="lorax.", dir=tempfile.gettempdir())
# create the yumbase object
installtree = os.path.join(tempdir, "installtree")
os.mkdir(installtree)
yumtempdir = os.path.join(tempdir, "yum")
os.mkdir(yumtempdir)
yumconf = create_yumconf(repositories, opts.mirrorlist, yumtempdir)
yb = create_yumbase_object(yumconf, installtree)
if yb is None:
print("error: unable to create the yumbase object", file=sys.stderr)
shutil.rmtree(tempdir)
sys.exit(1)
# run lorax
params = { "product" : opts.product,
"version" : opts.version,
"release" : opts.release,
"outputdir" : opts.outputdir,
"tempdir" : tempdir,
"installtree" : installtree,
"colors" : opts.colors,
"encoding" : opts.encoding,
"debug" : opts.debug,
"cleanup" : opts.cleanup,
"variant" : opts.variant,
"bugurl" : opts.bugurl,
"updates" : opts.updates }
lorax = pylorax.Lorax(yb, **params)
lorax.run()
def create_yumconf(repositories, mirrorlists=[], tempdir="/tmp/yum"):
def sanitize_repo(repo):
if repo.startswith("/"):
return "file://%s" % repo
elif repo.startswith("http://") or repo.startswith("ftp://"):
return repo
else:
return None
# sanitize the repositories
repositories = map(sanitize_repo, repositories)
# remove invalid repositories
repositories = filter(bool, repositories)
cachedir = os.path.join(tempdir, "cache")
if not os.path.isdir(cachedir):
os.mkdir(cachedir)
yumconf = os.path.join(tempdir, "yum.conf")
c = ConfigParser.ConfigParser()
# add the main section
section = "main"
data = { "cachedir" : cachedir,
"keepcache" : 0,
"gpgcheck" : 0,
"plugins" : 0,
"reposdir" : "",
"tsflags" : "nodocs" }
c.add_section(section)
map(lambda (key, value): c.set(section, key, value), data.items())
# add the main repository - the first repository from list
section = "lorax-repo"
data = { "name" : "lorax repo",
"baseurl" : repositories[0],
"enabled" : 1 }
c.add_section(section)
map(lambda (key, value): c.set(section, key, value), data.items())
# add the extra repositories
for n, extra in enumerate(repositories[1:], start=1):
section = "lorax-extra-repo-%d" % n
data = { "name" : "lorax extra repo %d" % n,
"baseurl" : extra,
"enabled" : 1 }
c.add_section(section)
map(lambda (key, value): c.set(section, key, value), data.items())
# add the mirrorlists
for n, mirror in enumerate(mirrorlists, start=1):
section = "lorax-mirrorlist-%d" % n
data = { "name" : "lorax mirrorlist %d" % n,
"mirrorlist" : mirror,
"enabled" : 1 }
c.add_section(section)
map(lambda (key, value): c.set(section, key, value), data.items())
# write the yumconf file
with open(yumconf, "w") as f:
c.write(f)
return yumconf
def create_yumbase_object(yumconf, installroot="/"):
yb = yum.YumBase()
yb.preconf.fn = yumconf
yb.preconf.root = installroot
yb._getConfig()
yb._getRpmDB()
yb._getRepos()
yb._getSacks()
return yb

View File

@ -0,0 +1,58 @@
#
# __init__.py
#
import sys
import os
import re
from mako.template import Template as MakoTemplate
from mako.lookup import TemplateLookup as MakoTemplateLookup
import actions
class TemplateParserError(Exception):
pass
class TemplateParser(object):
def __init__(self, variables):
self.variables = variables
self.actions_map = actions.get_map()
def get_actions(self, file):
template_actions = []
# we have to set the template lookup directories to ["/"],
# otherwise the relative and absolute includes don't work properly
lookup = MakoTemplateLookup(directories=["/"])
template = MakoTemplate(filename=file, lookup=lookup)
s = template.render(**self.variables)
# concatenate lines ending with "\"
#s = re.sub(r"\s*\\\s*\n", " ", s)
for lineno, line in enumerate(s.splitlines(), start=1):
# remove multiple whitespaces
line = re.sub(r"\s+", " ", line.strip())
if not line:
continue
# get the command
command, line = line.split(None, 1)
if command not in self.actions_map:
raise TemplateParserError("%s: %d: invalid command" % \
(file, lineno))
# create the action object
m = re.match(self.actions_map[command].REGEX, line)
if m:
new_action = self.actions_map[command](**m.groupdict())
template_actions.append(new_action)
else:
raise TemplateParserError("%s: %d: invalid command format" % \
(file, lineno))
return template_actions

View File

@ -0,0 +1,31 @@
#
# __init__.py
#
import sys
import os
def get_map():
actions = {}
root, actions_dir = os.path.split(os.path.dirname(__file__))
sys.path.insert(0, root)
modules = set()
for filename in os.listdir(os.path.join(root, actions_dir)):
if filename.endswith(".py") and not filename == "__init__.py":
basename, extension = os.path.splitext(filename)
modules.add(os.path.join(actions_dir, basename).replace("/", "."))
for module in modules:
imported = __import__(module, globals(), locals(), [module], -1)
commands = getattr(imported, "COMMANDS", {})
for command, classname in commands.items():
actions[command] = getattr(imported, classname)
sys.path.pop(0)
return actions

View File

@ -0,0 +1,37 @@
#
# base.py
#
class LCSAction(object):
"""LCS Action base class.
To create your own custom action, subclass this class, and override
the methods you need.
A valid action has to have a REGEX class variable, which specifies
the format of the action command, so the needed parameters can be
properly extracted, and an execute() method, where all the work
should be done. This medhod will be called by Lorax.
Don't forget to include a command : action map for your new action
in the COMMANDS dictionary in the beginning of your file.
Action classes which are not in the COMMANDS dictionary will not
be loaded by Lorax.
"""
# regular expression for extracting the parameters from the command
REGEX = r""
def __init__(self):
if self.__class__ is LCSAction:
raise TypeError("LCSAction is an abstract class, " \
"cannot be used this way")
self._attrs = {}
def __str__(self):
return "%s: %s" % (self.__class__.__name__, self._attrs)
def execute(self):
raise NotImplementedError("execute() method not implemented")

View File

@ -0,0 +1,282 @@
#
# file.py
#
import os
from base import LCSAction
import pylorax.utils as utils
COMMANDS = { "remove" : "Remove",
"copy" : "Copy",
"symlink" : "SymLink",
"touch" : "Touch",
"mkdir" : "MkDir",
"makedirs" : "MakeDirs",
"chown" : "Chown",
"chmod" : "Chmod",
"edit" : "Edit",
"replace" : "Replace" }
class Remove(LCSAction):
REGEX = r"^(?P<filename>.*?)$"
def __init__(self, **kwargs):
LCSAction.__init__(self)
self._attrs["filename"] = kwargs.get("filename")
def execute(self):
utils.remove(self.filename)
@property
def filename(self):
return self._attrs["filename"]
# TODO add the ignore_errors flag
class Copy(LCSAction):
REGEX = r"^(?P<src_root>.*?)\s(?P<src_path>.*?)\sto\s" \
"(?P<dst_root>.*?)\s(?P<dst_path>.*?)" \
"(\s(?P<nosymlinks>nosymlinks))?$"
def __init__(self, **kwargs):
LCSAction.__init__(self)
self._attrs["src_root"] = kwargs.get("src_root")
self._attrs["src_path"] = kwargs.get("src_path")
self._attrs["dst_root"] = kwargs.get("dst_root")
self._attrs["dst_path"] = kwargs.get("dst_path")
nosymlinks = kwargs.get("nosymlinks")
if nosymlinks is not None:
self._attrs["symlinks"] = False
else:
self._attrs["symlinks"] = True
def execute(self):
utils.dcopy(src_root=self.src_root, src_path=self.src_path,
dst_root=self.dst_root, dst_path=self.dst_path,
symlinks=self.symlinks)
@property
def src(self):
path = os.path.join(self._attrs["src_root"], self._attrs["src_path"])
return os.path.normpath(path)
@property
def src_root(self):
return self._attrs["src_root"]
@property
def src_path(self):
return self._attrs["src_path"]
@property
def dst(self):
path = os.path.join(self._attrs["dst_root"], self._attrs["dst_path"])
return os.path.normpath(path)
@property
def dst_root(self):
return self._attrs["dst_root"]
@property
def dst_path(self):
return self._attrs["dst_path"]
@property
def symlinks(self):
return self._attrs["symlinks"]
class SymLink(LCSAction):
REGEX = r"^name\s(?P<name>.*?)\starget\s(?P<target>.*?)$"
def __init__(self, **kwargs):
LCSAction.__init__(self)
self._attrs["name"] = kwargs.get("name")
self._attrs["target"] = kwargs.get("target")
def execute(self):
utils.symlink(link_name=self.name, link_target=self.target)
@property
def name(self):
return self._attrs["name"]
@property
def target(self):
return self._attrs["target"]
class Touch(LCSAction):
REGEX = r"^(?P<filename>.*?)$"
def __init__(self, **kwargs):
LCSAction.__init__(self)
self._attrs["filename"] = kwargs.get("filename")
def execute(self):
utils.touch(self.filename)
@property
def filename(self):
return self._attrs["filename"]
class MkDir(LCSAction):
REGEX = r"^(?P<dir>.*?)(\smode\s(?P<mode>.*?))?$"
def __init__(self, **kwargs):
LCSAction.__init__(self)
self._attrs["dir"] = kwargs.get("dir")
mode = kwargs.get("mode")
if mode is not None:
self._attrs["mode"] = int(mode, 8)
else:
self._attrs["mode"] = None
def execute(self):
utils.mkdir(self.dir, self.mode)
@property
def dir(self):
return self._attrs["dir"]
@property
def mode(self):
return self._attrs["mode"]
class MakeDirs(MkDir):
def __init__(self, **kwargs):
MkDir.__init__(self, **kwargs)
def execute(self):
utils.makedirs(self.dir, self.mode)
class Chown(LCSAction):
REGEX = r"^(?P<filename>.*?)\suser\s(?P<user>.*?)" \
"\sgroup\s(?P<group>.*?)(\s(?P<recursive>recursive))?$"
def __init__(self, **kwargs):
LCSAction.__init__(self)
self._attrs["filename"] = kwargs.get("filename")
self._attrs["user"] = kwargs.get("user")
self._attrs["group"] = kwargs.get("group")
recursive = kwargs.get("recursive")
if recursive is not None:
self._attrs["recursive"] = True
else:
self._attrs["recursive"] = False
def execute(self):
utils.chown(self.filename, self.user, self.group, self.recursive)
@property
def filename(self):
return self._attrs["filename"]
@property
def user(self):
return self._attrs["user"]
@property
def group(self):
return self._attrs["group"]
@property
def recursive(self):
return self._attrs["recursive"]
class Chmod(LCSAction):
REGEX = r"^(?P<filename>.*?)\smode\s(?P<mode>[0-7]*?)" \
"(\s(?P<recursive>recursive))?$"
def __init__(self, **kwargs):
LCSAction.__init__(self)
self._attrs["filename"] = kwargs.get("filename")
self._attrs["mode"] = int(kwargs.get("mode"), 8)
recursive = kwargs.get("recursive")
if recursive is not None:
self._attrs["recursive"] = True
else:
self._attrs["recursive"] = False
def execute(self):
utils.chmod(self.filename, self.mode, self.recursive)
@property
def filename(self):
return self._attrs["filename"]
@property
def mode(self):
return self._attrs["mode"]
@property
def recursive(self):
return self._attrs["recursive"]
class Edit(Touch):
REGEX = r'^(?P<filename>.*?)\stext\s"(?P<text>.*?)"' \
'(\s(?P<append>append))?$'
def __init__(self, **kwargs):
Touch.__init__(self, **kwargs)
self._attrs["text"] = kwargs.get("text")
append = kwargs.get("append")
if append is not None:
self._attrs["append"] = True
else:
self._attrs["append"] = False
def execute(self):
utils.edit(self.filename, self.text, self.append)
@property
def text(self):
return self._attrs["text"]
@property
def append(self):
return self._attrs["append"]
class Replace(Touch):
REGEX = r'^(?P<filename>.*?)\sfind\s"(?P<find>.*?)"' \
'\sreplace\s"(?P<replace>.*?)"$'
def __init__(self, **kwargs):
Touch.__init__(self, **kwargs)
self._attrs["find"] = kwargs.get("find")
self._attrs["replace"] = kwargs.get("replace")
def execute(self):
utils.replace(self.filename, self.find, self.replace)
@property
def find(self):
return self._attrs["find"]
@property
def replace(self):
return self._attrs["replace"]

View File

@ -0,0 +1,39 @@
#
# ssh.py
#
import commands
from base import LCSAction
import pylorax.utils as utils
COMMANDS = { "gensshkey" : "GenerateSSHKey" }
class GenerateSSHKey(LCSAction):
REGEX = r"^(?P<filename>.*?)\stype\s(?P<type>.*?)$"
def __init__(self, **kwargs):
LCSAction.__init__(self)
self._attrs["filename"] = kwargs.get("filename")
self._attrs["type"] = kwargs.get("type")
def execute(self):
cmd = "/usr/bin/ssh-keygen -q -t %s -f %s -C '' -N ''" % \
(self.type, self.filename)
err, output = commands.getstatusoutput(cmd)
if not err:
utils.chmod(self.filename, 0600)
utils.chmod(self.filename + ".pub", 0644)
@property
def filename(self):
return self._attrs["filename"]
@property
def type(self):
return self._attrs["type"]

View File

@ -1,41 +0,0 @@
#
# misc.py
# miscellaneous functions
#
# Copyright (C) 2009 Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# Red Hat Author(s): Martin Gracik <mgracik@redhat.com>
#
import commands
def seq(arg):
if type(arg) not in (type([]), type(())):
return [arg]
else:
return arg
def get_console_size():
err, output = commands.getstatusoutput("stty size")
if not err:
height, width = output.split()
height, width = int(height), int(width)
else:
# set defaults
height, width = 24, 80
return height, width

View File

@ -1,35 +1,15 @@
#
# output.py
# output control
#
# Copyright (C) 2009 Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# Red Hat Author(s): Martin Gracik <mgracik@redhat.com>
#
import sys
import singleton
# color codes
### color codes
C_DEFAULT = "\x1b[39m"
C_RESET = "\x1b[0m"
C_BOLD = "\x1b[1m"
C_UNDERLINE = "\x1b[4m"
C_BLACK = "\x1b[0;30m"
C_WHITE = "\x1b[1;37m"
C_RED = "\x1b[0;31m"
@ -39,53 +19,39 @@ C_LIGHTRED = "\x1b[1;31m"
C_LIGHTGREEN = "\x1b[1;32m"
C_LIGHTBLUE = "\x1b[1;34m"
# font types
C_BOLD = "\x1b[1m"
C_UNDERLINE = "\x1b[4m"
### font types
BOLD = 0b01
UNDERLINE = 0b10
### output levels
CRITICAL = 50
ERROR = 40
WARNING = 30
INFO = 20
DEBUG = 10
NOTSET = 0
class OutputError(Exception):
pass
class Output(object):
class Terminal(singleton.Singleton):
def __init__(self, output=sys.stdout, colors=True, encoding="utf-8",
verbose=False):
def __init__(self):
self.__colors = True
self.__encoding = "utf-8"
self.__output_level = INFO
self.__indent_level = 0
self.output = output
if not hasattr(self.output, "write"):
raise OutputError, "output does not support write()"
self.is_flushable = hasattr(self.output, "flush")
def basic_config(self, colors=None, encoding=None, level=None):
if colors is not None:
self.__colors = colors
self.colors = colors
self.encoding = encoding
self.verbose = verbose
if encoding is not None:
self.__encoding = encoding
self.__indent_level = 0
def write(self, s, color=C_RESET, type=None):
s = self.format(s, color=color, type=type)
self.output.write(s)
if self.is_flushable:
self.output.flush()
def format(self, s, color=C_RESET, type=None):
s = s.encode(self.encoding)
if self.colors:
if type is not None and (type & BOLD):
s = "%s%s" % (C_BOLD, s)
if type is not None and (type & UNDERLINE):
s = "%s%s" % (C_UNDERLINE, s)
s = "%s%s%s" % (color, s, C_RESET)
return s
def writeline(self, s, color=C_RESET, type=None):
s = "%s%s\n" % (" " * self.__indent_level, s)
self.write(s, color=color, type=type)
if level is not None:
self.__output_level = level
def indent(self):
self.__indent_level += 1
@ -94,31 +60,43 @@ class Output(object):
if self.__indent_level > 0:
self.__indent_level -= 1
def newline(self):
self.output.write("\n")
def write(self, s, color=C_RESET, type=None, file=sys.stdout):
s = self.format(s, color=color, type=type)
file.write(s)
file.flush()
def banner(self, s):
self.writeline(s, color=C_GREEN, type=BOLD)
def format(self, s, color=C_RESET, type=None):
s = s.encode(self.__encoding)
def header(self, s):
self.writeline(s, type=BOLD)
if self.__colors:
if type is not None and (type & BOLD):
s = "%s%s" % (C_BOLD, s)
if type is not None and (type & UNDERLINE):
s = "%s%s" % (C_UNDERLINE, s)
s = "%s%s%s" % (color, s, C_RESET)
def info(self, s):
self.writeline(s)
return s
def error(self, s):
self.writeline(s, color=C_RED, type=BOLD)
def writeline(self, s, color=C_RESET, type=None, file=sys.stdout):
s = "%s%s" % (" " * self.__indent_level, s)
self.write(s + "\n", color=color, type=type, file=file)
def warning(self, s):
self.writeline(s, color=C_RED)
def critical(self, s, file=sys.stdout):
if self.__output_level <= CRITICAL:
self.writeline("** critical: %s" % s, file=file)
def debug(self, s):
if self.verbose:
self.writeline(s)
def error(self, s, file=sys.stdout):
if self.__output_level <= ERROR:
self.writeline("** error: %s" % s, file=file)
def warning(self, s, file=sys.stdout):
if self.__output_level <= WARNING:
self.writeline("** warning: %s" % s, file=file)
def initialize(verbose=False):
stdout = Output(output=sys.stdout, verbose=verbose)
stderr = Output(output=sys.stderr, verbose=verbose)
return stdout, stderr
def info(self, s, file=sys.stdout):
if self.__output_level <= INFO:
self.writeline(s, file=file)
def debug(self, s, file=sys.stdout):
if self.__output_level <= DEBUG:
self.writeline(s, file=file)

435
src/pylorax/ramdisk.py Normal file
View File

@ -0,0 +1,435 @@
#
# ramdisk.py
#
import sys
import os
import glob
import shutil
import commands
import re
import gzip
import config
import output
import lcs
import utils
class Ramdisk(object):
def __init__(self):
# get the config, paths and output objects
self.conf = config.LoraxConfig.get()
self.paths = config.LoraxPaths.get()
self.output = output.Terminal.get()
self.actions = self.get_actions_from_template()
def get_actions_from_template(self):
variables = { "instroot" : self.conf.installtree,
"initrd" : self.conf.ramdisktree,
"libdir" : self.conf.libdir,
"arch" : self.conf.arch,
"basearch" : self.conf.basearch,
"confdir" : self.conf.confdir,
"datadir" : self.conf.datadir }
if self.conf.initrd_template is not None:
template = lcs.TemplateParser(variables)
return template.get_actions(self.conf.initrd_template)
return []
# XXX we have to do this, otherwise we get an error, when copying
def remove_modules_broken_links(self):
# remove build and source links from modules directories
build = os.path.join(self.paths.MODULES_DIR, "build")
if os.path.islink(build):
utils.remove(build)
source = os.path.join(self.paths.MODULES_DIR, "source")
if os.path.islink(source):
utils.remove(source)
def move_shared_files(self):
dirs = [os.path.join(self.paths.INITRD_DATADIR, "noarch"),
os.path.join(self.paths.INITRD_DATADIR, self.conf.arch)]
self.output.info(":: copying the custom initrd files")
for dir in [dir for dir in dirs if os.path.isdir(dir)]:
utils.scopy(src_root=dir, src_path="*",
dst_root=self.conf.ramdisktree, dst_path="")
def process_actions(self):
for action in self.actions:
action.execute()
def create_modinfo(self, moddir, target):
modules_map = {}
for root, dirs, files in os.walk(moddir):
for file in files:
modules_map[file] = os.path.join(root, file)
modules = { "scsi_hostadapter" : "block",
"eth" : "networking" }
blacklist = ( "floppy",
"scsi_mod",
"libiscsi" )
list = {}
for type, file_suffix in modules.items():
list[type] = {}
filename = os.path.join(moddir, "modules.%s" % file_suffix)
if not os.path.isfile(filename):
continue
with open(filename, "r") as f:
for line in f:
line = line.strip()
if line in modules_map:
modname, ext = os.path.splitext(line)
if modname in blacklist:
continue
cmd = "%s -F description %s" % (self.paths.MODINFO,
modules_map[line])
err, output = commands.getstatusoutput(cmd)
if err:
self.output.warning(output)
desc = ""
else:
desc = output.split("\n")[0]
desc = desc.strip()
desc = desc[:65]
if not desc:
desc = "%s driver" % modname
info = '%s\n\t%s\n\t"%s"\n' % (modname, type, desc)
list[type][modname] = info
with open(target, "w") as f:
f.write("Version 0\n")
for type in list:
modlist = sorted(list[type].keys())
for mod in modlist:
f.write("%s\n" % list[type][mod])
def get_kernel_modules(self):
src_moddir = self.paths.MODULES_DIR
dst_moddir = os.path.join(self.conf.ramdisktree, "lib", "modules",
self.conf.kernelver)
# expand modules
modules = set()
for name in self.conf.modules:
if name.startswith("="):
group = name[1:]
if group in ("scsi", "ata"):
path = os.path.join(src_moddir, "modules.block")
elif group == "net":
path = os.path.join(src_moddir, "modules.networking")
else:
path = os.path.join(src_moddir, "modules.%s" % group)
if os.path.isfile(path):
with open(path, "r") as f:
for line in f:
module = re.sub(r"\.ko$", "", line.strip())
modules.add(module)
else:
modules.add(name)
# resolve modules dependencies
with open(self.paths.MODULES_DEP, "r") as f:
lines = map(lambda l: l.strip(), f.readlines())
modpattern = re.compile(r"^.*/(?P<name>.*)\.ko:(?P<deps>.*)$")
deppattern = re.compile(r"^.*/(?P<name>.*)\.ko$")
changed = True
while changed:
for line in lines:
changed = False
m = modpattern.match(line)
modname = m.group("name")
if modname in modules:
# add the dependencies
for dep in m.group("deps").split():
m = deppattern.match(dep)
depname = m.group("name")
if depname not in modules:
changed = True
modules.add(depname)
# copy all modules to the ramdisk tree
src_path = src_moddir.replace(self.conf.installtree, "", 1)
if src_path.startswith("/"):
src_path = src_path[1:]
dst_path = "lib/modules"
utils.scopy(src_root=self.conf.installtree, src_path=src_path,
dst_root=self.conf.ramdisktree, dst_path=dst_path)
# remove not needed modules
for root, dirs, files in os.walk(dst_moddir):
for file in files:
full_path = os.path.join(root, file)
name, ext = os.path.splitext(file)
if ext == ".ko":
if name not in modules:
utils.remove(full_path)
else:
# get the required firmware
cmd = "%s -F firmware %s" % (self.paths.MODINFO,
full_path)
err, output = commands.getstatusoutput(cmd)
if err:
self.output.warning(output)
continue
for fw in output.split():
dst = os.path.join(self.conf.ramdisktree,
"lib", "firmware", fw)
# create the destination directory
dir = os.path.dirname(dst)
if not os.path.isdir(dir):
utils.makedirs(dir)
# copy the firmware
path = os.path.join("lib", "firmware", fw)
utils.scopy(src_root=self.conf.installtree,
src_path=path,
dst_root=self.conf.ramdisktree,
dst_path=path)
# copy additional firmware
fw = [ ("ipw2100", "ipw2100*"),
("ipw2200", "ipw2200*"),
("iwl3945", "iwlwifi-3945*"),
("iwl4965", "iwlwifi-4965*"),
("atmel", "atmel_*.bin"),
("zd1211rw", "zd1211"),
("qla2xxx", "ql*") ]
for module, file in fw:
if module in modules:
utils.scopy(src_root=self.conf.installtree,
src_path=os.path.join("lib", "firmware", file),
dst_root=self.conf.ramdisktree,
dst_path=os.path.join("lib", "firmware"))
# compress modules
for root, dirs, files in os.walk(dst_moddir):
for file in files:
if not file.endswith(".ko"):
continue
kopath = os.path.join(root, file)
with open(kopath, "rb") as f:
kodata = f.read()
gzipped = gzip.open(kopath + ".gz", "wb")
gzipped.write(kodata)
gzipped.close()
os.unlink(kopath)
# create modinfo
modinfo = os.path.join(self.conf.tempdir, "module-info")
self.create_modinfo(src_moddir, modinfo)
target = os.path.join(self.conf.ramdisktree, "lib", "modules",
"module-info")
cmd = "%s --modinfo-file %s --ignore-missing --modinfo %s > %s" % \
(self.paths.MODLIST, modinfo, " ".join(list(modules)), target)
err, output = commands.getstatusoutput(cmd)
if err:
self.output.warning(output)
# run depmod
cmd = "%s -a -F %s -b %s %s" % (
self.paths.DEPMOD, self.paths.SYSTEM_MAP, self.conf.installtree,
self.conf.kernelver)
err, output = commands.getstatusoutput(cmd)
if err:
self.output.warning(output)
# remove leftovers
utils.remove(os.path.join(dst_moddir, "modules.*map"))
def get_keymaps(self):
if os.path.isfile(self.paths.KEYMAPS_OVERRIDE):
dst = os.path.join(self.conf.ramdisktree, "etc", "keymaps.gz")
shutil.copy2(self.paths.KEYMAPS_OVERRIDE, dst)
else:
cmd = "%s %s %s %s" % (
self.paths.GETKEYMAPS, self.conf.arch,
os.path.join(self.conf.ramdisktree, "etc", "keymaps.gz"),
self.conf.installtree)
err, output = commands.getstatusoutput(cmd)
if err:
self.output.error(output)
return False
return True
def create_locales(self):
dir = os.path.join(self.conf.ramdisktree, "usr", "lib", "locale")
utils.makedirs(dir)
cmd = "%s -c -i en_US -f UTF-8 --prefix %s en_US" % \
(self.paths.LOCALEDEF, self.conf.ramdisktree)
err, output = commands.getstatusoutput(cmd)
if err:
self.output.error(output)
return False
return True
def compress(self, filename):
self.output.info(":: compressing the image file")
cwd = os.getcwd()
os.chdir(self.conf.ramdisktree)
# XXX python cpioarchive does not support writing
cpioarchive = filename + ".cpio"
cmd = "find . | cpio --quiet -c -o > %s" % cpioarchive
err, output = commands.getstatusoutput(cmd)
if err:
return False
os.chdir(cwd)
with open(cpioarchive, "rb") as f:
cpiodata = f.read()
gzipped = gzip.open(filename, "wb")
gzipped.write(cpiodata)
gzipped.close()
os.unlink(cpioarchive)
return True
def prepare(self):
# copy the .buildstamp file
shutil.copy2(self.conf.buildstamp, self.conf.ramdisktree)
self.remove_modules_broken_links()
self.move_shared_files()
self.process_actions()
self.get_kernel_modules()
self.get_keymaps()
self.create_locales()
def create(self):
self.prepare()
f = getattr(self, "create_%s" % self.conf.arch, None)
if f:
return f()
def create_i386(self):
initrd_filename = "initrd.img"
kernel_filename = "vmlinuz"
if self.conf.kernelfile.endswith("PAE"):
initrd_filename = "initrd-PAE.img"
kernel_filename = "vmlinuz-PAE"
text = """[images-xen]
kernel = images/pxeboot/vmlinuz-PAE
initrd = images/pxeboot/initrd-PAE.img
"""
utils.edit(self.conf.treeinfo, append=True, text=text)
initrd_filename = os.path.join(self.conf.tempdir, initrd_filename)
self.compress(initrd_filename)
kernel_filename = os.path.join(self.conf.tempdir, kernel_filename)
shutil.copy2(self.conf.kernelfile, kernel_filename)
return kernel_filename, initrd_filename
def create_x86_64(self):
return self.create_i386()
def run_s390(self):
initrd_filename = os.path.join(self.conf.tempdir, "initrd.img")
self.compress(initrd_filename)
kernel_filename = os.path.join(self.conf.tempdir, "kernel.img")
shutil.copy2(self.conf.kernelfile, kernel_filename)
cmd = "%s %s %s" % (self.paths.GENINITRDSZ,
os.path.getsize(initrd_filename),
os.path.join(self.conf.imagesdir, "initrd.size"))
err, output = commands.getstatusoutput(cmd)
if err:
self.output.warning(output)
for filename in (self.paths.REDHAT_EXEC, self.paths.GENERIC_PRM):
shutil.copy2(filename, self.conf.imagesdir)
shutil.copy2(filename, self.conf.outputdir)
cmd = "%s -i %s -r %s -p %s -o %s" % (
MKS390CD, kernel_filename, initrd_filename,
self.paths.GENERIC_PRM,
os.path.join(self.conf.imagesdir, "cdboot.img"))
err, output = commands.getstatusoutput(cmd)
if err:
self.output.warning(output)
text = """[images-%s]
kernel = images/kernel.img
initrd = images/initrd.img
initrd.size = images/initrd.size
generic.prm = images/generic.prm
generic.ins = generic.ins
cdboot.img = images/cdboot.img
""" % self.conf.arch
utils.edit(self.conf.treeinfo, append=True, text=text)
return kernel_filename, initrd_filename
def run_s390x(self):
return self.run_s390()
# XXX this should be removed
def run_alpha(self):
raise NotImplementedError
def run_ia64(self):
raise NotImplementedError
def run_ppc(self):
raise NotImplementedError
def run_ppc64(self):
raise NotImplementedError

14
src/pylorax/singleton.py Normal file
View File

@ -0,0 +1,14 @@
#
# singleton.py
#
class Singleton(object):
__instance = None
@classmethod
def get(cls):
if cls.__instance is None:
cls.__instance = cls()
return cls.__instance

View File

@ -1,113 +0,0 @@
#
# template.py
# initrd template class
#
# Copyright (C) 2009 Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# Red Hat Author(s): Martin Gracik <mgracik@redhat.com>
#
import sys
import os
import re
class TemplateError(Exception):
pass
class Template(object):
def __init__(self):
self._actions = []
self.lines = []
self.included_files = []
def preparse(self, filename):
try:
f = open(filename, 'r')
except IOError as why:
sys.stderr.write("ERROR: Unable to open template file '%s': %s\n" % (filename, why))
return False
else:
lines = f.readlines()
f.close()
self.included_files.append(filename)
for line in lines:
line = line.strip()
if line.startswith('#include'):
file_to_include = line.split()[1]
path = os.path.join(os.path.dirname(filename), file_to_include)
if path not in self.included_files:
self.preparse(path)
else:
self.lines.append(line)
def parse(self, supported_actions, variables):
lines = self.lines
# append next line if line ends with '\'
temp = []
for line in lines:
line = line.strip()
if line.endswith('\\'):
line = line[:-1]
line = line.rstrip()
line = line + ' '
else:
line = line + '\n'
temp.append(line)
temp = ''.join(temp)
lines = temp.splitlines()
# check template variables
for lineno, line in enumerate(lines, start=1):
for var in filter(lambda var: var not in variables, re.findall(r'@(.*?)@', line)):
raise TemplateError, "unknown variable '%s' on line %d" % (var, lineno)
# parse the template
for lineno, line in enumerate(lines, start=1):
line, sep, comment = line.partition('#')
if not line:
continue
# expand variables
for var, value in variables.items():
line = re.sub(r'@%s@' % var, value, line)
# get the command
command, line = line.split(None, 1)
if command not in supported_actions:
raise TemplateError, "unknown command '%s' on line %d" % (command, lineno)
# create the action object
regex = supported_actions[command].REGEX
m = re.match(regex, line)
if m:
new_action = supported_actions[command](**m.groupdict())
self._actions.append(new_action)
else:
# didn't match the regex
raise TemplateError, "invalid command format '%s' on line %d" % (line, lineno)
return True
@property
def actions(self):
return self._actions

405
src/pylorax/utils.py Normal file
View File

@ -0,0 +1,405 @@
#
# utils.py
#
import sys
import os
import shutil
import glob
import fileinput
import re
import pwd
import grp
import commands
def expand_path(path, globs=True):
l = []
m = re.match(r"(?P<prefix>.*){(?P<expand>.*?)}(?P<suffix>.*)", path)
if m:
for f in re.split(r"\s*,\s*", m.group("expand")):
l.extend(expand_path(m.group("prefix") + f + m.group("suffix"),
globs=globs))
else:
if globs:
l.extend(glob.glob(path))
else:
l.append(path)
return l
def remove(file):
for fname in expand_path(file):
if os.path.islink(fname) or os.path.isfile(fname):
os.unlink(fname)
else:
shutil.rmtree(fname)
def __copy(src_path, dst_path, src_root="/", dst_root="/", symlinks=True,
ignore_errors=False, deps=False):
# ensure that roots end with "/"
if not src_root.endswith("/"):
src_root = src_root + "/"
if not dst_root.endswith("/"):
dst_root = dst_root + "/"
smartcopy = SmartCopy(src_root, dst_root, symlinks, ignore_errors)
src = os.path.join(src_root, src_path)
for fname in expand_path(src):
fname = fname.replace(src_root, "", 1)
smartcopy.copy(fname, dst_path)
if deps:
smartcopy.get_deps()
smartcopy.process()
def scopy(src_path, dst_path, src_root="/", dst_root="/", symlinks=True,
ignore_errors=False):
__copy(src_path, dst_path, src_root, dst_root, symlinks,
ignore_errors, deps=False)
def dcopy(src_path, dst_path, src_root="/", dst_root="/", symlinks=True,
ignore_errors=False):
__copy(src_path, dst_path, src_root, dst_root, symlinks,
ignore_errors, deps=True)
def symlink(link_target, link_name):
if os.path.islink(link_name) or os.path.isfile(link_name):
os.unlink(link_name)
os.symlink(link_target, link_name)
def touch(file):
if os.path.exists(file):
os.utime(file, None)
else:
with open(file, "w") as f:
pass
def mkdir(dir, mode=None):
if mode is None:
mode = 0755
for d in expand_path(dir, globs=False):
if not os.path.isdir(d):
os.mkdir(d, mode)
def makedirs(dir, mode=None):
if mode is None:
mode = 0755
for d in expand_path(dir, globs=False):
if not os.path.isdir(d):
os.makedirs(d, mode)
def chown(file, user=None, group=None, recursive=False):
# if uid or gid is set to -1, it will not be changed
uid = gid = -1
if user is not None:
uid = pwd.getpwnam(user)[2]
if group is not None:
gid = grp.getgrnam(group)[2]
for fname in expand_path(file):
os.chown(fname, uid, gid)
if recursive and os.path.isdir(fname):
for nested in os.listdir(fname):
nested = os.path.join(fname, nested)
chown(nested, user, group, recursive)
def chmod(file, mode, recursive=False):
for fname in expand_path(file):
os.chmod(fname, mode)
if recursive and os.path.isdir(fname):
for nested in os.listdir(fname):
nested = os.path.join(fname, nested)
chmod(nested, mode, recursive)
def edit(file, text, append=False):
mode = "w"
if append:
mode = "a"
with open(file, mode) as f:
f.write(text)
def replace(file, find, replace):
fin = fileinput.input(file, inplace=1)
for line in fin:
line = re.sub(find, replace, line)
sys.stdout.write(line)
fin.close()
class SmartCopyError(Exception):
pass
class SmartCopy(object):
def __init__(self, src_root="/", dst_root="/", symlinks=True,
ignore_errors=False):
self.src_root = src_root
self.dst_root = dst_root
self.symlinks = symlinks
self.ignore_errors = ignore_errors
self.linker = Linker(src_root)
self.clear()
def clear(self):
self.makedirs = []
self.copyfiles = set()
self.links = set()
self.errors = []
def copy(self, src_path, dst_path):
src = os.path.normpath(os.path.join(self.src_root, src_path))
dst = os.path.normpath(os.path.join(self.dst_root, dst_path))
# check if the source exists
if not os.path.exists(src):
err_msg = "cannot stat '%s': No such file or directory" % src
if not self.ignore_errors:
raise SmartCopyError(err_msg)
else:
self.errors.append(err_msg)
return # EXIT
if os.path.isfile(src):
self.__copy_file(src_path, dst_path, src, dst)
elif os.path.isdir(src):
self.__copy_dir(src_path, dst_path, src, dst)
def __copy_file(self, src_path, dst_path, src, dst):
# if destination is an existing directory,
# append the source filename to the destination path
if os.path.isdir(dst):
dst = os.path.join(dst, os.path.basename(src))
# check if the new destination is still an existing directory
if os.path.isdir(dst):
# do not overwrite a directory with a file
err_msg = "cannot overwrite directory '%s' " \
"with non-directory" % dst
if not self.ignore_errors:
raise SmartCopyError(err_msg)
else:
self.errors.append(err_msg)
return # EXIT
if os.path.islink(src):
if not self.symlinks:
real_src = os.path.realpath(src)
self.copyfiles.add((real_src, dst))
else:
self.__copy_link(src_path, dst_path, src, dst)
else:
self.copyfiles.add((src, dst))
def __copy_dir(self, src_path, dst_path, src, dst):
# append the source directory name to the destination path
dirname = os.path.basename(src)
new_dst = os.path.join(dst, dirname)
# remove the trailing "/",
# to make sure, that we don't try to create "dir" and "dir/"
if new_dst.endswith("/"):
new_dst = new_dst[:-1]
if os.path.islink(src):
if not self.symlinks:
real_src = os.path.realpath(src)
if not os.path.exists(new_dst) and \
new_dst not in self.makedirs:
self.makedirs.append(new_dst)
for fname in os.listdir(real_src):
fname = os.path.join(real_src, fname)
self.copy(fname, new_dst)
else:
self.__copy_link(src_path, dst_path, src, new_dst)
else:
# create the destination directory, if it does not exist
if not os.path.exists(new_dst) and \
new_dst not in self.makedirs:
self.makedirs.append(new_dst)
elif os.path.isfile(new_dst):
err_msg = "cannot overwrite file '%s' with a directory" \
% new_dst
if not self.ignore_errors:
raise SmartCopyError(err_msg)
else:
self.errors.append(err_msg)
return # EXIT
new_dst_path = os.path.join(dst_path, dirname)
try:
fnames = os.listdir(src)
except OSError as why:
err_msg = "cannot list directory '%s': %s'" % (src, why)
if not self.ignore_errors:
raise SmartCopyError(err_msg)
else:
self.errors.append(err_msg)
return # EXIT
for fname in fnames:
fname = os.path.join(src_path, fname)
self.copy(fname, new_dst_path)
def __copy_link(self, src_path, dst_path, src, dst):
# read the link target
link_target = os.readlink(src)
# get the target source and destination paths
target_src_path = os.path.join(os.path.dirname(src_path), link_target)
target_dst_dir = os.path.join(dst_path, os.path.dirname(link_target))
# if the link target is an absolute path,
# make sure we copy it relative to the dst_root
if target_dst_dir.startswith("/"):
target_dst_dir = target_dst_dir[1:]
# remove the trailing "/"
if target_dst_dir.endswith("/"):
target_dst_dir = target_dst_dir[:-1]
# create the destination directory, if it doesn't exist
target_dst = os.path.join(self.dst_root, target_dst_dir)
if not os.path.exists(target_dst) and \
target_dst not in self.makedirs:
self.makedirs.append(target_dst)
# copy the target along with the link
self.copy(target_src_path, target_dst_dir)
# create the symlink named dst, pointing to link_target
self.links.add((link_target, dst))
def get_deps(self):
deps = set()
for src, dst in self.copyfiles:
if self.linker.is_elf(src):
deps = deps.union(self.linker.get_deps(src))
for src in deps:
src_path = src.replace(self.src_root, "", 1)
dst_path = os.path.dirname(src_path)
# create the destination directory
dst_dir = os.path.join(self.dst_root, dst_path)
if not os.path.exists(dst_dir) and \
dst_dir not in self.makedirs:
self.makedirs.append(dst_dir)
self.copy(src_path, dst_path)
def process(self):
# create required directories
map(mkdir, self.makedirs)
# copy all the files
# remove the dst, if it is a link to src
for src, dst in self.copyfiles:
if os.path.realpath(dst) == src:
os.unlink(dst)
map(lambda (src, dst): shutil.copy2(src, dst), self.copyfiles)
# create symlinks
map(lambda (target, name): symlink(target, name), self.links)
class LinkerError(Exception):
pass
class Linker(object):
LIBDIRS = ( "lib64",
"usr/lib64",
"lib",
"usr/lib" )
def __init__(self, root="/"):
libdirs = map(lambda path: os.path.join(root, path), self.LIBDIRS)
libdirs = ":".join(libdirs)
ld_linux = None
with open("/usr/bin/ldd", "r") as f:
for line in f:
m = re.match(r"^RTLDLIST=(?P<ld_linux>.*)$", line.strip())
if m:
ld_linux = m.group("ld_linux")
break
if ld_linux is None:
raise LinkerError("unable to find the ld_linux executable")
self.lddcmd = "LD_LIBRARY_PATH=%s %s --list" % (libdirs, ld_linux)
self.pattern = re.compile(r"^[a-zA-Z0-9.-_/]*\s=>\s" \
r"(?P<lib>[a-zA-Z0-9.-_/]*)" \
r"\s\(0x[0-9a-f]*\)$")
def is_elf(self, file):
err, output = commands.getstatusoutput("file --brief %s" % file)
if err:
raise LinkerError("error getting the file type")
if not output.startswith("ELF"):
return False
return True
def get_deps(self, file):
err, output = commands.getstatusoutput("%s %s" % (self.lddcmd, file))
if err:
raise LinkerError("error getting the file dependencies")
deps = set()
for line in output.splitlines():
m = self.pattern.match(line.strip())
if m:
deps.add(m.group("lib"))
return deps

View File

@ -1,306 +0,0 @@
#
# fileutils.py
# functions for working with files
#
# Copyright (C) 2009 Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# Red Hat Author(s): Martin Gracik <mgracik@redhat.com>
#
import sys
import os
import shutil
import glob
import fileinput
import re
def normalize(src_root, src_path, dst_root, dst_path):
src = os.path.join(src_root, src_path)
dst = os.path.join(dst_root, dst_path)
src = os.path.normpath(src)
dst = os.path.normpath(dst)
return src, dst
def remove(target, verbose=False):
for fname in glob.iglob(target):
if verbose:
print "removing '%s'" % (fname,)
if os.path.islink(fname) or os.path.isfile(fname):
os.unlink(fname)
else:
shutil.rmtree(fname, ignore_errors=True)
def touch(filename, verbose=False):
if verbose:
print "touching '%s'" % (filename,)
if os.path.exists(filename):
os.utime(filename, None)
else:
try:
f = open(filename, "w")
except IOError as why:
print >> sys.stderr, "cannot create '%s': %s" % (filename, why)
return False
else:
f.close()
return True
def copy(src_path, dst_path, src_root="/", dst_root="/",
nolinks=False, ignore_errors=False, verbose=False):
filecopy = Copy(ignore_errors, verbose)
src = os.path.join(src_root, src_path)
for fname in glob.iglob(src):
fname = fname.replace(src_root, "", 1)
if src_path[0] != "/" and fname[0] == "/":
fname = fname[1:]
filecopy.copy(fname, dst_path, src_root, dst_root, nolinks)
return filecopy.errors
def move(src_path, dst_path, src_root="/", dst_root="/",
nolinks=False, ignore_errors=False, verbose=False):
errors = copy(src_path, dst_path, src_root, dst_root,
nolinks, ignore_errors, verbose)
# if everything was copied ok, remove the source
if not errors:
src, dst = normalize(src_root, src_path, dst_root, dst_path)
remove(src, verbose)
return errors
def chmod(target, mode, recursive=False, verbose=False):
mode = int(mode)
for fname in glob.iglob(target):
if verbose:
print "changing permissions on '%s'" % (fname,)
os.chmod(fname, mode)
if recursive and os.path.isdir(fname):
for nested in os.listdir(fname):
nested = os.path.join(fname, nested)
chmod(nested, mode, recursive, verbose)
def edit(filename, text, append=False, verbose=False):
mode = "w"
if append:
mode = "a"
if verbose:
print "editing '%s'" % (filename,)
try:
f = open(filename, mode)
except IOError as why:
print >> sys.stderr, "cannot edit '%s': %s" % (filename, why)
return False
else:
f.write(text)
f.close()
return True
def replace(filename, find, replace, verbose=False):
if verbose:
print "replacing '%s' for '%s' in '%s'" % (find, replace, filename)
fin = fileinput.input(filename, inplace=1)
for line in fin:
line = re.sub(find, replace, line)
sys.stdout.write(line)
fin.close()
return True
class CopyError(Exception):
pass
class Copy(object):
def __init__(self, ignore_errors=False, verbose=False):
self.Error = CopyError
self.ignore_errors = ignore_errors
self.verbose = verbose
self.errors = []
def copy(self, src_path, dst_path, src_root="/", dst_root="/", nolinks=False):
# normalize the source and destination paths
src, dst = normalize(src_root, src_path, dst_root, dst_path)
# check if the source exists
if not os.path.exists(src):
err_msg = "cannot stat '%s': No such file or directory" % (src,)
if not self.ignore_errors:
raise self.Error, err_msg
else:
print >> sys.stderr, err_msg
self.errors.append(err_msg)
return False # EXIT
if os.path.isfile(src):
# if destination is an existing directory, append the source filename
# to the destination path
if os.path.isdir(dst):
dst = os.path.join(dst, os.path.basename(src))
# check if the destination exists
if os.path.isfile(dst):
# overwrite file
try:
if self.verbose:
print "overwriting '%s'" % (dst,)
os.unlink(dst)
except OSError as why:
err_msg = "cannot overwrite file '%s': %s" % (dst, why)
if not self.ignore_errors:
raise self.Error, err_msg
else:
print >> sys.stderr, err_msg
self.errors.append(err_msg)
return False # EXIT
elif os.path.isdir(dst):
# do not overwrite directory with a file
err_msg = "cannot overwrite directory '%s' with non-directory" \
% (dst,)
if not self.ignore_errors:
raise self.Error, err_msg
else:
print >> sys.stderr, err_msg
self.errors.append(err_msg)
return False # EXIT
if os.path.islink(src):
if nolinks:
self.__copy_file(os.path.realpath(src), dst)
else:
self.__copy_link(src_path, dst_path, src_root, dst_root,
src, dst)
else:
self.__copy_file(src, dst)
elif os.path.isdir(src):
# append the source directory name to the destination path
dirname = os.path.basename(src)
new_dst = os.path.join(dst, dirname)
if os.path.islink(src):
if nolinks:
real_src = os.path.realpath(src)
if not os.path.exists(new_dst):
os.makedirs(new_dst)
for fname in os.listdir(real_src):
fname = os.path.join(real_src, fname)
if os.path.isfile(fname):
self.__copy_file(fname, new_dst)
else:
dst = os.path.join(new_dst, os.path.basename(fname))
shutil.copytree(fname, dst, symlinks=False)
else:
self.__copy_link(src_path, dst_path, src_root, dst_root,
src, new_dst)
else:
# create the destination directory if it does not exist
if not os.path.exists(new_dst):
os.makedirs(new_dst)
if os.path.isfile(new_dst):
err_msg = "cannot overwrite file '%s' with a directory" \
% (new_dst,)
if not self.ignore_errors:
raise self.Error, err_msg
else:
print >> sys.stderr, err_msg
self.errors.append(err_msg)
return False # EXIT
new_dst_path = os.path.join(dst_path, dirname)
fnames = []
try:
fnames = os.listdir(src)
except OSError as why:
err_msg = "cannot list directory '%s': %s'" % (src, why)
if not self.ignore_errors:
raise self.Error, err_msg
else:
print >> sys.stderr, err_msg
self.errors.append(err_msg)
for fname in fnames:
fname = os.path.join(src_path, fname)
self.copy(fname, new_dst_path, src_root, dst_root)
def __copy_file(self, src, dst):
if self.verbose:
print "copying '%s' to '%s'" % (src, dst)
try:
shutil.copy(src, dst)
except (shutil.Error, IOError) as why:
err_msg = "cannot copy '%s' to '%s': %s" % (src, dst, why)
if not self.ignore_errors:
raise self.Error, err_msg
else:
print >> sys.stderr, err_msg
self.errors.append(err_msg)
def __copy_link(self, src_path, dst_path, src_root, dst_root, src, dst):
# read the link target
link_target = os.readlink(src)
# get the target source and destination paths
target_src_path = os.path.join(os.path.dirname(src_path), link_target)
target_dst_path = os.path.join(dst_path, os.path.dirname(link_target))
# create the destination directory if it doesn't exist
target_dst = os.path.join(dst_root, target_dst_path)
if not os.path.exists(target_dst):
os.makedirs(target_dst)
# copy the target along with the link
self.copy(target_src_path, target_dst_path, src_root, dst_root)
# create the symlink named dst, pointing to link_target
os.symlink(link_target, dst)

View File

@ -1,88 +0,0 @@
#
# ldd.py
# library dependencies
#
# Copyright (C) 2009 Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# Red Hat Author(s): Martin Gracik <mgracik@redhat.com>
#
import os
import re
import commands
class LDD(object):
def __init__(self, libroots=["/lib", "/usr/lib"]):
f = open("/usr/bin/ldd", "r")
for line in f.readlines():
line = line.strip()
if line.startswith("RTLDLIST="):
rtldlist, sep, ld_linux = line.partition("=")
break
f.close()
self._lddcmd = "LD_LIBRARY_PATH=%s %s --list" % (":".join(libroots),
ld_linux)
pattern = r"^([a-zA-Z0-9.]*\s=>\s)(?P<lib>[a-zA-Z0-9./-]*)\s\(0x[0-9a-f]*\)$"
self.pattern = re.compile(pattern)
self._deps = set()
self._errors = []
def is_elf(self, filename):
cmd = "file --brief %s" % (filename)
err, out = commands.getstatusoutput(cmd)
if err:
return False
if not out.split()[0] == "ELF":
return False
return True
def getDeps(self, filename):
# skip no elf files
if not self.is_elf(filename):
return
cmd = "%s %s" % (self._lddcmd, filename)
err, out = commands.getstatusoutput(cmd)
if err:
self._errors.append((filename, out))
return
lines = out.splitlines()
for line in lines:
line = line.strip()
m = self.pattern.match(line)
if m:
lib = m.group("lib")
if lib not in self._deps:
self._deps.add(lib)
self.getDeps(lib)
@property
def deps(self):
return self._deps
@property
def errors(self):
return self._errors

View File

@ -1,129 +0,0 @@
#
# yumwrapper.py
# yum wrapper
#
# Copyright (C) 2009 Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# Red Hat Author(s): Martin Gracik <mgracik@redhat.com>
#
import sys
import os
import yum
import yum.callbacks
import yum.rpmtrans
from pylorax.misc import seq, get_console_size
class Callback(yum.rpmtrans.SimpleCliCallBack):
def __init__(self):
yum.rpmtrans.SimpleCliCallBack.__init__(self)
self.height, self.width = get_console_size()
def event(self, package, action, te_current, te_total, ts_current, ts_total):
progress = float(te_current) / float(te_total)
percentage = int(progress * 100)
bar_length = 20
bar = int(percentage / (100 / bar_length))
total_progress_str = "[%s/%s] " % (ts_current, ts_total)
package_progress_str = " [%s%s] %3d%%" % ("#" * bar, "-" * (bar_length - bar),
percentage)
action_str = "%s %s" % (self.action[action], package)
chars_left = self.width - len(total_progress_str) - len(package_progress_str)
if len(action_str) > chars_left:
action_str = action_str[:chars_left-3]
action_str = action_str + "..."
else:
action_str = action_str + " " * (chars_left - len(action_str))
msg = total_progress_str + action_str + package_progress_str
sys.stdout.write(msg)
sys.stdout.write("\r")
if percentage == 100:
sys.stdout.write("\n")
sys.stdout.flush()
class Yum(object):
def __init__(self, yumconf="/etc/yum/yum.conf", installroot="/",
errfile="/dev/null"):
self.yb = yum.YumBase()
self.yumconf = os.path.abspath(yumconf)
self.installroot = os.path.abspath(installroot)
self.errfile = errfile
self.yb.preconf.fn = self.yumconf
self.yb.preconf.root = self.installroot
self.yb._getConfig()
self.yb._getRpmDB()
self.yb._getRepos()
self.yb._getSacks()
def find(self, patterns):
pl = self.yb.doPackageLists(patterns=seq(patterns))
return pl.installed, pl.available
def add_package(self, pattern):
try:
self.yb.install(name=pattern)
except yum.Errors.InstallError:
# didn't find an exact package name match
try:
self.yb.install(pattern=pattern)
except yum.Errors.InstallError:
# no package found
return False
return True
def install(self):
self.yb.resolveDeps()
self.yb.buildTransaction()
cb = yum.callbacks.ProcessTransBaseCallback()
#cb = yum.callbacks.ProcessTransNoOutputCallback()
rpmcb = Callback()
# XXX ATTENTION! ugly rpm error output hack
# we redirect the error output from rpm to errfile,
# so it does not show up in our "nice" output
# 2 = err descriptor
standard_err = os.dup(2)
my_err = open(self.errfile, "a")
os.dup2(my_err.fileno(), 2)
# now we process the transactions without errors showing up in the output
self.yb.processTransaction(callback=cb, rpmDisplay=rpmcb)
# and we put the standard error output back, so nobody will notice
os.dup2(standard_err, 2)
my_err.close()
self.yb.closeRpmDB()
self.yb.close()

View File

@ -0,0 +1,9 @@
#%PAM-1.0
auth required pam_env.so
auth sufficient pam_unix.so likeauth nullok
auth required pam_deny.so
account required pam_unix.so
password sufficient pam_unix.sp nullok use_authtok md5 shadow
password required pam_deny.so
session required pam_limits.so
session required pam_unix.so

View File

@ -0,0 +1,9 @@
#%PAM-1.0
auth required pam_env.so
auth sufficient pam_unix.so likeauth nullok
auth required pam_deny.so
account required pam_unix.so
password sufficient pam_unix.sp nullok use_authtok md5 shadow
password required pam_deny.so
session required pam_limits.so
session required pam_unix.so

View File

@ -0,0 +1 @@
s390