Compare commits

...

33 Commits

Author SHA1 Message Date
Brian C. Lane
41b7808000 Automatic commit of package [lorax] release [24.22-1].
Created by command:

/usr/bin/tito tag
2017-02-22 10:36:03 -08:00
Colin Walters
d917213427 templates: Enusre basic.target.wants dir exists for rngd
There's something racy here; in my Atomic Workstation CI/CD I'm seeing:

```
01:12:43   symlink /lib/systemd/system/rngd.service etc/systemd/system/basic.target.wants/rngd.service
01:12:43   FileNotFoundError: [Errno 2] No such file or directory: '/lib/systemd/system/rngd.service' -> '/var/tmp/lorax.7cgdtz1_/installtree/etc/systemd/system/basic.target.wants/rngd.service'
```

Rather than debug this right now, let's just make sure it exists,
like we do right above for `tmp.mount`.

(cherry picked from commit 4f1f118cee)
2017-02-22 10:35:37 -08:00
Brian C. Lane
f157308246 Create /dev/random and /dev/urandom before running rpm -qa (#1420523)
In order to run rpm inside the newly created image it now needs to
create a couple device nodes to satisfy nss, which is used by rpm.

(cherry picked from commit d95e69aa34)
2017-02-22 10:24:01 -08:00
Brian C. Lane
daa8689c0b Automatic commit of package [lorax] release [24.21-1]. 2016-09-26 15:30:24 -07:00
Manjunath A Kumatagi
60c314b6fb Add ppc64le kernel path
(cherry picked from commit f4a1302358)
2016-09-19 09:59:35 -07:00
Brian C. Lane
88c7fc72fe Automatic commit of package [lorax] release [24.20-1]. 2016-07-08 16:52:20 -07:00
Brian C. Lane
9bf1a846da livemedia-creator: Fix off by 1024 error (#1353140)
commit 4699c88109 changed how the disk
size is estimated and not all users took into account that the return
value is in MiB.

This would result in qemu based iso installations having a rootfs.img
that was 1024x too large.

(cherry picked from commit 6798f7c5ec)
2016-07-07 17:09:04 -07:00
Brian C. Lane
4a2d28553e livemedia-creator: Create runtime using kickstart partition size (#1353140)
When using no-virt the runtime filesystem size comes from the kickstart.
For virt installs lmc was creating a runtime filesystem that was just
slightly larger than the space used by the files installed by anaconda.
This can run into problems with larger filesystem. It is also
inconsistent behavior between virt and no-virt installations.

With this commit the virt runtime filesystem will also come from the
kickstart.

(cherry picked from commit 4699c88109)
2016-07-07 16:07:23 -07:00
Brian C. Lane
0eb89a457c Automatic commit of package [lorax] release [24.19-1]. 2016-06-02 17:17:14 -07:00
Brian C. Lane
9cb5951b76 livemedia-creator: Always copy novirt logs before cleanup
Before attempting to cleanup any dangling anaconda mounts copy the
anaconda logs to their final location.

Also, catch failures to cleanup the mounts, log it, and continue trying
the other mountpoints. A cleanup failure will result in an InstallError
instead of a CalledProcessError.
2016-06-01 11:20:24 -07:00
Brian C. Lane
2a025e8360 Update lmc UEFI support to use the edk2-ovmf package
Fedora now has a edk2 package so use the OVMF code from there. This also
adds using a copy of OVMF_VARS for each boot instead of reusing the one
provided by the package.
2016-05-23 16:14:33 -07:00
Brian C. Lane
6989afb5fd Automatic commit of package [lorax] release [24.18-1]. 2016-04-18 10:52:34 -07:00
Brian C. Lane
30c5b000d4 livemedia-creator: Make sure make-iso kickstart includes dracut-live
iso creation requires the dracut-live package, otherwise rebuilding the
initrd will crash. Since it takes a long time to discover let's fail
early.

(cherry picked from commit 607d7c1eeb)
2016-04-06 17:11:24 -07:00
Brian C. Lane
72e0a4b699 livemedia-creator: Simplify cleanup for no-virt
If an anaconda no-virt run crashes it can leave things mounted under
/mnt/sysimage. Previously anaconda-cleanup was used to handle this, but
it will also try to cleanup host mountpoints which isn't desired.

(cherry picked from commit bae111d5a3)
2016-04-06 17:05:22 -07:00
Brian C. Lane
e3457c1ec1 Copying same file shouldn't crash (#1269213)
When using the template install command copying the same file to itself
shouldn't crash. Just log the error and continue.

Also copy the s390 configuration files for use with livemedia-creator

Resolves: rhbz#1269213
(cherry picked from commit 701ab02619)
2016-04-06 17:00:42 -07:00
Brian C. Lane
96a10acec6 livemedia-creator: Use correct suffix on default image names (#1318958)
When an image name hasn't been passed, and the compression type is
something other than xz, the default image name should use the user
specified compression suffix.

Resolves: rhbz#1318958
(cherry picked from commit f753a064b8)
2016-03-30 14:27:54 -07:00
Brian C. Lane
00185ad7c5 Automatic commit of package [lorax] release [24.17-1]. 2016-03-29 17:37:44 -07:00
Brian C. Lane
436b15cd5b livemedia-creator: Pass -Xbcj to mksquashfs
Some cases of mksquashfs were not using -Xbcj when it is available for
the arch. This adds a function to return the correct args based on the
arch and the cmdline args.

(cherry picked from commit 3740df3756)
2016-03-29 09:50:25 -07:00
Brian C. Lane
ce895bbeb1 templates: On 32 bit systems limit the amount of memory xz uses
This uses --memlimit-compress=3700MiB on i386 and arm when building the
product and updates images.

(cherry picked from commit 99e575e61b)
2016-03-29 09:46:57 -07:00
Brian C. Lane
0400b8c393 ltmpl: Add compressor selection and argument passing to installimg
Allow the template to select a different compression type or arguments
for the installimg command.

On 32bit builds running inside a mock xz sees the full amount of system
memory which can result in xz failing with a memory error. This allows
the template to limit the amount of memory it tries to use.

(cherry picked from commit 422a9a5859)
2016-03-29 09:46:44 -07:00
Brian C. Lane
d81b50cf41 Automatic commit of package [lorax] release [24.16-1]. 2016-03-28 17:32:02 -07:00
Brian C. Lane
1c12f47696 livemedia-creator: Update example kickstarts
Update the URL, add network command where needed, make sure all auth
commands are using sha512 now.

Removed the fedora-livemedia-ec2 example, Fedora doesn't have grub and
it has never really been tested.

(cherry picked from commit 44c359523e)
2016-03-28 17:30:48 -07:00
Brian C. Lane
06d226caa8 image-minimizer: Fix argument parsing
Can't pass metavar to args that are just switches.

(cherry picked from commit 11f9cb4483)
2016-03-28 17:30:38 -07:00
Brian C. Lane
15fe625743 livemedia-creator: Check selinux state and exit
lmc --no-virt was switching selinux to permissive if it was enforcing
and restore it when done. This works fine when it is the only session
running, but would cause problems if it was run in parallel.

It now only checks the state and exits with an error if it isn't already
disabled or in Permissive mode.

Users will need to run setenforce 0 before running lmc.

(cherry picked from commit b91e79d9bc)
2016-03-28 16:55:50 -07:00
Brian C. Lane
7b33b80dac livemedia-creator: Catch dnf download error
If there isn't enough space for DNF to download packages it will log:

"Not enough disk space to download the packages."

So add this to the messages in monitor that trigger an error.

(cherry picked from commit a7fb48d0da)
2016-03-24 09:51:56 -07:00
Brian C. Lane
2ff1998597 templates: Fix runtime_img check
commit 66241f7cd7 added a check on
runtime_img to create UDF iso's. Ends up it is only in outroot for live,
so switch all the checks to look at it in inroot instead.

(cherry picked from commit 077167cdb2)
2016-03-24 09:48:35 -07:00
Brian C. Lane
f21f126fb8 Create UDF iso when stage2 is >= 4GiB (#1312158)
Some images are becoming REALLY large. When a file is >= 4GiB we need to
pass -allow-limited-size to mkisofs to tell it to make a UDF image. Note
that the manpage says that this may result in it not booting on all
systems.

(cherry picked from commit 66241f7cd7)
2016-03-24 09:48:05 -07:00
Brian C. Lane
39e9609209 Automatic commit of package [lorax] release [24.15-1]. 2016-03-11 10:34:54 -08:00
Brian C. Lane
6c237a9cb3 pylorax: proc.returncode can be None
So use %s to keep it from generating a Traceback. If a callback is used
and it exits before the process does the returncode can be None.

(cherry picked from commit 4fea0ba7f1)
2016-03-11 09:32:02 -08:00
Brian C. Lane
9655e4d5a5 Change location of basearch to dnf.rpm.basearch (#1312087)
The dnf fix for the busted API change is also busted, so just change it
everywhere.

(cherry picked from commit 8085395678)
2016-03-11 09:31:09 -08:00
Brian C. Lane
d9ae3bbf99 livemedia-creator: Change fsck.ext4 discard failures to errors (#1315541)
Something is causing problems with the ext4 rootfs.img when running with
no-virt inside koji. This results in a failed image that looks good
until you try to boot it.

make_squashfs will now return False if it fails, and make_live_image
will return None (instead of the result path). lmc will exit with a 1
and log an error.

(cherry picked from commit 3e9efdcf48)
2016-03-11 09:30:46 -08:00
Brian C. Lane
9c81a598dd Merge branch 'f24-branch' of github.com:rhinstaller/lorax into f24-branch 2016-03-11 09:28:15 -08:00
Vratislav Podzimek
625cb20b3d Install the libblockdev-lvm-dbus plugin (#1264816)
This will allow blivet to make use of the LVM DBus PoC API.
2016-03-09 13:43:14 +01:00
31 changed files with 392 additions and 239 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -1 +1 @@
24.14-1 ./
24.22-1 ./

View File

@ -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}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -0,0 +1 @@
ro ramdisk_size=40000 cio_ignore=all,!condev

View File

@ -0,0 +1 @@
ro ramdisk_size=40000 cio_ignore=all,!condev rd.cmdline=ask

View File

@ -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'

View File

@ -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} \

View File

@ -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} \

View File

@ -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} \

View File

@ -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}

View File

@ -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

View File

@ -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?

View File

@ -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} \

View File

@ -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()

View File

@ -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)

View File

@ -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 "")

View File

@ -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 ##############

View File

@ -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):
'''

View File

@ -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",

View File

@ -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

View File

@ -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)