X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=build.common;h=983ed75a058c343d5586ed5f1d3d27fec43717fe;hb=609197895d9d77a009fc6c24b0c920cb27fe0b48;hp=7d20d75a5591b23d3c7e47ebed76f1ef8f35ec61;hpb=1890937f0931d7ccf1356472ea78c518c070ce89;p=build.git diff --git a/build.common b/build.common index 7d20d75a..983ed75a 100644 --- a/build.common +++ b/build.common @@ -6,39 +6,92 @@ # Marc E. Fiuczynski # Copyright (C) 2007 The Trustees of Princeton University # -# $Id: build.common,v 1.2 2007/08/31 02:20:54 mef Exp $ +# $Id$ # -function pl_getDefaultFedoraRelease() { +function pl_getDefaultDistro() { # FC4 is currently the default release - return 4 + echo "Fedora" + return 0 } -function pl_getFedoraRelease() { - pl_getDefaultFedoraRelease - defaultFedoraRelease=$? - if [ -f "/etc/fedora-release" ] ; then - fedoraRelease=$(awk ' { if ($2=="Core") print $4; else print $3 } ' /etc/fedora-release) - [ $fedoraRelease -lt $defaultFedoraRelease ] && fedoraRelease=$defaultFedoraRelease +function pl_getDefaultRelease() { + # FC4 is currently the default release + echo "4" + return 0 +} + +function pl_getDistro() { + defaultDistro=$(pl_getDefaultDistro) + if [ -f "/etc/redhat-release" ] ; then + distro=$(awk ' { print $1 } ' /etc/redhat-release) else - fedoraRelease=$defaultFedoraRelease + distro=$defaultDistro fi - return $fedoraRelease + echo "$distro" + return 0 +} + +function pl_getRelease() { + defaultRelease=$(pl_getDefaultRelease) + if [ -f "/etc/redhat-release" ] ; then + release=$(awk ' { if ($1=="Fedora" && $2=="Core") print $4 ; if (($1=="Fedora" && $2!="Core")||$1=="CentOS") print $3 } ' /etc/redhat-release) + [ $release -lt $defaultRelease ] && release=$defaultRelease + else + release=$defaultRelease + fi + echo "$release" + return 0 +} + +# vserver expects something like fc4 or f7 +# for fedora and centos only for now +function pl_getReleaseName () { + distro=$1; shift + release=$1; shift + case $distro in + [Ff]edora*) + if [ "$release" -le 6 ] ; then + releasename=fc$release + else + releasename=f$release + fi ;; + [Cc]entOS*) + if [ "$release" = "4.5" ] ; then + # centos 4.5 is just centos4 + enhancements + releasename=centos4 + else + releasename=centos$release + fi ;; + *) + releasename="unknown-name-for-${pl_DISTRO}-please-edit-build.common" + echo 1>&2 "build.common: WARNING - releasename not set for distro=$distro" + return 1 + ;; + esac + echo "$releasename" + return 0 } -# select basearch of the host devel environment -pl_FEDORA_ARCH=$(uname -i) +# figure out which redhat distro we are using (fedora, centos, redhat) +pl_DISTRO=$(pl_getDistro) + +# select basearch of the host devel environment - protected for macos for local tests +pl_DISTRO_ARCH=$(uname -i 2>/dev/null|| echo unknownarch) # let mkfedora select one of its mirrors -pl_FEDORA_URL="" +pl_DISTRO_URL="" + +# the release number (plain number) +pl_DISTRO_RELEASE=$(pl_getRelease) -pl_getFedoraRelease -pl_FEDORA_RELEASE=$? +# the release name - for vserver build - like fc4, f8 or centos4 +pl_DISTRO_NAME=$(pl_getReleaseName $pl_DISTRO $pl_DISTRO_RELEASE) -# get patch to appropriate yumgroups.xml file -# XXX This path should be relative to PLDISTRO, as defined in -# build/Makefile -pl_YUMGROUPSXML="../build/groups/v4_yumgroups.xml" +# get path to appropriate yumgroups.xml file +# Thierry: quick & dirty improvement +# this file is updated by the toplevel build, from groups/.xml +pl_DISTRO_YUMGROUPS="../../../RPMS/yumgroups.xml" function pl_process_fedora_options () { # Get options @@ -46,22 +99,23 @@ function pl_process_fedora_options () { while getopts "l:r:a:h" opt ; do case $opt in l) - pl_FEDORA_URL=$OPTARG + pl_DISTRO_URL=$OPTARG let shiftcount=$shiftcount+2 ;; r) - pl_FEDORA_RELEASE=$OPTARG + pl_DISTRO_RELEASE=$OPTARG let shiftcount=$shiftcount+2 ;; a) - pl_FEDORA_ARCH=$OPTARG + pl_DISTRO_ARCH=$OPTARG let shiftcount=$shiftcount+2 ;; h|*) echo "Usage: $0 [OPTION]..." - echo " -l url Fedora mirror location (default: $pl_FEDORA_URL)" - echo " -r release Fedora release number (default: $pl_FEDORA_RELEASE)" - echo " -a arch Fedora architecture (default: $pl_FEDORA_ARCH)" + echo " -l url distro mirror location (default: $pl_DISTRO_URL)" + echo " -r release distro release number (default: $pl_DISTRO_RELEASE)" + echo " -a arch distro architecture (default: $pl_DISTRO_ARCH)" + echo "where distro can be either fedora, centos, or redhat" echo " -h This message" exit 1 ;; @@ -70,7 +124,17 @@ function pl_process_fedora_options () { return $shiftcount } -function pl_makedevs() { +######################################## handling a root image +function pl_root_rpm_macros () { + cat < $(pl_locateDistroFile ../build/ $OPTARG.mirrors))) + mirrors=(file://$OPTARG) + fi + ;; + r) + releasever=$OPTARG + ;; + a) + basearch=$OPTARG + ;; + g) + groups[${#groups[*]}]="$OPTARG" + ;; + p) + packages[${#packages[*]}]="$OPTARG" + ;; + x) + exclude[${#exclude[*]}]="$OPTARG" + ;; + f) + pkgsfile=$OPTARG + ;; + k) + exclude_kernel="exclude=kernel* ulogd iptables" + ;; + v) + verbose=1 + set -x + ;; + h|*) + mkfedora_usage + ;; + esac + done + + shift $(($OPTIND - 1)) + [[ -n "$@" ]] || mkfedora_usage + vroot=$1 ; shift + vroot=$(cd $vroot && pwd -P) + [[ -z "$@" ]] || mkfedora_usage + [ -d $vroot ] || mkfedora_usage + + function mkfedora_fetch () + { + curl --fail --silent --max-time 60 "$1" + } + + # set list of attempted locations according to releasever + if [ $releasever -ge 7 ] ; then + attempts=" +linux/releases/$releasever/Everything/$basearch/os +$releasever/Everything/$basearch/os +core/$releasever/Everything/$basearch/os +linux/core/$releasever/$basearch/os +" + else + attempts=" + linux/core/$releasever/$basearch/os + core/$releasever/$basearch/os + $releasever/$basearch/os + " + fi + + echo "$0: candidate mirrors" + for mirror in "${mirrors[@]}" ; do + echo "* candidate mirror $mirror" + done + baseurl="" + for mirror in "${mirrors[@]}" ; do + for attempt in $attempts; do + attempturl=$mirror/$attempt + if mkfedora_fetch $attempturl/repodata/repomd.xml >/dev/null ; then + baseurl=$attempturl + break 2 + fi + done + done + + if [ -z "$baseurl" ] ; then + echo "Error: $releasever/$basearch/os/repodata/repomd.xml" + echo " could not be found in any of the following locations:" + echo + for mirror in ${mirrors[@]} ; do + for attempt in $attempts ; do + echo $mirror/$attempt + done + done + echo + mkfedora_usage + else + echo "* selecting mirror with baseurl=$baseurl" + fi + + # Do not tolerate errors + set -e + + ## make rpms ignore installing stuff to special fs entries like /proc + # Because of https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=52725 + # you have to use at least one language beside 'C' + # Prevent all locales from being installed in reference image + mkdir -p $vroot/etc/rpm + pl_root_rpm_macros > $vroot/etc/rpm/macros + + # Trick rpm and yum, who read the real root /etc/rpm/macros file + # rather than the one installed in the reference image, despite what + # you might expect the --root and --installroot options to mean. Both + # programs always read $HOME/.rpmmacros. + export HOME=$vroot/tmp + mkdir -p $vroot/tmp + pl_root_rpm_macros > $vroot/tmp/.rpmmacros + + function mkfedora_cleanup () { + umount -l $vroot/proc + umount -l $vroot/dev/shm + umount -l $vroot/dev/pts + } + + # Clean up before exiting if anything goes wrong + trap "mkfedora_cleanup" ERR INT + + # Mount in reference image + mount -t devpts none $vroot/dev/pts + mount -t tmpfs none $vroot/dev/shm + mkdir -p $vroot/proc + mount -t proc none $vroot/proc + + # Create a /var/lib dirs for yum & rpm + mkdir -p $vroot/var/lib/yum + mkdir -p $vroot/var/lib/rpm + mkdir -p $vroot/usr/share/info + + # Create a dummy /etc/fstab in reference image + mkdir -p $vroot/etc + cat >$vroot/etc/fstab < $vroot/etc/sysconfig/network + + # Initialize RPM database in reference image + mkdir -p $vroot/var/lib/rpm + rpm --root $vroot --initdb + rpm --root $vroot --import $baseurl/RPM-GPG-KEY-fedora + + # Initialize yum in reference image + mkdir -p $vroot/var/cache/yum $vroot/var/log + if [ $releasever -lt 7 ] ; then + corename="Core " + else + corename="" + fi + + cat >$vroot/etc/yum.conf <>$vroot/etc/yum.conf <>$vroot/etc/yum.conf </dev/null ; then + echo "* Warning: Missing packages" + rpm --root $vroot -q "${packages[@]}" | grep "not installed" + fi + fi + + if [ ${#groups[*]} -gt 0 ] ; then + ## call yum sequentially to get finer-grained info on dependencies + for grp in "${groups[@]}" ; do + echo "* Installing optional group $grp" + yum -c $vroot/etc/yum.conf --installroot=$vroot -y $excludes \ + groupinstall "$grp" + done + fi + + # formerly in bootcd/prep.sh : to optimize footprint + echo "* Removing unnecessary junk" + + pushd $vroot + + # Save precious files + [ -n "$precious" ] && tar --ignore-failed-read -cpf precious.tar $precious + + # Remove unnecessary junk + [ -n "$junk" ] && rm -rf $junk + + # Restore precious files + [ -n "$precious" ] && tar -xpf precious.tar && rm -f precious.tar + + popd + +### # FC2 dev %preinstall checks /proc/mounts to make sure that /dev is +### # not currently mounted as devfs. If it thinks it is, it will refuse +### # to install the package. On a modern system running udev that mounts +### # /dev as tmpfs, this check fails. Since we are installing into a +### # chroot, whether /dev is mounted on the host system or not doesn't +### # matter. If dev was explicitly mentioned in the packages list, force +### # its installation. +### if [ "$releasever" = "2" ] ; then +### for package in "${packages[@]}" ; do +### if [ "$package" = "dev" ] && ! rpm --root $vroot -q dev >/dev/null 2>&1 ; then +### rpm --root $vroot -Uvh --noscripts $baseurl/Fedora/RPMS/dev-3.3.13-1.i386.rpm +### break +### fi +### done +### fi + + # Clean yum cache + echo "* Cleaning up" + yum -c $vroot/etc/yum.conf --installroot=$vroot -y clean all + + # Clean RPM state + rm -f $vroot/var/lib/rpm/__db* + + # Set time zone to UTC + if [ -f $vroot/usr/share/zoneinfo/UTC -a -f $vroot/etc/localtime ] ; then + rm -f $vroot/etc/localtime + ln -s /usr/share/zoneinfo/UTC $vroot/etc/localtime + fi + + # remove trap handler, as we are about to call it directly. + trap - ERR INT + + # Clean up + mkfedora_cleanup + + return 0 } -function pl_setup_chroot() { - root=$1 - shift - options=$@ +function pl_root_setup_chroot() { + root=$1; shift + options="$@" - pl_mkfedora $root $options + pl_root_makedevs $root + pl_root_mkfedora $options $root # Disable all services in reference image chroot $root sh -c "/sbin/chkconfig --list | awk '{ print \$1 }' | xargs -i /sbin/chkconfig {} off" @@ -156,7 +609,7 @@ function pl_move_dirs() { fi rm -rf ${root}/${datadir} mkdir -p $(dirname ${root}/${datadir}) - ln -nsf /${store}/${datadir} ${root}/${datadir} + ln -nsf ${store}/${datadir} ${root}/${datadir} done } @@ -205,3 +658,123 @@ function pl_fixdirs() { done } +########## .pkgs format +# comments start with a # - this is needed only if you use a keyword in a comment + +function pl_getPkgsAttribute () { + keyword=$1; shift + file=$1; shift + grep -v '^#' $file | grep --regexp="^${keyword}:" | sed -e "s,${keyword}:,," +} + + +# for a given keyword like 'package' : +# we support fcdistro-dependant format, for tokens (pkgname) without whitespace +# you can e.g. use +# package: pkg1 .. pkgn +# package+f8: pkg1 .. pkgn +# package-f8: pkg1 .. pkgn + +function pl_parsePkgs () { + + keyword=$1;shift + fcdistro=$1; shift + # remaining arguments are paths to the pkgs files + + # grab regular descriptions + all=$(grep -v '^#' "$@" | grep --regexp="^${keyword}:" | sed -e "s,${keyword}:,,") + # grab additions + add=$(grep -v '^#' "$@" | grep --regexp="^${keyword}+${fcdistro}:" | sed -e "s,${keyword}+${fcdistro}:,,") + # grab exclusions + sub=$(grep -v '^#' "$@" | grep --regexp="^${keyword}-${fcdistro}:" | sed -e "s,${keyword}-${fcdistro}:,,") + + for i in $all $add; do + for exclude in $sub; do + [ "$i" = "$exclude" ] && continue 2 + done + echo "$i " + done + return 0 +} + +function pl_getPackages() { fcdistro=$1; shift ; pl_parsePkgs package $fcdistro "$@" ; } +function pl_getGroups() { fcdistro=$1; shift ; pl_parsePkgs group $fcdistro "$@" ; } + +# locates a pldistro-dependant file +# tries first in build//, then in build/planetlab/ +function pl_locateDistroFile () { + builddir=$1; shift + pldistro=$1; shift + pkgsfile=$1; shift + + pkgspath="" + # locate it + paths="$builddir/config.$pldistro/$pkgsfile $builddir/config.planetlab/$pkgsfile" + for path in $paths; do + if [ -f $path ] ; then + pkgspath=$path + break + fi + done + if [ -z "$pkgspath" ] ; then + echo 1>&2 "pl_locateDistroFile - in $(pwd) : cannot locate $pkgsfile in $builddir" + echo 1>&2 "candidates were $paths" + echo "not-found-by-pl_locateDistroFile" + return 1 + else + echo 1>&2 "pl_locateDistroFile: using $pkgspath" + echo $pkgspath + return 0 + fi +} + +# experimental +function yumgroups_from_pkgs () { + builddir=$1; shift + pldistro=$1; shift + fcdistro=$1; shift + pkgsnames=$@ + +sedargs="-e s,@FCDISTRO@,$fcdistro,g" + + cat <<__header + + + +__header + + for pkgsname in $pkgsnames; do + pkgsfile=$(pl_locateDistroFile $builddir $pldistro $pkgsname) + packages=$(pl_getPackages $fcdistro $pkgsfile) + + groupname=$(pl_getPkgsAttribute groupname $pkgsfile | sed $sedargs) + groupdesc=$(pl_getPkgsAttribute groupdesc $pkgsfile | sed $sedargs) + + if [ -z "$groupname" -o -z "$groupdesc" ] ; then + echo "Cannot find groupname: and groupdesc: in $pkgsfile -- skipped" 1>&2 + continue + fi + + cat << __group_header + + $(echo $groupname|tr A-Z a-z) + $groupname + true + $groupdesc + false + +__group_header + for package in $packages; do + echo "$package" + done + cat << __group_footer + + +__group_footer + done +cat <<__footer + +__footer +} + +