diff options
author | Richard Jones <rjones@trick.home.annexia.org> | 2009-06-15 11:50:35 +0100 |
---|---|---|
committer | Richard Jones <rjones@trick.home.annexia.org> | 2009-06-15 20:38:12 +0100 |
commit | 414aa67f2bcbbc5009b92f32611aa9196836736b (patch) | |
tree | a7090c4d47440b3979b6c0a21ba6de378acc2bb6 /appliance | |
parent | eebec43a15a5de3a5b9f1281654f9cbdd44e19cf (diff) | |
download | libguestfs-414aa67f2bcbbc5009b92f32611aa9196836736b.tar.gz libguestfs-414aa67f2bcbbc5009b92f32611aa9196836736b.tar.xz libguestfs-414aa67f2bcbbc5009b92f32611aa9196836736b.zip |
Experimental implementation of the supermin appliance (passes most tests).
Diffstat (limited to 'appliance')
-rw-r--r-- | appliance/Makefile.am | 69 | ||||
-rwxr-xr-x | appliance/guestfs-supermin-helper.in | 80 | ||||
-rw-r--r-- | appliance/kmod.whitelist.in (renamed from appliance/kmod.whitelist) | 0 | ||||
-rwxr-xr-x | appliance/make.sh.in | 14 | ||||
-rwxr-xr-x | appliance/supermin-make.sh.in | 33 | ||||
-rwxr-xr-x | appliance/supermin-split.sh.in | 93 |
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 |