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 executable script
|
||||
#
|
||||
# Copyright (C) 2009 Red Hat, Inc.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
# Red Hat Author(s): David Cantrell <dcantrell@redhat.com>
|
||||
# Martin Gracik <mgracik@redhat.com>
|
||||
#
|
||||
|
||||
import sys
|
||||
import os
|
||||
from optparse import OptionParser, OptionGroup
|
||||
|
||||
import pylorax
|
||||
import pylorax.launcher
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
version = "%s 0.1" % (os.path.basename(sys.argv[0]),)
|
||||
usage = "%prog -p PRODUCT -v VERSION -r RELEASE -o OUTPUTDIR REPOSITORY"
|
||||
|
||||
parser = OptionParser(usage=usage)
|
||||
|
||||
def check_dir(option, opt_str, value, parser):
|
||||
if os.path.isdir(value):
|
||||
setattr(parser.values, option.dest, value)
|
||||
else:
|
||||
parser.error("'%s' is not a directory" % (value,))
|
||||
|
||||
|
||||
# required
|
||||
# XXX "options" should not be required
|
||||
group = OptionGroup(parser, "Required")
|
||||
group.add_option("-p", "--product", help="Product name",
|
||||
metavar="STRING")
|
||||
group.add_option("-v", "--version", help="Version identifier",
|
||||
metavar="STRING")
|
||||
group.add_option("-r", "--release", help="Release information or comment",
|
||||
metavar="STRING")
|
||||
group.add_option("-o", "--output", help="Destination directory",
|
||||
metavar="PATHSPEC")
|
||||
parser.add_option_group(group)
|
||||
|
||||
# optional
|
||||
# XXX are all of these used?
|
||||
group = OptionGroup(parser, "Optional")
|
||||
group.add_option("-d", "--debug", help="Enable debugging messages",
|
||||
action="store_true", default=False)
|
||||
group.add_option("-t", "--variant", help="Variant name",
|
||||
metavar="STRING")
|
||||
group.add_option("-b", "--bugurl", help="Bug reporting URL for the product",
|
||||
metavar="URL",
|
||||
default="your distribution provided bug reporting tool")
|
||||
group.add_option("-u", "--updates", help="Directory containing updates",
|
||||
metavar="PATHSPEC")
|
||||
group.add_option("-m", "--mirrorlist",
|
||||
help="Mirror list repository (may be listed multiple times)",
|
||||
metavar="REPOSITORY", action="append", default=[])
|
||||
group.add_option("-c", "--confdir", help="Path to config files (default: /etc/lorax)",
|
||||
metavar="PATHSPEC", action="callback", callback=check_dir,
|
||||
type="string", default="/etc/lorax")
|
||||
group.add_option("-C", "--cleanup", help="Clean up on exit",
|
||||
action="store_true", default=False)
|
||||
group.add_option("-V", help="Print version and exit",
|
||||
action="store_true", default=False, dest="printver")
|
||||
parser.add_option_group(group)
|
||||
|
||||
# additional information
|
||||
group = OptionGroup(parser, "Additional information",
|
||||
"A 'REPOSITORY' specification is a valid yum repository path.\n"
|
||||
"See the man page lorax(8) for more information.")
|
||||
parser.add_option_group(group)
|
||||
|
||||
(opts, args) = parser.parse_args()
|
||||
|
||||
if opts.printver:
|
||||
print(version)
|
||||
sys.exit(0)
|
||||
|
||||
if not opts.product or not opts.version or not opts.release or not opts.output:
|
||||
parser.error("Missing required argument")
|
||||
|
||||
if not args:
|
||||
parser.error("Missing repository")
|
||||
|
||||
config = pylorax.Config()
|
||||
config.set(confdir=opts.confdir,
|
||||
debug=opts.debug,
|
||||
cleanup=opts.cleanup)
|
||||
|
||||
# required
|
||||
config.set(product=opts.product,
|
||||
version=opts.version,
|
||||
release=opts.release,
|
||||
outdir=opts.output,
|
||||
repos=args)
|
||||
|
||||
# optional
|
||||
config.set(variant=opts.variant,
|
||||
bugurl=opts.bugurl,
|
||||
updates=opts.updates,
|
||||
mirrorlist=opts.mirrorlist)
|
||||
|
||||
lorax = pylorax.Lorax(config=config)
|
||||
lorax.run()
|
||||
pylorax.launcher.main(sys.argv)
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
# lorax configuration
|
||||
#
|
||||
# Copyright (C) 2009 Red Hat, Inc.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
# Red Hat Author(s): Martin Gracik <mgracik@redhat.com>
|
||||
#
|
||||
|
||||
from misc import seq
|
||||
import os
|
||||
|
||||
import singleton
|
||||
import output
|
||||
|
||||
|
||||
class Container(object):
|
||||
class LoraxConfig(singleton.Singleton):
|
||||
|
||||
def __init__(self, attrs=None):
|
||||
self.__dict__["__internal"] = {}
|
||||
self.__dict__["__internal"]["attrs"] = set()
|
||||
def __init__(self):
|
||||
self.confdir = "/etc/lorax"
|
||||
self.datadir = "/usr/share/lorax"
|
||||
|
||||
if attrs:
|
||||
self.addAttr(attrs)
|
||||
|
||||
def __str__(self):
|
||||
return str(self.__makeDict())
|
||||
|
||||
def __iter__(self):
|
||||
return iter(self.__makeDict())
|
||||
|
||||
def __getitem__(self, attr):
|
||||
self.__checkInternal(attr)
|
||||
|
||||
if attr not in self.__dict__:
|
||||
raise AttributeError, "object has no attribute '%s'" % attr
|
||||
|
||||
return self.__dict__[attr]
|
||||
self.colors = True
|
||||
self.encoding = "utf-8"
|
||||
self.debug = False
|
||||
self.cleanup = False
|
||||
|
||||
def __setattr__(self, attr, value):
|
||||
raise AttributeError, "you can't do that, use addAttr() and/or set() instead"
|
||||
output.Terminal.get().debug("[%s = %s]" % (attr, value))
|
||||
singleton.Singleton.__setattr__(self, attr, value)
|
||||
|
||||
def __delattr__(self, attr):
|
||||
raise AttributeError, "you can't do that, use delAttr() instead"
|
||||
|
||||
def addAttr(self, attrs):
|
||||
for attr in filter(lambda attr: attr not in self.__dict__, seq(attrs)):
|
||||
self.__checkInternal(attr)
|
||||
class LoraxPaths(singleton.Singleton):
|
||||
|
||||
self.__dict__[attr] = None
|
||||
self.__dict__["__internal"]["attrs"].add(attr)
|
||||
def __init__(self):
|
||||
self.datadir = LoraxConfig.get().datadir
|
||||
self.installtree = LoraxConfig.get().installtree
|
||||
|
||||
def delAttr(self, attrs):
|
||||
for attr in filter(lambda attr: attr in self.__dict__, seq(attrs)):
|
||||
self.__checkInternal(attr)
|
||||
@property
|
||||
def ANACONDA_PACKAGE(self): return "anaconda"
|
||||
|
||||
del self.__dict__[attr]
|
||||
self.__dict__["__internal"]["attrs"].discard(attr)
|
||||
@property
|
||||
def INITRD_DATADIR(self):
|
||||
return os.path.join(self.datadir, "initrd")
|
||||
|
||||
def set(self, **kwargs):
|
||||
unknown = set()
|
||||
for attr, value in kwargs.items():
|
||||
self.__checkInternal(attr)
|
||||
@property
|
||||
def INSTALLTREE_DATADIR(self):
|
||||
return os.path.join(self.datadir, "installtree")
|
||||
|
||||
if attr in self.__dict__:
|
||||
self.__dict__[attr] = value
|
||||
else:
|
||||
unknown.add(attr)
|
||||
@property
|
||||
def OUTPUTDIR_DATADIR(self):
|
||||
return os.path.join(self.datadir, "outputdir")
|
||||
|
||||
return unknown
|
||||
@property
|
||||
def BOOTDIR(self):
|
||||
return os.path.join(self.installtree, "boot")
|
||||
|
||||
def __makeDict(self):
|
||||
d = {}
|
||||
for attr in self.__dict__["__internal"]["attrs"]:
|
||||
d[attr] = self.__dict__[attr]
|
||||
@property
|
||||
def BOOTDIR_IA64(self):
|
||||
return os.path.join(self.BOOTDIR, "efi", "EFI", "redhat")
|
||||
|
||||
return d
|
||||
@property
|
||||
def ANACONDA_RUNTIME(self):
|
||||
return os.path.join(self.installtree, "usr", "lib", "anaconda-runtime")
|
||||
|
||||
def __checkInternal(self, attr):
|
||||
if attr.startswith("__"):
|
||||
raise AttributeError, "do not mess with internal objects"
|
||||
@property
|
||||
def ANACONDA_BOOT(self):
|
||||
return os.path.join(self.ANACONDA_RUNTIME, "boot")
|
||||
|
||||
@property
|
||||
def SYSLINUXDIR(self):
|
||||
return os.path.join(self.installtree, "usr", "lib", "syslinux")
|
||||
|
||||
@property
|
||||
def ISOLINUXBIN(self):
|
||||
return os.path.join(self.SYSLINUXDIR, "isolinux.bin")
|
||||
|
||||
@property
|
||||
def SYSLINUXCFG(self):
|
||||
return os.path.join(self.ANACONDA_BOOT, "syslinux.cfg")
|
||||
|
||||
@property
|
||||
def GRUBCONF(self):
|
||||
return os.path.join(self.ANACONDA_BOOT, "grub.conf")
|
||||
|
||||
@property
|
||||
def GRUBEFI(self):
|
||||
return os.path.join(self.BOOTDIR, "efi", "EFI", "redhat", "grub.efi")
|
||||
|
||||
@property
|
||||
def VESASPLASH(self):
|
||||
return os.path.join(self.ANACONDA_RUNTIME, "syslinux-vesa-splash.jpg")
|
||||
|
||||
@property
|
||||
def VESAMENU(self):
|
||||
return os.path.join(self.SYSLINUXDIR, "vesamenu.c32")
|
||||
|
||||
@property
|
||||
def SPLASHTOOLS(self):
|
||||
return os.path.join(self.ANACONDA_RUNTIME, "splashtools.sh")
|
||||
|
||||
@property
|
||||
def SPLASHLSS(self):
|
||||
return os.path.join(self.ANACONDA_BOOT, "splash.lss")
|
||||
|
||||
@property
|
||||
def SYSLINUXSPLASH(self):
|
||||
return os.path.join(self.ANACONDA_BOOT, "syslinux-splash.jpg")
|
||||
|
||||
@property
|
||||
def SPLASHXPM(self):
|
||||
return os.path.join(self.BOOTDIR, "grub", "splash.xpm.gz")
|
||||
|
||||
@property
|
||||
def MODULES_DIR(self):
|
||||
return os.path.join(self.installtree, "lib", "modules",
|
||||
LoraxConfig.get().kernelver)
|
||||
|
||||
@property
|
||||
def MODULES_DEP(self):
|
||||
return os.path.join(self.MODULES_DIR, "modules.dep")
|
||||
|
||||
@property
|
||||
def MODINFO(self): return "/sbin/modinfo"
|
||||
|
||||
@property
|
||||
def MODLIST(self):
|
||||
return os.path.join(self.ANACONDA_RUNTIME, "modlist")
|
||||
|
||||
@property
|
||||
def DEPMOD(self): return "/sbin/depmod"
|
||||
|
||||
@property
|
||||
def GETKEYMAPS(self):
|
||||
return os.path.join(self.ANACONDA_RUNTIME, "getkeymaps")
|
||||
|
||||
@property
|
||||
def LOCALEDEF(self): return "/usr/bin/localedef"
|
||||
|
||||
@property
|
||||
def GENINITRDSZ(self):
|
||||
return os.path.join(self.ANACONDA_RUNTIME, "geninitrdsz")
|
||||
|
||||
@property
|
||||
def REDHAT_EXEC(self):
|
||||
return os.path.join(self.ANACONDA_BOOT, "redhat.exec")
|
||||
|
||||
@property
|
||||
def GENERIC_PRM(self):
|
||||
return os.path.join(self.ANACONDA_BOOT, "generic.prm")
|
||||
|
||||
@property
|
||||
def MKS390CD(self):
|
||||
return os.path.join(self.ANACONDA_RUNTIME, "mk-s390-cdboot")
|
||||
|
||||
@property
|
||||
def MKSQUASHFS(self): return "/sbin/mksquashfs"
|
||||
|
||||
@property
|
||||
def MKCRAMFS(self): return "/sbin/mkfs.cramfs"
|
||||
|
||||
@property
|
||||
def MKISOFS(self): return "/usr/bin/mkisofs"
|
||||
|
||||
@property
|
||||
def MKDOSFS(self): return "/sbin/mkdosfs"
|
||||
|
||||
@property
|
||||
def ISOHYBRID(self): return "/usr/bin/isohybrid"
|
||||
|
||||
@property
|
||||
def SYSTEM_MAP(self):
|
||||
return os.path.join(self.BOOTDIR,
|
||||
"System.map-%s" % LoraxConfig.get().kernelver)
|
||||
|
||||
@property
|
||||
def KEYMAPS_OVERRIDE(self):
|
||||
return os.path.join(self.ANACONDA_RUNTIME,
|
||||
"keymaps-override-%s" % LoraxConfig.get().arch)
|
||||
|
||||
@property
|
||||
def LANGTABLE(self):
|
||||
return os.path.join(self.installtree, "usr", "lib", "anaconda",
|
||||
"lang-table")
|
||||
|
||||
@property
|
||||
def LOCALEPATH(self):
|
||||
return os.path.join(self.installtree, "usr", "share", "locale")
|
||||
|
||||
@property
|
||||
def MANCONFIG(self):
|
||||
return os.path.join(self.installtree, "etc", "man.config")
|
||||
|
||||
@property
|
||||
def FEDORAKMODCONF(self):
|
||||
return os.path.join(self.installtree, "etc", "yum", "pluginconf.d",
|
||||
"fedorakmod.conf")
|
||||
|
213
src/pylorax/efi.py
Normal file
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 control
|
||||
#
|
||||
# Copyright (C) 2009 Red Hat, Inc.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
# Red Hat Author(s): Martin Gracik <mgracik@redhat.com>
|
||||
#
|
||||
|
||||
import sys
|
||||
import singleton
|
||||
|
||||
|
||||
# color codes
|
||||
### color codes
|
||||
C_DEFAULT = "\x1b[39m"
|
||||
C_RESET = "\x1b[0m"
|
||||
|
||||
C_BOLD = "\x1b[1m"
|
||||
C_UNDERLINE = "\x1b[4m"
|
||||
|
||||
C_BLACK = "\x1b[0;30m"
|
||||
C_WHITE = "\x1b[1;37m"
|
||||
C_RED = "\x1b[0;31m"
|
||||
@ -39,53 +19,39 @@ C_LIGHTRED = "\x1b[1;31m"
|
||||
C_LIGHTGREEN = "\x1b[1;32m"
|
||||
C_LIGHTBLUE = "\x1b[1;34m"
|
||||
|
||||
# font types
|
||||
C_BOLD = "\x1b[1m"
|
||||
C_UNDERLINE = "\x1b[4m"
|
||||
|
||||
### font types
|
||||
BOLD = 0b01
|
||||
UNDERLINE = 0b10
|
||||
|
||||
### output levels
|
||||
CRITICAL = 50
|
||||
ERROR = 40
|
||||
WARNING = 30
|
||||
INFO = 20
|
||||
DEBUG = 10
|
||||
NOTSET = 0
|
||||
|
||||
class OutputError(Exception):
|
||||
pass
|
||||
|
||||
class Output(object):
|
||||
class Terminal(singleton.Singleton):
|
||||
|
||||
def __init__(self, output=sys.stdout, colors=True, encoding="utf-8",
|
||||
verbose=False):
|
||||
def __init__(self):
|
||||
self.__colors = True
|
||||
self.__encoding = "utf-8"
|
||||
self.__output_level = INFO
|
||||
self.__indent_level = 0
|
||||
|
||||
self.output = output
|
||||
if not hasattr(self.output, "write"):
|
||||
raise OutputError, "output does not support write()"
|
||||
def basic_config(self, colors=None, encoding=None, level=None):
|
||||
if colors is not None:
|
||||
self.__colors = colors
|
||||
|
||||
self.is_flushable = hasattr(self.output, "flush")
|
||||
if encoding is not None:
|
||||
self.__encoding = encoding
|
||||
|
||||
self.colors = colors
|
||||
self.encoding = encoding
|
||||
self.verbose = verbose
|
||||
|
||||
self.__indent_level = 0
|
||||
|
||||
def write(self, s, color=C_RESET, type=None):
|
||||
s = self.format(s, color=color, type=type)
|
||||
self.output.write(s)
|
||||
|
||||
if self.is_flushable:
|
||||
self.output.flush()
|
||||
|
||||
def format(self, s, color=C_RESET, type=None):
|
||||
s = s.encode(self.encoding)
|
||||
|
||||
if self.colors:
|
||||
if type is not None and (type & BOLD):
|
||||
s = "%s%s" % (C_BOLD, s)
|
||||
if type is not None and (type & UNDERLINE):
|
||||
s = "%s%s" % (C_UNDERLINE, s)
|
||||
s = "%s%s%s" % (color, s, C_RESET)
|
||||
|
||||
return s
|
||||
|
||||
def writeline(self, s, color=C_RESET, type=None):
|
||||
s = "%s%s\n" % (" " * self.__indent_level, s)
|
||||
self.write(s, color=color, type=type)
|
||||
if level is not None:
|
||||
self.__output_level = level
|
||||
|
||||
def indent(self):
|
||||
self.__indent_level += 1
|
||||
@ -94,31 +60,43 @@ class Output(object):
|
||||
if self.__indent_level > 0:
|
||||
self.__indent_level -= 1
|
||||
|
||||
def newline(self):
|
||||
self.output.write("\n")
|
||||
def write(self, s, color=C_RESET, type=None, file=sys.stdout):
|
||||
s = self.format(s, color=color, type=type)
|
||||
file.write(s)
|
||||
file.flush()
|
||||
|
||||
def banner(self, s):
|
||||
self.writeline(s, color=C_GREEN, type=BOLD)
|
||||
def format(self, s, color=C_RESET, type=None):
|
||||
s = s.encode(self.__encoding)
|
||||
|
||||
def header(self, s):
|
||||
self.writeline(s, type=BOLD)
|
||||
if self.__colors:
|
||||
if type is not None and (type & BOLD):
|
||||
s = "%s%s" % (C_BOLD, s)
|
||||
if type is not None and (type & UNDERLINE):
|
||||
s = "%s%s" % (C_UNDERLINE, s)
|
||||
s = "%s%s%s" % (color, s, C_RESET)
|
||||
|
||||
def info(self, s):
|
||||
self.writeline(s)
|
||||
return s
|
||||
|
||||
def error(self, s):
|
||||
self.writeline(s, color=C_RED, type=BOLD)
|
||||
def writeline(self, s, color=C_RESET, type=None, file=sys.stdout):
|
||||
s = "%s%s" % (" " * self.__indent_level, s)
|
||||
self.write(s + "\n", color=color, type=type, file=file)
|
||||
|
||||
def warning(self, s):
|
||||
self.writeline(s, color=C_RED)
|
||||
def critical(self, s, file=sys.stdout):
|
||||
if self.__output_level <= CRITICAL:
|
||||
self.writeline("** critical: %s" % s, file=file)
|
||||
|
||||
def debug(self, s):
|
||||
if self.verbose:
|
||||
self.writeline(s)
|
||||
def error(self, s, file=sys.stdout):
|
||||
if self.__output_level <= ERROR:
|
||||
self.writeline("** error: %s" % s, file=file)
|
||||
|
||||
def warning(self, s, file=sys.stdout):
|
||||
if self.__output_level <= WARNING:
|
||||
self.writeline("** warning: %s" % s, file=file)
|
||||
|
||||
def initialize(verbose=False):
|
||||
stdout = Output(output=sys.stdout, verbose=verbose)
|
||||
stderr = Output(output=sys.stderr, verbose=verbose)
|
||||
def info(self, s, file=sys.stdout):
|
||||
if self.__output_level <= INFO:
|
||||
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