This patch adds support for another installation variant. The livecd-creator
produces ISO images which boot using syslinux. The image-creator creates a
single file containing a filesystem in which the OS is installated. This patch
adds a new disk-creator, which creates a single file containing a partitioned
disk with potentially many filesystems in which the OS is installed. Furthermore
it installs grub in the boot sector, so this image is immediately bootable in
a virtual machine.
The idea is that this serves as a tool for creating pre-installed appliances
suitable for distribution to end users, with no further installation steps
required, beyond potentially an appliance specific firstboot script.
I've used this tool to create an instance of the oVirt web management appliance
from its kickstart recipe. Currently developers building the appliance have to
boot a VM using the F8 boot.iso and run the kickstart script in the VM and so
on. While this works, involves many steps with potential for failure. This new
tool reduces the problem to simply
disk-creator --name ovirt-wui-demo.dsk ovirt-wui-appliance.ks
A short while later you end up with 'ovirt-wui-demo.dks' which you can boot
straight up in KVM / Xen / etc.
With the background information out of the way, here's some info about the
changes in this patch...
Most of the change here involves re-factoring the imgcreate/fs.py module.
The SparseExtLoopbackMount, SparseLoopbackMount, LoopbackMount classes all
have the built-in limitation that the image being produced corresponds to
a single filesystem / loop mount. With the disk creator, the image being
produced can be partitioned into multiple chunks, with many filesystems.
Furthermore, not all of them require loopback mounts, as the partitions
themselves are already visible via /dev/mapper/
So this patch separates the roles. There are now classes which deal with
accessing / creating disks:
Disk - generic base for disks
RawDisk - a disk backed by a block device
LoopbackDisk - a disk backed by a file
SparseLoopbackDisk - a disk backed by a sparse file
The 'create' method must make the disk visible as a block device - eg
by calling losetup. For RawDisk, this is obviously a no-op. The 'cleanup'
method must undo the 'create' operation.
There are then classes which deal with mounting things:
Mount - generic base for mounts
DiskMount - able to mount a Disk object
ExtDiskMount - able to format/resize ext3 filesystems when mounting
The livecd-creator/image-creator tools are updated to take account of these
API changes.
Next, up we have a new class 'PartitionedMount'. This takes a Disk object
and adds one or more partitions to it. It then creates further Disk and
Mount object instances for each partition. So, mounting a 'PartitionedMount'
object will in fact mount all its partitions (formatting the filesystems
or swap space as needed).
Currently only ext3/swap is supported for partition types. We use parted
to create partitions. This works well enough, but parted will spew lots
of scary looking warnings about being unable to tell the kernel to reload
its partition table. This is because loop devices don't support partition
tables. In this scenario though its not a problem because we then use the
kpartx tool to add entries to /dev/mapper for each partition.
When mounting partitions, PartitionedMount, figures out the correct order
based on the mount points, so it ensures the / is mounted before /boot.
The imgcreator/disk.py class contains the DiskImageCreator class which is
a subclass of ImageCreator. This uses the PartitionedMount object to
do an installation of the kickstart. It is fairly simple at the moment,
only being able to cope with 'part' entries in the kickstart which are
either ext3 or swap, and which have an explicit size given - ie --grow
is not supported. For testing I've been using
part /boot --fstype ext3 --size=100 --ondisk=sda
part swap --fstype swap --size=500 --ondisk=sda
part /var/lib/pgsql --fstype ext3 --size=300 --ondisk=sda
part / --fstype ext3 --size=3000 --ondisk=sda
part /home --fstype ext3 --size=500 --ondisk=sda
part /var --fstype ext3 --size=1000 --ondisk=sda
Which ensures it correctly deals with adding extended and logical partitions.
It doesn't currently care about --ondisk only outputting a single disk
image, but I intend to extend the CLI to allow creation of installs which
spawn multiple output disks.
Aside from partitioning, DiskImageCreator will setup an fstab file containing
entries for all the filesystems and swap space. It will add the grub device
map file, and create a grub.cfg based off the installed kernel. It is able
to cope with a layout where grub config is on /, or a separate /boot partition.
We can't use grub-install since it doesn't understand loopdevices, so to do
the MBR install we invoke grub manually.
If the disk image happens to be the same size or smaller than one of your
USB flash drives, you can also dd the entire image straight to the driver
with no modifications required. It should 'just boot' in any machine able
to boot off USB
Future enhancements for this:
- Autosize partitions when --grow is used
- Support LVM volumes
- Allow splitting across multiple disks (sda, sdb, etc)
- Deal with disk filesytem labels
- Deal with non-ext3 filesystems
- Install to pre-existing block device / LVM vol instead of file
- When staging final image, use qemu-img to generate qcow2, vmdk
or raw files at user's choice. qcow2 would give huge size savings
- Output XML file for use with 'virt-image' tool, so that the entire
build and deploy process consists of nothing more than:
# disk-creator ovirt-wui-appliance.ks
# virt-image ovirt-wui-appliance.xml
The last two options are probably my most immediate TODO items because this
will result in an excellant virtual appliance creation tool for Fedora
derived distros.
Perhaps it should be called appliance-creator instead of disk-creator ?
Final note - the patch contains a tonne of 'print' statements for debugging.
Debugging this stuff can be 'fun' when things go wrong, so I think it may
be useful if we make use of the python logging module throughout the livecd
tools. If folks agree, I'll switch the 'print' to logging.debug(), otherwise
I'll just remove them entirely before reposting this patch
The attached patch changes:
API | 4
Makefile | 3
imgcreate/__init__.py | 3
imgcreate/creator.py | 17 +
imgcreate/disk.py | 20 +-
imgcreate/fs.py | 425 ++++++++++++++++++++++++++++++++++++++-----------
imgcreate/kickstart.py | 3
imgcreate/live.py | 6
livecd-tools.spec | 1
9 files changed, 376 insertions(+), 106 deletions(-)
I'm also attaching the kickstart file I'm using as a demonstration...
Regards,
Dan.
--
|=- Red Hat, Engineering, Emerging Technologies, Boston. +1 978 392 2496 -=|
|=- Perl modules:
http://search.cpan.org/~danberr/ -=|
|=- Projects:
http://freshmeat.net/~danielpb/ -=|
|=- GnuPG: 7D3B9505 F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 -=|