Albert Hopkins df1d7650d8 Baselayout-2/openrc compatibility and stage4 tarballs.
The first major change here is the support of baselayout-2/openrc.  So far
Gentoo has not released a stage3 tarball with baselayout-2, but I've tested
this enough that I feel it works even when doing an upgrade.  The
baselayout-1 stuff has been converted, however it is recommended to not use
this until baselayout-2 is available in Gentoo stage3s as I don't want to
support converting, or you can do this:

stage4 tarball support.  I'm not sure why I didn't support this before.
Now not only can stage4 tarballs be build, instead of or in addition to
virtual appliance images, but stage4 tarballs can also be used in lieu of a
stage3.  There is a new "stage4" make target, and also when building the
Makefile will first look for stage4/<appliance>-stage4.tar.bz2 and if that
exists use it instead of the Gentoo stage3.  If you specify stage4 as a
target and also already have a stage4, then the Makefile will unpack the
stage4 into the chroot, perform updates, and then re-create the stage4
based on the updates (atomically).  In addition there is a new Makefile
variable, SOFTWARE.  The default value is "1" meaning it will call the
software target (thereby installing/updatein software), but if you set
SOFTWARE=0, then the software phase will not be run.  This can allow, for
example, to build a VM image from a stage4 without performing software
updates, in effect a straight stage4 to image for quick image building.

Since most appliances are pretty much based on the "base" appliance, one
could imply copy the base stage4 to the new appliance stage4 and start from
there, instead of having to start from a vanilla stage3, for example:

# cp stage4/base-stage4.tar.bz2 stage4/kde-stage4.tar.bz2
# make APPLIANCE=kde stage4

Will take the already existing base stage4 and simply update it to kde,
which will be easier/faster than starting from a stage3.

There are still some tweaks that need to be done for the stage4 support.
Specifically Makefile targets need to be written with the assumption that
they may be called more than once (e.g. updating a stage4 or going from
stage4 to image with SOFTWARE=1).  For the most part things work according
to that assumption, but there are a few things that need to be tweeked,
such as the inittab settings if one is building a "headed" image but it's
based off a headless stage4.  New appliance authors should also write their
"preinstall" and "postinstall" targets with the assmption that it may be
called more than once.
2011-05-17 20:44:04 -04:00

339 lines
9.3 KiB
Makefile

