X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=build.common;h=622bd8005fa5cb3b0d89b847d1947fafb777fc8e;hb=refs%2Fheads%2Flxc_devel;hp=2c4ccb1873bb360850196a1594d22fd3de3e1d42;hpb=6b63eb793c2275be559a7e6f8c1a100a422b020d;p=build.git diff --git a/build.common b/build.common index 2c4ccb18..622bd800 100644 --- a/build.common +++ b/build.common @@ -6,63 +6,55 @@ # Marc E. Fiuczynski # Copyright (C) 2007 The Trustees of Princeton University # -# $Id$ +# supported distros f8, f10, f12, centos5 # +# for locating pkgs.py +export PATH=.:$PATH -function pl_getDefaultDistro() { - # FC4 is currently the default release - echo "Fedora" - return 0 -} - -function pl_getDefaultRelease() { - # FC4 is currently the default release - echo "4" - return 0 -} - +# returns 'Fedora' or 'CentOS' for now function pl_getDistro() { - defaultDistro=$(pl_getDefaultDistro) if [ -f "/etc/redhat-release" ] ; then distro=$(awk ' { print $1 } ' /etc/redhat-release) + case $distro in Scientific*) distro="SL" ; esac else - distro=$defaultDistro + echo "build.common.pl_getDistro-unknown" + exit 1 fi echo "$distro" return 0 } +# returns something like 8, 10, or 5.3 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 + release=$(awk ' { if ($1=="Fedora" && $2=="Core") print $4 ; if (($1=="Fedora" && $2!="Core")||$1=="CentOS") print $3 ; if ($1=="Scientific") print $4 } ' /etc/redhat-release) else - release=$defaultRelease + echo "build.common.pl_getRelease-unknown" + exit 1 fi - echo "$release" + # keep only the major number + echo "$release" | cut -d. -f1 return 0 } -# vserver expects something like fc4 or f7 -# for fedora and centos only for now +# returns stuff for vserver, i.e. something like 'f8' or 'centos5' 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 ;; + releasename=f$release + ;; [Cc]entOS*) - if [ "$release" = "4.5" ] ; then - # centos 4.5 is just centos4 + enhancements - releasename=centos4 - else - releasename=centos$release - fi ;; + old_IFS="$IFS" + IFS="." + set -- $release + IFS="$old_IFS" + releasename=centos$1 + ;; + [Ss]L*) + releasename=sl$release + ;; *) releasename="unknown-name-for-${pl_DISTRO}-please-edit-build.common" echo 1>&2 "build.common: WARNING - releasename not set for distro=$distro" @@ -73,6 +65,28 @@ function pl_getReleaseName () { return 0 } +# on fedora 8 or above, we use libnl from the stock repos +# on centos5 we build it locally +function pl_getKexcludes () { + distroname=$1; shift + case $distroname in + # when using k27, we need our own flavour of iproute + # for now we build only for k32, regardless of fcdistro + f8) + echo 'kernel* util-vserver* iptables iptables-ipv6 drupal' ;; + f16) + echo 'drupal' ;; + f*) + echo 'util-vserver* drupal' ;; + centos5) + echo 'kernel kernel-vserver kernel-devel kernel-headers kernel-debuginfo util-vserver* iptables drupal inotify-tools* libnl' ;; + sl*) + echo 'kernel kernel-debug kernel-debug-devel kernel-devel kernel-doc kernel-firmware kernel-headers iptables' ;; + *) + echo "pl_DISTRO_NAME=$pl_DISTRO_NAME not supported in getexcludes.sh" ; exit 1 ;; + esac +} + # figure out which redhat distro we are using (fedora, centos, redhat) pl_DISTRO=$(pl_getDistro) @@ -82,12 +96,15 @@ pl_DISTRO_ARCH=$(uname -i 2>/dev/null|| echo unknownarch) # the release number (plain number) pl_DISTRO_RELEASE=$(pl_getRelease) -# the release name - for vserver build - like fc4, f8 or centos4 +# the release name - for vserver build ... pl_DISTRO_NAME=$(pl_getReleaseName $pl_DISTRO $pl_DISTRO_RELEASE) +# the packages to exclude +pl_KEXCLUDES=$(pl_getKexcludes $pl_DISTRO_NAME) + # get path to appropriate yumgroups.xml file # Thierry: quick & dirty improvement -# this file is updated by the toplevel build, from groups/.xml +# this file is updated by the toplevel build, from the .pkgs files pl_DISTRO_YUMGROUPS="../../../RPMS/yumgroups.xml" function pl_process_fedora_options () { @@ -163,7 +180,7 @@ function pl_root_makedevs() { mknod -m 600 $vroot/dev/net/tun c 10 200 # For mkinitrd (in case a kernel is being installed) - # As well for loop back mounting within a vserver. + # As well as for loop back mounting within a vserver. for i in $(seq 0 255) ; do mknod -m 640 $vroot/dev/loop$i b 7 $i done @@ -198,25 +215,10 @@ function pl_root_mkfedora () { basearch=$pl_DISTRO_ARCH # Get options - mirrors="" - while getopts "l:r:a:vh" opt ; do + while getopts "vh" opt ; do case $opt in - l) - mirrors="$mirrors $OPTARG" - ;; - r) - releasever=$OPTARG - ;; - a) - basearch=$OPTARG - ;; - v) - verbose=1 - set -x - ;; - h|*) - mkfedora_usage - ;; + v) verbose=1; set -x ;; + h|*) mkfedora_usage ;; esac done @@ -233,75 +235,38 @@ function pl_root_mkfedora () { fcdistro=${pl_DISTRO_NAME} pkgs_packages=$(pl_parsePkgs package $fcdistro $pldistro $pkgsfile) pkgs_groups=$(pl_parsePkgs group $fcdistro $pldistro $pkgsfile) - # packages to exclude - obsolete, was maybe useful when installing a group - pkgs_excludes=$(pl_parsePkgs exclude $fcdistro $pldistro $pkgsfile) + # what can get trashed to save space pkgs_junk=$(pl_parsePkgs junk $fcdistro $pldistro $pkgsfile) + # but not this pkgs_precious=$(pl_parsePkgs precious $fcdistro $pldistro $pkgsfile) - # formerly related to mkfedora -k - pkgs_kexcludes=$(pl_parsePkgs kexclude $fcdistro $pldistro $pkgsfile) + # formerly related to mkfedora -k : packages to take from our own build + # and thus need be excluded frem the stock repos + pkgs_kexcludes=$(pl_parsePkgs kexclude $fcdistro $pldistro $pkgsfile | sed -e s,@KEXCLUDE@,"$pl_KEXCLUDES",) # get mirrors if not specified with -l if [ -z "$mirrors" ] ; then mirrorsfile=$(pl_locateDistroFile ../build/ $pldistro "$pldistro.mirrors") mirrors=$(pl_parsePkgs mirror $fcdistro $pldistro $mirrorsfile) fi - exclude_kernel="" - [ -n "$pkgs_kexcludes" ] && exclude_kernel="exclude=$pkgs_kexcludes" - - 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 + kexclude_line="" + [ -n "$pkgs_kexcludes" ] && kexclude_line="exclude=$pkgs_kexcludes" 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" + # the repo part of the final yum.conf + yum_conf_repos=$vroot/xxxmkfedora-repos.confxxx + if ! yumconf_mirrors $yum_conf_repos ../build/ $fcdistro "$kexclude_line" $mirrors ; then + echo xxx -- error ; return 1 fi - + # Do not tolerate errors set -e + public_gpg_key=$(yumconf_gpgkey $yum_conf_repos) + ## 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' @@ -352,22 +317,20 @@ EOF # 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 + rpm --root $vroot --import $public_gpg_key # 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 < $yum_conf <>$vroot/etc/yum.conf <> $yum_conf # If we are being built as part of an automated RPM build, solve the # bootstrap problem by including any just built packages in the yum @@ -413,29 +354,36 @@ EOF if [ -n "$SUDO_USER" ] ; then chown -R $SUDO_USER $RPM_RPMS_DIR fi - cat >>$vroot/etc/yum.conf <> $yum_conf < /dev/null && yum_options="$yum_options --verbose" + yum_options="$yum_options -y" + yum_options="$yum_options -c $yum_conf" + yum_options="$yum_options --installroot=$vroot" # glibc must be specified explicitly for the correct arch to be # chosen. echo "* Installing glibc" - yum -c $vroot/etc/yum.conf --installroot=$vroot -y $exclude_arg install glibc + # ignore yum's return code that is basically undefined + yum $yum_options install glibc || : # Go, baby, go if [ -n "$pkgs_packages" ] ; then echo "* Installing optional packages" $pkgs_packages - yum -c $vroot/etc/yum.conf --installroot=$vroot -y $exclude_arg \ - install $pkgs_packages + # ignore yum's return code that is basically undefined + echo "* Install options" $vroot $yum_options + yum $yum_options install $pkgs_packages || : if ! rpm --root $vroot -q $pkgs_packages >/dev/null ; then echo "* Warning: Missing packages" rpm --root $vroot -q $pkgs_packages | grep "not installed" @@ -444,10 +392,11 @@ fi if [ -n "$pkgs_groups" ] ; then ## call yum sequentially to get finer-grained info on dependencies - for grp in $pkgs_groups ; do - echo "* Installing optional group $grp" - yum -c $vroot/etc/yum.conf --installroot=$vroot -y $exclude_arg \ - groupinstall "$grp" + for group_plus in $pkgs_groups ; do + group=$(echo $group_plus | sed -e "s,+++, ,g") + echo "* Installing optional group $group" + # ignore yum's return code that is basically undefined + yum $yum_options groupinstall "$group" || : done fi @@ -466,7 +415,25 @@ fi # Clean yum cache echo "* Cleaning up" - yum -c $vroot/etc/yum.conf --installroot=$vroot -y clean all + + # NOTE: this hack is for Fedora >= 12. + # if kernel-debug is installed, clean it up + # we link to our version of kernel/initrd and clean up + # kernel-debug manually + if rpm --root $vroot --quiet -q kernel-debug ; then + echo "* Cleaning up kernel-debug - (workaround for f12)" + pushd $vroot/boot/ + rm -rf kernel-boot kernel-bootsmp initrd-boot initrd-bootsmp + ln -s vmlinuz-*${pldistro}* kernel-boot + ln -s vmlinuz-*${pldistro}* kernel-bootsmp + ln -s initrd-*${pldistro}* initrd-boot + ln -s initrd-*${pldistro}* initrd-bootsmp + rpm --root $vroot --nodeps -e kernel-debug || : + popd + fi + + # ignore yum's return code that is basically undefined + yum $yum_options clean all || : # Clean RPM state rm -f $vroot/var/lib/rpm/__db* @@ -477,6 +444,9 @@ fi ln -s /usr/share/zoneinfo/UTC $vroot/etc/localtime fi + echo "Dumping current list of rpms in /etc/mkfedora-rpms.txt" + chroot $vroot rpm -aq | sort > $vroot/etc/mkfedora-rpms.txt + # remove trap handler, as we are about to call it directly. trap - ERR INT @@ -569,14 +539,24 @@ function pl_fixdirs() { } ########## .pkgs format -# comments start with a # - this is needed only if you use a keyword in a comment +# Usage: pl_parsePkgs keyword [-a arch] fcdistro pldistro pkgs-file[..s] +# pkgs.py should be found in PATH, like this file build.common +function pl_parsePkgs () { + target_arch=$pl_DISTRO_ARCH + keyword=$1;shift + [ "$1" == "-a" ] && { shift; target_arch="$1"; shift; } + fcdistro=$1; shift + pldistro=$1; shift -function pl_getPkgsAttribute () { - keyword=$1; shift - file=$1; shift - grep -v '^#' $file | grep --regexp="^${keyword}:" | sed -e "s,${keyword}:,," + echo 1>&2 "pl_parsePkgs: using -a $target_arch -f $fcdistro -d $pldistro $keyword $@" + pkgs.py -a $target_arch -f $fcdistro -d $pldistro $keyword "$@" } +# usage: pl_getPackages [-a arch] fcdistro pldistro pkg-file[..s] +function pl_getPackages() { pl_parsePkgs package "$@" ; } +function pl_getGroups() { pl_parsePkgs group "$@" ; } +############################## +### temporary - only for checking the new python version # for a given keyword like 'package' : # we support fcdistro-dependant format, for tokens (pkgname) without whitespace # you can e.g. use @@ -586,9 +566,15 @@ function pl_getPkgsAttribute () { # # values can contain @arch@, @fcdistro@ or @pldistro@ that are replaced with the current values # -function pl_parsePkgs () { +# the reason for the -a option is for when we build the build vserver itself; in this case +# pl_DISTRO_ARCH is the one we obtain from the root context, and that's wrong +# specify -sa arch AFTER keyword, so as to keep pl_getPackages and pl_getGroups simple +# +function pl_parsePkgs_old () { + target_arch=$pl_DISTRO_ARCH keyword=$1;shift + [ "$1" == "-a" ] && { shift; target_arch="$1"; shift; } fcdistro=$1; shift pldistro=$1; shift # remaining arguments are paths to the pkgs files @@ -600,17 +586,15 @@ function pl_parsePkgs () { # grab exclusions sub=$(grep -v '^#' "$@" | grep --regexp="^${keyword}-${fcdistro}:" | sed -e "s,${keyword}-${fcdistro}:,,") - for i in $all $add; do + for rpm in $all $add; do for exclude in $sub; do - [ "$i" = "$exclude" ] && continue 2 + [ "$rpm" = "$exclude" ] && continue 2 done - echo "$i " | sed -e "s,@arch@,$pl_DISTRO_ARCH,g" -e "s,@fcdistro@,$fcdistro,g" -e "s,@pldistro@,$pldistro,g" + echo "${rpm} " | sed -e "s,@arch@,${target_arch},g" -e "s,@fcdistro@,$fcdistro,g" -e "s,@pldistro@,$pldistro,g" done return 0 } - -function pl_getPackages() { fcdistro=$1; shift ; pldistro=$1; shift ; pl_parsePkgs package $fcdistro $pldistro "$@" ; } -function pl_getGroups() { fcdistro=$1; shift ; pldistro=$1; shift ; pl_parsePkgs group $fcdistro $pldistro "$@" ; } +############################## # locates a pldistro-dependant file # tries first in build//, then in build/planetlab/ @@ -620,6 +604,14 @@ function pl_locateDistroFile () { pkgsfile=$1; shift pkgspath="" + # if config dir is missing but a .svnpath or a .gitpath exists, use it to extract the config dir + configdir="$builddir/config.${pldistro}" + if [ ! -d $configdir ] ; then + if [ -f "${configdir}.svnpath" -o -f "${configdir}.gitpath" ] ; then + echo 1>&2 "Invoking make to extract remote config.${pldistro}" + make 1>&2 --silent --no-print-directory -C $builddir stage1=true config.${pldistro} + fi + fi # locate it paths="$builddir/config.$pldistro/$pkgsfile $builddir/config.planetlab/$pkgsfile" for path in $paths; do @@ -640,14 +632,13 @@ function pl_locateDistroFile () { fi } -# experimental function yumgroups_from_pkgs () { builddir=$1; shift pldistro=$1; shift fcdistro=$1; shift pkgsnames=$@ -sedargs="-e s,@FCDISTRO@,$fcdistro,g" + sedargs="-e s,@FCDISTRO@,$fcdistro,g" cat <<__header @@ -659,8 +650,8 @@ __header pkgsfile=$(pl_locateDistroFile $builddir $pldistro $pkgsname) packages=$(pl_getPackages $fcdistro $pldistro $pkgsfile) - groupname=$(pl_getPkgsAttribute groupname $pkgsfile | sed $sedargs) - groupdesc=$(pl_getPkgsAttribute groupdesc $pkgsfile | sed $sedargs) + groupname=$(pkgs.py groupname $pkgsfile | sed $sedargs) + groupdesc=$(pkgs.py groupdesc $pkgsfile | sed $sedargs) if [ -z "$groupname" -o -z "$groupdesc" ] ; then echo "Cannot find groupname: and groupdesc: in $pkgsfile -- skipped" 1>&2 @@ -671,9 +662,8 @@ __header $(echo $groupname|tr A-Z a-z) $groupname - true $groupdesc - false + true __group_header for package in $packages; do @@ -688,3 +678,89 @@ cat <<__footer __footer } + + +function build_fetch () { + curl --fail --silent --max-time 60 --output /dev/null "$1" +} + +# tries to compute a valid yum.conf for that pldistro from the template in mirroring/ +# returns 0 and writes on success +# returns 1 on failure, in which case is deleted +function yumconf_mirrors () { + dest_yumconf=$1; shift + builddir=$1; shift + fcdistro=$1; shift + kexclude_line="$1" ; shift + mirrors="$@" + + template=$builddir/mirroring/$fcdistro/yum.repos.d/building.repo.in + + if [ ! -f $template ] ; then + echo "yumconf_mirrors: cannot locate template $template" + rm -f $dest_yumconf + return 1 + fi + + for mirror in $mirrors; do + if yumconf_mirror $dest_yumconf $template "$kexclude_line" $mirror; then + return 0 + fi + done + echo 'yumconf_mirrors in build.common : ran out of mirrors -- BAILING OUT' + rm -f $dest_yumconf + return 1 +} + +# computes a yum.conf from the template, and checks that all baseurl defined in there are valid repos +# returns 0 on success and 1 on failure +function yumconf_mirror () { + dest_yumconf=$1; shift + template=$1; shift + kexclude_line="$1" ; shift + mirror=$1; shift + + sed -e "s,@MIRRORURL@,$mirror,g" \ + -e "/baseurl=/i\\ +$kexclude_line" $template > $dest_yumconf + + # capture all lines defining baseurl + baseurl_defs=$(grep '^baseurl=' $dest_yumconf) + if [ -z "$baseurl_defs" ] ; then + return 1 + fi + + for baseurl_def in $baseurl_defs; do + baseurl=$(echo $baseurl_def | sed \ + -e s,baseurl=,, \ + -e 's,$basearch,'"$pl_DISTRO_ARCH",g) + repomd=$baseurl/repodata/repomd.xml + + echo "* Trying to fetch $repomd" + if ! build_fetch $repomd ; then + echo "* Failed to fetch $repomd" + return 1 + fi + done + echo "* Selected mirror $mirror" + return 0 +} + +# from a yum.conf as generated above, computes the gpgkey urls +function yumconf_gpgkey () { + dest_yumconf=$1; shift + + values=$(grep -h '^gpgkey=' $dest_yumconf | sed -e s,gpgkey=,, | sed -e 's,$basearch,'"$pl_DISTRO_ARCH",g | sed -e 's, ,\n,g' | sort | uniq | xargs) + [ -n "$values" ] || return 1 + echo $values + return 0 +} + +# patches a yum conf to insert an exclude line in each declared repo +function yumconf_exclude () { + repo=$1; shift + kexclude_line="$1" ; shift + + sed -i -e "/#baseurl=.*$/i\\ +$kexclude_line" $repo +}