#!/bin/bash # $Id$ TOOLCHAIN="" BASESYSTEM="" PROFILE="" MROOT="" ABORT_AFTER_STAGE1=false MY_MAGEDIR="" MY_PKGDIR="" MAGEUPDATE=true MAGEUPDATETARBALL=false die() { echo "ERROR: $@" trap_exit exit 1 } read_magerc() { local var="$1" local magerc="$2" local value # local all possible vars of a magerc file # to prevent bad issues local PKGDIR local BUILDDIR local INSTALLDB local MAGEDIR local MLIBDIR local VIRTUALDB_DEFAULTS local VIRTUALDB_FILE local SOURCEDIR local BINDIR local SMAGESCRIPTSDIR local MROOT local PKGSUFFIX local VERBOSE local MAGEDEBUG local ARCH local MAGE_UNINSTALL_TIMEOUT local CHOST local CFLAGS local CXXFLAGS local SMAGE_USE_CCACHE local SMAGE_USE_DISTCC local MAKEOPTS local DISTCC_HOSTS local DISTCC_DIR local DISTCC_VERBOSE local DISTCC_LOG local MIRRORS local RSYNC local SMAGE2RSYNC # sanity checks [ -f /etc/mage.rc.global ] && source /etc/mage.rc.global || \ die "get_value_from_magefile: /etc/mage.rc.global not found." [ -f ${magerc} ] && source ${magerc} || \ die "get_value_from_magefile: ${magerc} not found." [ -z "${var}" ] && die "get_value_from_magefile: \$var not given." source ${magerc} eval value=\$$(echo ${var}) echo "${value}" } add_initrc() { local var="$1" # sanity checks [ -z "${MROOT}" ] && die "\$MROOT not given." echo "${var}" >> ${MROOT}/.installrc || die "add_initrc() adding \$var" } enter_chroot() { mount -t proc proc ${MROOT}/proc || die "mount proc" mount -t sysfs sysfs ${MROOT}/sys || die "mount sys" mount -o bind /dev ${MROOT}/dev || die "mount dev" chroot ${MROOT} /bin/bash -i /.installrc || die "chr00ting" umount ${MROOT}/dev ${MROOT}/sys ${MROOT}/proc || die "mount proc/sys/dev" [ -f ${MROOT}/.installrc ] && rm ${MROOT}/.installrc } is_loc_mounted() { local filesys local i filesys=$1 i="$(cat /proc/mounts | grep " ${filesys} " | cut -d ' ' -f2)" [[ ${i} != ${filesys} ]] && return 1 return 0 } trap_exit() { is_loc_mounted "${MROOT}/dev" && umount ${MROOT}/dev is_loc_mounted "${MROOT}/proc" && umount ${MROOT}/proc is_loc_mounted "${MROOT}/sys" && umount ${MROOT}/sys is_loc_mounted "${MY_MAGEDIR}" && umount ${MY_MAGEDIR} is_loc_mounted "${MY_PKGDIR}" && umount ${MY_PKGDIR} echo "bootstrap aborted" exit 1 } print_usage() { echo "mage-bootstrap, version @VERSION@" echo "Usage: $(basename $0) --opt arg ..." echo echo "Options:" echo " --profile, -p -- select a profile (needed)" echo " --root, -r -- location to new root (needed)" echo " --magerc, -m -- location of mage.rc (needed)" echo echo " --toolchain, -t -- select other toolchain than from profile" echo " --basesystem, -b -- select other basesystem than from profile" echo " --stage1, -s1 -- if set, abort after stage1 (toolchain)" echo " --update-tarball, -ut -- update via tarball not rsync" echo " --no-update, -u -- do not update the mage tree" echo " --help, -h -- prints this help" echo exit 1 } # set some proper traps trap "trap_exit" SIGINT SIGQUIT # show usage if no opts given [[ -z $* ]] && print_usage # very basic getops for i in $* do case $1 in --toolchain|-t) shift; TOOLCHAIN="$1" ;; --basesystem|-b) shift; BASESYSTEM="$1" ;; --profile|-p) shift; PROFILE="$1" ;; --root|-r) shift; MROOT="$1" ;; --stage1|-s1) ABORT_AFTER_STAGE1=true ;; --magerc|-m) shift; MAGERC="$1" ;; --update-tarball|-ut) MAGEUPDATETARBALL=true ;; --no-update|-u) MAGEUPDATE=false ;; --help|-h) print_usage ;; '') shift;; *) echo "Unkown option '$1', use --help or -h to get more info."; exit 1 ;; esac shift done # sanity checks; abort if not given [ -z "${MROOT}" ] && die "\$MROOT not given." [ -z "${MAGERC}" ] && die "\$MAGERC not given." [ -z "${PROFILE}" ] && die "\$PROFILE not given." # they may be empty, they are included in the profile [ -z "${TOOLCHAIN}" ] && echo "\$TOOLCHAIN not given, using toolchain from profile." [[ ${ABORT_AFTER_STAGE1} = false ]] && [ -z "${BASESYSTEM}" ] \ && echo "\$BASESYSTEM not given, using basesystem from profile." # check needed global commands, dirs and files [ ! -d /usr/mage ] && die "/usr/mage does not exists" [ ! -x /sbin/mage ] && die "'/sbin/mage' not found. Please install '>= app-mage/mage-0.4' first." [ ! -x /bin/mount ] && die "'/bin/mount' not found. Please install '>= sys-apps/util-linux' first." [ ! -f ${MAGERC} ] && die "Please setup your mage.rc first." [ ! -f /etc/resolv.conf ] && die "/etc/resolv.conf missing. Please setup your networking first." # install fake-root if not exist [ ! -d ${MROOT} ] && { install -d ${MROOT} || die "create fakedir"; } # create a fake dirs and mount them to / of the host system MY_MAGEDIR="$(read_magerc MAGEDIR ${MAGERC})" MY_PKGDIR="$(read_magerc PKGDIR ${MAGERC})" install -d ${MROOT}/${MY_MAGEDIR} || die "create magedir" install -d ${MROOT}/${MY_PKGDIR} || die "create pkgdir" mount -o bind ${MROOT}/${MY_MAGEDIR} ${MY_MAGEDIR} || die "mount magedir" mount -o bind ${MROOT}/${MY_PKGDIR} ${MY_PKGDIR} || die "mount pkgdir" # link to the right profile ln -snf ${MY_MAGEDIR}/profiles/${PROFILE} /etc/mage-profile || die "link profile" # update mage tree if [[ ${MAGEUPDATE} = true ]] then if [[ ${MAGEUPDATETARBALL} = true ]] then MAGERC="${MAGERC}" mage update-tarball || die "update mage-tree" else MAGERC="${MAGERC}" mage update || die "update mage-tree" fi fi # now get the toolchain and the basesystem layout file # [ -z "${TOOLCHAIN}" ] && TOOLCHAIN="toolchain.defaults" # [ -z "${BASESYSTEM}" ] && BASESYSTEM="basesystem.defaults" # # read them # TOOLCHAIN="$(< /etc/mage-profile/${TOOLCHAIN})" # BASESYSTEM="$(< /etc/mage-profile/${BASESYSTEM})" # this way toolchain and basesystem can be packages; # only if nothing set the layout files from the profile will be taken [ -z "${TOOLCHAIN}" ] && TOOLCHAIN="$(< ${MY_MAGEDIR}/profiles/${PROFILE}/toolchain.defaults)" [ -z "${BASESYSTEM}" ] && BASESYSTEM="$(< ${MY_MAGEDIR}/profiles/${PROFILE}/basesystem.defaults)" # install toolchain if ! MROOT="${MROOT}" MAGERC="${MAGERC}" magequery -n ${TOOLCHAIN} then CONFIG_PROTECT="-*" MROOT="${MROOT}" MAGERC="${MAGERC}" mage install ${TOOLCHAIN} || die "toolchain install" fi # umount dirs, they are not needed anymore umount ${MY_MAGEDIR} ${MY_PKGDIR} || die "umount mage/pkgdir" # copy some needed files to the fake-root install -m 0644 ${MAGERC} ${MROOT}/etc/mage.rc || die "install mage.rc" install -m 0644 /etc/resolv.conf ${MROOT}/etc/resolv.conf || die "install resolv.conf" # abort if wanted if [[ ${ABORT_AFTER_STAGE1} = true ]] then echo "Stage1 complete; user requested to abort after this step." echo "Exiting ..." exit 0 fi # now create an initrc for the installation of the basesystem :> ${MROOT}/.installrc add_initrc "export MAGE_BOOTSTRAP=true" add_initrc "export HOME=/root" add_initrc "export PATH=/bin:/usr/bin:/sbin:/usr/sbin" add_initrc "export BASESYSTEM=${BASESYSTEM}" add_initrc "export PROFILE=${PROFILE}" add_initrc "export CONFIG_PROTECT=-*" add_initrc "export MY_MAGEDIR=${MY_MAGEDIR}" # add proxies if defined [[ -n ${http_proxy} ]] && add_initrc "export http_proxy=${http_proxy}" [[ -n ${ftp_proxy} ]] && add_initrc "export ftp_proxy=${ftp_proxy}" [[ -n ${no_proxy} ]] && add_initrc "export no_proxy=${no_proxy}" [[ -n ${RSYNC_PROXY} ]] && add_initrc "export RSYNC_PROXY=${RSYNC_PROXY}" # install comands add_initrc "ln -snf ${MY_MAGEDIR}/profiles/${PROFILE} /etc/mage-profile" add_initrc "mage install ${BASESYSTEM}" add_initrc "mage clean" # chroot the toolchain enter_chroot echo "System bootstrap to '${MROOT}' finished." exit 0