CHROOT=./vabuild
APPLIANCE = base
HOSTNAME = $(APPLIANCE)
RAW_IMAGE = $(HOSTNAME).img
QCOW_IMAGE = $(HOSTNAME).qcow
VMDK_IMAGE = $(HOSTNAME).vmdk
STAGE4_TARBALL = stage4/$(HOSTNAME)-stage4.tar.bz2
KERNEL_CONFIG = kernel.config
VIRTIO = NO
TIMEZONE = UTC
DISK_SIZE = 6.0G
SWAP_SIZE = 30
SWAP_FILE = $(CHROOT)/.swap
ARCH = amd64
MAKEOPTS = -j4
PRUNE_CRITICAL = NO
REMOVE_PORTAGE_TREE = YES
ENABLE_SSHD = NO
CHANGE_PASSWORD = YES
HEADLESS = NO
EXTERNAL_KERNEL = NO
UDEV = YES
SOFTWARE = 1
ACCEPT_KEYWORDS = amd64
DASH = NO
M4 = m4
EMERGE = /usr/bin/emerge
M4_DEFS = -D HOSTNAME=$(HOSTNAME)
M4C = $(M4) $(M4_DEFS)
NBD_DEV = /dev/nbd0
USEPKG = --usepkg --binpkg-respect-use=y
RSYNC_MIRROR = rsync://mirrors.rit.edu/gentoo/
KERNEL = gentoo-sources
PACKAGE_FILES = $(APPLIANCE)/package.*
WORLD = $(APPLIANCE)/world
CRITICAL = $(APPLIANCE)/critical
-include $(APPLIANCE)/$(APPLIANCE).cfg
-include $(profile).cfg
inroot := chroot $(CHROOT)
ifneq ($(SOFTWARE),0)
software_extra = build-software
endif
ifneq ($(PKGDIR),)
MOUNT_PKGDIR = mkdir -p $(CHROOT)/var/portage/packages; \
mount -o bind "$(PKGDIR)" $(CHROOT)/var/portage/packages
UMOUNT_PKGDIR = umount $(CHROOT)/var/portage/packages
ADD_PKGDIR = echo PKGDIR="/var/portage/packages" >> $(CHROOT)/etc/make.conf
endif
ifeq ($(PRUNE_CRITICAL),YES)
COPY_ARGS = --exclude-from=rsync-excludes \
--exclude-from=rsync-excludes-critical
UNMERGE_CRITICAL = $(inroot) $(EMERGE) -C `cat $(CRITICAL)`
else
COPY_ARGS = --exclude-from=rsync-excludes
endif
ifeq ($(CHANGE_PASSWORD),YES)
ifdef ROOT_PASSWORD
change_password = $(inroot) usermod -p '$(ROOT_PASSWORD)' root
else
change_password = $(inroot) passwd -d root; $(inroot) passwd -e root
endif
endif
ifeq ($(REMOVE_PORTAGE_TREE),YES)
COPY_ARGS += --exclude=usr/portage
endif
ifeq ($(VIRTIO),YES)
VIRTIO_FSTAB = sed -i 's/sda/vda/' $(CHROOT)/etc/fstab
VIRTIO_GRUB = sed -i 's/sda/vda/' $(CHROOT)/boot/grub/grub.conf
endif
ifeq ($(HEADLESS),YES)
HEADLESS_INITTAB = sed -ri 's/^(c[0-9]:)/\#\1/' $(CHROOT)/etc/inittab
HEADLESS_GRUB = sed -i -f grub-headless.sed $(CHROOT)/boot/grub/grub.conf
endif
ifeq ($(ENABLE_SSHD),YES)
enable_sshd = $(inroot) /sbin/rc-update add sshd default
endif
gcc_config = $(inroot) gcc-config 1
export APPLIANCE ACCEPT_KEYWORDS CHROOT EMERGE HEADLESS M4 M4C inroot
export HOSTNAME MAKEOPTS PRUNE_CRITICAL TIMEZONE USEPKG WORLD OVERLAY
unexport PKGDIR ARCH NBD_DEV
all: image
$(RAW_IMAGE):
qemu-img create -f raw $(RAW_IMAGE) $(DISK_SIZE)
partitions: $(RAW_IMAGE)
parted -s $(RAW_IMAGE) mklabel msdos
parted -s $(RAW_IMAGE) mkpart primary ext2 0 $(DISK_SIZE)
parted -s $(RAW_IMAGE) set 1 boot on
qemu-nbd -c $(NBD_DEV) $(RAW_IMAGE)
sleep 3
mkfs.ext4 -O sparse_super,^has_journal -L "$(APPLIANCE)"_root $(NBD_DEV)p1
touch partitions
mounts: stage3
mkdir -p $(CHROOT)
if [ ! -e mounts ] ; then \
mount -t proc none $(CHROOT)/proc; \
mount -o bind /dev $(CHROOT)/dev; \
mount -o bind /var/tmp $(CHROOT)/var/tmp; \
fi
touch mounts
sync_portage:
rsync --no-motd -L $(RSYNC_MIRROR)/snapshots/portage-latest.tar.bz2 portage-latest.tar.bz2
touch sync_portage
portage: sync_portage stage3
tar xjf portage-latest.tar.bz2 -C $(CHROOT)/usr
$(MOUNT_PKGDIR)
touch portage
preproot: stage3 mounts portage
cp -L /etc/resolv.conf $(CHROOT)/etc/
$(inroot) sed -i 's/root:.*/root::9797:0:::::/' /etc/shadow
touch preproot
stage3:
mkdir -p $(CHROOT)
if test -e "$(STAGE4_TARBALL)"; \
then tar xjpf "$(STAGE4_TARBALL)" -C $(CHROOT); \
else rsync --no-motd $(RSYNC_MIRROR)/releases/`echo $(ARCH)|sed 's/i.86/x86/'`/autobuilds/latest-stage3.txt .; \
rsync --no-motd $(RSYNC_MIRROR)/releases/`echo $(ARCH)|sed 's/i.86/x86/'`/autobuilds/`tail -n 1 latest-stage3.txt` stage3-$(ARCH)-latest.tar.bz2; \
tar xjpf stage3-$(ARCH)-latest.tar.bz2 -C $(CHROOT); \
fi
touch stage3
compile_options: portage make.conf locale.gen $(PACKAGE_FILES)
cp make.conf $(CHROOT)/etc/make.conf
$(ADD_PKGDIR)
echo ACCEPT_KEYWORDS=$(ACCEPT_KEYWORDS) >> $(CHROOT)/etc/make.conf
cp locale.gen $(CHROOT)/etc/locale.gen
$(inroot) locale-gen
mkdir -p $(CHROOT)/etc/portage
for f in $(PACKAGE_FILES) ; do \
cp $$f $(CHROOT)/etc/portage/ ; \
done
touch compile_options
base_system: mounts compile_options
touch base_system
kernel: base_system $(KERNEL_CONFIG)
$(inroot) cp /usr/share/zoneinfo/$(TIMEZONE) /etc/localtime
echo $(TIMEZONE) > "$(CHROOT)"/etc/timezone
ifneq ($(EXTERNAL_KERNEL),YES)
$(inroot) $(EMERGE) -n $(USEPKG) sys-kernel/$(KERNEL)
cp $(KERNEL_CONFIG) $(CHROOT)/usr/src/linux/.config
$(gcc_config)
$(inroot) make $(MAKEOPTS) -C /usr/src/linux oldconfig
$(inroot) make $(MAKEOPTS) -C /usr/src/linux
$(inroot) make $(MAKEOPTS) -C /usr/src/linux modules_install
$(inroot) make $(MAKEOPTS) -C /usr/src/linux install
cd $(CHROOT)/boot ; \
k=`/bin/ls -1 --sort=time vmlinuz-*|head -n 1` ; \
ln -nsf $$k vmlinuz
endif
touch kernel
$(SWAP_FILE): preproot
dd if=/dev/zero of=$(SWAP_FILE) bs=1M count=$(SWAP_SIZE)
/sbin/mkswap $(SWAP_FILE)
$(CHROOT)/etc/fstab: fstab preproot
cp fstab $(CHROOT)/etc/fstab
$(CHROOT)/etc/conf.d/hostname: preproot
echo hostname=$(HOSTNAME) > $(CHROOT)/etc/conf.d/hostname
sysconfig: preproot $(SWAP_FILE) $(CHROOT)/etc/fstab $(CHROOT)/etc/conf.d/hostname
@echo $(VIRTIO)
$(VIRTIO_FSTAB)
ifeq ($(VIRTIO),YES)
sed -i 's:clock_hctosys="YES":clock_hctosys="NO":g' "$(CHROOT)/etc/conf.d/hwclock"
sed -i '/^rc_sys=/d' "$(CHROOT)/etc/rc.conf"
echo 'rc_sys=""' >> "$(CHROOT)/etc/rc.conf"
endif
sed -i 's/^#s0:/s0:/' $(CHROOT)/etc/inittab
$(HEADLESS_INITTAB)
echo 'modules="dhclient"' > $(CHROOT)/etc/conf.d/net
echo 'config_eth0="dhcp"' >> $(CHROOT)/etc/conf.d/net
echo 'dhcp_eth0="release"' >> $(CHROOT)/etc/conf.d/net
$(inroot) ln -nsf net.lo /etc/init.d/net.eth0
$(inroot) ln -nsf /etc/init.d/net.eth0 /etc/runlevels/default/net.eth0
$(inroot) rm -f /etc/runlevels/boot/consolefont
touch sysconfig
systools: sysconfig compile_options
$(inroot) $(EMERGE) -n $(USEPKG) app-admin/syslog-ng
$(inroot) /sbin/rc-update add syslog-ng default
$(inroot) $(EMERGE) -n $(USEPKG) sys-power/acpid
$(inroot) /sbin/rc-update add acpid default
$(inroot) $(EMERGE) -n $(USEPKG) net-misc/dhcp
ifeq ($(DASH),YES)
if ! test -e "$(STAGE4_TARBALL)"; \
then $(inroot) $(EMERGE) -n $(USEPKG) app-shells/dash; \
echo /bin/dash >> $(CHROOT)/etc/shells; \
$(inroot) chsh -s /bin/dash root; \
fi
endif
$(inroot) ln -sf dash /bin/sh
touch systools
grub: stage3 grub.conf kernel partitions
ifneq ($(EXTERNAL_KERNEL),YES)
$(inroot) $(EMERGE) -nN $(USEPKG) sys-boot/grub
cp grub.conf $(CHROOT)/boot/grub/grub.conf
$(VIRTIO_GRUB)
$(HEADLESS_GRUB)
endif
touch grub
build-software: systools issue etc-update.conf $(CRITICAL) $(WORLD)
$(MAKE) -C $(APPLIANCE) preinstall
cp etc-update.conf $(CHROOT)/etc/
# some packages, like, tar need xz-utils to unpack, but it not part of
# the stage3 so may not be installed yet
$(inroot) $(EMERGE) -1n $(USEPKG) app-arch/xz-utils
$(inroot) $(EMERGE) $(USEPKG) --update --newuse --deep `cat $(WORLD)`
$(gcc_config)
# Need gentoolkit to run revdep-rebuild
$(inroot) $(EMERGE) -1n $(USEPKG) app-portage/gentoolkit
$(inroot) revdep-rebuild -i
cp issue $(CHROOT)/etc/issue
$(gcc_config)
$(inroot) $(EMERGE) $(USEPKG) --update --newuse --deep world
# Per bug #357009
$(inroot) eselect python update
$(inroot) $(EMERGE) --depclean --with-bdeps=n
$(gcc_config)
$(inroot) etc-update
$(MAKE) -C $(APPLIANCE) postinstall
$(enable_sshd)
$(change_password)
$(UNMERGE_CRITICAL)
software: stage3 $(software_extra)
touch software
device-map: $(RAW_IMAGE)
echo '(hd0) ' $(RAW_IMAGE) > device-map
image: software device-map grub.shell grub
mkdir -p loop
mount -o noatime $(NBD_DEV)p1 loop
mkdir -p gentoo
mount -o bind $(CHROOT) gentoo
rsync -ax $(COPY_ARGS) gentoo/ loop/
ifneq ($(EXTERNAL_KERNEL),YES)
loop/sbin/grub --device-map=device-map --no-floppy --batch < grub.shell
endif
ifeq ($(UDEV),NO)
rm -f loop/dev/vda*
/bin/mknod loop/dev/vda b 254 0
/bin/mknod loop/dev/vda1 b 254 1
/bin/mknod loop/dev/vda2 b 254 2
chown root:disk loop/dev/vda*
rm -f loop/etc/runlevels/sysinit/udev
endif
umount gentoo
rmdir gentoo
umount loop
sleep 3
rmdir loop
qemu-nbd -d $(NBD_DEV)
touch image
$(QCOW_IMAGE): $(RAW_IMAGE) image
qemu-img convert -f raw -O qcow2 -c $(RAW_IMAGE) $(QCOW_IMAGE)
qcow: $(QCOW_IMAGE)
$(VMDK_IMAGE): $(RAW_IMAGE) image
qemu-img convert -f raw -O vmdk $(RAW_IMAGE) $(VMDK_IMAGE)
vmdk: $(VMDK_IMAGE)
$(STAGE4_TARBALL): software kernel rsync-excludes rsync-excludes-critical
mkdir -p stage4
mkdir -p gentoo
mount -o bind $(CHROOT) gentoo
tar -jScf "$(STAGE4_TARBALL)".tmp --numeric-owner $(COPY_ARGS) -C gentoo --one-file-system .
umount gentoo
rmdir gentoo
mv "$(STAGE4_TARBALL)".tmp "$(STAGE4_TARBALL)"
stage4: $(STAGE4_TARBALL)
umount:
$(UMOUNT_PKGDIR)
umount $(CHROOT)/var/tmp
umount $(CHROOT)/dev
umount $(CHROOT)/proc
touch umount
remove_checkpoints:
rm -f mounts compile_options base_system portage sync_portage
rm -f parted kernel grub stage3 software preproot sysconfig systools image partitions device-map
clean: umount remove_checkpoints
rm -f umount
rm -rf loop gentoo
rm -rf gentoo
rm -rf $(CHROOT)
realclean: clean
${RM} $(RAW_IMAGE) $(QCOW_IMAGE) $(VMDK_IMAGE)
distclean:
rm -f *.qcow *.img *.vmdk
rm -f latest-stage3.txt stage3-*-latest.tar.bz2
rm -f *-stage4.tar.bz2
rm -f portage-latest.tar.bz2
.PHONY: qcow vmdk clean realclean distclean remove_checkpoints build-software