413b2fd552
If asked to do so, mkarchiso simply copies a directory full of addons to the iso root. On boot, after union-mounting /real_root, the archiso hook will look for and source an addon config file. This file is a plain old bash script, which makes it quite flexible. The addon config should be written to take care of any mounting that needs to be done, an example of typical tasks is also included. Signed-off-by: Simo Leone <simo@archlinux.org>
258 lines
7.9 KiB
Bash
Executable File
258 lines
7.9 KiB
Bash
Executable File
#!/bin/sh
|
|
|
|
CPIOCONFIG="$(pwd)/archiso-mkinitcpio.conf"
|
|
DEF_CONFIG_DIR="$(pwd)/default-config"
|
|
PKGFILE="$(pwd)/packages.list"
|
|
PKGLIST=""
|
|
QUIET="y"
|
|
FORCE="n"
|
|
ADDON_DIR=""
|
|
|
|
command_name=""
|
|
work_dir=""
|
|
isoname=""
|
|
|
|
APPNAME=$(basename "${0}")
|
|
|
|
# usage: usage <exitvalue>
|
|
usage ()
|
|
{
|
|
echo "usage ${APPNAME} [options] command <command options>"
|
|
echo " general options:"
|
|
echo " -f Force overwrite of working files/squashfs image/iso"
|
|
echo " -i CPIO_CONFIG Use CONFIG file for mkinitcpio. default: ${CPIOCONFIG}"
|
|
echo " -P PKGFILE File with list of packages to install. default: ${PKGFILE}"
|
|
echo " -p PACKAGE Additional package to install, can be used multiple times"
|
|
echo " -a ADDON_DIR Use addons from DIR. default: none"
|
|
echo " -v Enable verbose output."
|
|
echo " -h This message."
|
|
echo " commands:"
|
|
echo " install <working dir> : where to build the ISO root"
|
|
echo " squash <working dir> : generate a squashfs image of the ISO root"
|
|
echo " iso <working dir> <iso name> : build an ISO from the working directory"
|
|
echo " all <working dir> <iso name> : perform all of the above, in order"
|
|
exit $1
|
|
}
|
|
|
|
while getopts 'i:P:p:a:fvh' arg; do
|
|
case "${arg}" in
|
|
i) CPIOCONFIG="${OPTARG}" ;;
|
|
P) PKGFILE="${OPTARG}" ;;
|
|
p) PKGLIST="${PKGLIST} ${OPTARG}" ;;
|
|
a) ADDON_DIR="${OPTARG}" ;;
|
|
f) FORCE="y" ;;
|
|
v) QUIET="n" ;;
|
|
h|?) usage 0 ;;
|
|
*) echo "invalid argument '${arg}'"; usage 1 ;;
|
|
esac
|
|
done
|
|
|
|
# do UID checking here so someone can at least get usage instructions
|
|
if [ "$EUID" != "0" ]; then
|
|
echo "error: This script must be run as root."
|
|
exit 1
|
|
fi
|
|
|
|
shift $(($OPTIND - 1))
|
|
echo "ARGS: $@"
|
|
|
|
[ $# -le 1 ] && usage 1
|
|
|
|
command_name="${1}"
|
|
case "${command_name}" in
|
|
install) work_dir="${2}" ;;
|
|
squash) work_dir="${2}" ;;
|
|
iso) work_dir="${2}"; isoname="${3}" ;;
|
|
all) work_dir="${2}"; isoname="${3}" ;;
|
|
*) echo "invalid command name '${command_name}'"; usage 1 ;;
|
|
esac
|
|
|
|
[ "x${work_dir}" = "x" ] && (echo "please specify a working directory" && usage 1)
|
|
|
|
isoroot="${work_dir}/iso"
|
|
instroot="${work_dir}/install"
|
|
|
|
_kversion ()
|
|
{
|
|
source ${instroot}/etc/mkinitcpio.d/kernel26.kver
|
|
echo ${ALL_kver}
|
|
}
|
|
|
|
# usage: _pacman <packages>...
|
|
_pacman ()
|
|
{
|
|
local ret
|
|
if [ "${QUIET}" = "y" ]; then
|
|
mkarchroot -f ${instroot} $* 2>&1 >/dev/null
|
|
ret=$?
|
|
else
|
|
mkarchroot -f ${instroot} $*
|
|
ret=$?
|
|
fi
|
|
if [ $ret -ne 0 ]; then
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# usage: install_pkgfile <packagesfile>
|
|
install_pkgfile ()
|
|
{
|
|
if [ -e "${1}" ]; then
|
|
toinstall=""
|
|
while read pkg; do
|
|
toinstall="${toinstall} ${pkg}"
|
|
done < ${1}
|
|
_pacman "${toinstall}"
|
|
else
|
|
echo "error: Package file '${1}' does not exist, aborting."
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# Go through the main commands in order. If 'all' was specified, then we want
|
|
# to do everything. Start with 'install'.
|
|
if [ "${command_name}" = "install" -o "${command_name}" = "all" ]; then
|
|
echo "====> Installing/building ISO root"
|
|
if [ -e "${work_dir}" -a "${FORCE}" = "n" ]; then
|
|
echo "error: Working dir '${work_dir}' already exists, aborting."
|
|
exit 1
|
|
fi
|
|
|
|
mkdir -p "${isoroot}"
|
|
mkdir -p "${instroot}"
|
|
|
|
echo "Installing packages..."
|
|
echo " Installing packages from '${PKGFILE}'"
|
|
install_pkgfile "${PKGFILE}"
|
|
|
|
for pkg in ${PKGLIST}; do
|
|
echo " Installing package '${pkg}'"
|
|
_pacman "${pkg}"
|
|
done
|
|
|
|
echo "Updating kernel module dependancies"
|
|
kernelver=$(_kversion)
|
|
depmod -a -b "${instroot}" -v "${kernelver}" -F "${instroot}/boot/System.map26" >/dev/null
|
|
# remove the initcpio images that were generated for the host system
|
|
find "${instroot}/boot" -name *.img -delete
|
|
|
|
echo "Applying default configuration for the Arch ISO"
|
|
cp -ra --remove-destination --no-preserve=ownership ${DEF_CONFIG_DIR}/* "${instroot}"
|
|
|
|
echo "Copyright (C) 2007, Arch Linux (Judd Vinet)" > "${instroot}/etc/copyright"
|
|
|
|
echo "Creating initial device nodes"
|
|
rm -f "${instroot}/dev/console" "${instroot}/dev/null" "${instroot}/dev/zero"
|
|
mknod -m 644 "${instroot}/dev/console" c 5 1
|
|
mknod -m 666 "${instroot}/dev/null" c 1 3
|
|
mknod -m 666 "${instroot}/dev/zero" c 1 5
|
|
|
|
echo "Creating default home directory"
|
|
install -d -o1000 -g100 -m0755 "${instroot}/home/arch"
|
|
|
|
# Cleanup
|
|
echo "Cleaning up ISO root files..."
|
|
find "${instroot}" -name *.pacnew -name *.pacsave -name *.pacorig -delete
|
|
|
|
# delete a lot of unnecessary cache/log files
|
|
kill_dirs="var/abs var/cache/man var/cache/pacman var/log/* var/mail tmp/* usr/include initrd"
|
|
for x in ${kill_dirs}; do
|
|
if [ -e "${instroot}/${x}" ]; then
|
|
rm -rf "${instroot}/${x}"
|
|
fi
|
|
done
|
|
|
|
# delete static libraries
|
|
find "${instroot}/lib" -name *.a -delete
|
|
find "${instroot}/usr/lib" -name *.a -delete
|
|
|
|
# pacman DBs are big, delete all sync dbs
|
|
for d in ${instroot}/var/lib/pacman/*; do
|
|
[ "$(basename ${d})" != "local" ] && rm -rf "${d}"
|
|
done
|
|
|
|
if [ -e "${instroot}/boot" ]; then
|
|
rm -rf "${isoroot}/boot"
|
|
mv "${instroot}/boot" "${isoroot}"
|
|
fi
|
|
|
|
# TODO: this might belong somewhere else
|
|
if [ -d "${ADDON_DIR}" ]; then
|
|
echo "Copying addons from ${ADDON_DIR}..."
|
|
cp -r ${ADDON_DIR} ${isoroot}/addons
|
|
fi
|
|
fi
|
|
|
|
# Squash is the next step.
|
|
if [ "${command_name}" = "squash" -o "${command_name}" = "all" ]; then
|
|
echo "====> Generating SquashFS image"
|
|
imagename="${isoroot}/archlive.sqfs"
|
|
if [ -e "${imagename}" ]; then
|
|
if [ "${FORCE}" = "y" ]; then
|
|
echo -n "Removing old SquashFS image..."
|
|
rm "${imagename}"
|
|
echo "done."
|
|
else
|
|
echo "error: SquashFS image '${imagename}' already exists, aborting."
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
echo "Creating squashfs image. This may take some time..."
|
|
start=$(date +%s)
|
|
if [ "${QUIET}" = "y" ]; then
|
|
mksquashfs "${instroot}" "${imagename}" >/dev/null
|
|
else
|
|
mksquashfs "${instroot}" "${imagename}"
|
|
fi
|
|
minutes=$(echo $start $(date +%s) | awk '{ printf "%0.2f",($2-$1)/60 }')
|
|
echo "Image creation done in $minutes minutes."
|
|
fi
|
|
|
|
# Finally, make the iso.
|
|
if [ "${command_name}" = "iso" -o "${command_name}" = "all" ]; then
|
|
echo "====> Making ISO image"
|
|
[ "x${isoname}" = "x" ] && (echo "ISO image name must be specified" && usage 1)
|
|
if [ -e "${isoname}" ]; then
|
|
if [ "${FORCE}" = "y" ]; then
|
|
echo "Removing existing ISO image..."
|
|
rm -rf "${isoname}"
|
|
else
|
|
echo "error: ISO image '${isoname}' already exists, aborting."
|
|
exit 1
|
|
fi
|
|
fi
|
|
if [ ! -e "${CPIOCONFIG}" ]; then
|
|
echo "error: mkinitcpio config '${CPIOCONFIG}' does not exist, aborting."
|
|
exit 1
|
|
fi
|
|
|
|
kernelver=$(_kversion)
|
|
basedir=${instroot}
|
|
[ "${instroot:0:1}" != "/" ] && basedir="$(pwd)/${instroot}"
|
|
echo "Generating initcpio for ISO..."
|
|
if [ "${QUIET}" = "y" ]; then
|
|
mkinitcpio -c "${CPIOCONFIG}" -b "${basedir}" -k "${kernelver}" -g "${isoroot}/boot/archlive.img" >/dev/null
|
|
ret=$?
|
|
else
|
|
mkinitcpio -c "${CPIOCONFIG}" -b "${basedir}" -k "${kernelver}" -g "${isoroot}/boot/archlive.img"
|
|
ret=$?
|
|
fi
|
|
if [ $ret -ne 0 ]; then
|
|
echo "error: initcpio image creation failed..."
|
|
exit 1
|
|
fi
|
|
|
|
cp ${instroot}/usr/lib/grub/i386-pc/* "${isoroot}/boot/grub"
|
|
|
|
echo "Creating ISO image..."
|
|
q=""
|
|
[ "${QUIET}" = "y" ] && qflag="-q"
|
|
mkisofs ${qflag} -r -l -b "boot/grub/stage2_eltorito" -uid 0 -gid 0 -no-emul-boot \
|
|
-boot-load-size 4 -boot-info-table -publisher "Arch Linux <archlinux.org>" \
|
|
-input-charset=UTF-8 -p "prepared by $NAME" -A "Arch Linux Live/Rescue CD" \
|
|
-copyright /etc/copyright -o "${isoname}" "${isoroot}"
|
|
fi
|
|
|
|
# vim:ts=4:sw=4:et:
|