Compare commits
33 Commits
master
...
f24-branch
Author | SHA1 | Date | |
---|---|---|---|
|
41b7808000 | ||
|
d917213427 | ||
|
f157308246 | ||
|
daa8689c0b | ||
|
60c314b6fb | ||
|
88c7fc72fe | ||
|
9bf1a846da | ||
|
4a2d28553e | ||
|
0eb89a457c | ||
|
9cb5951b76 | ||
|
2a025e8360 | ||
|
6989afb5fd | ||
|
30c5b000d4 | ||
|
72e0a4b699 | ||
|
e3457c1ec1 | ||
|
96a10acec6 | ||
|
00185ad7c5 | ||
|
436b15cd5b | ||
|
ce895bbeb1 | ||
|
0400b8c393 | ||
|
d81b50cf41 | ||
|
1c12f47696 | ||
|
06d226caa8 | ||
|
15fe625743 | ||
|
7b33b80dac | ||
|
2ff1998597 | ||
|
f21f126fb8 | ||
|
39e9609209 | ||
|
6c237a9cb3 | ||
|
9655e4d5a5 | ||
|
d9ae3bbf99 | ||
|
9c81a598dd | ||
|
625cb20b3d |
@ -1,14 +1,14 @@
|
||||
# Minimal Disk Image
|
||||
|
||||
# Use network installation
|
||||
url --url="http://dl.fedoraproject.org/pub/fedora/linux/development/rawhide/x86_64/os/"
|
||||
url --url="http://dl.fedoraproject.org/pub/fedora/linux/development/rawhide/Everything/x86_64/os/"
|
||||
|
||||
# Root password
|
||||
rootpw --plaintext replace-this-pw
|
||||
# Network information
|
||||
network --bootproto=dhcp --activate
|
||||
# System authorization information
|
||||
auth --useshadow --enablemd5
|
||||
auth --useshadow --passalgo=sha512
|
||||
# System keyboard
|
||||
keyboard --xlayouts=us --vckeymap=us
|
||||
# System language
|
||||
|
@ -1,124 +0,0 @@
|
||||
# Build a basic Fedora AMI using livemedia-creator
|
||||
lang en_US.UTF-8
|
||||
keyboard us
|
||||
timezone --utc America/New_York
|
||||
auth --useshadow --enablemd5
|
||||
selinux --enforcing
|
||||
firewall --service=ssh
|
||||
bootloader --location=none
|
||||
services --enabled=network,sshd,rsyslog
|
||||
shutdown
|
||||
|
||||
# By default the root password is emptied
|
||||
rootpw --plaintext removethispw
|
||||
|
||||
#
|
||||
# Define how large you want your rootfs to be
|
||||
# NOTE: S3-backed AMIs have a limit of 10G
|
||||
#
|
||||
clearpart --all --initlabel
|
||||
part / --size 10000 --fstype ext4
|
||||
part swap --size=512
|
||||
|
||||
#
|
||||
# Repositories
|
||||
url --url="http://dl.fedoraproject.org/pub/fedora/linux/development/rawhide/x86_64/os/"
|
||||
|
||||
#
|
||||
#
|
||||
# Add all the packages after the base packages
|
||||
#
|
||||
%packages --nobase
|
||||
@core
|
||||
system-config-securitylevel-tui
|
||||
audit
|
||||
pciutils
|
||||
bash
|
||||
coreutils
|
||||
kernel
|
||||
# Make sure that DNF doesn't pull in debug kernel to satisfy kmod() requires
|
||||
kernel-modules
|
||||
kernel-modules-extra
|
||||
|
||||
e2fsprogs
|
||||
passwd
|
||||
policycoreutils
|
||||
chkconfig
|
||||
rootfiles
|
||||
yum
|
||||
vim-minimal
|
||||
acpid
|
||||
openssh-clients
|
||||
openssh-server
|
||||
curl
|
||||
sudo
|
||||
|
||||
#Allow for dhcp access
|
||||
dhclient
|
||||
iputils
|
||||
|
||||
-firstboot
|
||||
-biosdevname
|
||||
|
||||
# package to setup cloudy bits for us
|
||||
cloud-init
|
||||
|
||||
grub
|
||||
-dracut-config-rescue
|
||||
%end
|
||||
|
||||
# more ec2-ify
|
||||
%post --erroronfail
|
||||
|
||||
# create ec2-user
|
||||
/usr/sbin/useradd ec2-user
|
||||
/bin/echo -e 'ec2-user\tALL=(ALL)\tNOPASSWD: ALL' >> /etc/sudoers
|
||||
|
||||
# fstab mounting is different for x86_64 and i386
|
||||
cat <<EOL > /etc/fstab
|
||||
/dev/xvda1 / ext4 defaults 1 1
|
||||
/dev/xvda2 /mnt ext3 defaults 0 0
|
||||
/dev/xvda3 swap swap defaults 0 0
|
||||
EOL
|
||||
|
||||
if [ ! -d /lib64 ] ; then
|
||||
# workaround xen performance issue (bz 651861)
|
||||
echo "hwcap 1 nosegneg" > /etc/ld.so.conf.d/libc6-xen.conf
|
||||
fi
|
||||
|
||||
# Install grub.conf
|
||||
# idle=nomwait is to allow xen images to boot and not try use cpu features that are not supported
|
||||
INITRD=`ls /boot/initramfs-* | head -n1`
|
||||
KERNEL=`ls /boot/vmlinuz-* | head -n1`
|
||||
mkdir /boot/grub
|
||||
pushd /boot/grub
|
||||
cat <<EOL > grub.conf
|
||||
default 0
|
||||
timeout 0
|
||||
|
||||
title Fedora Linux
|
||||
root (hd0)
|
||||
kernel $KERNEL root=/dev/xvda1 idle=halt
|
||||
initrd $INITRD
|
||||
EOL
|
||||
# symlink grub.conf to menu.lst for use by EC2 pv-grub
|
||||
ln -s grub.conf menu.lst
|
||||
popd
|
||||
|
||||
# the firewall rules get saved as .old without this we end up not being able
|
||||
# ssh in as iptables blocks access
|
||||
rename -v .old "" /etc/sysconfig/*old
|
||||
|
||||
# setup systemd to boot to the right runlevel
|
||||
rm /etc/systemd/system/default.target
|
||||
ln -s /lib/systemd/system/multi-user.target /etc/systemd/system/default.target
|
||||
|
||||
# remove the root password
|
||||
passwd -d root > /dev/null
|
||||
|
||||
%end
|
||||
|
||||
%post
|
||||
# Remove random-seed
|
||||
rm /var/lib/systemd/random-seed
|
||||
%end
|
@ -291,6 +291,10 @@ echo 'File created by kickstart. See systemd-update-done.service(8).' \
|
||||
|
||||
# Remove random-seed
|
||||
rm /var/lib/systemd/random-seed
|
||||
|
||||
# Remove the rescue kernel and image to save space
|
||||
# Installation will recreate these on the target
|
||||
rm -f /boot/*-rescue*
|
||||
%end
|
||||
|
||||
%post --nochroot
|
||||
@ -388,6 +392,7 @@ EOF
|
||||
@printing
|
||||
@printing
|
||||
@workstation-product
|
||||
gnome-terminal
|
||||
aajohan-comfortaa-fonts
|
||||
anaconda
|
||||
fedora-productimg-workstation
|
||||
|
@ -4,12 +4,14 @@ sshpw --username=root --plaintext randOmStrinGhERE
|
||||
# Firewall configuration
|
||||
firewall --enabled
|
||||
# Use network installation
|
||||
url --url="http://dl.fedoraproject.org/pub/fedora/linux/development/rawhide/x86_64/os/"
|
||||
url --url="http://dl.fedoraproject.org/pub/fedora/linux/development/rawhide/Everything/x86_64/os/"
|
||||
# Network information
|
||||
network --bootproto=dhcp --device=link --activate
|
||||
|
||||
# Root password
|
||||
rootpw --plaintext removethispw
|
||||
# System authorization information
|
||||
auth --useshadow --enablemd5
|
||||
auth --useshadow --passalgo=sha512
|
||||
# System keyboard
|
||||
keyboard --xlayouts=us --vckeymap=us
|
||||
# System language
|
||||
|
@ -4,12 +4,14 @@ sshpw --username=root --plaintext randOmStrinGhERE
|
||||
# Firewall configuration
|
||||
firewall --enabled
|
||||
# Use network installation
|
||||
url --url="http://dl.fedoraproject.org/pub/fedora/linux/development/rawhide/x86_64/os/"
|
||||
url --url="http://dl.fedoraproject.org/pub/fedora/linux/development/rawhide/Everything/x86_64/os/"
|
||||
# Network information
|
||||
network --bootproto=dhcp --device=link --activate
|
||||
|
||||
# Root password
|
||||
rootpw --plaintext removethispw
|
||||
# System authorization information
|
||||
auth --useshadow --enablemd5
|
||||
auth --useshadow --passalgo=sha512
|
||||
# System keyboard
|
||||
keyboard --xlayouts=us --vckeymap=us
|
||||
# System language
|
||||
@ -55,6 +57,9 @@ syslinux
|
||||
# dracut needs these included
|
||||
dracut-network
|
||||
tar
|
||||
|
||||
# lorax for image-minimizer
|
||||
lorax
|
||||
%end
|
||||
|
||||
#
|
||||
@ -107,5 +112,6 @@ droprpm sgpio
|
||||
droprpm syslinux
|
||||
droprpm system-config-firewall-base
|
||||
droprpm usermode
|
||||
|
||||
# Not needed after image-minimizer is done
|
||||
droprpm lorax
|
||||
%end
|
||||
|
@ -3,14 +3,14 @@
|
||||
# Firewall configuration
|
||||
firewall --enabled
|
||||
# Use network installation
|
||||
url --url="http://dl.fedoraproject.org/pub/fedora/linux/development/rawhide/x86_64/os/"
|
||||
url --url="http://dl.fedoraproject.org/pub/fedora/linux/development/rawhide/Everything/x86_64/os/"
|
||||
|
||||
# Root password
|
||||
rootpw --plaintext replace-this-pw
|
||||
# Network information
|
||||
network --bootproto=dhcp --activate
|
||||
# System authorization information
|
||||
auth --useshadow --enablemd5
|
||||
auth --useshadow --passalgo=sha512
|
||||
# System keyboard
|
||||
keyboard --xlayouts=us --vckeymap=us
|
||||
# System language
|
||||
|
@ -4,7 +4,9 @@
|
||||
# Firewall configuration
|
||||
firewall --enabled
|
||||
# Use network installation
|
||||
url --url="http://dl.fedoraproject.org/pub/fedora/linux/development/rawhide/x86_64/os/"
|
||||
url --url="http://dl.fedoraproject.org/pub/fedora/linux/development/rawhide/Everything/x86_64/os/"
|
||||
# Network information
|
||||
network --bootproto=dhcp --activate
|
||||
|
||||
# Root account is locked, access via sudo from vagrant user
|
||||
rootpw --lock
|
||||
@ -14,7 +16,7 @@ user --name=vagrant
|
||||
sshkey --username=vagrant "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzIw+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoPkcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NOTd0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcWyLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQ== vagrant insecure public key"
|
||||
|
||||
# System authorization information
|
||||
auth --useshadow --enablemd5
|
||||
auth --useshadow --passalgo=sha512
|
||||
# System keyboard
|
||||
keyboard --xlayouts=us --vckeymap=us
|
||||
# System language
|
||||
|
50
lorax.spec
50
lorax.spec
@ -3,7 +3,7 @@
|
||||
%define debug_package %{nil}
|
||||
|
||||
Name: lorax
|
||||
Version: 24.14
|
||||
Version: 24.22
|
||||
Release: 1%{?dist}
|
||||
Summary: Tool for creating the anaconda install images
|
||||
|
||||
@ -46,7 +46,7 @@ Requires: kpartx
|
||||
Requires: libselinux-python3
|
||||
Requires: python3-mako
|
||||
Requires: python3-kickstart
|
||||
Requires: python3-dnf >= 1.1.0
|
||||
Requires: python3-dnf >= 1.1.7
|
||||
|
||||
|
||||
%if 0%{?fedora}
|
||||
@ -90,6 +90,7 @@ Summary: livemedia-creator libvirt dependencies
|
||||
Requires: lorax = %{version}-%{release}
|
||||
Requires: libvirt-python3
|
||||
Requires: virt-install
|
||||
Requires: edk2-ovmf
|
||||
|
||||
%description lmc-virt
|
||||
Additional dependencies required by livemedia-creator when using it with virt-install.
|
||||
@ -147,6 +148,51 @@ make DESTDIR=$RPM_BUILD_ROOT mandir=%{_mandir} install
|
||||
|
||||
|
||||
%changelog
|
||||
* Wed Feb 22 2017 Brian C. Lane <bcl@redhat.com> 24.22-1
|
||||
- templates: Enusre basic.target.wants dir exists for rngd (walters@verbum.org)
|
||||
- Create /dev/random and /dev/urandom before running rpm -qa (#1420523) (bcl@redhat.com)
|
||||
|
||||
* Mon Sep 26 2016 Brian C. Lane <bcl@redhat.com> 24.21-1
|
||||
- Add ppc64le kernel path (mkumatag@in.ibm.com)
|
||||
|
||||
* Fri Jul 08 2016 Brian C. Lane <bcl@redhat.com> 24.20-1
|
||||
- livemedia-creator: Fix off by 1024 error (#1353140) (bcl@redhat.com)
|
||||
- livemedia-creator: Create runtime using kickstart partition size (#1353140) (bcl@redhat.com)
|
||||
|
||||
* Thu Jun 02 2016 Brian C. Lane <bcl@redhat.com> 24.19-1
|
||||
- livemedia-creator: Always copy novirt logs before cleanup (bcl@redhat.com)
|
||||
- Update lmc UEFI support to use the edk2-ovmf package (bcl@redhat.com)
|
||||
|
||||
* Mon Apr 18 2016 Brian C. Lane <bcl@redhat.com> 24.18-1
|
||||
- livemedia-creator: Make sure make-iso kickstart includes dracut-live
|
||||
(bcl@redhat.com)
|
||||
- livemedia-creator: Simplify cleanup for no-virt (bcl@redhat.com)
|
||||
- Copying same file shouldn't crash (#1269213) (bcl@redhat.com)
|
||||
- livemedia-creator: Use correct suffix on default image names (#1318958)
|
||||
(bcl@redhat.com)
|
||||
|
||||
* Tue Mar 29 2016 Brian C. Lane <bcl@redhat.com> 24.17-1
|
||||
- livemedia-creator: Pass -Xbcj to mksquashfs (bcl@redhat.com)
|
||||
- templates: On 32 bit systems limit the amount of memory xz uses
|
||||
(bcl@redhat.com)
|
||||
- ltmpl: Add compressor selection and argument passing to installimg
|
||||
(bcl@redhat.com)
|
||||
|
||||
* Mon Mar 28 2016 Brian C. Lane <bcl@redhat.com> 24.16-1
|
||||
- livemedia-creator: Update example kickstarts (bcl@redhat.com)
|
||||
- image-minimizer: Fix argument parsing (bcl@redhat.com)
|
||||
- livemedia-creator: Check selinux state and exit (bcl@redhat.com)
|
||||
- livemedia-creator: Catch dnf download error (bcl@redhat.com)
|
||||
- templates: Fix runtime_img check (bcl@redhat.com)
|
||||
- Create UDF iso when stage2 is >= 4GiB (#1312158) (bcl@redhat.com)
|
||||
|
||||
* Fri Mar 11 2016 Brian C. Lane <bcl@redhat.com> 24.15-1
|
||||
- pylorax: proc.returncode can be None (bcl@redhat.com)
|
||||
- Change location of basearch to dnf.rpm.basearch (#1312087) (bcl@redhat.com)
|
||||
- livemedia-creator: Change fsck.ext4 discard failures to errors (#1315541)
|
||||
(bcl@redhat.com)
|
||||
- Install the libblockdev-lvm-dbus plugin (#1264816) (vpodzime@redhat.com)
|
||||
|
||||
* Tue Mar 01 2016 Brian C. Lane <bcl@redhat.com> 24.14-1
|
||||
- Add glibc-all-langpacks (#1312607) (dshea@redhat.com)
|
||||
|
||||
|
@ -1 +1 @@
|
||||
24.14-1 ./
|
||||
24.22-1 ./
|
||||
|
@ -1,4 +1,4 @@
|
||||
<%page args="kernels, runtime_img, basearch, outroot, product, isolabel"/>
|
||||
<%page args="kernels, runtime_img, basearch, inroot, outroot, product, isolabel"/>
|
||||
<%
|
||||
configdir="tmp/config_files/aarch64"
|
||||
PXEBOOTDIR="images/pxeboot"
|
||||
@ -7,6 +7,16 @@ STAGE2IMG="images/install.img"
|
||||
LORAXDIR="usr/share/lorax/"
|
||||
%>
|
||||
|
||||
## Test ${runtime_img} to see if udf is needed
|
||||
<%
|
||||
import os
|
||||
from pylorax.sysutils import joinpaths
|
||||
if os.stat(joinpaths(inroot, runtime_img)).st_size >= 4*1024**3:
|
||||
udfargs = "-allow-limited-size"
|
||||
else:
|
||||
udfargs = ""
|
||||
%>
|
||||
|
||||
mkdir images
|
||||
install ${runtime_img} ${STAGE2IMG}
|
||||
treeinfo stage2 mainimage ${STAGE2IMG}
|
||||
@ -54,7 +64,8 @@ mkdir ${KERNELDIR}
|
||||
%if exists("boot/efi/EFI/*/gcdaa64.efi"):
|
||||
## make boot.iso
|
||||
runcmd mkisofs -o ${outroot}/images/boot.iso \
|
||||
${efiargs} -R -J -V '${isolabel}' -T -graft-points \
|
||||
${efiargs} -R -J -V '${isolabel}' -T ${udfargs} \
|
||||
-graft-points \
|
||||
${KERNELDIR}=${outroot}/${KERNELDIR} \
|
||||
${STAGE2IMG}=${outroot}/${STAGE2IMG} \
|
||||
${efigraft} ${imggraft}
|
||||
|
@ -43,7 +43,7 @@ treeinfo ${basearch} platforms ${platforms}
|
||||
<% images=["product", "updates"] %>
|
||||
%for img in images:
|
||||
%if exists("%s/%s/" % (LORAXDIR, img)):
|
||||
installimg ${LORAXDIR}/${img}/ images/${img}.img
|
||||
installimg --xz -9 --memlimit-compress=3700MiB ${LORAXDIR}/${img}/ images/${img}.img
|
||||
%endif
|
||||
%endfor
|
||||
|
||||
|
@ -36,7 +36,7 @@ mkdir ${KERNELDIR}
|
||||
<% images=["product", "updates"] %>
|
||||
%for img in images:
|
||||
%if exists("%s/%s/" % (LORAXDIR, img)):
|
||||
installimg ${LORAXDIR}/${img}/ images/${img}.img
|
||||
installimg --xz -9 --memlimit-compress=3700MiB ${LORAXDIR}/${img}/ images/${img}.img
|
||||
%endif
|
||||
%endfor
|
||||
|
||||
|
@ -0,0 +1,5 @@
|
||||
* minimal lpar ins file
|
||||
images/kernel.img 0x00000000
|
||||
images/initrd.img @INITRD_LOAD_ADDRESS@
|
||||
images/genericdvd.prm 0x00010480
|
||||
images/initrd.addrsize 0x00010408
|
@ -0,0 +1 @@
|
||||
ro ramdisk_size=40000 cio_ignore=all,!condev
|
@ -0,0 +1 @@
|
||||
ro ramdisk_size=40000 cio_ignore=all,!condev rd.cmdline=ask
|
@ -0,0 +1,9 @@
|
||||
/* */
|
||||
'CL RDR'
|
||||
'PURGE RDR ALL'
|
||||
'SPOOL PUNCH * RDR'
|
||||
'PUNCH KERNEL IMG A (NOH'
|
||||
'PUNCH GENERIC PRM A (NOH'
|
||||
'PUNCH INITRD IMG A (NOH'
|
||||
'CH RDR ALL KEEP NOHOLD'
|
||||
'I 00C'
|
@ -20,6 +20,16 @@ prepboot = ""
|
||||
isolabel = ''.join(ch if ch.isalnum() else '_' for ch in isolabel)
|
||||
%>
|
||||
|
||||
## Test ${runtime_img} to see if udf is needed
|
||||
<%
|
||||
import os
|
||||
from pylorax.sysutils import joinpaths
|
||||
if os.stat(joinpaths(inroot, runtime_img)).st_size >= 4*1024**3:
|
||||
udfargs = "-allow-limited-size"
|
||||
else:
|
||||
udfargs = ""
|
||||
%>
|
||||
|
||||
mkdir ${LIVEDIR}
|
||||
install ${runtime_img} ${LIVEDIR}/squashfs.img
|
||||
treeinfo stage2 mainimage ${LIVEDIR}/squashfs.img
|
||||
@ -95,7 +105,8 @@ runcmd mkisofs -o ${outroot}/images/boot.iso -chrp-boot -U \
|
||||
-volset "${product.version}" -volset-size 1 -volset-seqno 1 \
|
||||
-hfs-volid ${product.version} -hfs-bless ${outroot}/${MACDIR} \
|
||||
-map ${inroot}/${configdir}/mapping \
|
||||
-no-desktop -allow-multidot -graft-points \
|
||||
-no-desktop -allow-multidot ${udfargs} \
|
||||
-graft-points \
|
||||
${BOOTDIR}=${outroot}/${BOOTDIR} \
|
||||
${GRUBDIR}=${outroot}/${GRUBDIR} \
|
||||
${NETBOOTDIR}=${outroot}/${NETBOOTDIR} \
|
||||
|
@ -1,4 +1,4 @@
|
||||
<%page args="kernels, runtime_img, basearch, outroot, product, isolabel"/>
|
||||
<%page args="kernels, runtime_img, basearch, inroot, outroot, product, isolabel"/>
|
||||
<%
|
||||
configdir="tmp/config_files/x86"
|
||||
SYSLINUXDIR="usr/share/syslinux"
|
||||
@ -15,6 +15,16 @@ def valid_label(ch):
|
||||
isolabel = ''.join(ch if valid_label(ch) else '-' for ch in isolabel)
|
||||
%>
|
||||
|
||||
## Test ${runtime_img} to see if udf is needed
|
||||
<%
|
||||
import os
|
||||
from pylorax.sysutils import joinpaths
|
||||
if os.stat(joinpaths(inroot, runtime_img)).st_size >= 4*1024**3:
|
||||
udfargs = "-allow-limited-size"
|
||||
else:
|
||||
udfargs = ""
|
||||
%>
|
||||
|
||||
mkdir ${LIVEDIR}
|
||||
install ${runtime_img} ${LIVEDIR}/squashfs.img
|
||||
treeinfo stage2 mainimage ${LIVEDIR}/squashfs.img
|
||||
@ -75,10 +85,14 @@ hardlink ${KERNELDIR}/initrd.img ${BOOTDIR}
|
||||
%endif
|
||||
|
||||
# Create optional product.img and updates.img
|
||||
<% imggraft=""; images=["product", "updates"] %>
|
||||
<% imggraft=""; images=["product", "updates"]; compressargs=None; %>
|
||||
%if basearch == 'i386':
|
||||
# Limit the amount of memory xz uses on i386
|
||||
<% compressargs="--xz -9 --memlimit-compress=3700MiB" %>
|
||||
%endif
|
||||
%for img in images:
|
||||
%if exists("%s/%s/" % (LORAXDIR, img)):
|
||||
installimg ${LORAXDIR}/${img}/ images/${img}.img
|
||||
installimg ${compressargs} ${LORAXDIR}/${img}/ images/${img}.img
|
||||
<% imggraft += " images/{0}.img={1}/images/{0}.img".format(img, outroot) %>
|
||||
%endif
|
||||
%endfor
|
||||
@ -87,7 +101,8 @@ hardlink ${KERNELDIR}/initrd.img ${BOOTDIR}
|
||||
runcmd mkisofs -o ${outroot}/images/boot.iso \
|
||||
-b ${BOOTDIR}/isolinux.bin -c ${BOOTDIR}/boot.cat \
|
||||
-boot-load-size 4 -boot-info-table -no-emul-boot \
|
||||
${efiargs} -R -J -V '${isolabel}' -T -graft-points \
|
||||
${efiargs} -R -J -V '${isolabel}' -T ${udfargs} \
|
||||
-graft-points \
|
||||
${BOOTDIR}=${outroot}/${BOOTDIR} \
|
||||
${KERNELDIR}=${outroot}/${KERNELDIR} \
|
||||
${LIVEDIR}=${outroot}/${LIVEDIR} \
|
||||
|
@ -23,6 +23,16 @@ isolabel = ''.join(ch if ch.isalnum() else '_' for ch in isolabel)
|
||||
rootarg = ""
|
||||
%>
|
||||
|
||||
## Test ${runtime_img} to see if udf is needed
|
||||
<%
|
||||
import os
|
||||
from pylorax.sysutils import joinpaths
|
||||
if os.stat(joinpaths(inroot, runtime_img)).st_size >= 4*1024**3:
|
||||
udfargs = "-allow-limited-size"
|
||||
else:
|
||||
udfargs = ""
|
||||
%>
|
||||
|
||||
mkdir images
|
||||
install ${runtime_img} ${STAGE2IMG}
|
||||
treeinfo stage2 mainimage ${STAGE2IMG}
|
||||
@ -105,7 +115,7 @@ runcmd mkisofs -o ${outroot}/images/boot.iso -chrp-boot -U \
|
||||
-volset "${product.version}" -volset-size 1 -volset-seqno 1 \
|
||||
-hfs-volid ${product.version} -hfs-bless ${outroot}/${MACDIR} \
|
||||
-map ${inroot}/${configdir}/mapping \
|
||||
-no-desktop -allow-multidot -graft-points \
|
||||
-no-desktop -allow-multidot ${udfargs} -graft-points \
|
||||
${BOOTDIR}=${outroot}/${BOOTDIR} \
|
||||
${GRUBDIR}=${outroot}/${GRUBDIR} \
|
||||
${NETBOOTDIR}=${outroot}/${NETBOOTDIR} \
|
||||
|
@ -16,6 +16,16 @@ isolabel = ''.join(ch if ch.isalnum() else '_' for ch in isolabel)
|
||||
rootarg = ""
|
||||
%>
|
||||
|
||||
## Test ${runtime_img} to see if udf is needed
|
||||
<%
|
||||
import os
|
||||
from pylorax.sysutils import joinpaths
|
||||
if os.stat(joinpaths(inroot, runtime_img)).st_size >= 4*1024**3:
|
||||
udfargs = "-allow-limited-size"
|
||||
else:
|
||||
udfargs = ""
|
||||
%>
|
||||
|
||||
mkdir images
|
||||
install ${runtime_img} ${STAGE2IMG}
|
||||
treeinfo stage2 mainimage ${STAGE2IMG}
|
||||
@ -82,7 +92,7 @@ runcmd mkisofs -v -U -J -R -T \
|
||||
-volset "${product.version}" -volset-size 1 -volset-seqno 1 \
|
||||
-hfs-volid ${product.version} \
|
||||
-chrp-boot -map ${inroot}/${configdir}/mapping \
|
||||
-no-desktop -allow-multidot -graft-points \
|
||||
-no-desktop -allow-multidot ${udfargs} -graft-points \
|
||||
${BOOTDIR}=${outroot}/${BOOTDIR} \
|
||||
${GRUBDIR}=${outroot}/${GRUBDIR} \
|
||||
${STAGE2IMG}=${outroot}/${STAGE2IMG} ${imggraft}
|
||||
|
@ -87,6 +87,9 @@ installpkg system-storage-manager
|
||||
installpkg device-mapper-persistent-data
|
||||
installpkg xfsdump
|
||||
|
||||
## extra libblockdev plugins
|
||||
installpkg libblockdev-lvm-dbus
|
||||
|
||||
## needed for LUKS escrow
|
||||
installpkg volume_key
|
||||
installpkg nss-tools
|
||||
|
@ -30,6 +30,7 @@ mkdir etc/systemd/system/local-fs.target.wants/
|
||||
symlink /lib/systemd/system/tmp.mount etc/systemd/system/local-fs.target.wants/tmp.mount
|
||||
|
||||
## Start rngd
|
||||
mkdir etc/systemd/system/basic.target.wants/
|
||||
symlink /lib/systemd/system/rngd.service etc/systemd/system/basic.target.wants/rngd.service
|
||||
|
||||
## Disable unwanted systemd services
|
||||
@ -126,6 +127,9 @@ remove etc/lvm/lvm.conf
|
||||
append etc/lvm/lvm.conf "global {\n\tuse_lvmetad = 1\n}\n"
|
||||
|
||||
## Record the package versions used to create the image
|
||||
runcmd chroot ${root} /bin/rpm -qa --pipe "tee /root/lorax-packages.log"
|
||||
## rpm initializes nss, which requires /dev/urandom to be present, hence the mknod
|
||||
runcmd chroot ${root} /usr/bin/mknod -m 666 /dev/random c 1 8
|
||||
runcmd chroot ${root} /usr/bin/mknod -m 666 /dev/urandom c 1 9
|
||||
runcmd chroot ${root} /usr/bin/rpm -qa --pipe "tee /root/lorax-packages.log"
|
||||
|
||||
## TODO: we could run prelink here if we wanted?
|
||||
|
@ -1,4 +1,4 @@
|
||||
<%page args="kernels, runtime_img, runtime_base, basearch, outroot, product, isolabel"/>
|
||||
<%page args="kernels, runtime_img, runtime_base, basearch, inroot, outroot, product, isolabel"/>
|
||||
<%
|
||||
configdir="tmp/config_files/x86"
|
||||
SYSLINUXDIR="usr/share/syslinux"
|
||||
@ -15,6 +15,16 @@ def valid_label(ch):
|
||||
isolabel = ''.join(ch if valid_label(ch) else '-' for ch in isolabel)
|
||||
%>
|
||||
|
||||
## Test ${runtime_img} to see if udf is needed
|
||||
<%
|
||||
import os
|
||||
from pylorax.sysutils import joinpaths
|
||||
if os.stat(joinpaths(inroot, runtime_img)).st_size >= 4*1024**3:
|
||||
udfargs = "-allow-limited-size"
|
||||
else:
|
||||
udfargs = ""
|
||||
%>
|
||||
|
||||
mkdir images
|
||||
install ${runtime_img} ${STAGE2IMG}
|
||||
treeinfo stage2 mainimage images/${runtime_base}
|
||||
@ -77,10 +87,14 @@ hardlink ${KERNELDIR}/initrd.img ${BOOTDIR}
|
||||
%endif
|
||||
|
||||
# Create optional product.img and updates.img
|
||||
<% imggraft=""; images=["product", "updates"] %>
|
||||
<% imggraft=""; images=["product", "updates"]; compressargs=None; %>
|
||||
%if basearch == 'i386':
|
||||
# Limit the amount of memory xz uses on i386
|
||||
<% compressargs="--xz -9 --memlimit-compress=3700MiB" %>
|
||||
%endif
|
||||
%for img in images:
|
||||
%if exists("%s/%s/" % (LORAXDIR, img)):
|
||||
installimg ${LORAXDIR}/${img}/ images/${img}.img
|
||||
installimg ${compressargs} ${LORAXDIR}/${img}/ images/${img}.img
|
||||
<% imggraft += " images/{0}.img={1}/images/{0}.img".format(img, outroot) %>
|
||||
%endif
|
||||
%endfor
|
||||
@ -96,7 +110,8 @@ hardlink ${KERNELDIR}/initrd.img ${BOOTDIR}
|
||||
runcmd mkisofs -o ${outroot}/images/boot.iso \
|
||||
-b ${BOOTDIR}/isolinux.bin -c ${BOOTDIR}/boot.cat \
|
||||
-boot-load-size 4 -boot-info-table -no-emul-boot \
|
||||
${efiargs} -R -J -V '${isolabel}' -T -graft-points \
|
||||
${efiargs} -R -J -V '${isolabel}' -T ${udfargs} \
|
||||
-graft-points \
|
||||
${STAGE2IMG}=${outroot}/${STAGE2IMG} \
|
||||
${BOOTDIR}=${outroot}/${BOOTDIR} \
|
||||
${KERNELDIR}=${outroot}/${KERNELDIR} \
|
||||
|
@ -2,7 +2,7 @@
|
||||
#
|
||||
# image-minimizer: removes files and packages on the filesystem
|
||||
#
|
||||
# Copyright 2007-2015 Red Hat, Inc.
|
||||
# Copyright 2007-2016 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
|
||||
@ -70,7 +70,7 @@ class ImageMinimizer:
|
||||
not_found = True
|
||||
for hdr in mi:
|
||||
not_found = False
|
||||
rpms.add(hdr['name'])
|
||||
rpms.add(hdr['name'].decode("utf8"))
|
||||
if self.verbose and not_found:
|
||||
print("%s package not found" % pattern)
|
||||
|
||||
@ -115,37 +115,31 @@ class ImageMinimizer:
|
||||
if os.path.isdir(tag):
|
||||
self.visited.add(tag)
|
||||
else:
|
||||
if self.dryrun:
|
||||
print('rm ' + tag)
|
||||
else:
|
||||
if self.verbose:
|
||||
print('rm ' + tag)
|
||||
if self.dryrun or self.verbose:
|
||||
print("rm %s" % tag)
|
||||
if not self.dryrun:
|
||||
os.remove(tag)
|
||||
|
||||
#remove all empty directory. Every 8k counts!
|
||||
for d in sorted(self.visited, reverse=True):
|
||||
if len(os.listdir(d)) == 0:
|
||||
if self.dryrun:
|
||||
print('rm -rf ' + d)
|
||||
else:
|
||||
if self.verbose:
|
||||
print('rm -rf ' + d)
|
||||
if self.dryrun or self.verbose:
|
||||
print("rm -rf %s" % d)
|
||||
if not self.dryrun:
|
||||
os.rmdir(d)
|
||||
|
||||
def remove_rpm(self):
|
||||
|
||||
def runCallback(reason, amount, total, key, client_data):
|
||||
if self.verbose and reason == rpm.RPMCALLBACK_UNINST_STOP:
|
||||
print(key, "erased")
|
||||
print("%s erased" % key)
|
||||
|
||||
if len(self.drops_rpm) == 0:
|
||||
return
|
||||
|
||||
for pkg in self.drops_rpm:
|
||||
if self.dryrun:
|
||||
print("erasing ", pkg)
|
||||
else:
|
||||
self.ts.addErase(pkg)
|
||||
if self.verbose:
|
||||
print("erasing: %s " % pkg)
|
||||
self.ts.addErase(pkg)
|
||||
if not self.dryrun:
|
||||
# skip ts.check(), equivalent to --nodeps
|
||||
self.ts.run(runCallback, "erase")
|
||||
@ -166,10 +160,10 @@ def parse_options():
|
||||
help="Root path to prepend to all file patterns and installation root for RPM "
|
||||
"operations. Defaults to INSTALL_ROOT or /mnt/sysimage/")
|
||||
|
||||
parser.add_argument("--dryrun", metavar="BOOL", action="store_true", dest="dryrun",
|
||||
parser.add_argument("--dryrun", action="store_true", dest="dryrun",
|
||||
help="If set, no filesystem changes are made.")
|
||||
|
||||
parser.add_argument("-v", "--verbose", metavar="BOOL", action="store_true", dest="verbose",
|
||||
parser.add_argument("-v", "--verbose", action="store_true", dest="verbose",
|
||||
help="Display every action as it is performed.")
|
||||
|
||||
parser.add_argument("filename", metavar="STRING", help="Filename to process")
|
||||
@ -186,7 +180,7 @@ def main():
|
||||
except SystemExit as e:
|
||||
sys.exit(e.code)
|
||||
except KeyboardInterrupt as e:
|
||||
print("Aborted at user request", file=sys.stderr)
|
||||
print("Aborted at user request")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
@ -62,7 +62,7 @@ class ArchData(DataHolder):
|
||||
def __init__(self, buildarch):
|
||||
super(ArchData, self).__init__()
|
||||
self.buildarch = buildarch
|
||||
self.basearch = dnf.arch.basearch(buildarch)
|
||||
self.basearch = dnf.rpm.basearch(buildarch)
|
||||
self.libdir = "lib64" if self.basearch in self.lib64_arches else "lib"
|
||||
self.bcj = self.bcj_arch.get(self.basearch)
|
||||
|
||||
|
@ -192,7 +192,7 @@ def _run_program(argv, root='/', stdin=None, stdout=None, env_prune=None, log_ou
|
||||
raise
|
||||
|
||||
with program_log_lock:
|
||||
program_log.debug("Return code: %d", proc.returncode)
|
||||
program_log.debug("Return code: %s", proc.returncode)
|
||||
|
||||
if proc.returncode and raise_err:
|
||||
output = (output_string or "") + (err_string or "")
|
||||
|
@ -281,6 +281,7 @@ def estimate_size(rootdir, graft=None, fstype=None, blocksize=4096, overhead=256
|
||||
total += round_to_blocks(getsize(join(top,f)), blocksize)
|
||||
if fstype == "btrfs":
|
||||
total = max(256*1024*1024, total) # btrfs minimum size: 256MB
|
||||
logger.info("Size of %s block %s fs at %s estimated to be %s", blocksize, fstype, rootdir, total)
|
||||
return total
|
||||
|
||||
######## Execution contexts - use with the 'with' statement ##############
|
||||
|
@ -26,6 +26,7 @@ logger = logging.getLogger("pylorax.ltmpl")
|
||||
import os, re, glob, shlex, fnmatch
|
||||
from os.path import basename, isdir
|
||||
from subprocess import CalledProcessError
|
||||
import shutil
|
||||
|
||||
from pylorax.sysutils import joinpaths, cpfile, mvfile, replace, remove
|
||||
from pylorax.dnfhelper import LoraxDownloadCallback, LoraxRpmCallback
|
||||
@ -269,11 +270,14 @@ class LoraxTemplateRunner(object):
|
||||
install /usr/share/myconfig/grub.conf.in /boot/grub.conf
|
||||
'''
|
||||
for src in rglob(self._in(srcglob), fatal=True):
|
||||
cpfile(src, self._out(dest))
|
||||
try:
|
||||
cpfile(src, self._out(dest))
|
||||
except shutil.Error as e:
|
||||
logger.error(e)
|
||||
|
||||
def installimg(self, srcdir, destfile):
|
||||
def installimg(self, *args):
|
||||
'''
|
||||
installimg SRCDIR DESTFILE
|
||||
installimg [--xz|--gzip|--bzip2|--lzma] [-ARG|--ARG=OPTION] SRCDIR DESTFILE
|
||||
Create a compressed cpio archive of the contents of SRCDIR and place
|
||||
it in DESTFILE.
|
||||
|
||||
@ -282,11 +286,35 @@ class LoraxTemplateRunner(object):
|
||||
Examples:
|
||||
installimg ${LORAXDIR}/product/ images/product.img
|
||||
installimg ${LORAXDIR}/updates/ images/updates.img
|
||||
installimg --xz -6 ${LORAXDIR}/updates/ images/updates.img
|
||||
installimg --xz -9 --memlimit-compress=3700MiB ${LORAXDIR}/updates/ images/updates.img
|
||||
|
||||
Optionally use a different compression type and override the default args
|
||||
passed to it. The default is xz -9
|
||||
'''
|
||||
COMPRESSORS = ("--xz", "--gzip", "--bzip2", "--lzma")
|
||||
if len(args) < 2:
|
||||
raise ValueError("Not enough args for installimg.")
|
||||
|
||||
srcdir = args[-2]
|
||||
destfile = args[-1]
|
||||
if not os.path.isdir(self._in(srcdir)) or not os.listdir(self._in(srcdir)):
|
||||
return
|
||||
|
||||
compression = "xz"
|
||||
compressargs = []
|
||||
if args[0] in COMPRESSORS:
|
||||
compression = args[0][2:]
|
||||
|
||||
for arg in args[1:-2]:
|
||||
if arg.startswith('-'):
|
||||
compressargs.append(arg)
|
||||
else:
|
||||
raise ValueError("Argument is missing -")
|
||||
|
||||
logger.info("Creating image file %s from contents of %s", self._out(destfile), self._in(srcdir))
|
||||
mkcpio(self._in(srcdir), self._out(destfile))
|
||||
logger.debug("Using %s %s compression", compression, compressargs or "")
|
||||
mkcpio(self._in(srcdir), self._out(destfile), compression=compression, compressargs=compressargs)
|
||||
|
||||
def mkdir(self, *dirs):
|
||||
'''
|
||||
@ -400,7 +428,10 @@ class LoraxTemplateRunner(object):
|
||||
If DEST doesn't exist, SRC will be copied to a file with
|
||||
that name, if the path leading to it exists.
|
||||
'''
|
||||
cpfile(self._out(src), self._out(dest))
|
||||
try:
|
||||
cpfile(self._out(src), self._out(dest))
|
||||
except shutil.Error as e:
|
||||
logger.error(e)
|
||||
|
||||
def move(self, src, dest):
|
||||
'''
|
||||
|
@ -103,6 +103,7 @@ class LogRequestHandler(socketserver.BaseRequestHandler):
|
||||
"Out of memory:",
|
||||
"Call Trace:",
|
||||
"insufficient disk space:",
|
||||
"Not enough disk space to download the packages",
|
||||
"error populating transaction after",
|
||||
"traceback script(s) have been run",
|
||||
"crashed on signal",
|
||||
|
@ -57,8 +57,8 @@ class IsoMountpoint(object):
|
||||
else:
|
||||
self.mount_dir = self.initrd_path
|
||||
|
||||
self.kernel = self.mount_dir+"/isolinux/vmlinuz"
|
||||
self.initrd = self.mount_dir+"/isolinux/initrd.img"
|
||||
kernel_list = [("/isolinux/vmlinuz", "/isolinux/initrd.img"),
|
||||
("/ppc/ppc64/vmlinuz", "/ppc/ppc64/initrd.img")]
|
||||
|
||||
if os.path.isdir(self.mount_dir+"/repodata"):
|
||||
self.repo = self.mount_dir
|
||||
@ -68,9 +68,15 @@ class IsoMountpoint(object):
|
||||
os.path.exists(self.mount_dir+"/images/install.img")
|
||||
|
||||
try:
|
||||
for f in [self.kernel, self.initrd]:
|
||||
if not os.path.isfile(f):
|
||||
raise Exception("Missing file on iso: {0}".format(f))
|
||||
for kernel, initrd in kernel_list:
|
||||
if (os.path.isfile(self.mount_dir+kernel) and
|
||||
os.path.isfile(self.mount_dir+initrd)):
|
||||
self.kernel = self.mount_dir+kernel
|
||||
self.initrd = self.mount_dir+initrd
|
||||
break
|
||||
else:
|
||||
raise Exception("Missing kernel and initrd file in iso, failed"
|
||||
" to search under: {0}".format(kernel_list))
|
||||
except:
|
||||
self.umount()
|
||||
raise
|
||||
|
@ -34,6 +34,7 @@ import hashlib
|
||||
import glob
|
||||
import json
|
||||
from math import ceil
|
||||
import selinux
|
||||
|
||||
# Use pykickstart to calculate disk image size
|
||||
from pykickstart.parser import KickstartParser
|
||||
@ -70,7 +71,6 @@ DRACUT_DEFAULT = ["--xz", "--add", "livenet dmsquash-live convertfs pollcdrom qe
|
||||
|
||||
ROOT_PATH = "/mnt/sysimage/"
|
||||
RUNTIME = "images/install.img"
|
||||
UEFI_FIRMWARE="loader={0}/OVMF_CODE.fd,loader_ro=yes,loader_type=pflash,nvram_template={0}/OVMF_VARS.fd"
|
||||
|
||||
|
||||
class InstallError(Exception):
|
||||
@ -185,13 +185,21 @@ class VirtualInstall(object):
|
||||
|
||||
if boot_uefi and ovmf_path:
|
||||
args.append("--boot")
|
||||
args.append(UEFI_FIRMWARE.format(ovmf_path))
|
||||
|
||||
# Make a copy of the OVMF_VARS.fd for this run
|
||||
ovmf_vars = tempfile.mktemp(prefix="lmc-OVMF_VARS-", suffix=".fd")
|
||||
shutil.copy2(joinpaths(ovmf_path, "/OVMF_VARS.fd"), ovmf_vars)
|
||||
|
||||
args.append("loader=%s/OVMF_CODE.fd,loader_ro=yes,loader_type=pflash,nvram_template=%s" % (ovmf_path, ovmf_vars))
|
||||
|
||||
log.info("Running virt-install.")
|
||||
try:
|
||||
execWithRedirect("virt-install", args, raise_err=True)
|
||||
except subprocess.CalledProcessError as e:
|
||||
raise InstallError("Problem starting virtual install: %s" % e)
|
||||
finally:
|
||||
if boot_uefi and ovmf_path:
|
||||
os.unlink(ovmf_vars)
|
||||
|
||||
conn = libvirt.openReadOnly(None)
|
||||
dom = conn.lookupByName(self.virt_name)
|
||||
@ -262,6 +270,21 @@ def get_arch(mount_dir):
|
||||
return "i386"
|
||||
return kernels[0].arch
|
||||
|
||||
def squashfs_args(opts):
|
||||
""" Returns the compression type and args to use when making squashfs
|
||||
|
||||
:param opts: ArgumentParser object with compression and compressopts
|
||||
:returns: tuple of compression type and args
|
||||
:rtype: tuple
|
||||
"""
|
||||
compression = opts.compression or "xz"
|
||||
arch = ArchData(opts.arch or os.uname().machine)
|
||||
if compression == "xz" and arch.bcj:
|
||||
compressargs = ["-Xbcj", arch.bcj]
|
||||
else:
|
||||
compressargs = []
|
||||
return (compression, compressargs)
|
||||
|
||||
|
||||
def make_appliance(disk_img, name, template, outfile, networks=None, ram=1024,
|
||||
vcpus=1, arch=None, title="Linux", project="Linux",
|
||||
@ -335,7 +358,7 @@ def make_fsimage(diskimage, fsimage, img_size=None, label="Anaconda"):
|
||||
mkext4img(img_mount.mount_dir, fsimage, size=img_size, label=label)
|
||||
|
||||
|
||||
def make_runtime(opts, mount_dir, work_dir):
|
||||
def make_runtime(opts, mount_dir, work_dir, size=None):
|
||||
"""
|
||||
Make the squashfs image from a directory
|
||||
|
||||
@ -343,6 +366,7 @@ def make_runtime(opts, mount_dir, work_dir):
|
||||
:type opts: argparse options
|
||||
:param str mount_dir: Directory tree to compress
|
||||
:param str work_dir: Output compressed image to work_dir+images/install.img
|
||||
:param int size: Size of disk image, in GiB
|
||||
"""
|
||||
kernel_arch = get_arch(mount_dir)
|
||||
|
||||
@ -359,8 +383,10 @@ def make_runtime(opts, mount_dir, work_dir):
|
||||
os.makedirs(joinpaths(work_dir, "images"))
|
||||
|
||||
rb = RuntimeBuilder(product, arch, fake_dbo)
|
||||
compression, compressargs = squashfs_args(opts)
|
||||
log.info("Creating runtime")
|
||||
rb.create_runtime(joinpaths(work_dir, RUNTIME), size=None)
|
||||
rb.create_runtime(joinpaths(work_dir, RUNTIME), size=size,
|
||||
compression=compression, compressargs=compressargs)
|
||||
|
||||
def rebuild_initrds_for_live(opts, sys_root_dir, results_dir):
|
||||
"""
|
||||
@ -600,6 +626,33 @@ def novirt_log_check(log_check, proc):
|
||||
return False
|
||||
|
||||
|
||||
def anaconda_cleanup(dirinstall_path):
|
||||
"""
|
||||
Cleanup any leftover mounts from anaconda
|
||||
|
||||
:param str dirinstall_path: Path where anaconda mounts things
|
||||
:returns: True if cleanups were successful. False if any of them failed.
|
||||
|
||||
If anaconda crashes it may leave things mounted under this path. It will
|
||||
typically be set to /mnt/sysimage/
|
||||
|
||||
Attempts to cleanup may also fail. Catch these and continue trying the
|
||||
other mountpoints.
|
||||
"""
|
||||
rc = True
|
||||
dirinstall_path = os.path.abspath(dirinstall_path)
|
||||
# unmount filesystems
|
||||
for mounted in reversed(open("/proc/mounts").readlines()):
|
||||
(_device, mountpoint, _rest) = mounted.split(" ", 2)
|
||||
if mountpoint.startswith(dirinstall_path) and os.path.ismount(mountpoint):
|
||||
try:
|
||||
umount(mountpoint)
|
||||
except subprocess.CalledProcessError:
|
||||
log.error("Cleanup of %s failed. See program.log for details", mountpoint)
|
||||
rc = False
|
||||
return rc
|
||||
|
||||
|
||||
def novirt_install(opts, disk_img, disk_size):
|
||||
"""
|
||||
Use Anaconda to install to a disk image
|
||||
@ -609,19 +662,11 @@ def novirt_install(opts, disk_img, disk_size):
|
||||
:param str disk_img: The full path to the disk image to be created
|
||||
:param int disk_size: The size of the disk_img in MiB
|
||||
|
||||
This method makes sure SELinux is permissive during the install, runs anaconda
|
||||
to create the image and then based on the opts passed create a qemu disk image
|
||||
or tarfile.
|
||||
This method runs anaconda to create the image and then based on the opts
|
||||
passed creates a qemu disk image or tarfile.
|
||||
"""
|
||||
import selinux
|
||||
dirinstall_path = ROOT_PATH
|
||||
|
||||
# Set selinux to Permissive if it is Enforcing
|
||||
selinux_enforcing = False
|
||||
if selinux.is_selinux_enabled() and selinux.security_getenforce():
|
||||
selinux_enforcing = True
|
||||
selinux.security_setenforce(0)
|
||||
|
||||
# Clean up /tmp/ from previous runs to prevent stale info from being used
|
||||
for path in ["/tmp/yum.repos.d/", "/tmp/yum.cache/"]:
|
||||
if os.path.isdir(path):
|
||||
@ -690,9 +735,6 @@ def novirt_install(opts, disk_img, disk_size):
|
||||
finally:
|
||||
log_monitor.shutdown()
|
||||
|
||||
# If anaconda failed there may be things needing cleanup
|
||||
execWithRedirect("anaconda-cleanup", [])
|
||||
|
||||
# Move the anaconda logs over to a log directory
|
||||
log_dir = os.path.abspath(os.path.dirname(opts.logfile))
|
||||
log_anaconda = joinpaths(log_dir, "anaconda")
|
||||
@ -702,6 +744,10 @@ def novirt_install(opts, disk_img, disk_size):
|
||||
shutil.copy2(l, log_anaconda)
|
||||
os.unlink(l)
|
||||
|
||||
# Make sure any leftover anaconda mounts have been cleaned up
|
||||
if not anaconda_cleanup(dirinstall_path):
|
||||
raise InstallError("novirt_install cleanup of anaconda mounts failed.")
|
||||
|
||||
if not opts.make_iso and not opts.make_fsimage:
|
||||
dm_name = os.path.splitext(os.path.basename(disk_img))[0]
|
||||
dm_path = "/dev/mapper/"+dm_name
|
||||
@ -709,9 +755,6 @@ def novirt_install(opts, disk_img, disk_size):
|
||||
dm_detach(dm_path)
|
||||
loop_detach(get_loop_name(disk_img))
|
||||
|
||||
if selinux_enforcing:
|
||||
selinux.security_setenforce(1)
|
||||
|
||||
# qemu disk image is used by bare qcow2 images and by Vagrant
|
||||
if opts.image_type:
|
||||
log.info("Converting %s to %s", disk_img, opts.image_type)
|
||||
@ -892,21 +935,28 @@ def virt_install(opts, install_log, disk_img, disk_size):
|
||||
shutil.rmtree(vagrant_dir)
|
||||
|
||||
|
||||
def make_squashfs(disk_img, work_dir, compression="xz", compressargs=None):
|
||||
def make_squashfs(opts, disk_img, work_dir):
|
||||
"""
|
||||
Create a squashfs image of an unpartitioned filesystem disk image
|
||||
|
||||
:param str disk_img: Path to the unpartitioned filesystem disk image
|
||||
:param str work_dir: Output compressed image to work_dir+images/install.img
|
||||
:param str compression: Compression type to use
|
||||
:returns: True if squashfs creation was successful. False if there was an error.
|
||||
:rtype: bool
|
||||
|
||||
Take disk_img and put it into LiveOS/rootfs.img and squashfs this
|
||||
tree into work_dir+images/install.img
|
||||
|
||||
fsck.ext4 is run on the disk image to make sure there are no errors and to zero
|
||||
out any deleted blocks to make it compress better. If this fails for any reason
|
||||
it will return False and log the error.
|
||||
"""
|
||||
# Make sure free blocks are actually zeroed so it will compress
|
||||
rc = execWithRedirect("/usr/sbin/fsck.ext4", ["-y", "-f", "-E", "discard", disk_img])
|
||||
if rc != 0:
|
||||
log.warning("Problem zeroing free blocks of %s", disk_img)
|
||||
log.error("Problem zeroing free blocks of %s", disk_img)
|
||||
return False
|
||||
|
||||
liveos_dir = joinpaths(work_dir, "runtime/LiveOS")
|
||||
os.makedirs(liveos_dir)
|
||||
@ -916,10 +966,32 @@ def make_squashfs(disk_img, work_dir, compression="xz", compressargs=None):
|
||||
if rc != 0:
|
||||
shutil.copy2(disk_img, joinpaths(liveos_dir, "rootfs.img"))
|
||||
|
||||
compression, compressargs = squashfs_args(opts)
|
||||
mksquashfs(joinpaths(work_dir, "runtime"),
|
||||
joinpaths(work_dir, RUNTIME), compression, compressargs)
|
||||
remove(joinpaths(work_dir, "runtime"))
|
||||
return True
|
||||
|
||||
def calculate_disk_size(opts, ks):
|
||||
""" Calculate the disk size from the kickstart
|
||||
|
||||
:param opts: options passed to livemedia-creator
|
||||
:type opts: argparse options
|
||||
:param str ks: Path to the kickstart to use for the installation
|
||||
:returns: Disk size in MiB
|
||||
:rtype: int
|
||||
|
||||
Use virt-install or anaconda to install to a disk image.
|
||||
"""
|
||||
# Disk size for a filesystem image should only be the size of /
|
||||
# to prevent surprises when using the same kickstart for different installations.
|
||||
unique_partitions = dict((p.mountpoint, p) for p in ks.handler.partition.partitions)
|
||||
if opts.no_virt and (opts.make_iso or opts.make_fsimage):
|
||||
disk_size = 2 + sum(p.size for p in unique_partitions.values() if p.mountpoint == "/")
|
||||
else:
|
||||
disk_size = 2 + sum(p.size for p in unique_partitions.values())
|
||||
log.info("Using disk size of %sMiB", disk_size)
|
||||
return disk_size
|
||||
|
||||
def make_image(opts, ks):
|
||||
"""
|
||||
@ -931,23 +1003,14 @@ def make_image(opts, ks):
|
||||
:returns: Path of the image created
|
||||
:rtype: str
|
||||
|
||||
Use virt-install or anaconda to install to a disk image.
|
||||
Use virt-install+boot.iso or anaconda to install to a disk image.
|
||||
"""
|
||||
# Disk size for a filesystem image should only be the size of /
|
||||
# to prevent surprises when using the same kickstart for different installations.
|
||||
unique_partitions = dict((p.mountpoint, p) for p in ks.handler.partition.partitions)
|
||||
if opts.no_virt and (opts.make_iso or opts.make_fsimage):
|
||||
disk_size = 2 + sum(p.size for p in unique_partitions.values() if p.mountpoint == "/")
|
||||
else:
|
||||
disk_size = 2 + sum(p.size for p in unique_partitions.values())
|
||||
log.info("disk_size = %sMiB", disk_size)
|
||||
|
||||
if opts.image_name:
|
||||
disk_img = joinpaths(opts.result_dir, opts.image_name)
|
||||
else:
|
||||
disk_img = tempfile.mktemp(prefix="lmc-disk-", suffix=".img", dir=opts.result_dir)
|
||||
log.info("disk_img = %s", disk_img)
|
||||
|
||||
disk_size = calculate_disk_size(opts, ks)
|
||||
try:
|
||||
if opts.no_virt:
|
||||
novirt_install(opts, disk_img, disk_size)
|
||||
@ -976,8 +1039,12 @@ def make_live_images(opts, work_dir, root_dir, rootfs_image=None, size=None):
|
||||
:param str work_dir: Directory for storing results
|
||||
:param str root_dir: Root directory of live filesystem tree
|
||||
:param str rootfs_image: Path to live rootfs image to be used
|
||||
:returns: Path of directory with created images
|
||||
:returns: Path of directory with created images or None
|
||||
:rtype: str
|
||||
|
||||
fsck.ext4 is run on the rootfs_image to make sure there are no errors and to zero
|
||||
out any deleted blocks to make it compress better. If this fails for any reason
|
||||
it will return None and log the error.
|
||||
"""
|
||||
sys_root = ""
|
||||
if opts.ostree:
|
||||
@ -991,7 +1058,8 @@ def make_live_images(opts, work_dir, root_dir, rootfs_image=None, size=None):
|
||||
# Make sure free blocks are actually zeroed so it will compress
|
||||
rc = execWithRedirect("/usr/sbin/fsck.ext4", ["-y", "-f", "-E", "discard", rootfs_image])
|
||||
if rc != 0:
|
||||
log.warning("Problem zeroing free blocks of %s", rootfs_image)
|
||||
log.error("Problem zeroing free blocks of %s", rootfs_image)
|
||||
return None
|
||||
|
||||
rc = execWithRedirect("/bin/ln", [rootfs_image, joinpaths(liveos_dir, "rootfs.img")])
|
||||
if rc != 0:
|
||||
@ -1003,10 +1071,9 @@ def make_live_images(opts, work_dir, root_dir, rootfs_image=None, size=None):
|
||||
log.info("Packing live rootfs image")
|
||||
add_pxe_args = []
|
||||
live_image_name = "live-rootfs.squashfs.img"
|
||||
mksquashfs(squashfs_root_dir,
|
||||
joinpaths(work_dir, live_image_name),
|
||||
opts.compression,
|
||||
opts.compress_args)
|
||||
compression, compressargs = squashfs_args(opts)
|
||||
mksquashfs(squashfs_root_dir, joinpaths(work_dir, live_image_name),
|
||||
compression, compressargs)
|
||||
|
||||
remove(squashfs_root_dir)
|
||||
|
||||
@ -1021,6 +1088,19 @@ def make_live_images(opts, work_dir, root_dir, rootfs_image=None, size=None):
|
||||
return work_dir
|
||||
|
||||
|
||||
def default_image_name(compression, basename):
|
||||
""" Return a default image name with the correct suffix for the compression type.
|
||||
|
||||
:param str compression: Compression type
|
||||
:param str basename: Base filename
|
||||
:returns: basename with compression suffix
|
||||
|
||||
If the compression is unknown it defaults to xz
|
||||
"""
|
||||
SUFFIXES = {"xz": ".xz", "gzip": ".gz", "bzip2": ".bz2", "lzma": ".lzma"}
|
||||
return basename + SUFFIXES.get(compression, ".xz")
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="Create Live Install Media",
|
||||
fromfile_prefix_chars="@")
|
||||
@ -1141,7 +1221,7 @@ def main():
|
||||
help="Passed to --arch command")
|
||||
virt_group.add_argument("--kernel-args",
|
||||
help="Additional argument to pass to the installation kernel")
|
||||
virt_group.add_argument("--ovmf-path", default="/usr/share/OVMF/",
|
||||
virt_group.add_argument("--ovmf-path", default="/usr/share/edk2/ovmf/",
|
||||
help="Path to OVMF firmware")
|
||||
virt_group.add_argument("--virt-uefi", action="store_true", default=False,
|
||||
help="Use OVMF firmware to boot the VM in UEFI mode")
|
||||
@ -1243,6 +1323,10 @@ def main():
|
||||
and not os.path.exists("/usr/sbin/anaconda"):
|
||||
errors.append("no-virt requires anaconda to be installed.")
|
||||
|
||||
if is_install and opts.no_virt:
|
||||
if selinux.is_selinux_enabled() and selinux.security_getenforce():
|
||||
errors.append("selinux must be disabled or in Permissive mode.")
|
||||
|
||||
if opts.make_appliance and not opts.app_template:
|
||||
opts.app_template = joinpaths(opts.lorax_templates,
|
||||
"appliance/libvirt.tmpl")
|
||||
@ -1308,17 +1392,17 @@ def main():
|
||||
opts.fs_label = "AMI"
|
||||
elif opts.make_tar:
|
||||
if not opts.image_name:
|
||||
opts.image_name = "root.tar.xz"
|
||||
opts.image_name = default_image_name(opts.compression, "root.tar")
|
||||
if opts.compression == "xz" and not opts.compress_args:
|
||||
opts.compress_args = ["-9"]
|
||||
elif opts.make_oci:
|
||||
if not opts.image_name:
|
||||
opts.image_name = "bundle.tar.xz"
|
||||
opts.image_name = default_image_name(opts.compression, "bundle.tar")
|
||||
if opts.compression == "xz" and not opts.compress_args:
|
||||
opts.compress_args = ["-9"]
|
||||
elif opts.make_vagrant:
|
||||
if not opts.image_name:
|
||||
opts.image_name = "vagrant.tar.xz"
|
||||
opts.image_name = default_image_name(opts.compression, "vagrant.tar")
|
||||
if opts.compression == "xz" and not opts.compress_args:
|
||||
opts.compress_args = ["-9"]
|
||||
|
||||
@ -1340,6 +1424,12 @@ def main():
|
||||
ks = KickstartParser(ks_version, errorsAreFatal=False, missingIncludeIsFatal=False)
|
||||
ks.readKickstart(opts.ks[0])
|
||||
|
||||
# live iso usually needs dracut-live so warn the user if it is missing
|
||||
if opts.ks and opts.make_iso:
|
||||
if "dracut-live" not in ks.handler.packages.packageList:
|
||||
log.error("dracut-live package is missing from the kickstart.")
|
||||
sys.exit(1)
|
||||
|
||||
# Make the disk or filesystem image
|
||||
if not opts.disk_image and not opts.fs_image:
|
||||
errors = []
|
||||
@ -1387,15 +1477,10 @@ def main():
|
||||
# Create iso from a filesystem image
|
||||
disk_img = opts.fs_image or disk_img
|
||||
|
||||
compression = opts.compression or "xz"
|
||||
if not opts.compress_args:
|
||||
arch = ArchData(opts.arch or os.uname().machine)
|
||||
if arch.bcj:
|
||||
compressargs = ["-Xbcj", arch.bcj]
|
||||
else:
|
||||
log.info("no BCJ filter for arch %s", arch.basearch)
|
||||
if not make_squashfs(opts, disk_img, work_dir):
|
||||
log.error("squashfs.img creation failed")
|
||||
sys.exit(1)
|
||||
|
||||
make_squashfs(disk_img, work_dir, compression, compressargs)
|
||||
with Mount(disk_img, opts="loop") as mount_dir:
|
||||
result_dir = make_livecd(opts, mount_dir, work_dir)
|
||||
else:
|
||||
@ -1403,7 +1488,7 @@ def main():
|
||||
disk_img = opts.disk_image or disk_img
|
||||
with PartitionMount(disk_img) as img_mount:
|
||||
if img_mount and img_mount.mount_dir:
|
||||
make_runtime(opts, img_mount.mount_dir, work_dir)
|
||||
make_runtime(opts, img_mount.mount_dir, work_dir, calculate_disk_size(opts, ks)/1024.0)
|
||||
result_dir = make_livecd(opts, img_mount.mount_dir, work_dir)
|
||||
|
||||
# --iso-only removes the extra build artifacts, keeping only the boot.iso
|
||||
@ -1461,6 +1546,9 @@ def main():
|
||||
finally:
|
||||
if mounted_sysroot_boot_dir:
|
||||
umount(mounted_sysroot_boot_dir)
|
||||
if result_dir is None:
|
||||
log.error("Creating live image failed.")
|
||||
sys.exit(1)
|
||||
|
||||
if opts.result_dir != opts.tmp and result_dir:
|
||||
copytree(result_dir, opts.result_dir, preserve=False)
|
||||
|
Loading…
Reference in New Issue
Block a user