b20ac0164d
Purpose: Reduce build times after a repo sync by pulling in pre-generated srpms and rpms and other build products created by a local reference build. Usage: repo sync generate-cgcs-centos-repo.sh ... populate_downloads.sh ... build-pkgs --build-avoidance [--build-avoidance-user <user> \ --build-avoidance-host <addr> --build-avoidance-dir <dir>] Reference builds: - A server performs a regular (daily?), automated builds using existing methods. Call these the reference builds. - The builds are timestamped, and preserved for some time. (weeks?) The MY_WORKSPACE directory for the build shall have a common root directory, and a leaf directory that is a UTC time stamp of format YYYYMMDDThhmmssZ. e.g. MY_WORKSPACE=/localdisk/loadbuild/jenkins/StarlingX/20180719T113021Z Alternative formats are possible by setting values in ... "$MY_REPO/local-build-data/build_avoidance_source" e.g. BUILD_AVOIDANCE_DATE_FORMAT="%Y-%m-%d" BUILD_AVOIDANCE_TIME_FORMAT="%H-%M-%S" BUILD_AVOIDANCE_DATE_TIME_DELIM="_" BUILD_AVOIDANCE_DATE_TIME_POSTFIX="" BUILD_AVOIDANCE_DATE_UTC=0 Which results in YYYY-MM-DD_hh-mm-ss format using local time. The one property that the timestamp must have is that they are sortable, and that the reference build and the consumer of the reference builds agree on the format. - A build CONTEXT is captured, consisting of the SHA of each and every git that contributed to the build. - For each package built, a file shall capture he md5sums of all the source code inputs to the build of that package. - All these build products are accessible locally (e.g. a regional office) via rsync (other protocols can be added later). ssh is also required to run remote query commands on the reference build. Initial ground work to support a selection variable .... BUILD_AVOIDANCE_FILE_TRANSFER="my-transfer-protocol" in $MY_REPO/local-build-data/build_avoidance_source" has been created, but "rsync" is the only valid value at this time. - Location of the reference build can be specified via command line, or defaults can be put in $MY_REPO/local-build-data/build_avoidance_source. The local-build-data directory is gitignored by stx-root and so can be customized for local needs. e.g. cat $MY_REPO/local-build-data/build_avoidance_source BUILD_AVOIDANCE_USR="jenkins" BUILD_AVOIDANCE_HOST="stx-build-server.myco.com" BUILD_AVOIDANCE_DIR="/localdisk/loadbuild/jenkins/StarlingX" Notes: - Build avoidance is only used if requested. - Build avoidance does not necessarily use the latest reference build. It compares the git context of all available reference builds vs your own git context, and chooses the most recent for which you gits have all the conent. i.e. all your gits will be same or newer than that used by the reference build. This also meens that some packages might still need to be rebuilt after the download step. - Normally build avoidance remembers the last download context and will only consider reference builds newer than the last download. You can reset using 'build-pkgs --build-avoidance --clear' to erase the download history. When might this matter to me? If you change to an old branch that hasn't been synced recently and want to build in that context. - The primary assumtion of Build Avoidance is that it is faster to download packages than to build them. This is typically true of a good LAN, but likely not true of a WAN. This is why we emphasize the local nature of your reference build server. Also in this update: - reworked context generation to be relative to 'dirname $MY_REPO' - Moved md5sum calculation to a common file, and fixed case where symlinks where canonacalized to paths outside of $MY_REPO. We'll make an exception to canonacalization to keep paths relative to $MY_REPO. - In future other functions could be moved to the common file. Story: 2002835 Task: 22754 Change-Id: I757780190cc6063d0a2d3ad9d0a6020ab5169e99 Signed-off-by: Scott Little <scott.little@windriver.com>
2384 lines
71 KiB
Bash
Executable File
2384 lines
71 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
#
|
|
# Copyright (c) 2018 Wind River Systems, Inc.
|
|
#
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
#
|
|
|
|
#
|
|
# Builds rpm files from src.rpm files.
|
|
#
|
|
# This version compiles packages in parrallel if sufficient resources
|
|
# (cpu's and memory) are available.
|
|
#
|
|
# The location of packages to be built is
|
|
# $MY_WORKSPACE/<build-type>/rpmbuild/SRPMS.
|
|
#
|
|
# The build order is a derived from the BuildRequires in the
|
|
# spec files in the src.rpms. Note that the BuildRequires sometimes
|
|
# create dependency loops, so no correct order can be computed. In these
|
|
# cases we add a retry loop. As long as one new package builds, we
|
|
# keep retrying the loop, until all are built, or no progress is made.
|
|
# So please don't panic and CTRL-C just because you see a few error
|
|
# messages go by!
|
|
#
|
|
|
|
|
|
export ME=$(basename "$0")
|
|
CMDLINE="$ME $@"
|
|
|
|
|
|
|
|
# Build for distribution. Currently 'centos' is only supported value.
|
|
export DISTRO="centos"
|
|
|
|
# Maximum number of parallel build environments
|
|
ABSOLUTE_MAX_WORKERS=4
|
|
|
|
# Maximum space in gb for each tmpfs based parallel build environment.
|
|
# Note: currently 11 gb is sufficient to build everything except ceph
|
|
MAX_MEM_PER_WORKER=11
|
|
|
|
# Minimum space in gb for each tmpfs based parallel build environment
|
|
# Note: tmpfs is typically 2.5 gb when compiling many small jobs
|
|
MIN_MEM_PER_WORKER=3
|
|
|
|
# Maximum number of disk based parallel build environments
|
|
MAX_DISK_BASED_WORKERS=2
|
|
|
|
# Minimum space in gb for each disk based parallel build environment
|
|
MIN_DISK_PER_WORKER=20
|
|
|
|
# How many srpms to build before we add another parallel build environment
|
|
MIN_TASKS_PER_CORE=3
|
|
|
|
# Max number of new concurrent builds to allow for
|
|
MAX_SHARE_FACTOR=4
|
|
|
|
# Always leave at least MEMORY_RESERVE gb of available mem for the system
|
|
MEMORY_RESERVE=1
|
|
|
|
# These two values will be reassigned in the 'compute_resources' subroutine
|
|
MOCKCHAIN_RESOURCE_ALLOCATION=""
|
|
MAX_WORKERS=$ABSOLUTE_MAX_WORKERS
|
|
|
|
|
|
CREATEREPO=$(which createrepo_c)
|
|
if [ $? -ne 0 ]; then
|
|
CREATEREPO="createrepo"
|
|
fi
|
|
|
|
DEPENDANCY_DIR="$MY_REPO/cgcs-tis-repo/dependancy-cache"
|
|
SRPM_DIRECT_REQUIRES_FILE="$DEPENDANCY_DIR/SRPM-direct-requires"
|
|
SRPM_TRANSITIVE_REQUIRES_FILE="$DEPENDANCY_DIR/SRPM-transitive-requires"
|
|
SRPM_TRANSITIVE_DESCENDANTS_FILE="$DEPENDANCY_DIR/SRPM-transitive-descendants"
|
|
SRPM_DIRECT_DESCENDANTS_FILE="$DEPENDANCY_DIR/SRPM-direct-descendants"
|
|
SRPM_RPM_DIRECT_REQUIRES_FILE="$DEPENDANCY_DIR/SRPM-direct-requires-rpm"
|
|
RPM_DIRECT_REQUIRES_FILE="$DEPENDANCY_DIR/RPM-direct-requires"
|
|
RPM_TO_SRPM_MAP_FILE="$DEPENDANCY_DIR/rpm-to-srpm"
|
|
SRPM_TO_RPM_MAP_FILE="$DEPENDANCY_DIR/srpm-to-rpm"
|
|
|
|
UNBUILT_PATTERN_FILE="$MY_REPO/build-data/unbuilt_rpm_patterns"
|
|
|
|
SIGN_SECURE_BOOT="sign-secure-boot"
|
|
SIGN_SECURE_BOOT_LOG="sign-secure-boot.log"
|
|
|
|
export MOCK=/usr/bin/mock
|
|
|
|
BUILD_RPMS_PARALLEL_DIR="$(dirname "$(readlink -f "${BASH_SOURCE[0]}" )" )"
|
|
source "${BUILD_RPMS_PARALLEL_DIR}/image-utils.sh"
|
|
source "${BUILD_RPMS_PARALLEL_DIR}/spec-utils"
|
|
source "${BUILD_RPMS_PARALLEL_DIR}/srpm-utils"
|
|
|
|
HOME=$(pwd)
|
|
|
|
usage () {
|
|
echo ""
|
|
echo "Usage: "
|
|
echo " $ME [ [--rt] [--no-required] [--no-descendants] [--no-build-info] [--no-autoclean] [--formal] <optional list of package names> ]"
|
|
echo " $ME --clean [ [--no-descendants] <optional list of package names> ]"
|
|
echo " $ME --help"
|
|
echo ""
|
|
}
|
|
|
|
|
|
number_of_users () {
|
|
users | tr ' ' '\n' | sort --uniq | wc -l
|
|
}
|
|
|
|
available_mem_gb () {
|
|
free -g | grep 'Mem:' | awk '{ print $7 }'
|
|
}
|
|
|
|
available_disk_gb () {
|
|
df -BG $MY_WORKSPACE | grep -v '^Filesystem' | awk '{ print $4 }' | sed 's#G$##'
|
|
}
|
|
|
|
number_of_cpus () {
|
|
/usr/bin/nproc
|
|
}
|
|
|
|
number_of_builds_in_progress () {
|
|
local x
|
|
x=$(ps -ef | grep build-pkgs-parallel | wc -l)
|
|
x=$((x-1))
|
|
echo $x
|
|
}
|
|
|
|
sqrt () {
|
|
echo -e "sqrt($1)" | bc -q -i | head -2 | tail -1
|
|
}
|
|
|
|
join_by () { local IFS="$1"; shift; echo "$*"; }
|
|
|
|
create-no-clean-list () {
|
|
local MY_YUM_CONF=$(create-yum-conf)
|
|
local NO_CLEAN_LIST_FILE=$MY_WORKSPACE/no_clean_list.txt
|
|
local NEED_REBUILD=0
|
|
|
|
if [ ! -f $NO_CLEAN_LIST_FILE ]; then
|
|
NEED_REBUILD=1
|
|
else
|
|
if [ -f $MY_BUILD_CFG ]; then
|
|
find "$MY_BUILD_CFG" -not -newermm "$NO_CLEAN_LIST_FILE" | grep -q $(basename $MY_BUILD_CFG)
|
|
if [ $? -eq 0 ]; then
|
|
NEED_REBUILD=1
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
if [ $NEED_REBUILD -eq 1 ]; then
|
|
local install_groups=""
|
|
local install_packages=""
|
|
local p
|
|
|
|
for p in $(grep "config_opts\['chroot_setup_cmd'\]" $MY_BUILD_CFG | tail -n1 | cut -d '=' -f 2 | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' -e "s/^'//" -e "s/'$//" -e 's/^install //'); do
|
|
if [[ $p == @* ]] ; then
|
|
install_groups=$(join_by ' ' $install_groups $(echo $p | cut -c 2-))
|
|
else
|
|
install_packages=$(join_by ' ' $install_packages $p)
|
|
fi
|
|
done
|
|
|
|
local noclean_last_list_len=0
|
|
local noclean_list=""
|
|
local tmp_list=""
|
|
local g
|
|
|
|
for g in $install_groups; do
|
|
tmp_list=$(yum -c $MY_YUM_CONF groupinfo $g 2>> /dev/null | awk 'f;/Mandatory Packages:/{f=1}' | cut -c 5-)
|
|
noclean_list=$(join_by ' ' $noclean_list $tmp_list)
|
|
done
|
|
|
|
noclean_list=$(join_by ' ' $noclean_list $install_packages)
|
|
noclean_list=$(echo $noclean_list | tr ' ' '\n' | sort --uniq)
|
|
noclean_list_len=$(echo $noclean_list | wc -w)
|
|
|
|
while [ $noclean_list_len -gt $noclean_last_list_len ]; do
|
|
noclean_last_list_len=$noclean_list_len
|
|
noclean_list=$( (yum -c $MY_YUM_CONF deplist $noclean_list 2>> /dev/null | grep provider: | awk '{ print $2 }' | awk -F . '{ print $1 }'; for p in $noclean_list; do echo $p; done) | sort --uniq)
|
|
noclean_list_len=$(echo $noclean_list | wc -w)
|
|
done
|
|
|
|
echo $noclean_list > $NO_CLEAN_LIST_FILE
|
|
fi
|
|
|
|
cat $NO_CLEAN_LIST_FILE
|
|
}
|
|
|
|
str_lst_contains() {
|
|
TARGET="$1"
|
|
LST="$2"
|
|
if [[ $LST =~ (^|[[:space:]])$TARGET($|[[:space:]]) ]] ; then
|
|
return 0
|
|
else
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
compute_resources () {
|
|
local weight=0
|
|
local b
|
|
|
|
echo ""
|
|
for f in $@; do
|
|
b=$(basename $f)
|
|
if [ -f $SOURCES_DIR/$b/BIG ] || [ ]; then
|
|
weight=$((weight+MIN_TASKS_PER_CORE))
|
|
else
|
|
weight=$((weight+1))
|
|
fi
|
|
done
|
|
weight=$((weight/MIN_TASKS_PER_CORE))
|
|
|
|
# gather data about the build machines resources
|
|
local users=$(number_of_users)
|
|
if [ $users -lt 1 ]; then users=1; fi
|
|
local mem=$(available_mem_gb)
|
|
local disk=$(available_disk_gb)
|
|
local cpus=$(number_of_cpus)
|
|
local num_users=$(sqrt $users)
|
|
local num_build=$(number_of_builds_in_progress)
|
|
num_build=$((num_build+1))
|
|
echo "compute_resources: total: cpus=$cpus, mem=$mem, disk=$disk, weight=$weight, num_build=$num_build"
|
|
|
|
# What fraction of the machine will we use
|
|
local share_factor=$num_users
|
|
if [ $share_factor -gt $((MAX_SHARE_FACTOR+num_build-1)) ]; then share_factor=$((MAX_SHARE_FACTOR+num_build-1)); fi
|
|
if [ $share_factor -lt $num_build ]; then share_factor=$num_build; fi
|
|
local mem_share_factor=$((share_factor-num_build))
|
|
if [ $mem_share_factor -lt 1 ]; then mem_share_factor=1; fi
|
|
echo "compute_resources: share_factor=$share_factor mem_share_factor=$mem_share_factor"
|
|
|
|
# What resources are we permitted to use
|
|
local mem_share=$(((mem-MEMORY_RESERVE)/mem_share_factor))
|
|
if [ $mem_share -lt 0 ]; then mem_share=0; fi
|
|
local disk_share=$((disk/share_factor))
|
|
local cpus_share=$((cpus/share_factor))
|
|
echo "compute_resources: our share: cpus=$cpus_share, mem=$mem_share, disk=$disk_share"
|
|
|
|
# How many build jobs, how many jobs will use tmpfs, and how much mem for each tmpfs
|
|
local workers=$cpus_share
|
|
if [ $workers -gt $MAX_WORKERS ]; then workers=$MAX_WORKERS; fi
|
|
if [ $workers -gt $weight ]; then workers=$weight; fi
|
|
if [ $workers -lt 1 ]; then workers=1; fi
|
|
local max_mem_based_workers=$((mem_share/MIN_MEM_PER_WORKER))
|
|
if [ $max_mem_based_workers -lt 0 ]; then max_mem_based_workers=0; fi
|
|
local max_disk_based_workers=$((disk_share/MIN_DISK_PER_WORKER))
|
|
if [ $max_disk_based_workers -gt $MAX_DISK_BASED_WORKERS ]; then max_disk_based_workers=$MAX_DISK_BASED_WORKERS; fi
|
|
if [ $max_disk_based_workers -lt 1 ]; then max_disk_based_workers=1; fi
|
|
echo "max_disk_based_workers=$max_disk_based_workers, max_mem_based_workers=$max_mem_based_workers"
|
|
local mem_based_workers=$max_mem_based_workers
|
|
if [ $mem_based_workers -ge $workers ]; then mem_based_workers=$((workers-1)); fi
|
|
local disk_based_workers=$((workers-mem_based_workers))
|
|
if [ $disk_based_workers -gt $max_disk_based_workers ]; then disk_based_workers=$max_disk_based_workers; fi
|
|
if [ $disk_based_workers -lt 1 ]; then disk_based_workers=1; fi
|
|
echo "disk_based_workers=$disk_based_workers, mem_based_workers=$mem_based_workers"
|
|
if [ $workers -gt $((disk_based_workers+mem_based_workers)) ]; then workers=$((disk_based_workers+mem_based_workers)); fi
|
|
local mem_spoken_for=$((mem_based_workers*MIN_MEM_PER_WORKER))
|
|
local avail_mem=$((mem_share-mem_spoken_for))
|
|
local x=""
|
|
for i in $(seq 0 $((workers-1))); do
|
|
if [ $i -lt $disk_based_workers ]; then
|
|
x="$x:0"
|
|
else
|
|
extra_mem=$(($MAX_MEM_PER_WORKER-$MIN_MEM_PER_WORKER))
|
|
if [ $extra_mem -gt $avail_mem ]; then extra_mem=$avail_mem; fi
|
|
avail_mem=$((avail_mem-extra_mem))
|
|
mem_for_worker=$((MIN_MEM_PER_WORKER+extra_mem))
|
|
x="$x:$mem_for_worker"
|
|
fi
|
|
done
|
|
|
|
# Our output is saved in environmnet variables
|
|
MOCKCHAIN_RESOURCE_ALLOCATION=$(echo $x | sed 's#^:##')
|
|
MAX_WORKERS=$workers
|
|
echo "compute_resources: MAX_WORKERS=$MAX_WORKERS, MOCKCHAIN_RESOURCE_ALLOCATION=$MOCKCHAIN_RESOURCE_ALLOCATION"
|
|
echo ""
|
|
}
|
|
|
|
|
|
#
|
|
# Delete old repodata and reate a new one
|
|
#
|
|
recreate_repodata () {
|
|
local DIR=${1}
|
|
|
|
(cd $DIR
|
|
if [ -f repodata/*comps*xml ]; then
|
|
\mv repodata/*comps*xml comps.xml
|
|
fi
|
|
\rm -rf repodata
|
|
\rm -rf .repodata
|
|
if [ -f comps.xml ]; then
|
|
$CREATEREPO -g comps.xml --workers $(number_of_cpus) $(pwd)
|
|
else
|
|
$CREATEREPO --workers $(number_of_cpus) $(pwd)
|
|
fi
|
|
)
|
|
}
|
|
|
|
#
|
|
# Update existing repodata
|
|
#
|
|
update_repodata () {
|
|
local DIR=${1}
|
|
|
|
(cd $DIR
|
|
TMP=$(mktemp /tmp/update_repodata_XXXXXX)
|
|
RC=0
|
|
if [ -f comps.xml ]; then
|
|
$CREATEREPO --update -g comps.xml --workers $(number_of_cpus) $(pwd) &> $TMP
|
|
RC=$?
|
|
else
|
|
$CREATEREPO --update --workers $(number_of_cpus) $(pwd) &> $TMP
|
|
RC=$?
|
|
fi
|
|
if [ $RC -ne 0 ]; then
|
|
cat $TMP
|
|
fi
|
|
\rm -f $TMP
|
|
)
|
|
}
|
|
|
|
#
|
|
# return array that is the intersection of two other arrays
|
|
#
|
|
# NEW_ARRAY=( $( intersection ARRAY1 ARRAY2 ) )
|
|
#
|
|
intersection () {
|
|
local Aname=$1[@]
|
|
local Bname=$2[@]
|
|
local A=("${!Aname}")
|
|
local B=("${!Bname}")
|
|
|
|
# echo "${A[@]}"
|
|
# echo "${B[@]}"
|
|
for a in "${A[@]}"; do
|
|
# echo "a=$a"
|
|
for b in "${B[@]}"; do
|
|
# echo "b=$b"
|
|
if [ "$a" == "$b" ]; then
|
|
echo "$a"
|
|
break
|
|
fi
|
|
done
|
|
done
|
|
}
|
|
|
|
#
|
|
# return array that is the union of two other arrays
|
|
#
|
|
# NEW_ARRAY=( $( union ARRAY1 ARRAY2 ) )
|
|
#
|
|
union () {
|
|
local Aname=$1[@]
|
|
local Bname=$2[@]
|
|
local A=("${!Aname}")
|
|
local B=("${!Bname}")
|
|
local a
|
|
local b
|
|
|
|
for a in "${A[@]}"; do
|
|
echo "$a"
|
|
done
|
|
|
|
for b in "${B[@]}"; do
|
|
local found=0
|
|
for a in "${A[@]}"; do
|
|
if [ "$a" == "$b" ]; then
|
|
found=1
|
|
break
|
|
fi
|
|
done
|
|
if [ $found -eq 0 ]; then
|
|
echo $b
|
|
fi
|
|
done
|
|
}
|
|
|
|
#
|
|
# returns 0 if element is in the array
|
|
#
|
|
# e.g. contains ARRAY $SEEKING && echo "$SEEKING is in 'ARRAY'"
|
|
#
|
|
contains () {
|
|
local Aname=$1[@]
|
|
local A=("${!Aname}")
|
|
local seeking=$2
|
|
local in=1
|
|
|
|
for a in "${A[@]}"; do
|
|
if [[ $a == $seeking ]]; then
|
|
in=0
|
|
break
|
|
fi
|
|
done
|
|
return $in
|
|
}
|
|
|
|
#
|
|
# Append element to array if not present
|
|
#
|
|
# ARRAY=( $( put ARRAY $ELEMENT ) )
|
|
#
|
|
put () {
|
|
local Aname=$1[@]
|
|
local A=("${!Aname}")
|
|
local element="$2"
|
|
for a in "${A[@]}"; do
|
|
echo "$a"
|
|
done
|
|
contains A "$element" || echo "$element"
|
|
}
|
|
|
|
build_order_recursive () {
|
|
local target=$1
|
|
local idx
|
|
local remainder_list
|
|
local needs
|
|
local needs_list
|
|
|
|
for((idx=0;idx<${#UNORDERED_LIST[@]};idx++)); do
|
|
if [ ${UNORDERED_LIST[idx]} == $target ]; then
|
|
remainder_list=( ${UNORDERED_LIST[@]:0:$idx} ${UNORDERED_LIST[@]:$((idx + 1))} )
|
|
UNORDERED_LIST=( ${remainder_list[@]} )
|
|
needs=( $(grep "^$target;" "$SRPM_DIRECT_REQUIRES_FILE" | sed "s/$target;//" | sed 's/,/ /g') )
|
|
needs_list=( $(intersection needs remainder_list) )
|
|
for((idx=0;idx<${#needs_list[@]};idx++)); do
|
|
build_order_recursive ${needs_list[idx]}
|
|
done
|
|
echo $target
|
|
break
|
|
fi
|
|
done
|
|
}
|
|
|
|
build_order () {
|
|
local Aname=$1[@]
|
|
local original_list=("${!Aname}")
|
|
local needs
|
|
local needs_list
|
|
local remainder_list
|
|
local idx
|
|
local element
|
|
local next_start=0
|
|
local old_next_start=0
|
|
local progress=1
|
|
|
|
while [ ${#original_list[@]} -gt 0 ] && [ $progress -gt 0 ]; do
|
|
progress=0
|
|
old_next_start=$next_start
|
|
for((idx=$next_start;idx<${#original_list[@]};idx++)); do
|
|
element=${original_list[idx]}
|
|
next_start=$idx
|
|
remainder_list=( ${original_list[@]:0:$idx} ${original_list[@]:$((idx + 1))} )
|
|
needs=( $(grep "^$element;" "$SRPM_DIRECT_REQUIRES_FILE" | sed "s/$element;//" | sed 's/,/ /g') )
|
|
needs_list=( $(intersection needs remainder_list) )
|
|
if [ ${#needs_list[@]} -eq 0 ]; then
|
|
echo "$element"
|
|
original_list=( "${remainder_list[@]}" )
|
|
if [ $next_start -ge ${#original_list[@]} ]; then
|
|
next_start=0
|
|
fi
|
|
progress=1
|
|
break
|
|
fi
|
|
done
|
|
if [ $old_next_start -ne 0 ]; then
|
|
progress=1
|
|
next_start=0
|
|
fi
|
|
done
|
|
|
|
if [ ${#original_list[@]} -gt 0 ]; then
|
|
# Had trouble calculating a build order for these remaining packages, so stick them at the end
|
|
UNORDERED_LIST=( ${original_list[@]} )
|
|
while [ ${#UNORDERED_LIST[@]} -gt 0 ]; do
|
|
element=${UNORDERED_LIST[0]}
|
|
build_order_recursive $element
|
|
done
|
|
fi
|
|
}
|
|
|
|
set_mock_symlinks () {
|
|
local LNK
|
|
local DEST
|
|
local CFG=$1
|
|
if [ -d /localdisk/loadbuild/mock ]; then
|
|
mkdir -p $MY_WORKSPACE
|
|
LNK=$(echo "/localdisk/loadbuild/mock/$(basename $CFG)" | sed 's/.cfg$//')
|
|
if [ ! -L $LNK ] && [ -d $LNK ]; then
|
|
echo "WARNING: Found directory at '$LNK' when symlink was expected. Fixing..."
|
|
\rm -rf $LNK
|
|
if [ -d $LNK ]; then
|
|
\mv $LNK $LNK.clean_me
|
|
fi
|
|
fi
|
|
if [ -L $LNK ]; then
|
|
DEST=$(readlink $LNK)
|
|
if [ "$DEST" != "$MY_WORKSPACE" ] || [ ! -d "$MY_WORKSPACE" ]; then
|
|
echo "WARNING: Found broken symlink at '$LNK'. Fixing..."
|
|
\rm -f $LNK
|
|
fi
|
|
fi
|
|
if [ ! -L $LNK ]; then
|
|
if [ ! -d "$MY_WORKSPACE" ]; then
|
|
echo "ERROR: Can't create symlink from $LNK to $MY_WORKSPACE as destination does not exist."
|
|
exit 1
|
|
fi
|
|
ln -s $MY_WORKSPACE $LNK
|
|
fi
|
|
fi
|
|
|
|
if [ -d /localdisk/loadbuild/mock-cache ]; then
|
|
mkdir -p $MY_WORKSPACE/cache
|
|
LNK=$(echo "/localdisk/loadbuild/mock-cache/$(basename $CFG)" | sed 's/.cfg$//')
|
|
if [ ! -L $LNK ] && [ -d $LNK ]; then
|
|
echo "WARNING: Found directory at '$LNK' when symlink was expected. Fixing..."
|
|
\rm -rf $LNK
|
|
if [ -d $LNK ]; then
|
|
\mv $LNK $LNK.clean_me
|
|
fi
|
|
fi
|
|
if [ -L $LNK ]; then
|
|
DEST=$(readlink $LNK)
|
|
if [ "$DEST" != "$MY_WORKSPACE/cache" ] || [ ! -d "$MY_WORKSPACE/cache" ]; then
|
|
echo "WARNING: Found broken symlink at '$LNK'. Fixing..."
|
|
\rm -f $LNK
|
|
fi
|
|
fi
|
|
if [ ! -L $LNK ]; then
|
|
if [ ! -d "$MY_WORKSPACE/cache" ]; then
|
|
echo "ERROR: Can't create symlink from $LNK to $MY_WORKSPACE/cache as destination does not exist."
|
|
exit 1
|
|
fi
|
|
ln -s $MY_WORKSPACE/cache $LNK
|
|
fi
|
|
fi
|
|
}
|
|
|
|
remove_mock_symlinks () {
|
|
local LNK
|
|
local CFG=$1
|
|
if [ -d /localdisk/loadbuild/mock ]; then
|
|
LNK=$(echo "/localdisk/loadbuild/mock/$(basename $CFG)" | sed 's/.cfg$//')
|
|
if [ -L $LNK ]; then
|
|
\rm -f $LNK
|
|
fi
|
|
if [ -d $LNK ]; then
|
|
\rm -rf $LNK
|
|
if [ $? -ne 0 ]; then
|
|
\mv -f $LNK $LNK.clean_me
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
if [ -d /localdisk/loadbuild/mock-cache ]; then
|
|
LNK=$(echo "/localdisk/loadbuild/mock-cache/$(basename $MY_BUILD_CFG)" | sed 's/.cfg$//')
|
|
if [ -L $LNK ]; then
|
|
\rm -f $MY_WORKSPACE/cache $LNK
|
|
fi
|
|
if [ -d $LNK ]; then
|
|
\rm -rf $LNK
|
|
if [ $? -ne 0 ]; then
|
|
\mv -f $LNK $LNK.clean_me
|
|
fi
|
|
fi
|
|
fi
|
|
}
|
|
|
|
umount_mock_root_as_tmpfs_all () {
|
|
for i in $(seq 0 $((ABSOLUTE_MAX_WORKERS-1))); do
|
|
umount_mock_root_as_tmpfs $i
|
|
done
|
|
}
|
|
|
|
umount_mock_root_as_tmpfs_cfg () {
|
|
local CFG=$1
|
|
local build_idx=$(basename $CFG | sed 's#.*[.]b\([0-9]*\)[.]cfg#\1#')
|
|
if [ "$build_idx" != "" ]; then
|
|
umount_mock_root_as_tmpfs $build_idx
|
|
else
|
|
echo "umount_mock_root_as_tmpfs_cfg: Failed to map '$CFG' to a build_idx"
|
|
fi
|
|
}
|
|
|
|
umount_mock_root_as_tmpfs () {
|
|
local build_idx=$1
|
|
local mount_dir=$(readlink -f $MY_WORKSPACE/mock)/b${build_idx}/root
|
|
local rc
|
|
|
|
mount | grep tmpfs | grep $mount_dir &> /dev/null
|
|
if [ $? -ne 0 ]; then
|
|
return 0
|
|
fi
|
|
mock_tmpfs_umount $mount_dir &> /dev/null
|
|
|
|
rc=$?
|
|
if [ $rc -ne 0 ]; then
|
|
echo "FAILED: mock_tmpfs_umount $mount_dir"
|
|
fi
|
|
return $rc
|
|
}
|
|
|
|
kill_descendents ()
|
|
{
|
|
local kill_pid=$1
|
|
local kill_all=$2
|
|
local need_stop=$3
|
|
local iteration=$4
|
|
local ret=0
|
|
local rc=0
|
|
|
|
# echo "kill_descendents pid=$kill_pid, all=$kill_all stop=$need_stop, iteration=$iteration"
|
|
|
|
local relevant_recursive_children="$ME"
|
|
local relevant_recursive_promote_children="mock"
|
|
local relevant_other_children="mockchain-parallel"
|
|
|
|
local recursive_promote_children=$(for relevant_child in $relevant_recursive_promote_children; do pgrep -P $kill_pid $relevant_child; done)
|
|
local recursive_children=$(for relevant_child in $relevant_recursive_children; do pgrep -P $kill_pid $relevant_child; done)
|
|
local other_children=""
|
|
|
|
if [ $kill_all -eq 1 ]; then
|
|
recursive_promote_children=""
|
|
recursive_children=$(pgrep -P $kill_pid)
|
|
fi
|
|
|
|
if [ $iteration -eq 0 ]; then
|
|
other_children=$(for relevant_child in $relevant_other_children; do pgrep -P $kill_pid $relevant_child; done)
|
|
if [ "$other_children" != "" ]; then
|
|
ret=1
|
|
fi
|
|
fi
|
|
|
|
if [ $need_stop -eq 1 ]; then
|
|
for pid in $recursive_children $recursive_promote_children; do
|
|
kill -SIGSTOP $pid &> /dev/null
|
|
done
|
|
fi
|
|
|
|
for pid in $recursive_children; do
|
|
kill_descendents "$pid" $kill_all $need_stop $((iteration + 1))
|
|
done
|
|
for pid in $recursive_promote_children; do
|
|
kill_descendents "$pid" 1 1 $((iteration + 1))
|
|
done
|
|
|
|
# echo "kill: $recursive_children $recursive_promote_children"
|
|
for pid in $recursive_children $recursive_promote_children; do
|
|
kill $pid &> /dev/null
|
|
rc=$?
|
|
if [ $need_stop -eq 1 ]; then
|
|
kill -SIGCONT $pid &> /dev/null
|
|
fi
|
|
if [ $rc -eq 0 ] && [ $iteration -eq 0 ]; then
|
|
wait $pid
|
|
fi
|
|
done
|
|
|
|
# echo "kill: $other_children"
|
|
for pid in $other_children; do
|
|
kill $pid &> /dev/null
|
|
rc=$?
|
|
if [ $rc -eq 0 ] && [ $iteration -eq 0 ]; then
|
|
wait $pid
|
|
fi
|
|
done
|
|
|
|
return $ret
|
|
}
|
|
|
|
function my_exit_n() {
|
|
local need_mock_cleanup
|
|
# echo "$BASHPID: $ME: my_exit: killing children"
|
|
local need_mock_cleanup
|
|
kill_descendents $BASHPID 0 0 0
|
|
need_mock_cleanup=$?
|
|
# echo "$BASHPID: $ME: my_exit: waiting"
|
|
wait
|
|
# echo "$BASHPID: $ME: my_exit: wait complete"
|
|
# echo "$BASHPID: $ME: my_exit: need_mock_cleanup=$need_mock_cleanup"
|
|
if [ $need_mock_cleanup -ne 0 ]; then
|
|
umount_mock_root_as_tmpfs_all
|
|
fi
|
|
}
|
|
|
|
function my_exit() {
|
|
local need_mock_cleanup
|
|
# echo "$BASHPID: $ME: my_exit: killing children"
|
|
local need_mock_cleanup
|
|
kill_descendents $BASHPID 0 0 0
|
|
need_mock_cleanup=$?
|
|
# echo "$BASHPID: $ME: my_exit: waiting"
|
|
wait
|
|
# echo "$BASHPID: $ME: my_exit: wait complete"
|
|
# echo "$BASHPID: $ME: my_exit: need_mock_cleanup=$need_mock_cleanup"
|
|
if [ $need_mock_cleanup -ne 0 ]; then
|
|
sleep 1
|
|
fi
|
|
umount_mock_root_as_tmpfs_all
|
|
}
|
|
|
|
function my_sigint_n() {
|
|
local ARG=$1
|
|
echo "$BASHPID: $ME: my_sigint_n: ARG=$ARG"
|
|
echo "$BASHPID: $ME: my_sigint_n: killing children"
|
|
local need_mock_cleanup
|
|
kill_descendents $BASHPID 0 0 0
|
|
need_mock_cleanup=$?
|
|
echo "$BASHPID: $ME: my_sigint_n: waiting"
|
|
wait
|
|
echo "$BASHPID: $ME: my_sigint_n: wait complete"
|
|
if [ $need_mock_cleanup -ne 0 ]; then
|
|
umount_mock_root_as_tmpfs_cfg $ARG
|
|
fi
|
|
exit 1
|
|
}
|
|
|
|
function my_sighup_n() {
|
|
local ARG=$1
|
|
echo "$BASHPID: $ME: my_sighup_n: ARG=$ARG"
|
|
echo "$BASHPID: $ME: my_sighup_n: killing children"
|
|
local need_mock_cleanup
|
|
kill_descendents $BASHPID 0 0 0
|
|
need_mock_cleanup=$?
|
|
echo "$BASHPID: $ME: my_sighup_n: waiting"
|
|
wait
|
|
echo "$BASHPID: $ME: my_sighup_n: wait complete"
|
|
if [ $need_mock_cleanup -ne 0 ]; then
|
|
umount_mock_root_as_tmpfs_cfg $ARG
|
|
fi
|
|
exit 1
|
|
}
|
|
|
|
function my_sigabrt_n() {
|
|
local ARG=$1
|
|
echo "$BASHPID: $ME: my_sigabrt_n: ARG=$ARG"
|
|
echo "$BASHPID: $ME: my_sigabrt_n: killing children"
|
|
local need_mock_cleanup
|
|
kill_descendents $BASHPID 0 0 0
|
|
need_mock_cleanup=$?
|
|
echo "$BASHPID: $ME: my_sigabrt_n: waiting"
|
|
wait
|
|
echo "$BASHPID: $ME: my_sigabrt_n: wait complete"
|
|
if [ $need_mock_cleanup -ne 0 ]; then
|
|
umount_mock_root_as_tmpfs_cfg $ARG
|
|
fi
|
|
exit 1
|
|
}
|
|
|
|
function my_sigterm_n() {
|
|
local ARG=$1
|
|
echo "$BASHPID: $ME: my_sigterm_n: ARG=$ARG"
|
|
echo "$BASHPID: $ME: my_sigterm_n: killing children"
|
|
local need_mock_cleanup
|
|
kill_descendents $BASHPID 0 0 0
|
|
need_mock_cleanup=$?
|
|
echo "$BASHPID: $ME: my_sigterm_n: waiting"
|
|
wait
|
|
echo "$BASHPID: $ME: my_sigterm_n: wait complete"
|
|
echo "$BASHPID: $ME: my_sigterm_n: need_mock_cleanup=$need_mock_cleanup"
|
|
if [ $need_mock_cleanup -ne 0 ]; then
|
|
umount_mock_root_as_tmpfs_cfg $ARG
|
|
fi
|
|
exit 1
|
|
}
|
|
|
|
function my_sigint() {
|
|
echo "$BASHPID: $ME: my_sigint: killing children"
|
|
local need_mock_cleanup
|
|
kill_descendents $BASHPID 0 0 0
|
|
need_mock_cleanup=$?
|
|
echo "$BASHPID: $ME: my_sigterm_n: waiting"
|
|
wait
|
|
echo "$BASHPID: $ME: my_sigterm_n: wait complete"
|
|
if [ $need_mock_cleanup -ne 0 ]; then
|
|
umount_mock_root_as_tmpfs_all
|
|
fi
|
|
exit 1
|
|
}
|
|
|
|
function my_sighup() {
|
|
echo "$BASHPID: $ME: my_sighup: killing children"
|
|
local need_mock_cleanup
|
|
kill_descendents $BASHPID 0 0 0
|
|
need_mock_cleanup=$?
|
|
echo "$BASHPID: $ME: my_sighup: waiting"
|
|
wait
|
|
echo "$BASHPID: $ME: my_sighup: wait complete"
|
|
if [ $need_mock_cleanup -ne 0 ]; then
|
|
umount_mock_root_as_tmpfs_all
|
|
fi
|
|
exit 1
|
|
}
|
|
|
|
function my_sigabrt() {
|
|
echo "$BASHPID: $ME: my_sigabrt: killing children"
|
|
local need_mock_cleanup
|
|
kill_descendents $BASHPID 0 0 0
|
|
need_mock_cleanup=$?
|
|
echo "$BASHPID: $ME: my_sigabrt: waiting"
|
|
wait
|
|
echo "$BASHPID: $ME: my_sigabrt: wait complete"
|
|
if [ $need_mock_cleanup -ne 0 ]; then
|
|
umount_mock_root_as_tmpfs_all
|
|
fi
|
|
exit 1
|
|
}
|
|
|
|
function my_sigterm() {
|
|
echo "$BASHPID: $ME: my_sigterm: killing children"
|
|
local need_mock_cleanup
|
|
kill_descendents $BASHPID 0 0 0
|
|
need_mock_cleanup=$?
|
|
echo "$BASHPID: $ME: my_sigterm: waiting"
|
|
wait
|
|
echo "$BASHPID: $ME: my_sigterm: wait complete"
|
|
echo "$BASHPID: $ME: my_sigterm: need_mock_cleanup=$need_mock_cleanup"
|
|
if [ $need_mock_cleanup -ne 0 ]; then
|
|
umount_mock_root_as_tmpfs_all
|
|
fi
|
|
exit 1
|
|
}
|
|
|
|
trapwrap() {
|
|
local WCMD=$1
|
|
shift
|
|
declare -i pid status=255
|
|
# set the trap for the foreground process
|
|
trap my_sigint INT
|
|
trap my_sighup HUP
|
|
trap my_sigabrt ABRT
|
|
trap my_sigterm TERM
|
|
# run the command in background
|
|
### "$@" & pid=$!
|
|
WARGS=()
|
|
x=0
|
|
for i in "$@"; do
|
|
WARGS[$x]="$i"
|
|
x=$((x+1))
|
|
done
|
|
echo "$WCMD ${WARGS[@]/#/}"
|
|
$WCMD "${WARGS[@]/#/}" & pid=$!
|
|
# wait until bg command finishes, handling interruptions by trapped signals
|
|
while (( status > 128 )); do
|
|
wait $pid
|
|
status=$?
|
|
done
|
|
# restore the trap
|
|
trap - INT
|
|
trap - HUP
|
|
trap - ABRT
|
|
trap - TERM
|
|
# return the command exit status
|
|
return $status
|
|
}
|
|
|
|
trapwrap_n() {
|
|
local ARG=$1
|
|
shift
|
|
local WCMD=$1
|
|
shift
|
|
declare -i pid status=255
|
|
# set the trap for the foreground process
|
|
trap my_exit_n EXIT
|
|
trap "my_sigint_n $ARG" INT
|
|
trap "my_sighup_n $ARG" HUP
|
|
trap "my_sigabrt_n $ARG" ABRT
|
|
trap "my_sigterm_n $ARG" TERM
|
|
# run the command in background
|
|
WARGS=()
|
|
x=0
|
|
for i in "$@"; do
|
|
WARGS[$x]="$i"
|
|
x=$((x+1))
|
|
done
|
|
echo "$WCMD ${WARGS[@]/#/}"
|
|
$WCMD "${WARGS[@]/#/}" & pid=$!
|
|
# wait until bg command finishes, handling interruptions by trapped signals
|
|
while (( status > 128 )); do
|
|
wait $pid
|
|
status=$?
|
|
done
|
|
# restore the trap
|
|
trap - INT
|
|
trap - HUP
|
|
trap - ABRT
|
|
trap - TERM
|
|
# return the command exit status
|
|
return $status
|
|
}
|
|
|
|
trap my_exit EXIT
|
|
|
|
mock_get_cache_dir () {
|
|
local CFG=$1
|
|
local CACHE_DIR="$MY_WORKSPACE/cache"
|
|
local CACHE_LINE=$(grep "config_opts[[][']cache_topdir['][]]" $CFG)
|
|
if [ $? -eq 0 ]; then
|
|
CACHE_DIR=$(echo "$CACHE_LINE" | awk -F \' '{ print $4 }')
|
|
fi
|
|
echo "$CACHE_DIR"
|
|
}
|
|
|
|
mock_get_root_dir () {
|
|
local CFG=$1
|
|
local ROOT_DIR="$MY_WORKSPACE/mock"
|
|
local ROOT_LINE=$(grep "config_opts[[][']root['][]]" $CFG)
|
|
if [ $? -eq 0 ]; then
|
|
ROOT_DIR="$MY_WORKSPACE/"$(echo "$ROOT_LINE" | awk -F \' '{ print $4 }')
|
|
fi
|
|
echo "$ROOT_DIR"
|
|
}
|
|
|
|
mock_clean_cfg () {
|
|
local CFG=$1
|
|
echo "${FUNCNAME[0]}: $CFG"
|
|
echo "=================================="
|
|
mock_clean_cache_cfg $CFG
|
|
echo "=================================="
|
|
echo "$MOCK -r $CFG --configdir $(dirname $CFG) --scrub=all"
|
|
trapwrap_n $CFG $MOCK -r $CFG --configdir $(dirname $CFG) --scrub=all
|
|
echo "=================================="
|
|
echo "$MOCK -r $CFG --configdir $(dirname $CFG) --clean"
|
|
trapwrap_n $CFG $MOCK -r $CFG --configdir $(dirname $CFG) --clean
|
|
### Note: this sometimes leaves behind a $MY_WORKSPACE/cache/mock/yum_cache/yumcache.lock
|
|
echo "=================================="
|
|
mock_clean_cache_all_cfg $CFG
|
|
echo "=================================="
|
|
}
|
|
|
|
mock_sub_configs () {
|
|
find $MY_WORKSPACE/configs/$MY_BUILD_ENVIRONMENT* -name "$MY_BUILD_ENVIRONMENT*b[0-9]*.cfg"
|
|
}
|
|
|
|
mock_clean () {
|
|
echo "${FUNCNAME[0]}: in"
|
|
echo "=================================="
|
|
remove_mock_symlinks $MY_BUILD_CFG
|
|
set_mock_symlinks $MY_BUILD_CFG
|
|
echo "=================================="
|
|
for SUB_CFG in $(mock_sub_configs); do
|
|
local PREFIX=$(echo $SUB_CFG | rev | cut -d . -f 2 | rev)
|
|
( mock_clean_cfg $SUB_CFG 2>&1 | sed "s#^#${PREFIX}: #" ; exit ${PIPESTATUS[0]} ) &
|
|
done
|
|
wait
|
|
echo "=================================="
|
|
remove_mock_symlinks $MY_BUILD_CFG
|
|
echo "${FUNCNAME[0]}: out"
|
|
}
|
|
|
|
mock_partial_clean_cfg () {
|
|
local CFG=$1
|
|
local SRPMS_LIST="$2"
|
|
local RPMS_LIST="$3"
|
|
local CMD
|
|
local TMP
|
|
local RC
|
|
|
|
echo "${FUNCNAME[0]}: CFG=$CFG SRPMS_LIST='$SRPMS_LIST' RPMS_LIST='$RPMS_LIST'"
|
|
|
|
TMP=$(mktemp /tmp/mock_partial_clean_cfg_XXXXXX)
|
|
if [ $? -ne 0 ]; then
|
|
echo "${FUNCNAME[0]}: mktemp failed"
|
|
return 1
|
|
fi
|
|
|
|
local ROOT_DIR=$(mock_get_root_dir $CFG)
|
|
|
|
if [ -d $ROOT_DIR/root/builddir/build/SOURCES ]; then
|
|
echo "rm -rf $ROOT_DIR/root/builddir/build/SOURCES/*"
|
|
\rm -rf $ROOT_DIR/root/builddir/build/SOURCES/* 2>> /dev/null
|
|
fi
|
|
|
|
if [ -d $ROOT_DIR/root/builddir/build/SPECS ]; then
|
|
echo "rm -rf $ROOT_DIR/root/builddir/build/SPECS/*"
|
|
\rm -rf $ROOT_DIR/root/builddir/build/SPECS/* 2>> /dev/null
|
|
fi
|
|
|
|
for s in $SRPMS_LIST; do
|
|
f=$(basename $s)
|
|
if [ -f $ROOT_DIR/root/builddir/build/SRPMS/$f ]; then
|
|
\rm -f -v $ROOT_DIR/root/builddir/build/SRPMS/$f 2>> /dev/null
|
|
fi
|
|
if [ -f $ROOT_DIR/root/builddir/build/originals/$f ]; then
|
|
\rm -f -v $ROOT_DIR/root/builddir/build/originals/$f 2>> /dev/null
|
|
fi
|
|
done
|
|
|
|
for r in $RPMS_LIST; do
|
|
for d in $(find $ROOT_DIR/root/builddir/build/BUILD/ -maxdepth 1 -name '$r*' 2>> /dev/null); do
|
|
echo "rm -rf $d"
|
|
\rm -rf $d 2>> /dev/null
|
|
done
|
|
if [ -d $ROOT_DIR/root/builddir/build/RPMS ]; then
|
|
for f in $(find $ROOT_DIR/root/builddir/build/RPMS -maxdepth 1 -name "$r*rpm" 2>> /dev/null); do
|
|
\rm -f -v $f 2>> /dev/null
|
|
done
|
|
fi
|
|
done
|
|
|
|
|
|
local NO_CLEAN_LIST=$(create-no-clean-list)
|
|
echo "NO_CLEAN_LIST=$NO_CLEAN_LIST"
|
|
|
|
local RPMS_CLEAN_LIST=""
|
|
local NEED_FULL_MOCK_CLEAN=0
|
|
for r in $RPMS_LIST; do
|
|
if ! str_lst_contains $r "$NO_CLEAN_LIST" ; then
|
|
RPMS_CLEAN_LIST=$(join_by ' ' $RPMS_CLEAN_LIST $r)
|
|
else
|
|
echo "Can't remove '$r' from mock environment without a wipe";
|
|
NEED_FULL_MOCK_CLEAN=1
|
|
fi
|
|
done
|
|
|
|
if [ $NEED_FULL_MOCK_CLEAN -eq 1 ]; then
|
|
echo "Wipe the mock environment"
|
|
mock_clean_cfg $CFG
|
|
RC=$?
|
|
else
|
|
# Intent of following is for $RPMS_LIST to be expand now while the remaining $ varaibles are for bash inside mock to expand
|
|
echo "Try to uninstall from the mock environment these packages: $RPMS_CLEAN_LIST"
|
|
CMD='LST="'$RPMS_CLEAN_LIST'";
|
|
DELETE_LIST="";
|
|
for r in $LST; do
|
|
FOUND=$(rpm -q $r) ;
|
|
if [ $? -eq 0 ]; then
|
|
DELETE_LIST="$DELETE_LIST $FOUND";
|
|
fi;
|
|
done;
|
|
echo "uninstalling these packages: $DELETE_LIST";
|
|
if [ "$DELETE_LIST" != "" ]; then
|
|
rpm -e --nodeps $DELETE_LIST;
|
|
fi'
|
|
echo "$MOCK -r $CFG --configdir $(dirname $CFG) --chroot bash -c $CMD" &> $TMP
|
|
trapwrap_n $CFG $MOCK -r $CFG --configdir $(dirname $CFG) --chroot "bash -c '$CMD'" &>> $TMP
|
|
RC=$?
|
|
if [ $RC -ne 0 ]; then
|
|
cat $TMP
|
|
\rm -f $TMP
|
|
return $RC
|
|
fi
|
|
|
|
mock_clean_cache_cfg $CFG
|
|
RC=$?
|
|
\rm -f $TMP
|
|
fi
|
|
|
|
return $RC
|
|
}
|
|
|
|
mock_partial_clean () {
|
|
local SRPMS_LIST="$1"
|
|
local RPMS_LIST="$2"
|
|
echo "${FUNCNAME[0]}: in"
|
|
echo "${FUNCNAME[0]}: '$SRPMS_LIST' '$RPMS_LIST'"
|
|
echo "=================================="
|
|
local NO_CLEAN_LIST=$(create-no-clean-list)
|
|
echo "=================================="
|
|
for SUB_CFG in $(mock_sub_configs); do
|
|
local PREFIX=$(echo $SUB_CFG | rev | cut -d . -f 2 | rev)
|
|
( mock_partial_clean_cfg $SUB_CFG "$SRPMS_LIST" "$RPMS_LIST" 2>&1 | sed "s#^#${PREFIX}: #" ; exit ${PIPESTATUS[0]} ) &
|
|
done
|
|
wait
|
|
echo "=================================="
|
|
echo "${FUNCNAME[0]}: out"
|
|
}
|
|
|
|
mock_clean_cache_cfg () {
|
|
local CFG=$1
|
|
local TMP
|
|
local RC
|
|
|
|
echo "${FUNCNAME[0]}: $CFG '$SRPMS_LIST' '$RPMS_LIST'"
|
|
|
|
TMP=$(mktemp /tmp/mock_clean_cache_cfg_XXXXXX)
|
|
if [ $? -ne 0 ]; then
|
|
echo "${FUNCNAME[0]}: mktemp failed"
|
|
return 1
|
|
fi
|
|
|
|
echo "${FUNCNAME[0]}: $CFG"
|
|
|
|
clean_yum_cache_cfg $CFG
|
|
|
|
echo "$MOCK -r $CFG --configdir $(dirname $CFG) --scrub=root-cache --scrub=yum-cache --scrub=cache" &> $TMP
|
|
trapwrap_n $CFG $MOCK -r $CFG --configdir $(dirname $CFG) --scrub=root-cache --scrub=yum-cache --scrub=cache &>> $TMP
|
|
RC=$?
|
|
if [ $RC -ne 0 ]; then
|
|
cat $TMP
|
|
fi
|
|
|
|
\rm -f $TPM
|
|
return $RC
|
|
}
|
|
|
|
mock_clean_cache () {
|
|
echo "${FUNCNAME[0]}: in"
|
|
for SUB_CFG in $(mock_sub_configs); do
|
|
local PREFIX=$(echo $SUB_CFG | rev | cut -d . -f 2 | rev)
|
|
( mock_clean_cache_cfg $SUB_CFG 2>&1 | sed "s#^#${PREFIX}: #" ; exit ${PIPESTATUS[0]} ) &
|
|
done
|
|
wait
|
|
# mock_clean_cache_cfg $BUILD_CFG
|
|
echo "${FUNCNAME[0]}: out"
|
|
}
|
|
|
|
mock_clean_cache_all_cfg () {
|
|
local CFG=$1
|
|
|
|
echo "${FUNCNAME[0]}: $CFG"
|
|
echo "=================================="
|
|
clean_yum_cache_cfg $CFG
|
|
echo "=================================="
|
|
echo "$MOCK -r $CFG --configdir $(dirname $CFG) --scrub=all"
|
|
trapwrap_n $CFG $MOCK -r $CFG --configdir $(dirname $CFG) --scrub=all
|
|
echo "=================================="
|
|
}
|
|
|
|
mock_clean_cache_all () {
|
|
echo "${FUNCNAME[0]}: in"
|
|
for SUB_CFG in $(mock_sub_configs); do
|
|
local PREFIX=$(echo $SUB_CFG | rev | cut -d . -f 2 | rev)
|
|
( mock_clean_cache_all_cfg $SUB_CFG 2>&1 | sed "s#^#${PREFIX}: #" ; exit ${PIPESTATUS[0]} ) &
|
|
done
|
|
wait
|
|
echo "${FUNCNAME[0]}: out"
|
|
}
|
|
|
|
mock_clean_metadata_cfg () {
|
|
local CFG=$1
|
|
local TMP
|
|
local RC
|
|
|
|
echo "${FUNCNAME[0]}: $CFG"
|
|
|
|
TMP=$(mktemp /tmp/mock_partial_clean_cfg_XXXXXX)
|
|
if [ $? -ne 0 ]; then
|
|
echo "${FUNCNAME[0]}: mktemp failed"
|
|
return 1
|
|
fi
|
|
|
|
CMD=$((cat $CFG; grep config_opts\\[\'yum.conf\'\\\] $CFG | sed 's#\\n#\n#g') | grep '^[[]' | grep -v main | sed 's/[][]//g' | sed 's#^#yum --enablerepo=#' | sed 's#$# clean metadata#' | sort -u | tr '\n' ';')
|
|
echo "$MOCK -r $CFG --configdir $(dirname $CFG) --chroot bash -c $CMD" &> $TMP
|
|
trapwrap_n $CFG $MOCK -r $CFG --configdir $(dirname $CFG) --chroot "bash -c '($CMD)'" &>>$TMP
|
|
RC=$?
|
|
if [ $RC -ne 0 ]; then
|
|
cat $TMP
|
|
fi
|
|
\rm -f $TMP
|
|
return $RC
|
|
}
|
|
|
|
mock_clean_metadata () {
|
|
echo "${FUNCNAME[0]}: in"
|
|
for SUB_CFG in $(mock_sub_configs); do
|
|
local PREFIX=$(echo $SUB_CFG | rev | cut -d . -f 2 | rev)
|
|
( mock_clean_metadata_cfg $SUB_CFG 2>&1 | sed "s#^#${PREFIX}: #" ; exit ${PIPESTATUS[0]} ) &
|
|
done
|
|
wait
|
|
echo "${FUNCNAME[0]}: out"
|
|
}
|
|
|
|
update_cgcs_repo () {
|
|
local REPO_NAME=$1
|
|
(
|
|
cd $MY_REPO/$REPO_NAME/
|
|
|
|
local CURR_HEAD=$(git rev-parse HEAD)
|
|
local LAST_HEAD_FILE="$MY_REPO/$REPO_NAME/.last_head"
|
|
local LAST_HEAD_FILE_OLD="$MY_WORKSPACE/$REPO_NAME.last_head"
|
|
local CHANGED
|
|
local NEW_UNTRACKED
|
|
local NEED_REBUILD
|
|
local NEED_MOCK_CLEAN=0
|
|
local d
|
|
|
|
if [ -f LAST_HEAD_FILE_OLD -a ! -f LAST_HEAD_FILE ]; then
|
|
\cp LAST_HEAD_FILE_OLD LAST_HEAD_FILE
|
|
fi
|
|
|
|
local LAST_HEAD=$(cat $LAST_HEAD_FILE | head -n 1)
|
|
|
|
for d in "Binary" "Source"; do
|
|
NEED_REBUILD=0
|
|
if [ ! -d $d/repodata ]; then
|
|
NEED_REBUILD=1
|
|
fi
|
|
if [ "$CURR_HEAD" != "$LAST_HEAD" ]; then
|
|
NEED_REBUILD=1
|
|
fi
|
|
|
|
CHANGED=$(git diff --name-only | grep $d)
|
|
if [ "x$CHANGED" != "x" ]; then
|
|
NEED_REBUILD=1
|
|
fi
|
|
|
|
NEW_UNTRACKED=$(git ls-files . --exclude-standard --others | grep $d)
|
|
if [ "x$NEW_UNTRACKED" != "x" ]; then
|
|
NEED_REBUILD=1
|
|
fi
|
|
|
|
if [ $NEED_REBUILD -eq 1 ]; then
|
|
NEED_MOCK_CLEAN=1
|
|
echo ""
|
|
echo "Need to recreate $REPO_NAME/$d/repodata"
|
|
mkdir -p $d
|
|
if [ -d $d/repodata ]; then
|
|
update_repodata "$d"
|
|
else
|
|
recreate_repodata "$d"
|
|
fi
|
|
fi
|
|
done
|
|
echo "$CURR_HEAD" > $LAST_HEAD_FILE
|
|
\cp $LAST_HEAD_FILE $LAST_HEAD_FILE_OLD
|
|
if [ $NEED_MOCK_CLEAN -eq 1 ]; then
|
|
echo ""
|
|
echo "Need to clean mock"
|
|
mock_clean
|
|
set_mock_symlinks $MY_BUILD_CFG
|
|
fi
|
|
)
|
|
}
|
|
|
|
mock_clean_mounts_dir () {
|
|
local MOUNT=$1
|
|
local RC
|
|
|
|
if [ "$MOUNT" == "" ]; then
|
|
return 1
|
|
fi
|
|
mount | grep "$MOUNT" >> /dev/null
|
|
if [ $? -eq 0 ]; then
|
|
RC=1
|
|
which mock_cache_umount >> /dev/null
|
|
if [ $? -eq 0 ]; then
|
|
echo "umount '$MOUNT'"
|
|
mock_cache_umount "$MOUNT"
|
|
if [ $? -eq 0 ]; then
|
|
RC=0
|
|
fi
|
|
fi
|
|
if [ $RC -eq 1 ]; then
|
|
echo "ERROR: Directory '$MOUNT' is already mounted and will cause a build failure within mock."
|
|
echo "Ask your system administrator to umount '$MOUNT'."
|
|
exit 1
|
|
fi
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
mock_clean_mounts_cfg () {
|
|
local CFG=$1
|
|
local ROOT_DIR=$(mock_get_root_dir $CFG)
|
|
local YUM_CACHE_MOUNT=$(readlink -f "$ROOT_DIR/root/var/cache/yum")
|
|
local PROC_MOUNT=$(readlink -f "$ROOT_DIR/root/proc")
|
|
local SYS_MOUNT=$(readlink -f "$ROOT_DIR/root/sys")
|
|
local SHM_MOUNT=$(readlink -f "$ROOT_DIR/root/dev/shm")
|
|
local PTS_MOUNT=$(readlink -f "$ROOT_DIR/root/dev/pts")
|
|
local MOUNT
|
|
|
|
echo "${FUNCNAME[0]}: $CFG"
|
|
for MOUNT in "$YUM_CACHE_MOUNT" "$PROC_MOUNT" "$SYS_MOUNT" "$SHM_MOUNT" "$PTS_MOUNT"; do
|
|
mock_clean_mounts_dir "$MOUNT"
|
|
done
|
|
}
|
|
|
|
mock_clean_mounts () {
|
|
echo "${FUNCNAME[0]}: in"
|
|
for SUB_CFG in $(mock_sub_configs); do
|
|
local PREFIX=$(echo $SUB_CFG | rev | cut -d . -f 2 | rev)
|
|
( mock_clean_mounts_cfg $SUB_CFG 2>&1 | sed "s#^#${PREFIX}: #" ; exit ${PIPESTATUS[0]} ) &
|
|
done
|
|
wait
|
|
echo "${FUNCNAME[0]}: out"
|
|
}
|
|
|
|
clean_yum_cache_cfg () {
|
|
local CFG=$1
|
|
local CACHE_DIR=$(mock_get_cache_dir $CFG)
|
|
local ROOT_DIR=$(mock_get_root_dir $CFG)
|
|
local RC=0
|
|
|
|
echo "${FUNCNAME[0]}: $CFG"
|
|
|
|
local YUM_CACHE_MOUNT=$(readlink -f "$ROOT_DIR/root/var/cache/yum")
|
|
local YUM_CACHE_LOCK="$CACHE_DIR/mock/yum_cache/yumcache.lock"
|
|
# echo "clean_yum_cache YUM_CACHE_MOUNT='$YUM_CACHE_MOUNT' YUM_CACHE_LOCK='$YUM_CACHE_LOCK'"
|
|
|
|
if [ "$YUM_CACHE_MOUNT" != "" ]; then
|
|
mock_clean_mounts_dir "$YUM_CACHE_MOUNT"
|
|
fi
|
|
|
|
if [ -f "$YUM_CACHE_LOCK" ]; then
|
|
RC=1
|
|
which mock_cache_unlock >> /dev/null
|
|
if [ $? -eq 0 ]; then
|
|
mock_cache_unlock "$YUM_CACHE_LOCK"
|
|
if [ $? -eq 0 ]; then
|
|
RC=0
|
|
fi
|
|
fi
|
|
if [ $RC -eq 1 ]; then
|
|
echo "ERROR: File '$YUM_CACHE_LOCK' exists and will cause a build failure within mock."
|
|
echo "Ask your system administrator to delete '$YUM_CACHE_LOCK'."
|
|
exit 1
|
|
fi
|
|
fi
|
|
return $RC
|
|
}
|
|
|
|
|
|
clean_yum_cache () {
|
|
echo "${FUNCNAME[0]}: in"
|
|
for SUB_CFG in $(mock_sub_configs); do
|
|
local PREFIX=$(echo $SUB_CFG | rev | cut -d . -f 2 | rev)
|
|
( clean_yum_cache_cfg $SUB_CFG 2>&1 | sed "s#^#${PREFIX}: #" ; exit ${PIPESTATUS[0]} ) &
|
|
done
|
|
wait
|
|
echo "${FUNCNAME[0]}: out"
|
|
}
|
|
|
|
mock_update_cfg () {
|
|
local CFG=$1
|
|
echo "${FUNCNAME[0]}: $CFG"
|
|
echo "=================================="
|
|
set_mock_symlinks $CFG
|
|
echo "$MOCK -r $CFG --configdir $(dirname $CFG) --update"
|
|
trapwrap_n $CFG $MOCK -r $CFG --configdir $(dirname $CFG) --update
|
|
echo "=================================="
|
|
}
|
|
|
|
mock_init_cfg () {
|
|
local CFG=$1
|
|
echo "${FUNCNAME[0]}: $CFG"
|
|
echo "=================================="
|
|
set_mock_symlinks $CFG
|
|
echo "$MOCK -r $CFG --configdir $(dirname $CFG) --init"
|
|
trapwrap_n $CFG $MOCK -r $CFG --configdir $(dirname $CFG) --init
|
|
echo "=================================="
|
|
}
|
|
|
|
mock_update_or_init_cfg () {
|
|
local CFG=$1
|
|
local TMP
|
|
local RC
|
|
echo "${FUNCNAME[0]}: $CFG"
|
|
local ROOT_DIR=$(mock_get_root_dir $CFG)
|
|
|
|
TMP=$(mktemp /tmp/mock_update_or_init_cfg_XXXXXX)
|
|
if [ $? -ne 0 ]; then
|
|
echo "${FUNCNAME[0]}: mktemp failed"
|
|
return 1
|
|
fi
|
|
if [ -d $ROOT_DIR/root ]; then
|
|
echo "Updating the mock environment"
|
|
set_mock_symlinks $CFG
|
|
echo "$MOCK -r $CFG --configdir $(dirname $CFG) --update"
|
|
trapwrap_n $CFG $MOCK -r $CFG --configdir $(dirname $CFG) --update &> $TMP
|
|
RC=$?
|
|
else
|
|
echo "Init the mock environment"
|
|
set_mock_symlinks $CFG
|
|
echo "$MOCK -r $CFG --configdir $(dirname $CFG) --init"
|
|
trapwrap_n $CFG $MOCK -r $CFG --configdir $(dirname $CFG) --init &> $TMP
|
|
RC=$?
|
|
fi
|
|
if [ $RC -ne 0 ]; then
|
|
cat $TMP
|
|
fi
|
|
\rm -f $TMP
|
|
return $RC
|
|
}
|
|
|
|
mock_update_or_init () {
|
|
echo "${FUNCNAME[0]}: in"
|
|
for SUB_CFG in $(mock_sub_configs); do
|
|
local PREFIX=$(echo $SUB_CFG | rev | cut -d . -f 2 | rev)
|
|
( mock_update_or_init_cfg $SUB_CFG 2>&1 | sed "s#^#${PREFIX}: #" ; exit ${PIPESTATUS[0]} ) &
|
|
done
|
|
wait
|
|
echo "${FUNCNAME[0]}: out"
|
|
}
|
|
|
|
if [ "x$PROJECT" == "x" ]; then
|
|
echo "PROJECT environmnet variable is not defined."
|
|
exit 1
|
|
fi
|
|
|
|
if [ "x$SRC_BUILD_ENVIRONMENT" == "x" ]; then
|
|
echo "SRC_BUILD_ENVIRONMENT environmnet variable is not defined."
|
|
exit 1
|
|
fi
|
|
|
|
NO_DESCENDANTS=0
|
|
NO_REQUIRED=0
|
|
NO_AUTOCLEAN=0
|
|
NO_BUILD_INFO=0
|
|
HELP=0
|
|
CLEAN_FLAG=0
|
|
FORMAL_FLAG=0
|
|
CAREFUL=0
|
|
|
|
# read the options
|
|
TEMP=$(getopt -o ha::bc: --long parallel,std,rt,installer,no-required,no-descendants,no-autoclean,no-build-info,clean,tmpfs-clean,formal,careful,help,arga::,argb,argc: -n "$ME" -- "$@")
|
|
|
|
if [ $? -ne 0 ]; then
|
|
usage
|
|
exit 1
|
|
fi
|
|
|
|
eval set -- "$TEMP"
|
|
|
|
export BUILD_TYPE=std
|
|
trap my_exit EXIT
|
|
|
|
# extract options and their arguments into variables.
|
|
while true ; do
|
|
case "$1" in
|
|
-a|--arga)
|
|
case "$2" in
|
|
"") ARG_A='some default value' ; shift 2 ;;
|
|
*) ARG_A=$2 ; shift 2 ;;
|
|
esac ;;
|
|
-b|--argb) ARG_B=1 ; shift ;;
|
|
--careful) CAREFUL=1 ; shift ;;
|
|
--no-descendants) NO_DESCENDANTS=1 ; shift ;;
|
|
--no-required) NO_REQUIRED=1 ; shift ;;
|
|
--no-autoclean) NO_AUTOCLEAN=1; shift ;;
|
|
--no-build-info) NO_BUILD_INFO=1; shift ;;
|
|
--formal) FORMAL_FLAG=1; shift ;;
|
|
--std) BUILD_TYPE=std; shift ;;
|
|
--rt) BUILD_TYPE=rt; shift ;;
|
|
--installer) BUILD_TYPE=installer; shift ;;
|
|
-h|--help) HELP=1 ; shift ;;
|
|
--clean) CLEAN_FLAG=1 ; shift ;;
|
|
--tmpfs-clean) if [ -n "$MY_WORKSPACE" ]; then export MY_WORKSPACE=$MY_WORKSPACE/$BUILD_TYPE; exit 0; fi ;;
|
|
-c|--argc)
|
|
case "$2" in
|
|
"") shift 2 ;;
|
|
*) ARG_C=$2 ; shift 2 ;;
|
|
esac ;;
|
|
--parallel) shift ;;
|
|
--) shift ; break ;;
|
|
*) echo "Internal error!" ; exit 1 ;;
|
|
esac
|
|
done
|
|
|
|
|
|
# Reset variables
|
|
if [ -n "$MY_WORKSPACE" ]; then
|
|
export MY_WORKSPACE_TOP=${MY_WORKSPACE_TOP:-$MY_WORKSPACE}
|
|
export MY_WORKSPACE=$MY_WORKSPACE_TOP/$BUILD_TYPE
|
|
else
|
|
export MY_PATCH_WORKSPACE_TOP=${MY_PATCH_WORKSPACE_TOP:-$MY_PATCH_WORKSPACE}
|
|
export MY_PATCH_WORKSPACE=$MY_PATCH_WORKSPACE_TOP/$BUILD_TYPE
|
|
fi
|
|
|
|
export MY_BUILD_DIR_TOP=${MY_BUILD_DIR_TOP:-$MY_BUILD_DIR}
|
|
export MY_BUILD_DIR=$MY_BUILD_DIR_TOP/$BUILD_TYPE
|
|
|
|
export MY_BUILD_ENVIRONMENT_TOP=${MY_BUILD_ENVIRONMENT_TOP:-$MY_BUILD_ENVIRONMENT}
|
|
export MY_BUILD_ENVIRONMENT=$MY_BUILD_ENVIRONMENT_TOP-$BUILD_TYPE
|
|
|
|
export MY_SRC_RPM_BUILD_DIR=$MY_BUILD_DIR/rpmbuild
|
|
export MY_BUILD_ENVIRONMENT_FILE=$MY_BUILD_ENVIRONMENT.cfg
|
|
export MY_BUILD_CFG=$MY_WORKSPACE/$MY_BUILD_ENVIRONMENT_FILE
|
|
export MY_MOCK_ROOT=$MY_WORKSPACE/mock/root
|
|
|
|
IMAGE_INC_FILE="${MY_WORKSPACE}/image.inc"
|
|
image_inc_list iso ${BUILD_TYPE} ${DISTRO} > "${IMAGE_INC_FILE}"
|
|
|
|
LAST_PLATFORM_RELEASE_FILE="$MY_BUILD_DIR/.platform_release"
|
|
|
|
TARGETS=$@
|
|
|
|
if [ $HELP -eq 1 ]; then
|
|
usage
|
|
exit 0
|
|
fi
|
|
|
|
if [ $FORMAL_FLAG -eq 1 ]; then
|
|
export FORMAL_BUILD=1
|
|
fi
|
|
|
|
SRC_ROOT="$MY_REPO"
|
|
if [ "x$MY_REPO" == "x" ]; then
|
|
SRC_ROOT=$HOME
|
|
fi
|
|
|
|
BUILD_ROOT="$MY_WORKSPACE"
|
|
if [ "x$MY_WORKSPACE" == "x" ]; then
|
|
BUILD_ROOT="$MY_PATCH_WORKSPACE"
|
|
|
|
if [ "x$MY_PATCH_WORKSPACE" == "x" ]; then
|
|
echo "ERROR: reqiure one of MY_WORKSPACE or MY_PATCH_WORKSPACE be defined"
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
export BUILD_BASE="$BUILD_ROOT"
|
|
export CCACHE_DIR="$BUILD_ROOT/.ccache"
|
|
export RESULT_DIR="$BUILD_BASE/results"
|
|
export SRC_BASE="$SRC_ROOT"
|
|
export STX_BASE=$SRC_BASE/stx
|
|
|
|
if [ "x$MY_SRC_RPM_BUILD_DIR" != "x" ]; then
|
|
RPM_BUILD_ROOT=$MY_SRC_RPM_BUILD_DIR
|
|
else
|
|
RPM_BUILD_ROOT=$BUILD_BASE/rpmbuild
|
|
fi
|
|
|
|
RELEASE_INFO_FILE=$STX_BASE/stx-integ/utilities/build-info/release-info.inc
|
|
if [ -f $RELEASE_INFO_FILE ]; then
|
|
source $RELEASE_INFO_FILE
|
|
else
|
|
echo "ERROR: failed to find RELEASE_INFO_FILE=$RELEASE_INFO_FILE"
|
|
exit 1
|
|
fi
|
|
|
|
if [ "x$PLATFORM_RELEASE" == "x" ]; then
|
|
echo "ERROR: PLATFORM_RELEASE is not defined in $RELEASE_INFO_FILE"
|
|
exit 1
|
|
fi
|
|
|
|
export RPM_BUILD_BASE="$RPM_BUILD_ROOT"
|
|
export SRPM_OUT="$RPM_BUILD_BASE/SRPMS"
|
|
export RPM_DIR="$RPM_BUILD_BASE/RPMS"
|
|
export SPECS_DIR="$RPM_BUILD_BASE/SPECS"
|
|
export SOURCES_DIR="$RPM_BUILD_BASE/SOURCES"
|
|
export PLATFORM_RELEASE
|
|
|
|
if [ ! -d $BUILD_BASE ]; then
|
|
echo "ERROR: expected to find directory at '$BUILD_BASE'"
|
|
exit 1
|
|
fi
|
|
|
|
|
|
mkdir -p $RPM_BUILD_BASE
|
|
if [ $? -ne 0 ]; then
|
|
echo "ERROR: Failed to create directory '$RPM_BUILD_BASE'"
|
|
exit 1
|
|
fi
|
|
|
|
mkdir -p $SRPM_OUT/repodata
|
|
if [ $? -ne 0 ]; then
|
|
echo "ERROR: Failed to create directory '$SRPM_OUT/repodata'"
|
|
exit 1
|
|
fi
|
|
|
|
mkdir -p $RPM_DIR/repodata
|
|
if [ $? -ne 0 ]; then
|
|
echo "ERROR: Failed to create directory '$RPM_DIR/repodata'"
|
|
exit 1
|
|
fi
|
|
|
|
if [ "x$MY_BUILD_CFG" == "x" ];then
|
|
echo "ERROR: reqiure MY_BUILD_CFG to be defined"
|
|
exit 1
|
|
fi
|
|
|
|
export BUILD_CFG="$MY_BUILD_CFG"
|
|
|
|
# Place build-time environement variables in mock environment
|
|
echo "FORMAL_BUILD=$FORMAL_BUILD"
|
|
echo "modify-build-cfg $BUILD_CFG"
|
|
${BUILD_RPMS_PARALLEL_DIR}/modify-build-cfg $BUILD_CFG
|
|
if [ $? -ne 0 ]; then
|
|
echo "Could not modifiy $BUILD_CFG";
|
|
exit 1
|
|
fi
|
|
|
|
if [ ! -f $BUILD_CFG ]; then
|
|
echo "ERROR: Mock config file not found at '$BUILD_CFG'"
|
|
exit 1
|
|
fi
|
|
|
|
# Create symlinks from /var/... to /localdisk/loadbuild/... if on a build server
|
|
|
|
set_mock_symlinks $MY_BUILD_CFG
|
|
|
|
if [ $CLEAN_FLAG -eq 1 ]; then
|
|
umount_mock_root_as_tmpfs_all
|
|
fi
|
|
|
|
if [ $CLEAN_FLAG -eq 0 ]; then
|
|
ls $SRPM_OUT/*.src.rpm &>> /dev/null
|
|
if [ $? -ne 0 ]; then
|
|
echo "Nothing to build in '$SRPM_OUT'"
|
|
exit 0
|
|
fi
|
|
fi
|
|
|
|
ALL=0
|
|
UNRESOLVED_TARGETS=" "
|
|
if [ "x$TARGETS" == "x" ]; then
|
|
echo "make: all"
|
|
ALL=1
|
|
else
|
|
echo "make: $TARGETS"
|
|
UNRESOLVED_TARGETS="$TARGETS"
|
|
fi
|
|
|
|
if [ "$BUILD_TYPE" != "std" ]; then
|
|
# This defines ...
|
|
# STD_SRPM_PKG_NAME_TO_PATH
|
|
# STD_SRPM_PKG_NAMES
|
|
srpm_build_std_dictionary $MY_WORKSPACE_TOP/std/rpmbuild/SRPMS
|
|
fi
|
|
|
|
# This defines ...
|
|
# SRPM_PKG_NAME_TO_PATH
|
|
# SRPM_PKG_NAMES
|
|
srpm_build_dictionary $SRPM_OUT
|
|
|
|
SRPMS_TO_COMPILE=()
|
|
SRPMS_LIST=""
|
|
RPMS_LIST=""
|
|
|
|
clean_list () {
|
|
local SRPMS_LIST="$1"
|
|
local RPMS_LIST="$2"
|
|
local ALL=$3
|
|
local TARGET
|
|
local b
|
|
local d
|
|
local f
|
|
local n
|
|
local p
|
|
local r
|
|
local s
|
|
local sn
|
|
local t
|
|
local SPEC_DIR
|
|
|
|
echo "${FUNCNAME[0]}: '$SRPMS_LIST' '$RPMS_LIST' '$ALL'"
|
|
if [ $ALL -eq 1 ]; then
|
|
for r in $(find $RPM_DIR -name "*.rpm"); do
|
|
\rm -f -v $r
|
|
done
|
|
|
|
if [ $CLEAN_FLAG -eq 1 ]; then
|
|
for d in $(find $SPECS_DIR -type d); do
|
|
echo "rm -rf $d"
|
|
\rm -rf "$d" 2>> /dev/null
|
|
done
|
|
fi
|
|
|
|
for d in $(find $RESULT_DIR/$USER-* -maxdepth 1 -type d 2>> /dev/null); do
|
|
echo "rm -rf $d"
|
|
\rm -rf "$d" 2>> /dev/null
|
|
done
|
|
else
|
|
for s in $SRPMS_LIST; do
|
|
(
|
|
SPEC_DIR=$(spec_cache_dir_from_srpm $s)
|
|
sn=$(rpm_get_name $s)
|
|
update_spec_cache $s
|
|
|
|
TARGET=$(rpm -qp --qf '%{NAME}-%{VERSION}\n' "$s")
|
|
for d in $(find $RESULT_DIR/$USER-* -maxdepth 1 -name "$TARGET*" 2>> /dev/null); do
|
|
echo "rm -rf $d"
|
|
\rm -rf "$d" 2>> /dev/null
|
|
done
|
|
|
|
for p in $(ls -1 $SPEC_DIR/BUILDS); do
|
|
for r in $(find $RESULT_DIR/$USER-* $RPM_DIR -name "$p-*.rpm" 2>> /dev/null); do
|
|
if [ -f $r ]; then
|
|
n=$(rpm_get_name $r)
|
|
if [ "$n" == "$p" ]; then
|
|
if [[ "$r" == *.src.rpm ]]; then
|
|
if [ "$n" != "$sn" ]; then
|
|
continue
|
|
fi
|
|
|
|
TARGET=$(rpm -qp --qf '%{NAME}-%{VERSION}\n' "$r")
|
|
for d in $(find $RESULT_DIR/$USER-* -maxdepth 1 -name "$TARGET*" 2>> /dev/null); do
|
|
echo "rm -rf $d"
|
|
\rm -rf "$d" 2>> /dev/null
|
|
done
|
|
|
|
else
|
|
rs=$(rpm_get_srpm $r)
|
|
if [[ "$rs" != "$sn"-[0-9]* ]]; then
|
|
continue
|
|
fi
|
|
fi
|
|
|
|
\rm -f -v $r
|
|
fi
|
|
fi
|
|
done
|
|
done
|
|
|
|
TARGET=$(rpm -qp --qf '%{NAME}-%{VERSION}\n' "$s")
|
|
|
|
if [ $CLEAN_FLAG -eq 1 ]; then
|
|
for d in $(find $SPECS_DIR -type d -name "$TARGET*" 2>> /dev/null); do
|
|
echo "rm -rf $d"
|
|
\rm -rf "$d" 2>> /dev/null
|
|
done
|
|
fi
|
|
|
|
for d in $(find $RESULT_DIR/$USER-* -maxdepth 1 -name "$TARGET*" 2>> /dev/null); do
|
|
echo "rm -rf $d"
|
|
\rm -rf "$d" 2>> /dev/null
|
|
done
|
|
) &
|
|
done
|
|
echo "waiting on file deletion"
|
|
wait
|
|
echo "wait complete"
|
|
fi
|
|
|
|
echo ""
|
|
echo "Cleaning repodata"
|
|
for d in $(find -L $MY_WORKSPACE/rpmbuild $MY_WORKSPACE/results -type d -name repodata); do
|
|
recreate_repodata $(dirname $d)
|
|
done
|
|
|
|
echo ""
|
|
echo "Cleaning mock environment"
|
|
echo ""
|
|
|
|
if [ $ALL -eq 1 ]; then
|
|
# Wipe everything
|
|
if [ "x$RPM_DIR" != "x" ]; then
|
|
\rm -rf -v $RPM_DIR/* 2>> /dev/null
|
|
fi
|
|
|
|
\rm -f -v $RESULT_DIR/mockchain.log 2>> /dev/null
|
|
mock_clean
|
|
else
|
|
# Wipe only traces of what we built
|
|
mock_partial_clean "$SRPMS_LIST" "$RPMS_LIST"
|
|
fi
|
|
}
|
|
|
|
echo "ALL=$ALL"
|
|
(
|
|
trap my_exit EXIT
|
|
trap my_sigint INT
|
|
trap my_sighup HUP
|
|
echo "$CMDLINE"
|
|
echo "ALL=$ALL"
|
|
|
|
if [ $CLEAN_FLAG -eq 0 ]; then
|
|
if [ -d $RESULT_DIR ]; then
|
|
# in case previous build recieved a ctrl-C and didn't get a change to copy it's successful work into RPM_DIR
|
|
for d in $(find $RESULT_DIR -name '*.rpm' | grep -v '[.]src[.]rpm' | xargs --no-run-if-empty --max-args=1 dirname | sort -u); do
|
|
rsync -u $d/*.rpm $RPM_DIR
|
|
done
|
|
for d in $(find -L $RESULT_DIR -type d -name repodata); do
|
|
update_repodata $(dirname $d)
|
|
done
|
|
fi
|
|
fi
|
|
|
|
spec_cache_dir_from_srpm () {
|
|
local SRPM=${1}
|
|
local SPEC_DIR=$(echo $SRPM | sed 's#/SRPMS/#/SPECS/#')
|
|
echo "$SPEC_DIR"
|
|
}
|
|
|
|
update_spec_cache () {
|
|
local SRPM=${1}
|
|
local SPEC_DIR=$(spec_cache_dir_from_srpm $SRPM)
|
|
local NEED_UPDATE=0
|
|
|
|
if [ ! -d $SPEC_DIR ]; then
|
|
mkdir -p $SPEC_DIR
|
|
NEED_UPDATE=1
|
|
else
|
|
find "$SPEC_DIR" -name '*.spec' | grep 'spec' >> /dev/null
|
|
if [ $? -ne 0 ]; then
|
|
# No spec file
|
|
NEED_UPDATE=1
|
|
fi
|
|
|
|
find "$SPEC_DIR" -not -newermm "$SRPM" -name '*.spec' | grep -q 'spec'
|
|
if [ $? -eq 0 ]; then
|
|
# spec is older than src.rpm
|
|
NEED_UPDATE=1
|
|
fi
|
|
fi
|
|
|
|
if [ $NEED_UPDATE -ne 0 ]; then
|
|
(
|
|
cd $SPEC_DIR
|
|
\rm -rf BUILDS BUILDS_VR *.spec 2>> /dev/null
|
|
mkdir -p BUILDS
|
|
mkdir -p NAMES
|
|
mkdir -p SERVICES
|
|
mkdir -p BUILDS_VR
|
|
rpm2cpio $SRPM | cpio -civ '*.spec'
|
|
if [ $? -ne 0 ]; then
|
|
echo "ERROR: no spec file found in '$SRPM'"
|
|
fi
|
|
for f in $(find . -name '*.spec' | sort -V); do
|
|
touch $f
|
|
for p in $(spec_list_ver_rel_packages $f); do
|
|
touch "BUILDS_VR/$p"
|
|
done
|
|
for p in $(spec_list_packages $f); do
|
|
touch "BUILDS/$p"
|
|
done
|
|
for p in $(spec_find_tag Name $f 2>> /dev/null); do
|
|
touch "NAMES/$p"
|
|
done
|
|
for p in $(spec_find_global service $f 2>> /dev/null); do
|
|
touch "SERVICES/$p"
|
|
done
|
|
done
|
|
)
|
|
fi
|
|
}
|
|
|
|
# Find the list of packages we must compile
|
|
|
|
echo "Find the list of packages we must compile"
|
|
|
|
NEED_BUILD_DIR=$(mktemp -d $MY_WORKSPACE/tmp/$USER-$ME-need-build-XXXXXX)
|
|
if [ $? -ne 0 ] || [ "x$NEED_BUILD_DIR" == "x" ]; then
|
|
echo "Failed to create temp directory under $MY_WORKSPACE/tmp"
|
|
exit 1
|
|
fi
|
|
|
|
UNRESOLVED_TARGETS_DIR=$(mktemp -d $MY_WORKSPACE/tmp/$USER-$ME-unresolved-XXXXXX)
|
|
if [ $? -ne 0 ] || [ "x$UNRESOLVED_TARGETS_DIR" == "x" ]; then
|
|
echo "Failed to create temp directory under $MY_WORKSPACE/tmp"
|
|
exit 1
|
|
fi
|
|
|
|
for n in ${UNRESOLVED_TARGETS}; do
|
|
touch $UNRESOLVED_TARGETS_DIR/$n
|
|
done
|
|
|
|
PLATFORM_RELEASE_CHANGED=0
|
|
if [ -f $LAST_PLATFORM_RELEASE_FILE ]; then
|
|
LAST_PLATFORM_RELEASE=$(cat $LAST_PLATFORM_RELEASE_FILE)
|
|
if [ "$LAST_PLATFORM_RELEASE" != "$PLATFORM_RELEASE" ]; then
|
|
PLATFORM_RELEASE_CHANGED=1
|
|
fi
|
|
else
|
|
PLATFORM_RELEASE_CHANGED=1
|
|
fi
|
|
|
|
for n in "${SRPM_PKG_NAMES[@]}"; do
|
|
(
|
|
s=${SRPM_PKG_NAME_TO_PATH[$n]}
|
|
SPEC_DIR=$(spec_cache_dir_from_srpm $s)
|
|
update_spec_cache $s
|
|
# echo "$BASHPID: considering $n: $s, SPEC_DIR=$SPEC_DIR"
|
|
NEED_BUILD=0
|
|
|
|
if [ "x$TARGETS" == "x" ]; then
|
|
# We weren't given a list of build targets.
|
|
# Build anything missing or out of date.
|
|
NEED_BUILD=0
|
|
BN=$(basename ${s//.src.rpm/})
|
|
|
|
if [ -f $RESULT_DIR/$MY_BUILD_ENVIRONMENT/$BN/fail ]; then
|
|
echo "Found: $RESULT_DIR/$MY_BUILD_ENVIRONMENT/$BN/fail"
|
|
echo "Previous build of $BN failed"
|
|
NEED_BUILD=1
|
|
elif [ ! -f $RESULT_DIR/$MY_BUILD_ENVIRONMENT/$BN/success ]; then
|
|
echo "Not Found: $RESULT_DIR/$MY_BUILD_ENVIRONMENT/$BN/success"
|
|
echo "No previous build of $BN"
|
|
NEED_BUILD=1
|
|
else
|
|
LOCAL_RPMS_VRA_LIST=$(ls -1 $SPEC_DIR/BUILDS_VR | tr '\n' ' ')
|
|
|
|
for f in $LOCAL_RPMS_VRA_LIST; do
|
|
m=$(find $RPM_DIR/$f*rpm 2>> /dev/null | wc -l)
|
|
if [ $m -eq 0 ] && [ -f "$UNBUILT_PATTERN_FILE" ]; then
|
|
echo $f | grep -f "$UNBUILT_PATTERN_FILE" >> /dev/null && m=1
|
|
if [ $m -eq 1 ]; then
|
|
echo "Excluding '$f' due to match in UNBUILT_PATTERN_FILE '$UNBUILT_PATTERN_FILE'"
|
|
if [ -f "$IMAGE_INC_FILE" ] ; then
|
|
for t in $(grep -v '^#' "$IMAGE_INC_FILE"); do
|
|
ii=$(echo $f | grep "^$t-[0-9]" | wc -l)
|
|
if [ $ii -gt 0 ]; then
|
|
echo "Including '$f' due to match in IMAGE_INC_FILE '$IMAGE_INC_FILE' due to pattern '^$t-[0-9]'"
|
|
m=0
|
|
break
|
|
fi
|
|
done
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
newer=$(find $RPM_DIR/$f*rpm -type f -not -newermm $s 2>> /dev/null | wc -l)
|
|
# echo "$m $newer=find $RPM_DIR/$f*rpm -type f -not -newermm $s 2>> /dev/null | wc -l"
|
|
if [ $m -eq 0 ] || [ $newer -gt 0 ] || [ $CLEAN_FLAG -eq 1 ]; then
|
|
if [ $newer -gt 0 ]; then
|
|
echo "Including '$f' due to newer code"
|
|
find $RPM_DIR/$f*rpm -type f -not -newermm $s
|
|
else
|
|
if [ $m -eq 0 ]; then
|
|
echo "Including '$f' due to m=0"
|
|
else
|
|
if [ $CLEAN_FLAG -eq 1 ]; then
|
|
echo "Including '$f' due to CLEAN_FLAG=1"
|
|
fi
|
|
fi
|
|
fi
|
|
NEED_BUILD=1
|
|
break
|
|
fi
|
|
done
|
|
fi
|
|
else
|
|
# We were given a list of build targets,
|
|
# try to find packages matching that list.
|
|
NEED_BUILD=0
|
|
for f in $(find $SPEC_DIR/NAMES $SPEC_DIR/SERVICES $SPEC_DIR/BUILDS -type f 2>> /dev/null); do
|
|
b=$(basename $f)
|
|
for t in $TARGETS; do
|
|
if [[ ( "$b" == "$t" ) || ( ( "$BUILD_TYPE" == "rt" ) && ( "$b" == "$t-rt" ) ) ]]; then
|
|
echo "Including named target '$f'"
|
|
TARGET_FOUND=$t
|
|
NEED_BUILD=1
|
|
# UNRESOLVED_TARGETS=$(echo "$UNRESOLVED_TARGETS" | sed "s/\(^\|[[:space:]]\)$TARGET_FOUND\([[:space:]]\|$\)/ /g")
|
|
if [ -f $UNRESOLVED_TARGETS_DIR/$TARGET_FOUND ]; then
|
|
\rm -f $UNRESOLVED_TARGETS_DIR/$TARGET_FOUND
|
|
fi
|
|
break
|
|
fi
|
|
done
|
|
done
|
|
fi
|
|
|
|
if [ $NO_BUILD_INFO -eq 0 ]; then
|
|
if [ "$n" == "build-info" ]; then
|
|
echo "Including '$n' by default"
|
|
NEED_BUILD=1
|
|
fi
|
|
fi
|
|
|
|
if [ $PLATFORM_RELEASE_CHANGED -eq 1 ]; then
|
|
grep '%{platform_release}' $SPEC_DIR/*.spec >> /dev/null
|
|
if [ $? -eq 0 ]; then
|
|
echo "Including '$n' due to changed platform_release"
|
|
NEED_BUILD=1
|
|
fi
|
|
fi
|
|
|
|
if [ $NEED_BUILD -eq 1 ]; then
|
|
echo "found $n: $s"
|
|
touch "$NEED_BUILD_DIR/$n"
|
|
# SRPMS_TO_COMPILE+=("$n")
|
|
fi
|
|
) &
|
|
done
|
|
echo "waiting"
|
|
wait
|
|
for n in $(ls -1 $NEED_BUILD_DIR); do
|
|
SRPMS_TO_COMPILE+=("$n")
|
|
done
|
|
UNRESOLVED_TARGETS=" "
|
|
for n in $(ls -1 $UNRESOLVED_TARGETS_DIR); do
|
|
UNRESOLVED_TARGETS="$UNRESOLVED_TARGETS $n"
|
|
done
|
|
\rm -rf $NEED_BUILD_DIR
|
|
\rm -rf $UNRESOLVED_TARGETS_DIR
|
|
|
|
ORIG_SRPMS_TO_COMPILE=( ${SRPMS_TO_COMPILE[@]} )
|
|
|
|
echo "SRPMS_TO_COMPILE = ${SRPMS_TO_COMPILE[@]}"
|
|
|
|
|
|
# adding dependant packages
|
|
if [ $CLEAN_FLAG -eq 0 ] && [ $NO_DESCENDANTS -eq 0 ] && [ -f $SRPM_DIRECT_DESCENDANTS_FILE ]; then
|
|
echo
|
|
echo "adding dependant packages"
|
|
|
|
# This array will accumulate a list of secondary build targets.
|
|
TRANSITIVE_SRPMS_TO_COMPILE=()
|
|
|
|
# Add packages that directly depend on the primary build targets in ORIG_SRPMS_TO_COMPILE
|
|
for n in ${ORIG_SRPMS_TO_COMPILE[@]}; do
|
|
needs=( $(grep "^$n;" "$SRPM_DIRECT_DESCENDANTS_FILE" | sed "s/$n;//" | sed 's/,/ /g'; alt_n=$(echo "$n" | sed 's#-rt$##'); if [ "$alt_n" != "$n" ]; then grep "^$alt_n;" "$SRPM_DIRECT_DESCENDANTS_FILE" | sed "s/$alt_n;//" | sed 's/,/ /g' | sed 's#\([^[:space:]]*\)#\1-rt#g'; fi ) )
|
|
|
|
# intersection of 'needs' and 'SRPM_PKG_NAMES' ... i.e. what should be compiled that we have source for
|
|
compilable_needs=( $(intersection needs SRPM_PKG_NAMES) )
|
|
TRANSITIVE_SRPMS_TO_COMPILE=( $(union compilable_needs TRANSITIVE_SRPMS_TO_COMPILE) )
|
|
done
|
|
|
|
# For non-std build, and if non specific build targets are named, then search all
|
|
# packages that we might build and check if they require a package that DID build
|
|
# in the std build. If so build the package as a secondary target, even though the
|
|
# primary target was from a different build_type.
|
|
if [ "$BUILD_TYPE" != "std" ] && [ $ALL -eq 1 ] && [ -f $SRPM_TO_RPM_MAP_FILE ] && [ -f $SRPM_RPM_DIRECT_REQUIRES_FILE ]; then
|
|
# Test all that we can build ...
|
|
for n in ${SRPM_PKG_NAMES[@]}; do
|
|
contains ORIG_SRPMS_TO_COMPILE $n
|
|
if [ $? -eq 0 ]; then
|
|
# Already on the primary build list, skip it.
|
|
echo "skip $n"
|
|
continue
|
|
fi
|
|
|
|
STD_NEEDS_BUILD=0
|
|
|
|
# Iterate over all binary rpms names produce by the candidate package
|
|
for b in $(grep "^$n;" "$SRPM_TO_RPM_MAP_FILE" | sed "s/$n;//" | sed 's/,/ /g'); do
|
|
# find an rpm file with the rpm name we seek
|
|
for bp in $(find $RPM_DIR -name "$b-[0-9]*.rpm" | grep -v '.src.rpm'); do
|
|
if [ "$b" != "$(rpm_get_name $bp)" ]; then
|
|
# rpm name doesn't match
|
|
continue
|
|
fi
|
|
|
|
# Iterate over binary rpms names required by the candidate package
|
|
for r in $(grep "^$n;" "$SRPM_RPM_DIRECT_REQUIRES_FILE" | sed "s/$n;//" | sed 's/,/ /g'); do
|
|
if [ $r == $n ]; then
|
|
# Ignore self dependency
|
|
continue
|
|
fi
|
|
|
|
# find a required rpm file with the rpm name we seek, AND is newer than the produced rpm file
|
|
for rp in $(find $(echo $RPM_DIR | sed "s#/$BUILD_TYPE/#/std/#") -name "$r-[0-9]*.rpm" -newermm $bp | grep -v '.src.rpm'); do
|
|
if [ "$r" != "$(rpm_get_name $rp)" ]; then
|
|
# rpm name doesn't match
|
|
continue
|
|
fi
|
|
|
|
# Ok, a required rpm is newer than a built rpm, we should rebuild!
|
|
echo "rebuild '$n' due to newer '$r'"
|
|
STD_NEEDS_BUILD=1
|
|
break
|
|
done
|
|
done
|
|
done
|
|
|
|
# Avoid pointless processing if we already have a positive result.
|
|
if [ $STD_NEEDS_BUILD -eq 1 ]; then
|
|
break
|
|
fi
|
|
done
|
|
|
|
if [ $STD_NEEDS_BUILD -eq 1 ]; then
|
|
# Compile is requires due to an updated required package in the std build.
|
|
# Add 'n' to array TRANSITIVE_SRPMS_TO_COMPILE.
|
|
TRANSITIVE_SRPMS_TO_COMPILE=( $(put TRANSITIVE_SRPMS_TO_COMPILE $n) )
|
|
fi
|
|
done
|
|
fi
|
|
|
|
# If the kernel or kernel-rt packages where absent from the primary build targets, but
|
|
# added as a secondary target, then make sure all out-of-tree kernel modules are also
|
|
# added.
|
|
for n in kernel kernel-rt; do
|
|
KERNEL_IN_ORIG=0
|
|
KERNEL_IN_TRANSITIVE=0
|
|
contains ORIG_SRPMS_TO_COMPILE "$n" && KERNEL_IN_ORIG=1
|
|
contains TRANSITIVE_SRPMS_TO_COMPILE "$n" && KERNEL_IN_TRANSITIVE=1
|
|
if [ $KERNEL_IN_TRANSITIVE -eq 1 ] && [ $KERNEL_IN_ORIG -eq 0 ]; then
|
|
needs=( $(grep "^$n;" "$SRPM_DIRECT_DESCENDANTS_FILE" | sed "s/$n;//" | sed 's/,/ /g'; alt_n=$(echo "$n" | sed 's#-rt$##'); if [ "$alt_n" != "$n" ]; then grep "^$alt_n;" "$SRPM_DIRECT_DESCENDANTS_FILE" | sed "s/$alt_n;//" | sed 's/,/ /g' | sed 's#\([^[:space:]]*\)#\1-rt#g'; fi ) )
|
|
|
|
# intersection of 'needs' and 'SRPM_PKG_NAMES' ... i.e. what should be compiled that we have source for
|
|
compilable_needs=( $(intersection needs SRPM_PKG_NAMES) )
|
|
TRANSITIVE_SRPMS_TO_COMPILE=( $(union compilable_needs TRANSITIVE_SRPMS_TO_COMPILE) )
|
|
fi
|
|
done
|
|
|
|
# Append the secondary targetc list to the primary list
|
|
SRPMS_TO_COMPILE=( $(union SRPMS_TO_COMPILE TRANSITIVE_SRPMS_TO_COMPILE) )
|
|
echo "SRPMS_TO_COMPILE = ${SRPMS_TO_COMPILE[@]}"
|
|
fi
|
|
|
|
|
|
MUST_SRPMS_TO_COMPILE=( ${SRPMS_TO_COMPILE[@]} )
|
|
|
|
# adding required packages
|
|
if [ $CLEAN_FLAG -eq 0 ] && [ "x$TARGETS" != "x" ] && [ $NO_REQUIRED -eq 0 ] && [ -f $SRPM_TRANSITIVE_REQUIRES_FILE ]; then
|
|
echo
|
|
echo "adding required packages"
|
|
TRANSITIVE_SRPMS_TO_COMPILE=()
|
|
for n in ${MUST_SRPMS_TO_COMPILE[@]}; do
|
|
needs=( $(grep "^$n;" "$SRPM_TRANSITIVE_REQUIRES_FILE" | sed "s/$n;//" | sed 's/,/ /g') )
|
|
|
|
# intersection of 'needs' and 'SRPM_PKG_NAMES' ... i.e. what should be compiled that we have source for
|
|
compilable_needs=( $(intersection needs SRPM_PKG_NAMES) )
|
|
TRANSITIVE_SRPMS_TO_COMPILE=( $(union compilable_needs TRANSITIVE_SRPMS_TO_COMPILE) )
|
|
|
|
for b in "${un[@]}"; do
|
|
echo $b
|
|
done
|
|
done
|
|
|
|
SRPMS_TO_COMPILE=( $(union TRANSITIVE_SRPMS_TO_COMPILE SRPMS_TO_COMPILE) )
|
|
echo "SRPMS_TO_COMPILE = ${SRPMS_TO_COMPILE[@]}"
|
|
fi
|
|
|
|
|
|
# Determine build order ... now done in mockchain4
|
|
SRPMS_TO_COMPILE=( $(echo ${SRPMS_TO_COMPILE[@]} | sed 's/ /\n/g' | sort -u) )
|
|
|
|
|
|
# convert pkg names to paths, clean work dirs if needed
|
|
echo
|
|
echo "Mapping packages to src rpm paths"
|
|
for n in ${SRPMS_TO_COMPILE[@]}; do
|
|
s=${SRPM_PKG_NAME_TO_PATH[$n]}
|
|
SPEC_DIR=$(spec_cache_dir_from_srpm $s)
|
|
update_spec_cache $s
|
|
|
|
SRPMS_LIST="$SRPMS_LIST $s"
|
|
# echo "SRPMS_LIST = $SRPMS_LIST"
|
|
|
|
TMP_RPMS_LIST=$(ls -1 $SPEC_DIR/BUILDS | tr '\n' ' ')
|
|
RPMS_LIST="$RPMS_LIST $TMP_RPMS_LIST"
|
|
done
|
|
echo
|
|
|
|
if [ $CLEAN_FLAG -eq 0 ]; then
|
|
update_cgcs_repo cgcs-centos-repo
|
|
if [ -d $MY_REPO/cgcs-3rd-party-repo ]; then
|
|
update_cgcs_repo cgcs-3rd-party-repo
|
|
fi
|
|
fi
|
|
|
|
mock_clean_mounts
|
|
|
|
# clean work dirs if needed
|
|
CLEAN_BEFORE_BUILD_SRPM_LIST=""
|
|
CLEAN_BEFORE_BUILD_RPM_LIST=""
|
|
if [ $CLEAN_FLAG -eq 0 ]; then
|
|
echo
|
|
echo "Calculating minimal clean list"
|
|
for nm in ${SRPMS_TO_COMPILE[@]}; do
|
|
MUST_CLEAN=0
|
|
contains MUST_SRPMS_TO_COMPILE $nm && MUST_CLEAN=1
|
|
|
|
s=${SRPM_PKG_NAME_TO_PATH[$nm]}
|
|
SPEC_DIR=$(spec_cache_dir_from_srpm $s)
|
|
update_spec_cache $s
|
|
|
|
LOCAL_RPMS_LIST=$(ls -1 $SPEC_DIR/BUILDS | tr '\n' ' ')
|
|
LOCAL_RPMS_VRA_LIST=$(ls -1 $SPEC_DIR/BUILDS_VR | tr '\n' ' ')
|
|
|
|
for f in $LOCAL_RPMS_VRA_LIST; do
|
|
m=$(find $RPM_DIR/$f*rpm 2>> /dev/null | wc -l)
|
|
if [ -f "$UNBUILT_PATTERN_FILE" ]; then
|
|
echo $f | grep -f "$UNBUILT_PATTERN_FILE" >> /dev/null && m=1
|
|
fi
|
|
|
|
n=$(find $RPM_DIR/$f*rpm -type f -not -newermm $s 2>> /dev/null | wc -l)
|
|
# echo "$n=find $RPM_DIR/$f*rpm -type f -not -newermm $s 2>> /dev/null | wc -l"
|
|
if [ $m -eq 0 ] || [ $n -gt 0 ] || [ $MUST_CLEAN -eq 1 ]; then
|
|
CLEAN_BEFORE_BUILD_SRPM_LIST="$CLEAN_BEFORE_BUILD_SRPM_LIST $s"
|
|
CLEAN_BEFORE_BUILD_RPM_LIST="$CLEAN_BEFORE_BUILD_RPM_LIST $LOCAL_RPMS_LIST"
|
|
break
|
|
fi
|
|
done
|
|
done
|
|
fi
|
|
|
|
|
|
if [ "$UNRESOLVED_TARGETS" != " " ]; then
|
|
if [ $CLEAN_FLAG -eq 0 ]; then
|
|
echo ""
|
|
echo "ERROR: failed to resolve build targets: $UNRESOLVED_TARGETS"
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
echo "SRPMS_LIST = $SRPMS_LIST"
|
|
echo "RPMS_LIST = $RPMS_LIST"
|
|
|
|
|
|
echo
|
|
if [ $CLEAN_FLAG -eq 0 ]; then
|
|
# pre-create these directories as $USER,
|
|
# else mock will create them as root and fails to clean them.
|
|
# Note: keep these in sync with mockchain-parallel!
|
|
for i in $(seq 0 $((MAX_WORKERS-1))); do
|
|
mkdir -p $MY_WORKSPACE/mock/b$i
|
|
mkdir -p $MY_WORKSPACE/cache/b$i/mock
|
|
done
|
|
|
|
mock_update_or_init
|
|
fi
|
|
set_mock_symlinks $MY_BUILD_CFG
|
|
|
|
echo
|
|
echo "Cleaning"
|
|
if [ $CLEAN_FLAG -eq 1 ]; then
|
|
# Clean what the user asked for
|
|
echo "========= clean_list '$SRPMS_LIST' '$RPMS_LIST' $ALL"
|
|
\rm -r -f -v $MY_WORKSPACE/mock-$USER-*
|
|
clean_list "$SRPMS_LIST" "$RPMS_LIST" "$ALL"
|
|
|
|
exit 0
|
|
else
|
|
# Clean what we intend to build
|
|
if [ $NO_AUTOCLEAN -eq 1 ]; then
|
|
echo "no-autoclean was requested"
|
|
else
|
|
if [ "$CLEAN_BEFORE_BUILD_SRPM_LIST" != "" ]; then
|
|
echo "========= clean_list '$CLEAN_BEFORE_BUILD_SRPM_LIST' '$CLEAN_BEFORE_BUILD_RPM_LIST' 0"
|
|
clean_list "$CLEAN_BEFORE_BUILD_SRPM_LIST" "$CLEAN_BEFORE_BUILD_RPM_LIST" 0
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
echo
|
|
echo "Cleaning repodata"
|
|
|
|
BUILD_ENVIRONMENT_DIR=$(basename $BUILD_CFG)
|
|
BUILD_ENVIRONMENT_DIR=${BUILD_ENVIRONMENT_DIR%.*}
|
|
LOCAL_URL=http://127.0.0.1:8088$BUILD_BASE/results/$BUILD_ENVIRONMENT_DIR/
|
|
LOCAL_SRC_URL=http://127.0.0.1:8088$BUILD_BASE/rpmbuild/SRPMS/
|
|
|
|
for d in $(find -L $RESULT_DIR -type d -name repodata); do
|
|
(cd $d/..
|
|
if [ -f repodata/*comps*xml ]; then
|
|
\mv repodata/*comps*xml comps.xml
|
|
fi
|
|
\rm -rf repodata
|
|
)
|
|
done
|
|
|
|
echo
|
|
echo "Cleaning Metadata"
|
|
|
|
MOCKCHAIN_LOG="$RESULT_DIR/mockchain.log"
|
|
mkdir -p $RESULT_DIR
|
|
touch $RESULT_DIR/build_start
|
|
\rm -rf $MOCKCHAIN_LOG
|
|
|
|
mock_clean_metadata
|
|
|
|
echo
|
|
echo "Building"
|
|
|
|
CMD_PREFIX=""
|
|
if [ -x /bin/ionice ]; then
|
|
CMD_PREFIX="nice -n 20 ionice -c Idle /bin/ionice "
|
|
fi
|
|
|
|
CMD_OPTIONS="-m --no-clean -m --no-cleanup-after"
|
|
if [ $CAREFUL -eq 1 ]; then
|
|
CMD_OPTIONS="-m --no-cleanup-after"
|
|
fi
|
|
echo "CAREFUL=$CAREFUL"
|
|
|
|
# Sets WORKERS and MOCKCHAIN_RESOURCE_ALLOCATION
|
|
compute_resources $SRPMS_LIST
|
|
|
|
|
|
if [ -f $SRPM_RPM_DIRECT_REQUIRES_FILE ]; then
|
|
CMD_OPTIONS="$CMD_OPTIONS --srpm-dependency-file $SRPM_RPM_DIRECT_REQUIRES_FILE"
|
|
fi
|
|
if [ -f "$RPM_DIRECT_REQUIRES_FILE" ]; then
|
|
CMD_OPTIONS="$CMD_OPTIONS --rpm-dependency-file $RPM_DIRECT_REQUIRES_FILE"
|
|
fi
|
|
if [ -f "$RPM_TO_SRPM_MAP_FILE" ]; then
|
|
CMD_OPTIONS="$CMD_OPTIONS --rpm-to-srpm-map-file $RPM_TO_SRPM_MAP_FILE"
|
|
fi
|
|
|
|
|
|
for s in $SRPMS_LIST; do
|
|
d=$(echo "$s" | sed 's#/SRPMS/#/SOURCES/#')
|
|
if [ -f $d/BIG ]; then
|
|
BUILD_SIZE=$(cat $d/BIG | { read first rest ; echo $first ; })
|
|
CMD_OPTIONS="$CMD_OPTIONS --mark-big-path $BUILD_SIZE:$s"
|
|
fi
|
|
if [ -f $d/SLOW ]; then
|
|
BUILD_SPEED=$(cat $d/SLOW | { read first rest ; echo $first ; })
|
|
CMD_OPTIONS="$CMD_OPTIONS --mark-slow-path $BUILD_SPEED:$s"
|
|
fi
|
|
done
|
|
echo "CMD_OPTIONS=$CMD_OPTIONS"
|
|
|
|
echo "MAX_WORKERS=$MAX_WORKERS"
|
|
echo "MOCKCHAIN_RESOURCE_ALLOCATION=$MOCKCHAIN_RESOURCE_ALLOCATION"
|
|
|
|
CMD="$CMD_PREFIX mockchain-parallel -r $BUILD_CFG -l $BUILD_BASE --recurse --workers=$MAX_WORKERS --worker-resources=$MOCKCHAIN_RESOURCE_ALLOCATION --basedir=$MY_WORKSPACE --log=$MOCKCHAIN_LOG --tmp_prefix=$USER --addrepo=$LOCAL_URL --addrepo=$LOCAL_SRC_URL $CMD_OPTIONS -m --rebuild $SRPMS_LIST"
|
|
echo ""
|
|
echo "$CMD -m --define='_tis_dist .tis' -m --define='platform_release $PLATFORM_RELEASE'"
|
|
echo ""
|
|
|
|
trapwrap stdbuf -o0 $CMD -m --define="_tis_dist .tis" -m --define="platform_release $PLATFORM_RELEASE"
|
|
MOCKCHAIN_RC=$?
|
|
|
|
echo $PLATFORM_RELEASE > $LAST_PLATFORM_RELEASE_FILE
|
|
|
|
if [ $CLEAN_FLAG -eq 0 ]; then
|
|
umount_mock_root_as_tmpfs_all
|
|
fi
|
|
|
|
for d in $(find $RESULT_DIR -name '*.rpm' | grep -v '[.]src[.]rpm' | xargs --max-args=1 dirname | sort -u); do
|
|
rsync -u $d/*.rpm $RPM_DIR
|
|
done
|
|
|
|
if [ $ALL -eq 1 ]; then
|
|
echo
|
|
echo "Auditing for obsolete srpms"
|
|
for r in $(find $RESULT_DIR $RPM_DIR -name '*.src.rpm'); do
|
|
(
|
|
f=$(basename $r)
|
|
if [ ! -f "$SRPM_OUT/$f" ]; then
|
|
\rm -fv $r
|
|
fi
|
|
) &
|
|
done
|
|
echo "waiting for srpm audit to complete"
|
|
wait
|
|
echo "Auditing for obsolete rpms"
|
|
for r in $(find $RESULT_DIR $RPM_DIR -name '*.rpm' | grep -v 'src.rpm'); do
|
|
(
|
|
s=$(rpm_get_srpm $r)
|
|
if [ ! -f "$SRPM_OUT/$s" ]; then
|
|
echo "Failed to find '$SRPM_OUT/$s'"
|
|
\rm -fv $r
|
|
fi
|
|
) &
|
|
done
|
|
echo "waiting for rpm audit to complete"
|
|
wait
|
|
echo "Audit complete"
|
|
echo ""
|
|
fi
|
|
|
|
if [ $MOCKCHAIN_RC -ne 0 ]; then
|
|
echo "ERROR: Failed to build rpms using '$CMD'"
|
|
exit 1
|
|
fi
|
|
|
|
echo "Recreate repodata"
|
|
for d in $(find -L $MY_WORKSPACE/rpmbuild $MY_WORKSPACE/results -type d -name repodata); do
|
|
update_repodata $(dirname "$d")
|
|
done
|
|
|
|
|
|
if [ -f $MOCKCHAIN_LOG ]; then
|
|
grep 'following pkgs could not be successfully built' $MOCKCHAIN_LOG >> /dev/null
|
|
if [ $? -eq 0 ]; then
|
|
FAILED_PKGS=""
|
|
for p in $(sed -n '/following pkgs could not be successfully built:/,/Results out to/p' $MOCKCHAIN_LOG | grep -v '*** Build Failed ***' | sed 1d | sed '$ d' | cut -d ':' -f2-); do
|
|
PKG=$(basename $p)
|
|
FAILED_PKGS="$PKG $FAILED_PKGS"
|
|
done
|
|
echo
|
|
echo "Failed to build packages: $FAILED_PKGS"
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
# If we're doing a nightly or formal build (i.e. not a developer build) then we
|
|
# want to sign certain packages. Note that only certain users (i.e. jenkins)
|
|
# have the authority to requiest that packages be signed.
|
|
#
|
|
# Signing is not actually done on this server (the keys are kept safe on a
|
|
# different server with very limited access) but we can invoke a script to
|
|
# make calls to the signing server. Note that this will NOT work if you are
|
|
# not Jenkins and don't have access to the Jenkins cross server login keys.
|
|
#
|
|
# Note that both std and rt builds must be complete before invoking the signing
|
|
# script
|
|
if [ 0$FORMAL_BUILD -eq 1 ] && [ "$USER" == "jenkins" ]; then
|
|
if [ -e $MY_WORKSPACE_TOP/std ] && [ -e $MY_WORKSPACE_TOP/rt ]; then
|
|
# Create dir for log, if it doesn't exit
|
|
mkdir -p $MY_WORKSPACE_TOP/export
|
|
echo "We are jenkins, and we are trying to do a formal build -- calling signing server"
|
|
echo " to sign boot RPMs with secure boot keys"
|
|
|
|
MY_WORKSPACE=$MY_WORKSPACE_TOP ${SIGN_SECURE_BOOT} > $MY_WORKSPACE_TOP/export/${SIGN_SECURE_BOOT_LOG} 2>&1
|
|
if [ $? -ne 0 ]; then
|
|
echo "Signing of packages failed -- see $MY_WORKSPACE_TOP/export/${SIGN_SECURE_BOOT_LOG}"
|
|
exit 1
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
exit 0
|
|
) 2>&1 | stdbuf -o0 awk '{ print strftime("%H:%M:%S"), $0; fflush(); }' | tee $(date "+$MY_WORKSPACE/build-rpms-parallel_%Y-%m-%d_%H-%M-%S.log") ; exit ${PIPESTATUS[0]}
|