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:
parent
2c6d450c58
commit
b672d9936e
@ -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
|
|
@ -1 +0,0 @@
|
|||||||
initrd.i386
|
|
@ -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
|
|
@ -1 +0,0 @@
|
|||||||
initrd.i386
|
|
@ -1 +0,0 @@
|
|||||||
initrd.i386
|
|
@ -1 +0,0 @@
|
|||||||
initrd.ppc
|
|
@ -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
|
|
@ -1 +0,0 @@
|
|||||||
initrd.s390
|
|
@ -1 +0,0 @@
|
|||||||
initrd.i386
|
|
@ -1 +0,0 @@
|
|||||||
initrd.i386
|
|
8
etc/lorax/config.i386
Normal file
8
etc/lorax/config.i386
Normal 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
1
etc/lorax/config.i586
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
config.i386
|
23
etc/lorax/config.noarch
Normal file
23
etc/lorax/config.noarch
Normal 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
11
etc/lorax/config.s390
Normal 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
1
etc/lorax/config.s390x
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
config.s390
|
1
etc/lorax/config.x86_64
Symbolic link
1
etc/lorax/config.x86_64
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
config.i386
|
242
etc/lorax/templates/initrd/includes/initrd
Normal file
242
etc/lorax/templates/initrd/includes/initrd
Normal 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
|
11
etc/lorax/templates/initrd/initrd.i386
Normal file
11
etc/lorax/templates/initrd/initrd.i386
Normal 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
|
51
etc/lorax/templates/initrd/initrd.s390
Normal file
51
etc/lorax/templates/initrd/initrd.s390
Normal 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
|
103
etc/lorax/templates/scrubs/scrubs.i386
Normal file
103
etc/lorax/templates/scrubs/scrubs.i386
Normal 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
|
@ -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
|
|
@ -1,2 +0,0 @@
|
|||||||
tgafb
|
|
||||||
crc32
|
|
@ -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
|
|
@ -1 +0,0 @@
|
|||||||
modules.s390
|
|
@ -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
|
|
@ -1 +0,0 @@
|
|||||||
aboot
|
|
@ -1,7 +0,0 @@
|
|||||||
pcmciautils
|
|
||||||
grub
|
|
||||||
dmidecode
|
|
||||||
efibootmgr
|
|
||||||
gpart
|
|
||||||
syslinux
|
|
||||||
memtest86+
|
|
@ -1 +0,0 @@
|
|||||||
packages.i386
|
|
@ -1,3 +0,0 @@
|
|||||||
dmidecode
|
|
||||||
efibootmgr
|
|
||||||
elilo
|
|
@ -1,6 +0,0 @@
|
|||||||
pcmciautils
|
|
||||||
pdisk
|
|
||||||
yaboot
|
|
||||||
hfsutils
|
|
||||||
fbset
|
|
||||||
ppc64-utils
|
|
@ -1 +0,0 @@
|
|||||||
packages.ppc
|
|
@ -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
|
|
@ -1 +0,0 @@
|
|||||||
packages.s390
|
|
@ -1,2 +0,0 @@
|
|||||||
tilo
|
|
||||||
silo
|
|
@ -1 +0,0 @@
|
|||||||
packages.i386
|
|
@ -1 +0,0 @@
|
|||||||
scrubs.i386
|
|
@ -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
|
|
@ -1 +0,0 @@
|
|||||||
scrubs.i386
|
|
@ -1 +0,0 @@
|
|||||||
scrubs.i386
|
|
@ -1 +0,0 @@
|
|||||||
scrubs.ppc
|
|
@ -1 +0,0 @@
|
|||||||
scrubs.s390
|
|
@ -1 +0,0 @@
|
|||||||
scrubs.i386
|
|
@ -1 +0,0 @@
|
|||||||
scrubs.i386
|
|
112
src/bin/lorax
112
src/bin/lorax
@ -2,119 +2,11 @@
|
|||||||
|
|
||||||
#
|
#
|
||||||
# lorax
|
# 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 sys
|
||||||
import os
|
import pylorax.launcher
|
||||||
from optparse import OptionParser, OptionGroup
|
|
||||||
|
|
||||||
import pylorax
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
version = "%s 0.1" % (os.path.basename(sys.argv[0]),)
|
pylorax.launcher.main(sys.argv)
|
||||||
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()
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -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)
|
|
@ -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
|
|
@ -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']
|
|
@ -1,90 +1,191 @@
|
|||||||
#
|
#
|
||||||
# config.py
|
# 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):
|
def __init__(self):
|
||||||
self.__dict__["__internal"] = {}
|
self.confdir = "/etc/lorax"
|
||||||
self.__dict__["__internal"]["attrs"] = set()
|
self.datadir = "/usr/share/lorax"
|
||||||
|
|
||||||
if attrs:
|
self.colors = True
|
||||||
self.addAttr(attrs)
|
self.encoding = "utf-8"
|
||||||
|
self.debug = False
|
||||||
def __str__(self):
|
self.cleanup = False
|
||||||
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]
|
|
||||||
|
|
||||||
def __setattr__(self, attr, value):
|
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):
|
class LoraxPaths(singleton.Singleton):
|
||||||
for attr in filter(lambda attr: attr not in self.__dict__, seq(attrs)):
|
|
||||||
self.__checkInternal(attr)
|
|
||||||
|
|
||||||
self.__dict__[attr] = None
|
def __init__(self):
|
||||||
self.__dict__["__internal"]["attrs"].add(attr)
|
self.datadir = LoraxConfig.get().datadir
|
||||||
|
self.installtree = LoraxConfig.get().installtree
|
||||||
|
|
||||||
def delAttr(self, attrs):
|
@property
|
||||||
for attr in filter(lambda attr: attr in self.__dict__, seq(attrs)):
|
def ANACONDA_PACKAGE(self): return "anaconda"
|
||||||
self.__checkInternal(attr)
|
|
||||||
|
|
||||||
del self.__dict__[attr]
|
@property
|
||||||
self.__dict__["__internal"]["attrs"].discard(attr)
|
def INITRD_DATADIR(self):
|
||||||
|
return os.path.join(self.datadir, "initrd")
|
||||||
|
|
||||||
def set(self, **kwargs):
|
@property
|
||||||
unknown = set()
|
def INSTALLTREE_DATADIR(self):
|
||||||
for attr, value in kwargs.items():
|
return os.path.join(self.datadir, "installtree")
|
||||||
self.__checkInternal(attr)
|
|
||||||
|
|
||||||
if attr in self.__dict__:
|
@property
|
||||||
self.__dict__[attr] = value
|
def OUTPUTDIR_DATADIR(self):
|
||||||
else:
|
return os.path.join(self.datadir, "outputdir")
|
||||||
unknown.add(attr)
|
|
||||||
|
|
||||||
return unknown
|
@property
|
||||||
|
def BOOTDIR(self):
|
||||||
|
return os.path.join(self.installtree, "boot")
|
||||||
|
|
||||||
def __makeDict(self):
|
@property
|
||||||
d = {}
|
def BOOTDIR_IA64(self):
|
||||||
for attr in self.__dict__["__internal"]["attrs"]:
|
return os.path.join(self.BOOTDIR, "efi", "EFI", "redhat")
|
||||||
d[attr] = self.__dict__[attr]
|
|
||||||
|
|
||||||
return d
|
@property
|
||||||
|
def ANACONDA_RUNTIME(self):
|
||||||
|
return os.path.join(self.installtree, "usr", "lib", "anaconda-runtime")
|
||||||
|
|
||||||
def __checkInternal(self, attr):
|
@property
|
||||||
if attr.startswith("__"):
|
def ANACONDA_BOOT(self):
|
||||||
raise AttributeError, "do not mess with internal objects"
|
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
213
src/pylorax/efi.py
Normal 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
|
@ -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
479
src/pylorax/install.py
Normal 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
|
@ -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
205
src/pylorax/launcher.py
Normal 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
|
58
src/pylorax/lcs/__init__.py
Normal file
58
src/pylorax/lcs/__init__.py
Normal 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
|
31
src/pylorax/lcs/actions/__init__.py
Normal file
31
src/pylorax/lcs/actions/__init__.py
Normal 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
|
37
src/pylorax/lcs/actions/base.py
Normal file
37
src/pylorax/lcs/actions/base.py
Normal 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")
|
282
src/pylorax/lcs/actions/file.py
Normal file
282
src/pylorax/lcs/actions/file.py
Normal 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"]
|
39
src/pylorax/lcs/actions/ssh.py
Normal file
39
src/pylorax/lcs/actions/ssh.py
Normal 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"]
|
@ -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
|
|
@ -1,35 +1,15 @@
|
|||||||
#
|
#
|
||||||
# output.py
|
# 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 sys
|
||||||
|
import singleton
|
||||||
|
|
||||||
|
|
||||||
# color codes
|
### color codes
|
||||||
C_DEFAULT = "\x1b[39m"
|
C_DEFAULT = "\x1b[39m"
|
||||||
C_RESET = "\x1b[0m"
|
C_RESET = "\x1b[0m"
|
||||||
|
|
||||||
C_BOLD = "\x1b[1m"
|
|
||||||
C_UNDERLINE = "\x1b[4m"
|
|
||||||
|
|
||||||
C_BLACK = "\x1b[0;30m"
|
C_BLACK = "\x1b[0;30m"
|
||||||
C_WHITE = "\x1b[1;37m"
|
C_WHITE = "\x1b[1;37m"
|
||||||
C_RED = "\x1b[0;31m"
|
C_RED = "\x1b[0;31m"
|
||||||
@ -39,53 +19,39 @@ C_LIGHTRED = "\x1b[1;31m"
|
|||||||
C_LIGHTGREEN = "\x1b[1;32m"
|
C_LIGHTGREEN = "\x1b[1;32m"
|
||||||
C_LIGHTBLUE = "\x1b[1;34m"
|
C_LIGHTBLUE = "\x1b[1;34m"
|
||||||
|
|
||||||
# font types
|
C_BOLD = "\x1b[1m"
|
||||||
|
C_UNDERLINE = "\x1b[4m"
|
||||||
|
|
||||||
|
### font types
|
||||||
BOLD = 0b01
|
BOLD = 0b01
|
||||||
UNDERLINE = 0b10
|
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",
|
def __init__(self):
|
||||||
verbose=False):
|
self.__colors = True
|
||||||
|
self.__encoding = "utf-8"
|
||||||
|
self.__output_level = INFO
|
||||||
|
self.__indent_level = 0
|
||||||
|
|
||||||
self.output = output
|
def basic_config(self, colors=None, encoding=None, level=None):
|
||||||
if not hasattr(self.output, "write"):
|
if colors is not None:
|
||||||
raise OutputError, "output does not support write()"
|
self.__colors = colors
|
||||||
|
|
||||||
self.is_flushable = hasattr(self.output, "flush")
|
|
||||||
|
|
||||||
self.colors = colors
|
if encoding is not None:
|
||||||
self.encoding = encoding
|
self.__encoding = encoding
|
||||||
self.verbose = verbose
|
|
||||||
|
|
||||||
self.__indent_level = 0
|
if level is not None:
|
||||||
|
self.__output_level = level
|
||||||
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)
|
|
||||||
|
|
||||||
def indent(self):
|
def indent(self):
|
||||||
self.__indent_level += 1
|
self.__indent_level += 1
|
||||||
@ -94,31 +60,43 @@ class Output(object):
|
|||||||
if self.__indent_level > 0:
|
if self.__indent_level > 0:
|
||||||
self.__indent_level -= 1
|
self.__indent_level -= 1
|
||||||
|
|
||||||
def newline(self):
|
def write(self, s, color=C_RESET, type=None, file=sys.stdout):
|
||||||
self.output.write("\n")
|
s = self.format(s, color=color, type=type)
|
||||||
|
file.write(s)
|
||||||
|
file.flush()
|
||||||
|
|
||||||
def banner(self, s):
|
def format(self, s, color=C_RESET, type=None):
|
||||||
self.writeline(s, color=C_GREEN, type=BOLD)
|
s = s.encode(self.__encoding)
|
||||||
|
|
||||||
def header(self, s):
|
if self.__colors:
|
||||||
self.writeline(s, type=BOLD)
|
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):
|
return s
|
||||||
self.writeline(s)
|
|
||||||
|
|
||||||
def error(self, s):
|
def writeline(self, s, color=C_RESET, type=None, file=sys.stdout):
|
||||||
self.writeline(s, color=C_RED, type=BOLD)
|
s = "%s%s" % (" " * self.__indent_level, s)
|
||||||
|
self.write(s + "\n", color=color, type=type, file=file)
|
||||||
|
|
||||||
def warning(self, s):
|
def critical(self, s, file=sys.stdout):
|
||||||
self.writeline(s, color=C_RED)
|
if self.__output_level <= CRITICAL:
|
||||||
|
self.writeline("** critical: %s" % s, file=file)
|
||||||
|
|
||||||
def debug(self, s):
|
def error(self, s, file=sys.stdout):
|
||||||
if self.verbose:
|
if self.__output_level <= ERROR:
|
||||||
self.writeline(s)
|
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):
|
def info(self, s, file=sys.stdout):
|
||||||
stdout = Output(output=sys.stdout, verbose=verbose)
|
if self.__output_level <= INFO:
|
||||||
stderr = Output(output=sys.stderr, verbose=verbose)
|
self.writeline(s, file=file)
|
||||||
|
|
||||||
return stdout, stderr
|
def debug(self, s, file=sys.stdout):
|
||||||
|
if self.__output_level <= DEBUG:
|
||||||
|
self.writeline(s, file=file)
|
||||||
|
435
src/pylorax/ramdisk.py
Normal file
435
src/pylorax/ramdisk.py
Normal 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
14
src/pylorax/singleton.py
Normal 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
|
@ -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
405
src/pylorax/utils.py
Normal 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
|
@ -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)
|
|
@ -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
|
|
@ -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()
|
|
9
usr/share/lorax/initrd/s390/etc/pam.d/remote
Normal file
9
usr/share/lorax/initrd/s390/etc/pam.d/remote
Normal 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
|
9
usr/share/lorax/initrd/s390/etc/pam.d/sshd
Normal file
9
usr/share/lorax/initrd/s390/etc/pam.d/sshd
Normal 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
|
1
usr/share/lorax/initrd/s390x
Symbolic link
1
usr/share/lorax/initrd/s390x
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
s390
|
Loading…
Reference in New Issue
Block a user