#!/bin/bash -e # Default location for a repository. repo=http://qafiler.boston.redhat.com/redhat/rawhide-i386/ # Default filesystem size (megabytes). fssize=1024 # Default root device (emulated, of course). rootdev=/dev/hda1 if test $# -lt 1; then echo Usage: `basename $0` imagename repo-url "[fssize(MB)]" "[rootdev]" "[package ...]" echo Default repo value is "$repo" echo Default fssize is ${fssize}MB "(can be increased later with resize2fs)." echo Default rootdev is ${rootdev}. echo Package groups can be specified in the form \"@Group\". exit 1 fi name=${1} repo=${2:-"$repo"} fssize=${3:-"$fssize"} rootdev=${4:-"$rootdev"} if test $# -le 4 ; then shift $# else shift 4 fi : echo Name: $name : echo Repository: $repo : echo FS Size: ${fssize}MB : echo Root Device: $rootdev : echo Other packages and groups: $* : sleep 2 # I have no idea if SELinux works on xenU kernels. selinux=disabled policy=targeted # Use the current directory as a chroot parent. root=`pwd`/${name}.chroot # Be ready to clean up if the user breaks out. Clean up any previously-canceled # runs if we find them. unmount() { set +e umount ${root}/sys umount ${root}/proc umount ${root}/dev umount ${root} rmdir ${root} } if test -d ${root} ; then unmount fi trap unmount EXIT # Create the image of the root filesystem if needed. if ! test -s ${name}.img ; then dd if=/dev/zero bs=1M seek=${fssize:-1024} count=1 of=${name}.img mke2fs -j -F ${name}.img fi # Mount the filesystem, and borrow /dev, /proc, and /sys. test -d ${root} || mkdir ${root} mount -o loop -t ext3 ${name}.img ${root} || exit test -d ${root}/dev || mkdir ${root}/dev test -d ${root}/proc || mkdir ${root}/proc test -d ${root}/sys || mkdir ${root}/sys mount --bind /dev ${root}/dev mount --bind /proc ${root}/proc mount --bind /sys ${root}/sys # Point yum at the repository which we want to use. cat > ${root}/yum.conf << EOF [main] debuglevel=1 assumeyes=1 [default] name=Default (i386) baseurl=$repo gpgcheck=0 EOF # Ouch, yum. Seriously, I really don't want you using repos from repos.d. # But this probably doesn't work anyway. yumflags= for repo in /etc/yum.repos.d/* ; do if grep -q '^enabled=1$' $repo ; then repo=`grep '^\[.*\]$' $repo | sed -r 's,\[(.*)\],\1,g'` yumflags="$yumflags --disablerepo=$repo" fi done # Create fstab. mkdir -p ${root}/etc/sysconfig cat > ${root}/etc/fstab << EOF ${rootdev} / ext3 defaults 1 1 /dev/devpts /dev/pts devpts gid=5,mode=620 0 0 /dev/shm /dev/shm tmpfs defaults 0 0 /dev/proc /proc proc defaults 0 0 /dev/sys /sys sysfs defaults 0 0 EOF # Create an RPM database. test -s ${root}/var/lib/rpm/Packages || rpm --root ${root} --initdb # Install a base system. yum -c ${root}/yum.conf $yumflags --installroot=${root} groupinstall Base # Install a xenU kernel (we need it) and xen runtime stuff. yum -c ${root}/yum.conf $yumflags --installroot=${root} install \ kernel-xenU xen yum netconfig # Install anything else the caller requested. while test $# -gt 0 ; do case "$1" in @*) yum -c ${root}/yum.conf $yumflags --installroot=${root} groupinstall "${1#@}" ;; *) yum -c ${root}/yum.conf $yumflags --installroot=${root} install "$1" ;; esac shift done # Clean up caches -- they may never be used again. yum -c ${root}/yum.conf $yumflags --installroot=${root} clean all # Mark that networking should be enabled, and create a basic file describing # eth0, and leave it at that. We can run "setup" to change things later. cat > ${root}/etc/sysconfig/network << EOF NETWORKING=yes EOF cat > $root/etc/hosts << EOF # Do not remove the following line, or various programs # that require network functionality will fail. 127.0.0.1 localhost.localdomain localhost EOF cat > $root/etc/sysconfig/network-scripts/ifcfg-eth0 << EOF DEVICE=eth0 EOF # Maybe we'll record a MAC somewhere at some point. randommac=`dd if=/dev/urandom bs=1 count=6 2> /dev/null | \ od -t x1 -An | sed -e s,^\ ,, -e s,\ ,:,g` # Set up the locale. cat > ${root}/etc/sysconfig/i18n << EOF LANG=${LANG:-en_US.UTF-8} EOF # Set up the SELinux configuration. cat > ${root}/etc/sysconfig/selinux << EOF # This file controls the state of SELinux on the system. # SELINUX= can take one of these three values: # enforcing - SELinux security policy is enforced. # permissive - SELinux prints warnings instead of enforcing. # disabled - SELinux is fully disabled. SELINUX=${selinux:-disabled} # SELINUXTYPE= type of policy in use. Possible values are: # targeted - Only targeted network daemons are protected. # strict - Full SELinux protection. SELINUXTYPE=${policy:-targeted} EOF if test -n "$selinux" ; then if test "$selinux" != disabled ; then touch ${root}/.autorelabel fi fi # Create a minimally-usable /dev, enough to be useful until udev is started. umount ${root}/dev chroot ${root} /sbin/MAKEDEV -x \ `basename $rootdev` `echo $rootdev | sed s,'[[:digit:]]*$',,g` \ core \ console \ fd \ full \ mem \ nfsd \ null \ port \ ramdisk \ random \ stderr \ stderr \ stdin \ stdin \ stdout \ stdout \ tty \ tty1 \ tty2 \ tty3 \ tty4 \ tty5 \ tty6 \ tty7 \ tty8 \ urandom \ X0R \ zero # Add the repository which we used to install the image to its configuration. cat >> ${root}/etc/yum.conf << EOF [default] name=Default (i386) baseurl=$repo EOF # These don't work, at least for me, at least for now. chroot ${root} /sbin/chkconfig --level 0123456 bluetooth off chroot ${root} /sbin/chkconfig --level 0123456 gpm off chroot ${root} /sbin/chkconfig --level 0123456 pcmcia off # Suppress the warning we'd get at the end of this process if /dev wasn't # still mounted. mount --bind /dev ${root}/dev