summaryrefslogtreecommitdiffstats
path: root/appliance
diff options
context:
space:
mode:
Diffstat (limited to 'appliance')
-rw-r--r--appliance/Makefile.am69
-rwxr-xr-xappliance/guestfs-supermin-helper.in80
-rw-r--r--appliance/kmod.whitelist.in (renamed from appliance/kmod.whitelist)0
-rwxr-xr-xappliance/make.sh.in14
-rwxr-xr-xappliance/supermin-make.sh.in33
-rwxr-xr-xappliance/supermin-split.sh.in93
6 files changed, 275 insertions, 14 deletions
diff --git a/appliance/Makefile.am b/appliance/Makefile.am
index 5dd6521e..3362992c 100644
--- a/appliance/Makefile.am
+++ b/appliance/Makefile.am
@@ -16,20 +16,37 @@
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
EXTRA_DIST = \
- make.sh update.sh
+ make.sh update.sh supermin-split.sh supermin-make.sh
# Build the root filesystem (appliance).
# Currently this is arch-dependent, so it seems like putting it in
# $(libdir) is best. When we build cross-architecture filesystems we
# should probably move them to $(datadir).
-
fsdir = $(libdir)/guestfs
-
+fs_DATA = $(APPLIANCE_FILES)
+
+# These are the resulting output files from the whole process:
+# VMLINUZ kernel for the full appliance
+# INITRAMFSIMG initramfs (ie. root fs) for the full appliance
+# For details of the supermin appliance, read the README file:
+# SUPERMINIMG initramfs (ie. partial root fs) for the supermin appliance
+# SUPERMINFILES list of missing files (the ones we will pull out of the
+# host filesystem at runtime) in the supermin appliance
+APPLIANCE_FILES = $(INITRAMFSIMG) $(VMLINUZ)
+if SUPERMIN
+APPLIANCE_FILES += $(SUPERMINIMG) $(SUPERMINFILES) kmod.whitelist
+bin_SCRIPTS = guestfs-supermin-helper
+endif
+
+# Don't change these names - they must be the same as in '*.sh' scripts.
INITRAMFSIMG = initramfs.$(REPO).$(host_cpu).img
VMLINUZ = vmlinuz.$(REPO).$(host_cpu)
+if SUPERMIN
+SUPERMINIMG = initramfs.$(REPO).$(host_cpu).supermin.img
+SUPERMINFILES = initramfs.$(REPO).$(host_cpu).supermin.hostfiles
+endif
-fs_DATA = $(INITRAMFSIMG) $(VMLINUZ)
-
+# This is for building the normal appliance:
$(INITRAMFSIMG) $(VMLINUZ): $(top_builddir)/initramfs/fakeroot.log
$(top_builddir)/initramfs/fakeroot.log: make.sh kmod.whitelist
@@ -37,15 +54,49 @@ $(top_builddir)/initramfs/fakeroot.log: make.sh kmod.whitelist
-mv $(VMLINUZ) $(VMLINUZ).bak
if ! bash make.sh; then rm -f $@; exit 1; fi
-$(INITRAMFSIMG): $(top_builddir)/initramfs/fakeroot.log $(top_builddir)/daemon/guestfsd
+$(INITRAMFSIMG): $(top_builddir)/initramfs/fakeroot.log $(top_builddir)/daemon/guestfsd update.sh
rm -f $@
bash update.sh
touch $@
-make.sh: make.sh.in
+kmod.whitelist: kmod.whitelist.in
+ grep -v '^[[:space:]]*$$' < $< | grep -v '^#' > $@
+
+# This is for building the supermin appliance. It has to be enabled
+# specifically with './configure --enable-supermin'. You really need
+# to read the README file.
+
+if SUPERMIN
+
+# First we need to decide which files go in and out of the supermin
+# appliance. This decision is made by 'supermin-split.sh'.
+$(SUPERMINFILES): supermin.incfiles
+supermin.incfiles: $(top_builddir)/initramfs/fakeroot.log supermin-split.sh
+ rm -f supermin.incfiles $(SUPERMINFILES)
+ bash supermin-split.sh
+
+# Second we need to create a supermin appliance with just the included
+# files (leaving out the host files, which we'll add back at runtime).
+$(SUPERMINIMG): supermin.incfiles supermin-make.sh
+ rm -f $@
+ bash supermin-make.sh
+
+endif
+
+# This should rebuild the scripts if the input files change, although
+# it doesn't always seem to work.
+%.sh: %.sh.in
cd .. && ./config.status appliance/$@
+ chmod +x $@
+
+guestfs-supermin-helper: guestfs-supermin-helper.in
+ cd .. && ./config.status appliance/$@
+ chmod +x $@
+
+#----------------------------------------------------------------------
+# Extra rules for testing the appliance.
-# Test-boot the image.
+# Test-boot the appliance.
test-boot: emptydisk
qemu-system-$(host_cpu) \
@@ -75,7 +126,7 @@ test-boot-realistic: emptydisk
# Make clean.
-CLEANFILES = $(fs_DATA)
+CLEANFILES = $(APPLIANCE_FILES)
clean-local:
rm -rf $(top_builddir)/initramfs
diff --git a/appliance/guestfs-supermin-helper.in b/appliance/guestfs-supermin-helper.in
new file mode 100755
index 00000000..1384ef66
--- /dev/null
+++ b/appliance/guestfs-supermin-helper.in
@@ -0,0 +1,80 @@
+#!/bin/bash -
+# @configure_input@
+# Copyright (C) 2009 Red Hat Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+# Helper script which constructs the supermin appliance at runtime.
+
+unset CDPATH
+
+set -e
+
+# Source directory containing the supermin input files.
+sourcedir=$(cd "$1" > /dev/null; pwd)
+
+# Output files.
+kernel="$2"
+initrd="$3"
+
+# Look for the kernel first. This is very unsophisticated: We
+# just look for any kernel named vmlinuz-*.$host_cpu which has a
+# corresponding /lib/modules/*.$host_cpu directory.
+
+for f in /boot/vmlinuz-*.@host_cpu@; do
+ b=$(basename "$f")
+ b=$(echo "$b" | sed 's,vmlinuz-,,')
+ modpath="/lib/modules/$b"
+ if [ -d "$modpath" ]; then
+ ln -sf "$f" "$kernel"
+ break
+ fi
+ modpath=
+done
+
+if [ -z "$modpath" ]; then
+ echo "$0: failed to find a suitable kernel" >&2
+ exit 1
+fi
+
+# The initrd consists of these components:
+# (1) The base skeleton appliance that we constructed at build time.
+# name = initramfs.@REPO@.@host_cpu@.supermin.img
+# format = compressed cpio
+# (2) The modules from modpath which are on the module whitelist.
+# format = plain cpio
+# (3) The host files which match wildcards in *.supermin.hostfiles.
+# format = plain cpio
+
+cp "$sourcedir"/initramfs.@REPO@.@host_cpu@.supermin.img "$initrd"
+
+# Kernel modules (2).
+exec 5<"$sourcedir"/kmod.whitelist
+whitelist=
+while read kmod 0<&5; do
+ whitelist="$whitelist -a -not -name $kmod"
+done
+exec 5<&-
+
+find "$modpath" -not -name '*.ko' -o \( -name '*.ko' $whitelist \) -a -print0 |
+ cpio --quiet -o -0 -H newc >> "$initrd"
+
+# Host files (3).
+
+(cd / && \
+ ls -1df $(
+ cat "$sourcedir"/initramfs.@REPO@.@host_cpu@.supermin.hostfiles
+ ) 2>/dev/null |
+ cpio --quiet -o -H newc ) >> "$initrd"
diff --git a/appliance/kmod.whitelist b/appliance/kmod.whitelist.in
index 4bf4cf81..4bf4cf81 100644
--- a/appliance/kmod.whitelist
+++ b/appliance/kmod.whitelist.in
diff --git a/appliance/make.sh.in b/appliance/make.sh.in
index 8f3b2127..9d77bea2 100755
--- a/appliance/make.sh.in
+++ b/appliance/make.sh.in
@@ -80,18 +80,22 @@ rm -f $koutput
# Don't need any keyboard maps.
@FEBOOTSTRAP_RUN@ initramfs -- rm -rf /lib/kbd
+# Remove anything in home directory. Because this is potentially
+# liable to monstrous fuck-ups, we don't put a slash before 'home'.
+(cd initramfs && echo home/*) |
+ xargs @FEBOOTSTRAP_RUN@ initramfs -- rm -rf
+
+# Remove /var/lib/yum stuff.
+@FEBOOTSTRAP_RUN@ initramfs -- rm -rf /var/lib/yum
+
# Kernel modules take up nearly half of the image. Only include ones
# which are on the whitelist.
-grep -v '^[[:space:]]*$' < appliance/kmod.whitelist |
- grep -v '^#' > kmod.whitelist.tmp
-exec 5<kmod.whitelist.tmp
+exec 5<appliance/kmod.whitelist
whitelist=
while read kmod 0<&5; do
whitelist="$whitelist -a -not -name $kmod"
done
exec 5<&-
-rm kmod.whitelist.tmp
-#echo whitelist=$whitelist
(cd initramfs && \
find lib/modules/*/kernel -name '*.ko' $whitelist -a -print0 ) |
diff --git a/appliance/supermin-make.sh.in b/appliance/supermin-make.sh.in
new file mode 100755
index 00000000..b993833a
--- /dev/null
+++ b/appliance/supermin-make.sh.in
@@ -0,0 +1,33 @@
+#!/bin/bash -
+# @configure_input@
+# Copyright (C) 2009 Red Hat Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+# Build the supermin appliance.
+# Read the README file!
+
+unset CDPATH
+
+set -e
+
+cd @top_builddir@
+
+output=appliance/initramfs.@REPO@.@host_cpu@.supermin.img
+
+# Generate final image.
+@FEBOOTSTRAP_TO_INITRAMFS@ --files=$(pwd)/appliance/supermin.incfiles initramfs > $output-t
+mv $output-t $output
+ls -lh $output
diff --git a/appliance/supermin-split.sh.in b/appliance/supermin-split.sh.in
new file mode 100755
index 00000000..fe4ab6ef
--- /dev/null
+++ b/appliance/supermin-split.sh.in
@@ -0,0 +1,93 @@
+#!/bin/bash -
+# @configure_input@
+# Copyright (C) 2009 Red Hat Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+# Decide which files will stay in the supermin appliance and which
+# files will be pulled out of the host at runtime.
+#
+# Read the README file!
+#
+# The basic idea is that we create two output files, one containing
+# the files that will stay, and the other listing the files that
+# will be pulled from the host (ie. not go into the appliance now).
+#
+# The list of files that stay ('supermin.incfiles') is just a straight
+# list of files and directories.
+#
+# The list of files that come from the host ('*.supermin.hostfiles')
+# can include wildcards, to allow libraries to be upgraded on the
+# host.
+
+unset CDPATH
+
+set -e
+
+cd @top_builddir@/initramfs
+
+incfiles=../appliance/supermin.incfiles
+hostfiles=../appliance/initramfs.@REPO@.@host_cpu@.supermin.hostfiles
+
+exec 5>$incfiles
+exec 6>$hostfiles
+
+# Note currently the initramfs contains ~2500 files, and none have
+# "funny characters" in the names. So this is reasonable just to
+# simplify the script.
+for path in $(find -not -name fakeroot.log); do
+ dir=$(dirname "$path")
+ file=$(basename "$path")
+
+ # All we're going to keep are the special files /init, the daemon,
+ # configuration files (/etc), devices and modifiable stuff (/var).
+ if [ "$path" = "./init" -o "$file" = "guestfsd" ]; then
+ echo "$path" >&5
+
+ elif [[ "$path" =~ '^\./etc' || "$path" =~ '^./dev' || "$path" =~ '^\./var' ]]; then
+ echo "$path" >&5
+
+ # Kernel modules are always copied in from the host, including all
+ # the dependency files.
+ elif [[ "$path" =~ '^\./lib/modules/' ]]; then
+ :
+
+ elif [ -d "$path" ]; then
+ # Always write directory names to both output files.
+ echo "$path" >&5
+ echo "$path" >&6
+
+ # Some libraries need fixed version numbers replaced by wildcards.
+
+ elif [[ "$file" =~ '^ld-[.0-9]+\.so$' ]]; then
+ echo "$dir/ld-*.so" >&6
+
+ # libfoo-1.2.3.so
+ elif [[ "$file" =~ '^lib(.*)-[-.0-9]+\.so$' ]]; then
+ echo "$dir/lib${BASH_REMATCH[1]}-*.so" >&6
+
+ # libfoo-1.2.3.so.1.2.3 (but NOT '*.so.N')
+ elif [[ "$file" =~ '^lib(.*)-[-.0-9]+\.so\.([0-9]+)\.' ]]; then
+ echo "$dir/lib${BASH_REMATCH[1]}-*.so.${BASH_REMATCH[2]}.*" >&6
+
+ # libfoo.so.1.2.3 (but NOT '*.so.N')
+ elif [[ "$file" =~ '^lib(.*)\.so\.([0-9]+)\.' ]]; then
+ echo "$dir/lib${BASH_REMATCH[1]}.so.${BASH_REMATCH[2]}.*" >&6
+
+ else
+ # Anything else comes from the host directly.
+ echo "$path" >&6
+ fi
+done