#!/bin/bash # set -x # # Copyright (c) 2018 Wind River Systems, Inc. # # SPDX-License-Identifier: Apache-2.0 # # # Create src.rpm files from source, or from a downloaded tarball # or src.rpm plus our additional patches. # # This version tries to compile many packages in parallel. # # The location of packages to be build are identified by # _pkg_dirs[_] files located at the root of # any git tree (e.g. stx/integ/centos_pkg_dirs). # # The build of an individul package is driven by it's build_srpm.data # file plus a .spec file or an srpm_path file. # export ME=$(basename "$0") CMDLINE="$ME $@" BUILD_SRPMS_PARALLEL_DIR="$(dirname "$(readlink -f "${BASH_SOURCE[0]}" )" )" source $BUILD_SRPMS_PARALLEL_DIR/git-utils.sh source $BUILD_SRPMS_PARALLEL_DIR/spec-utils source $BUILD_SRPMS_PARALLEL_DIR/srpm-utils source $BUILD_SRPMS_PARALLEL_DIR/classify source $BUILD_SRPMS_PARALLEL_DIR/build-srpms-common.sh source $BUILD_SRPMS_PARALLEL_DIR/image-utils.sh INITIAL_DIR=$(pwd) export DISTRO="centos" SRPM_SCRIPT="build_srpm" SRPM_DATA="build_srpm.data" PKG_DIRS_FILE="${DISTRO}_pkg_dirs" DEFAULT_SRPM_SCRIPT="$BUILD_SRPMS_PARALLEL_DIR/default_$SRPM_SCRIPT" SCRIPT_PATH="$DISTRO" DATA_PATH="$DISTRO" FILES_PATH="$DISTRO/files" PATCHES_PATH="$DISTRO/patches" ORIG_SPECS_PATH="$DISTRO" SRPM_LIST_PATH="$DISTRO/srpm_path" MIRROR_ROOT="$MY_REPO/${DISTRO}-repo" if [ ! -d ${MIRROR_ROOT} ]; then # Old value... a temporary measure for backward compatibility MIRROR_ROOT="$MY_REPO/cgcs-${DISTRO}-repo" if [ ! -d ${MIRROR_ROOT} ]; then MIRROR_ROOT="$MY_REPO/${DISTRO}-repo" fi fi THIRD_PARTY_ROOT="$MY_REPO/cgcs-3rd-party-repo" REPO_DOWNLOADS_ROOT="$MY_REPO" SRPM_REBUILT_LIST="" SRPM_FAILED_REBUILD_LIST="" STOP_SCHEDULING=0 ABSOLUTE_MAX_WORKERS=8 MAX_WORKERS=$(grep -c ^processor /proc/cpuinfo) if [ "$MAX_WORKERS" == "" ] || [ "$MAX_WORKERS" == "0" ]; then MAX_WORKERS=1 fi if [ $MAX_WORKERS -gt $ABSOLUTE_MAX_WORKERS ]; then MAX_WORKERS=$ABSOLUTE_MAX_WORKERS fi echo "MAX_WORKERS=$MAX_WORKERS" CREATEREPO=$(which createrepo_c) if [ $? -ne 0 ]; then CREATEREPO="createrepo" fi # # Create a list of rpms in the directory # create_lst () { local DIR=${1} (cd $DIR [ -f rpm.lst ] && \rm -rf rpm.lst [ -f srpm.lst ] && \rm -rf srpm.lst find . -name '*.rpm' -and -not -name '*.src.rpm' | sed 's#^[.][/]##' | sort > rpm.lst find . -name '*.src.rpm' | sed 's#^[.][/]##' | sort > srpm.lst ) } usage () { echo "" echo "Usage: " echo " Create source rpms:" echo " $ME [--rt | --std | --installer | --containers] [--layer=] [--no-descendants] [--formal] [ list of package names ]" echo "" echo " Delete source rpms, and the directories associated with it's creation:" echo " Note: does not clean an edit environment" echo " $ME --clean [--rt | --std | --installer | --containers] [optional list of package names]" echo "" echo " Extract an src.rpm into a pair of git trees to aid in editing it's contents," echo " one for source code and one for metadata such as the spec file." echo " If --no-meta-patch is specified, then WRS patches are omitted." echo " $ME --edit [--rt | --std | --installer | --containers] [--no-meta-patch] [list of package names]" echo "" echo " Delete an edit environment" echo " $ME --edit --clean [--rt | --std | --installer | --containers] [list of package names]" echo "" echo " This help page" echo " $ME --help" echo "" } spec_cache_dir_from_srpm () { local SRPM=${1} local SPEC_DIR=$(echo $SRPM | sed 's#/SRPMS/#/SPECS/#') echo "$SPEC_DIR" } result_dir_from_srpm () { local SRPM=$(basename ${1} | sed 's#.src.rpm$##') local RESULT_DIR="$MY_WORKSPACE/results/$MY_BUILD_ENVIRONMENT/$SRPM" echo "$RESULT_DIR" } # This function creates a bunch of subdirs in $MY_WORKSPACE and makes sure # that a $MY_BUILD_CFG file exists. # # The goal of this is to have a script do as much of the annoying # grunt-work so that the "how to build it" instructions aren't 200 lines create_output_dirs () { # make sure variables are sane before continuing # Note that $BUILD_ROOT contains either $MY_WORKSPACE or $MY_PATCH_WORKSPACE if [ "x$BUILD_ROOT" == "x" ]; then return fi if [ "x$MY_BUILD_CFG" == "x" ]; then return fi if [ "x$MY_BUILD_DIR" == "x" ]; then return fi if [ "x$MY_SRC_RPM_BUILD_DIR" == "x" ]; then return fi # create output dirs mkdir -p $MY_BUILD_DIR mkdir -p $MY_SRC_RPM_BUILD_DIR mkdir -p $MY_SRC_RPM_BUILD_DIR/SOURCES mkdir -p $MY_SRC_RPM_BUILD_DIR/SPECS mkdir -p $MY_SRC_RPM_BUILD_DIR/BUILD mkdir -p $MY_SRC_RPM_BUILD_DIR/RPMS mkdir -p $MY_SRC_RPM_BUILD_DIR/SRPMS # create $MY_BUILD_CFG, if required if [ ! -f $MY_BUILD_CFG ]; then echo "FORMAL_BUILD=$FORMAL_BUILD" echo "modify-build-cfg $MY_BUILD_CFG" ${DIR}/modify-build-cfg $MY_BUILD_CFG if [ $? -ne 0 ]; then echo "Could not modifiy $MY_BUILD_CFG"; exit 1 fi fi } NO_DESCENDANTS=0 NO_BUILD_INFO=0 HELP=0 CLEAN_FLAG=0 FORMAL_FLAG=0 BUILD_TYPE_FLAG=0 EDIT_FLAG=0 NO_META_PATCH_FLAG=0 # read the options TEMP=$(getopt -o h --long parallel,std,rt,installer,containers,no-descendants,no-meta-patch,no-build-info,help,formal,clean,edit,layer: -n "$ME" -- "$@") if [ $? -ne 0 ]; then usage exit 1 fi eval set -- "$TEMP" export BUILD_TYPE=std # extract options and their arguments into variables. while true ; do case "$1" in --no-descendants) NO_DESCENDANTS=1 ; shift ;; --no-build-info) NO_BUILD_INFO=1 ; shift ;; -h|--help) HELP=1 ; shift ;; --clean) CLEAN_FLAG=1 ; shift ;; --formal) FORMAL_FLAG=1 ; shift ;; --std) BUILD_TYPE_FLAG=1; BUILD_TYPE=std; shift ;; --rt) BUILD_TYPE_FLAG=1; BUILD_TYPE=rt; shift ;; --installer) BUILD_TYPE=installer; shift ;; --containers) BUILD_TYPE=containers; shift ;; --edit) EDIT_FLAG=1 ; shift ;; --no-meta-patch) NO_META_PATCH_FLAG=1 ; shift ;; --parallel) shift ;; --layer) export LAYER=$2 ; shift ; 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_BUILD_ENVIRONMENT_FILE=$MY_BUILD_ENVIRONMENT.cfg export MY_SRC_RPM_BUILD_DIR=$MY_BUILD_DIR/rpmbuild export MY_BUILD_CFG=$MY_WORKSPACE/$MY_BUILD_ENVIRONMENT_FILE export MY_MOCK_ROOT=$MY_WORKSPACE/mock/root if [ "$BUILD_TYPE" != "std" ]; then PKG_DIRS_FILE="${DISTRO}_pkg_dirs_${BUILD_TYPE}" fi echo "CLEAN_FLAG=$CLEAN_FLAG" TARGETS=$@ if [ $HELP -eq 1 ]; then usage exit 0 fi if [ $FORMAL_FLAG -eq 1 ]; then export FORMAL_BUILD="yes" fi if [ "x$TARGETS" == "x" ] && [ $EDIT_FLAG -eq 1 ]; then echo "ERROR: $FUNCNAME (${LINENO}): a package name is required when --edit is specified" usage exit 0 fi SRC_ROOT="$MY_REPO" if [ "x$MY_REPO" == "x" ]; then SRC_ROOT=$INITIAL_DIR 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: $FUNCNAME (${LINENO}): require one of MY_WORKSPACE or MY_PATCH_WORKSPACE be defined" exit 1 fi fi export CCACHE_DIR="$BUILD_ROOT/.ccache" export SRC_BASE="$SRC_ROOT" export STX_BASE="$SRC_BASE/stx" export CGCS_BASE="$STX_BASE" export DISTRO_REPO_BASE=$MIRROR_ROOT export SPECS_BASE="$ORIG_SPECS_PATH" export FILES_BASE="$FILES_PATH" export PATCHES_BASE="$PATCHES_PATH" export BUILD_BASE="$BUILD_ROOT" BUILD_INPUTS="$BUILD_BASE/inputs" SRPM_ASSEMBLE="$BUILD_BASE/srpm_assemble" SRPM_WORK="$BUILD_BASE/srpm_work" 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 create_output_dirs export RPM_BUILD_BASE="$RPM_BUILD_ROOT" export SRPM_OUT="$RPM_BUILD_BASE/SRPMS" export SOURCE_OUT="$RPM_BUILD_BASE/SOURCES" export RPM_DIR="$RPM_BUILD_BASE/RPMS" if [ ! -d $CGCS_BASE ]; then echo "ERROR: $FUNCNAME (${LINENO}): expected to find directory at '$CGCS_BASE'" exit 1 fi if [ ! -d $BUILD_BASE ]; then if [ $CLEAN_FLAG -eq 1 ]; then exit 0 fi echo "ERROR: $FUNCNAME (${LINENO}): expected to find directory at '$BUILD_BASE'" exit 1 fi RELEASE_INFO_FILE="$(get_release_info)" if [ -f "$RELEASE_INFO_FILE" ]; then source "$RELEASE_INFO_FILE" else echo "Warning: $FUNCNAME (${LINENO}): failed to find RELEASE_INFO_FILE=$RELEASE_INFO_FILE" fi if [ "x$PLATFORM_RELEASE" == "x" ]; then echo "Warning: $FUNCNAME (${LINENO}): PLATFORM_RELEASE is not defined in $RELEASE_INFO_FILE" PLATFORM_RELEASE=00.00 fi export PLATFORM_RELEASE mkdir -p $RPM_BUILD_BASE if [ $? -ne 0 ]; then echo "ERROR: $FUNCNAME (${LINENO}): Failed to create directory '$RPM_BUILD_BASE'" exit 1 fi mkdir -p $SRPM_OUT if [ $? -ne 0 ]; then echo "ERROR: $FUNCNAME (${LINENO}): Failed to create directory '$SRPM_OUT'" exit 1 fi mkdir -p $RPM_DIR if [ $? -ne 0 ]; then echo "ERROR: $FUNCNAME (${LINENO}): Failed to create directory '$RPM_DIR'" exit 1 fi mkdir -p $SRPM_ASSEMBLE if [ $? -ne 0 ]; then echo "ERROR: $FUNCNAME (${LINENO}): Failed to create directory '$SRPM_ASSEMBLE'" exit 1 fi mkdir -p $BUILD_INPUTS if [ $? -ne 0 ]; then echo "ERROR: $FUNCNAME (${LINENO}): Failed to create directory '$BUILD_INPUTS'" exit 1 fi build_dir () { local build_idx=$1 local d=$2 local w=$3 export PKG_BASE=$d export WORK_BASE=$w export SPECS_BASE="$PKG_BASE/$ORIG_SPECS_PATH" local RC local ORIG_DIR=$(pwd) # echo "build_dir: PKG_BASE=$PKG_BASE" cd "$PKG_BASE" if [ $? -ne 0 ]; then echo "ERROR: $FUNCNAME (${LINENO}): failed to cd into '$PKG_BASE'" return 1 fi if [ ! -d $ORIG_SPECS_PATH ]; then # nothing to do echo "WARNING: '$ORIG_SPECS_PATH' not found in '$PKG_BASE'" cd "$ORIG_DIR" return 0 fi SRPM_COUNT=0 ORIG_SRPM_PATH="" if [ -f $SRPM_LIST_PATH ]; then # we've found a file (ex centos/srpm_path) which lists a path to a source # RPM file # # The specified file can be of the form # # repo:path/to/file.src.rpm # mirror:path/to/file.src.rpm # /path/to/file.rpm # path/to/file.rpm # # If "repo:" is specified, then we search for the file relative to # $REPO_DOWNLOADS_ROOT (i.e. a path to the file in a "downloads subgit) # # If "mirror:" is specified, then we search for the file relateive to # $MIRROR_ROOT # # If "3rd_party:" is specified, then we search for the file relateive to # $THIRD_PARTY_ROOT # # An absolute path is parsed as an absolute path (mainly intended for # developer/experimental use without checking in files or messing with # your git repos) # # A lack of prefix (relative path name) is interpretted as "mirror:" # (legacy support for existing packages) # # Other prefixes (file:, http:, whatever:)are unsupported at this time for p in $(grep -v '^#' $SRPM_LIST_PATH | grep -v '^$'); do # absolute path source rpms echo "$p" | grep "^/" >/dev/null && ORIG_SRPM_PATH=$p if [ "${ORIG_SRPM_PATH}x" == "x" ]; then # handle repo: definitions echo "$p" | grep "^repo:" >/dev/null && ORIG_SRPM_PATH=$(echo $p | sed "s%^repo:%$REPO_DOWNLOADS_ROOT/%") fi if [ "${ORIG_SRPM_PATH}x" == "x" ]; then # handle 3rd_party: definitions echo "$p" | grep "^3rd_party:" >/dev/null && ORIG_SRPM_PATH=$(echo $p | sed "s%^3rd_party:%$THIRD_PARTY_ROOT/%") fi if [ "${ORIG_SRPM_PATH}x" == "x" ]; then # handle mirror: definitions echo "$p" | grep "^mirror:" >/dev/null && ORIG_SRPM_PATH=$(echo $p | sed "s%^mirror:%$MIRROR_ROOT/%" | sed "s#CentOS/tis-r3-CentOS/kilo/##" | sed "s#CentOS/tis-r3-CentOS/mitaka/##") fi if [ "${ORIG_SRPM_PATH}x" == "x" ]; then # we haven't found a valid prefix yet, so assume it's a legacy # file (mirror: interpretation) ORIG_SRPM_PATH="$MIRROR_ROOT/$p" fi # echo "ORIG_SRPM_PATH=$ORIG_SRPM_PATH" if [ -f $ORIG_SRPM_PATH ]; then SRPM_COUNT=$((SRPM_COUNT + 1)) else echo "ERROR: $FUNCNAME (${LINENO}): Invalid srpm path '$p', evaluated as '$ORIG_SRPM_PATH', found in '$PKG_BASE/$SRPM_LIST_PATH'" ORIG_SRPM_PATH="" return 3 fi done fi # Clean up an tmp_spec_*.spec file left by a prior failed build for f in $(find $ORIG_SPECS_PATH -name 'tmp_spec_*.spec'); do \rm -f $f done SPEC_COUNT=$(find $ORIG_SPECS_PATH -name '*.spec' | wc -l) if [ $SPEC_COUNT -eq 0 ]; then if [ -f $ORIG_SPECS_PATH/spec_path ]; then SPECS_BASE=$SRC_BASE/$(cat $SPECS_BASE/spec_path) SPEC_COUNT=$(find $SPECS_BASE -maxdepth 1 -name '*.spec' | wc -l) fi fi if [ $SPEC_COUNT -eq 0 ] && [ $SRPM_COUNT -eq 0 ]; then # nothing to do echo "ERROR: $FUNCNAME (${LINENO}): Neither srpm_path nor .spec file not found in '$PKG_BASE/$ORIG_SPECS_PATH'" cd "$ORIG_DIR" return 0 fi if [ $SPEC_COUNT -gt 0 ] && [ $SRPM_COUNT -gt 0 ]; then # nothing to do echo "ERROR: $FUNCNAME (${LINENO}): Please provide only one of srpm_path or .spec files, not both, in '$PKG_BASE/$ORIG_SPECS_PATH'" cd $ORIG_DIR return 0 fi if [ $SPEC_COUNT -gt 0 ]; then build_dir_spec $build_idx RC=$? cd "$ORIG_DIR" return $RC else build_dir_srpm $build_idx $ORIG_SRPM_PATH RC=$? cd "$ORIG_DIR" return $RC fi cd "$ORIG_DIR" return 0 } clean_srpm_dir () { local build_idx=$1 local DIR=$2 local EXCLUDE_MD5=$3 local SRPM_PATH local SRPM_FILE local SRPM_OUT_PATH local SRPM_NAME local SRPM_OUT_NAME local INPUTS_TO_CLEAN="" if [ "$EXCLUDE_MD5" == "" ]; then EXCLUDE_MD5=0 fi echo "clean_srpm_dir build_idx=$build_idx DIR=$DIR" INPUTS_TO_CLEAN=$(dirname $(dirname $DIR)) echo "$INPUTS_TO_CLEAN" | grep -q "^$BUILD_INPUTS/" if [ $? -ne 0 ] ; then INPUTS_TO_CLEAN="" fi for SRPM_PATH in $(find "$DIR" -name '*.src.rpm'); do SRPM_FILE=$(basename $SRPM_PATH) SRPM_NAME=$(rpm -q --queryformat '%{NAME}\n' --nosignature -p $SRPM_PATH 2>> /dev/null) if [ $CLEAN_FLAG -eq 1 ]; then sed -i "/^$SRPM_NAME$/d" $MY_WORKSPACE/tmp/UNRESOLVED_TARGETS_${build_idx} fi \rm -fv $SRPM_PATH $SRPM_OUT/$SRPM_FILE if [ -d $SRPM_ASSEMBLE/$SRPM_NAME ]; then echo "rm -rf $SRPM_ASSEMBLE/$SRPM_NAME" \rm -rf $SRPM_ASSEMBLE/$SRPM_NAME fi if [ -d $SOURCE_OUT/$SRPM_FILE ]; then echo "rm -rf $SOURCE_OUT/$SRPM_FILE" \rm -rf $SOURCE_OUT/$SRPM_FILE fi if [ $EXCLUDE_MD5 -eq 0 ] && [ -d $SOURCE_OUT/$SRPM_NAME ]; then echo "rm -rf $SOURCE_OUT/$SRPM_NAME" \rm -rf $SOURCE_OUT/$SRPM_NAME fi local d local src_d local spec local spec_name for d in $(find $BUILD_INPUTS -type d -name "${SRPM_NAME}*") ;do src_d=$(echo $d | sed "s#^$BUILD_INPUTS/#$MY_REPO/#") for spec in $(find $src_d/${DISTRO} -name '*.spec'); do spec_name=$(spec_find_tag Name $spec) if [ "$spec_name" == "$SRPM_NAME" ]; then INPUTS_TO_CLEAN=$(if [ "x$INPUTS_TO_CLEAN" != "x" ]; then echo $INPUTS_TO_CLEAN; fi; echo "$d") fi done done # Look for older versions of the same src rpm that also need cleaning for SRPM_OUT_PATH in $(ls -1 $SRPM_OUT/$SRPM_NAME*.src.rpm 2>> /dev/null); do SRPM_OUT_FILE=$(basename $SRPM_OUT_PATH) SRPM_OUT_NAME=$(rpm -q --queryformat '%{NAME}\n' -p $SRPM_OUT_PATH 2>> /dev/null) if [ "$SRPM_NAME" == "$SRPM_OUT_NAME" ]; then \rm -fv $SRPM_OUT_PATH if [ -d $SOURCE_OUT/$SRPM_OUT_FILE ]; then echo "rm -rf $SOURCE_OUT/$SRPM_OUT_FILE" \rm -rf $SOURCE_OUT/$SRPM_OUT_FILE fi fi done done if [ "x$INPUTS_TO_CLEAN" != "x" ]; then for d in $INPUTS_TO_CLEAN; do if [ -d $d/rpmbuild ]; then echo "rm -rf $d" \rm -rf $d fi done fi } build_dir_srpm () { local build_idx=$1 local ORIG_SRPM_PATH=$2 local ORIG_SRPM=$(basename $ORIG_SRPM_PATH) local NAME=$(rpm -q --queryformat '%{NAME}\n' --nosignature -p $ORIG_SRPM_PATH) local PKG_NAME_VER=$(rpm -q --queryformat '%{NAME}-%{VERSION}-%{RELEASE}\n' --nosignature -p $ORIG_SRPM_PATH) local PKG_DIR="$NAME" local TARGET_FOUND="" local RC=0 export SRPM_EXPORT_NAME=$NAME export SRPM_EXPORT_VER=$VER local NEED_BUILD=0 if [ "x$TARGETS" == "x" ]; then NEED_BUILD=1 TARGET_FOUND=$NAME else TARGET_LIST=( $TARGETS ) TARGET_FOUND=$(srpm_match_target_list TARGET_LIST "$ORIG_SRPM_PATH" 2>> /dev/null) if [ $? -eq 0 ]; then echo "found target '$TARGET_FOUND' in '$ORIG_SRPM'" NEED_BUILD=1 sed -i "/^$TARGET_FOUND$/d" $MY_WORKSPACE/tmp/UNRESOLVED_TARGETS_${build_idx} fi fi if [ $NEED_BUILD -eq 0 ]; then return 0 fi local ROOT_DIR="$SRPM_ASSEMBLE" if [ $EDIT_FLAG -eq 1 ]; then mkdir -p $SRPM_WORK ROOT_DIR="$SRPM_WORK" fi local PKG_ROOT_DIR="$ROOT_DIR/$PKG_DIR" local BUILD_DIR="$PKG_DIR/rpmbuild" local FULL_BUILD_DIR="$ROOT_DIR/$BUILD_DIR" local SRPM_DIR="$FULL_BUILD_DIR/SRPMS" local SOURCES_DIR="$SOURCE_OUT" if [ $CLEAN_FLAG -eq 1 ]; then # clean echo "===== Cleaning '$TARGET_FOUND' =====" if [ -d $SRPM_DIR ] && [ $EDIT_FLAG -eq 0 ]; then clean_srpm_dir $build_idx "$SRPM_DIR" 0 fi if [ -d $PKG_ROOT_DIR ]; then echo "rm -rf $PKG_ROOT_DIR" \rm -rf "$PKG_ROOT_DIR" fi else #build echo "===== Build SRPM for '$TARGET_FOUND' =====" echo "PKG_BASE=$PKG_BASE" echo "BUILD_DIR=$BUILD_DIR" echo "SRPM_DIR=$SRPM_DIR" if [ ! -d $ROOT_DIR ]; then mkdir -p "$ROOT_DIR" if [ $? -ne 0 ]; then echo "ERROR: $FUNCNAME (${LINENO}): mkdir '$ROOT_DIR' failed" return 1 fi fi # # Load data from build_srpm.data # export DATA="$DATA_PATH/$SRPM_DATA" if [ -f "$DATA" ]; then srpm_source_build_data "$DATA" "$SRC_BUILD_TYPE_SRPM" "$ORIG_SRPM_PATH" if [ $? -ne 0 ]; then echo "ERROR: $FUNCNAME (${LINENO}): failed to source $DATA" return 1 fi fi # # Capture md5 data for all input files # local TARGET_SOURCES_DIR="$SOURCES_DIR/$TARGET_FOUND" local INPUT_FILES_MD5="$TARGET_SOURCES_DIR/srpm_input.md5" local REFERENCE_MD5="$TARGET_SOURCES_DIR/srpm_reference.md5" mkdir -p "$TARGET_SOURCES_DIR" md5sums_from_input_vars "$SRC_BUILD_TYPE_SRPM" "$ORIG_SRPM_PATH" "$TARGET_SOURCES_DIR" > "$INPUT_FILES_MD5" if [ $? -ne 0 ]; then echo "ERROR: $FUNCNAME (${LINENO}): md5sums_from_input_vars '$SRC_BUILD_TYPE_SRPM' '$ORIG_SRPM_PATH' '$TARGET_SOURCES_DIR'" return 1 fi echo "Wrote: $INPUT_FILES_MD5" # # Is a rebuild required? # Compare md5 of current inputs vs md5 of previous build? # local BUILD_NEEDED=0 local SRPM_OUT_PATH2 local DIFF_LINE local DIFF_FILE if [ -f $REFERENCE_MD5 ]; then DIFF_LINE=$(diff "$INPUT_FILES_MD5" "$REFERENCE_MD5" | head -n 2 | tail -n 1; exit ${PIPESTATUS[0]}) if [ $? -ne 0 ]; then DIFF_FILE=$(echo "$DIFF_LINE" | cut -d ' ' -f4-) BUILD_NEEDED=1 case ${DIFF_LINE:0:1} in '>') echo "Rebuild required due to deleted file: $DIFF_FILE" ;; '<') echo "Rebuild required due to new or changed file: $DIFF_FILE" ;; *) echo "Rebuild required due to diff: $DIFF_LINE" ;; esac fi else echo "Rebuild required due to missing reference md5: $REFERENCE_MD5" BUILD_NEEDED=1 fi if [ -d "$FULL_BUILD_DIR/SRPMS" ]; then b="" for SRPM_PATH in $(find "$FULL_BUILD_DIR/SRPMS" -name '*.src.rpm' | sort -V); do b=$(basename $SRPM_PATH) SRPM_OUT_PATH2=$(find $SRPM_OUT -name $b) if [ "x$SRPM_OUT_PATH2" == "x" ]; then echo "Rebuild required due to missing srpm: $b" BUILD_NEEDED=1 fi done if [ "$b" == "" ]; then echo "Rebuild required due no src.rpm in directory: '$FULL_BUILD_DIR/SRPMS'" BUILD_NEEDED=1 fi else echo "Rebuild required due to missing directory: '$FULL_BUILD_DIR/SRPMS'" BUILD_NEEDED=1 fi if [ $BUILD_NEEDED -eq 0 ]; then echo "SRPM build not required for '$PKG_BASE'" echo "===== Build complete for '$TARGET_FOUND' =====" echo return 0 fi if [ $EDIT_FLAG -eq 0 ]; then clean_srpm_dir $build_idx "$FULL_BUILD_DIR/SRPMS" 1 if [ -d $PKG_ROOT_DIR ]; then echo "arf rm -rf $PKG_ROOT_DIR" \rm -rf $PKG_ROOT_DIR fi fi if [ $EDIT_FLAG -eq 1 ]; then PKG_CLASSIFICATION=$(classify $PKG_BASE) echo "$PKG_CLASSIFICATION = classify $PKG_BASE" if [ "$PKG_CLASSIFICATION" == "spec + tarball" ] || [ "$PKG_CLASSIFICATION" == "srpm + patches" ]; then echo "OK to edit $PKG_BASE" else echo "Can't edit this package, it is of type '$PKG_CLASSIFICATION', it is not derived from SRPM or tarball and patches" return 1 fi echo "srpm_extract_to_git '$ORIG_SRPM_PATH' '$PKG_BASE' '$ROOT_DIR' '$BUILD_DIR' '$PKG_NAME_VER' '$NO_META_PATCH_FLAG' '$TIS_PATCH_VER' '$PBR_VERSION'" srpm_extract_to_git $ORIG_SRPM_PATH $PKG_BASE $ROOT_DIR $BUILD_DIR $PKG_NAME_VER $NO_META_PATCH_FLAG $TIS_PATCH_VER $PBR_VERSION RC=$? if [ $RC -ne 0 ]; then if [ $RC -eq 1 ]; then echo "ERROR: $FUNCNAME (${LINENO}): failed to extract srpm '$ORIG_SRPM_PATH'" fi return $RC fi local LOC LOC=$(git_list_containing_tag "${PKG_ROOT_DIR}/gits" "pre_wrs_$PKG_NAME_VER" | head -n 1 ) echo "===== '$TARGET_FOUND' has been extracted for editing. =====" echo "===== Metadata can be found at: $PKG_ROOT_DIR/rpmbuild" echo "===== Source code can be found at: $LOC" return 0 fi # # Find age of youngest input file. # We will apply this as the creation/modification timestamp of the src.rpm we produce. # AGE=$(find $PKG_BASE $ORIG_SRPM_PATH -type f -exec stat --format '%Y' "{}" \; | grep -v '[/][.]git$' | grep -v '[/][.]git[/]' | sort -nr | head -n 1) if [ -f $PKG_BASE/$DATA ]; then AGE2=$( cd $PKG_BASE srpm_source_build_data "$DATA" "$SRC_BUILD_TYPE_SRPM" "$ORIG_SRPM_PATH" PATH_LIST="" # NOTE: SRC_DIR is not honored in this build path if [ "x$COPY_LIST" != "x" ]; then PATH_LIST="$PATH_LIST $COPY_LIST" fi # NOTE: COPY_LIST_TO_TAR is not honored in this build path if [ "x$PATH_LIST" == "x" ]; then echo "0" else AGE2=$(find $PATH_LIST -type f -exec stat --format '%Y' "{}" \; | grep -v '[/][.]git$' | grep -v '[/][.]git[/]' | sort -nr | head -n 1) echo "$AGE2" fi ) if [ $AGE2 -gt $AGE ]; then AGE=$AGE2 fi fi srpm_extract $ORIG_SRPM_PATH $PKG_BASE $ROOT_DIR $BUILD_DIR $PKG_NAME_VER if [ $? -ne 0 ]; then echo "ERROR: $FUNCNAME (${LINENO}): failed to extract srpm '$ORIG_SRPM_PATH'" return 1 fi if [ "x$COPY_LIST" != "x" ]; then echo "COPY_LIST: $COPY_LIST" for p in $COPY_LIST; do # echo "COPY_LIST: $p" \cp -L -r -f -v $p $FULL_BUILD_DIR/SOURCES if [ $? -ne 0 ]; then echo "ERROR: $FUNCNAME (${LINENO}): COPY_LIST: file not found: '$p'" return 1 fi done fi srpm_assemble $FULL_BUILD_DIR $TIS_PATCH_VER $PBR_VERSION if [ $? -ne 0 ]; then echo "ERROR: $FUNCNAME (${LINENO}): failed to assemble srpm for '$PKG_NAME_VER'" echo "$TARGET_FOUND" >> $MY_WORKSPACE/tmp/SRPM_FAILED_REBUILD_LIST_${build_idx} return 1 fi TS=$(date -d @$AGE +%Y-%m-%dT%H:%M:%S) for s in $(find $FULL_BUILD_DIR/SRPMS -name '*.src.rpm'); do \cp -L -f -v $s $SRPM_OUT/ ss=$(basename $s) touch $SRPM_OUT/$ss --date=$TS mkdir -p $SOURCES_DIR/$ss BIG_FLAG_FILE="$SOURCES_DIR/$ss/BIG" SLOW_FLAG_FILE="$SOURCES_DIR/$ss/SLOW" if [ $BUILD_IS_BIG -gt 0 ]; then echo "$BUILD_IS_BIG" > $BIG_FLAG_FILE else if [ -f $BIG_FLAG_FILE ]; then \rm -f $BIG_FLAG_FILE fi fi if [ $BUILD_IS_SLOW -gt 0 ]; then echo "$BUILD_IS_SLOW" > $SLOW_FLAG_FILE else if [ -f $SLOW_FLAG_FILE ]; then \rm -f $SLOW_FLAG_FILE fi fi \rm -f -v "$REFERENCE_MD5" \mv -v "$INPUT_FILES_MD5" "$REFERENCE_MD5" local SPEC_DIR=$(spec_cache_dir_from_srpm $SRPM_OUT/$ss) if [ -d $SPEC_DIR/BUILDS_VR ]; then for f in $(ls -1 $SPEC_DIR/BUILDS_VR); do for r in $(find $RPM_DIR -name "$f*rpm" 2>> /dev/null); do \rm -f -v $r done done fi local RESULT_DIR=$(result_dir_from_srpm $SRPM_OUT/$ss) if [ -d $RESULT_DIR ]; then echo "rm -rf $RESULT_DIR" \rm -rf $RESULT_DIR fi done echo "$TARGET_FOUND" >> $MY_WORKSPACE/tmp/SRPM_REBUILT_LIST_${build_idx} echo "SRPM build successful for '$PKG_NAME_VER'" echo "===== Build complete for '$TARGET_FOUND' =====" echo fi return 0 } build_dir_spec () { local build_idx=$1 local NEED_BUILD=0 local TARGET_FOUND="" if [ "x$TARGETS" == "x" ]; then NEED_BUILD=1 for f in $(find $SPECS_BASE -maxdepth 1 -name '*.spec'); do TARGET_FOUND=$(spec_find_tag Name "$f" 2>> /dev/null) if [ $? -ne 0 ]; then TARGET_FOUND=$(spec_find_global service "$f" 2>> /dev/null) if [ $? -ne 0 ]; then TARGET_FOUND="" fi fi done else TARGET_LIST=( $TARGETS ) for f in $(find $SPECS_BASE -maxdepth 1 -name '*.spec' 2>> /dev/null); do TARGET_FOUND=$(spec_match_target_list TARGET_LIST "$f" 2>> /dev/null) if [ $? -eq 0 ]; then echo "found target '$TARGET_FOUND' in '$f'" NEED_BUILD=1 sed -i "/^$TARGET_FOUND$/d" $MY_WORKSPACE/tmp/UNRESOLVED_TARGETS_${build_idx} break fi done fi if [ $NEED_BUILD -eq 1 ]; then MAKE_SRPM="$SCRIPT_PATH/$SRPM_SCRIPT" export DATA="$DATA_PATH/$SRPM_DATA" export RPMBUILD_BASE="$WORK_BASE/rpmbuild" SRPM_PATH="$RPMBUILD_BASE/SRPMS" SPEC_PATH="$RPMBUILD_BASE/SPECS" SOURCES_PATH="$RPMBUILD_BASE/SOURCES" local ROOT_DIR="$RPMBUILD_BASE" local PKG_ROOT_DIR="$RPMBUILD_BASE" local SPEC=$(find $SPECS_BASE -maxdepth 1 -name '*.spec' | head -n 1) local NAME=$(spec_find_tag Name $SPEC) local PKG_NAME_VER=$(spec_name_ver_rel $SPEC) local PKG_DIR="$NAME" local BUILD_DIR="$PKG_DIR/rpmbuild" local FULL_BUILD_DIR="$ROOT_DIR" local SRPM_DIR="$FULL_BUILD_DIR/SRPMS" local SOURCES_DIR="$SOURCE_OUT" if [ $EDIT_FLAG -eq 1 ]; then mkdir -p $SRPM_WORK ROOT_DIR="$SRPM_WORK" PKG_ROOT_DIR="$ROOT_DIR/$PKG_DIR" fi if [ $CLEAN_FLAG -eq 1 ]; then # clean echo "===== Cleaning '$TARGET_FOUND' =====" if [ -d $SRPM_PATH ] && [ $EDIT_FLAG -eq 0 ]; then clean_srpm_dir $build_idx $SRPM_PATH 0 fi if [ -d $PKG_ROOT_DIR ]; then echo "rm -rf $PKG_ROOT_DIR" \rm -rf "$PKG_ROOT_DIR" fi else # build echo "===== Build SRPM for '$TARGET_FOUND' =====" echo "PKG_BASE=$PKG_BASE" echo "WORK_BASE=$WORK_BASE" echo "RPMBUILD_BASE=$RPMBUILD_BASE" if [ ! -x $MAKE_SRPM ]; then if [ ! -f $DATA ]; then echo "expected to find an executable script at '$MAKE_SRPM' or data for the default script at '$DATA'" cd $INITIAL_DIR exit 1 else MAKE_SRPM="$DEFAULT_SRPM_SCRIPT" fi fi # # Load data from build_srpm.data # srpm_source_build_data "$DATA" "$SRC_BUILD_TYPE_SPEC" "$SPEC" if [ $? -ne 0 ]; then echo "ERROR: $FUNCNAME (${LINENO}): failed to source $DATA" return 1 fi # # Capture md5 data for all input files # local TARGET_SOURCES_DIR="$SOURCES_DIR/$TARGET_FOUND" local INPUT_FILES_MD5="$TARGET_SOURCES_DIR/srpm_input.md5" local REFERENCE_MD5="$TARGET_SOURCES_DIR/srpm_reference.md5" mkdir -p "$TARGET_SOURCES_DIR" md5sums_from_input_vars "$SRC_BUILD_TYPE_SPEC" "$SPEC" "$TARGET_SOURCES_DIR" > "$INPUT_FILES_MD5" if [ $? -ne 0 ]; then echo "ERROR: $FUNCNAME (${LINENO}): md5sums_from_input_vars '$SRC_BUILD_TYPE_SPEC' '$SPEC' '$TARGET_SOURCES_DIR'" return 1 fi echo "Wrote: $INPUT_FILES_MD5" # # Is a rebuild required? # Compare md5 of current inputs vs md5 of previous build? # local BUILD_NEEDED=0 local SRPM_OUT_PATH2 local DIFF_LINE local DIFF_FILE if [ -f $REFERENCE_MD5 ]; then DIFF_LINE=$(diff "$INPUT_FILES_MD5" "$REFERENCE_MD5" | head -n 2 | tail -n 1; exit ${PIPESTATUS[0]}) if [ $? -ne 0 ]; then DIFF_FILE=$(echo "$DIFF_LINE" | cut -d ' ' -f4-) BUILD_NEEDED=1 case ${DIFF_LINE:0:1} in '>') echo "Rebuild required due to deleted file: $DIFF_FILE" ;; '<') echo "Rebuild required due to new or changed file: $DIFF_FILE" ;; *) echo "Rebuild required due to diff: $DIFF_LINE" ;; esac fi else echo "Rebuild required due to missing reference md5: $REFERENCE_MD5" BUILD_NEEDED=1 fi if [ -d "$FULL_BUILD_DIR/SRPMS" ]; then if [ -d "$RPMBUILD_BASE/SRPMS" ]; then b="" for SRPM_PATH2 in $(find "$RPMBUILD_BASE/SRPMS" -name '*.src.rpm' | sort -V); do b=$(basename $SRPM_PATH2) SRPM_OUT_PATH2=$(find $SRPM_OUT -name $b) if [ "x$SRPM_OUT_PATH2" == "x" ]; then echo "Rebuild required due to missing srpm: $b" BUILD_NEEDED=1 fi done if [ "$b" == "" ]; then echo "Rebuild required due no src.rpm found in directory: '$RPMBUILD_BASE/SRPMS'" BUILD_NEEDED=1 fi else echo "Rebuild required due to missing directory: '$RPMBUILD_BASE/SRPMS'" BUILD_NEEDED=1 fi else echo "Rebuild required due to missing directory: '$FULL_BUILD_DIR/SRPMS'" BUILD_NEEDED=1 fi if [ $EDIT_FLAG -eq 1 ]; then PKG_CLASSIFICATION=$(classify $PKG_BASE) echo "$PKG_CLASSIFICATION = classify $PKG_BASE" if [ "$PKG_CLASSIFICATION" == "spec + tarball" ] || [ "$PKG_CLASSIFICATION" == "srpm + patches" ]; then echo "OK to edit $PKG_BASE" else echo "Can't edit this package, it is of type '$PKG_CLASSIFICATION', it is not derived from SRPM or tarball and patches" return 1 fi echo "tar_and_spec_extract_to_git '$SPEC' '$PKG_BASE' '$ROOT_DIR' '$BUILD_DIR' '$PKG_NAME_VER' '$NO_META_PATCH_FLAG' '$TIS_PATCH_VER' '$PBR_VERSION'" tar_and_spec_extract_to_git "$SPEC" "$PKG_BASE" "$ROOT_DIR" "$BUILD_DIR" "$PKG_NAME_VER" "$NO_META_PATCH_FLAG" "$TIS_PATCH_VER" "$PBR_VERSION" RC=$? if [ $RC -ne 0 ]; then if [ $RC -eq 1 ]; then echo "ERROR: $FUNCNAME (${LINENO}): failed to extract srpm '$ORIG_SRPM_PATH'" fi return $RC fi local LOC LOC=$(git_list_containing_branch "${PKG_ROOT_DIR}/gits" "${PKG_NAME_VER}" | head -n 1 ) echo "===== '$TARGET_FOUND' has been extracted for editing. =====" echo "===== Metadata can be found at: $PKG_ROOT_DIR/rpmbuild" echo "===== Source code can be found at: $LOC" return 0 fi if [ $BUILD_NEEDED -eq 0 ]; then echo "SRPM build not required for '$PKG_BASE'" echo "===== Build complete for '$TARGET_FOUND' =====" echo return 0 fi export SRC_BUILD_TYPE="$SRC_BUILD_TYPE_SPEC" export SRPM_OR_SPEC_PATH="$SPEC" echo "MAKE_SRPM=$MAKE_SRPM" echo "DATA=$DATA" echo "SRC_BUILD_TYPE=$SRC_BUILD_TYPE" echo "SRPM_OR_SPEC_PATH=$SRPM_OR_SPEC_PATH" if [ -d "$RPMBUILD_BASE/SRPMS" ]; then clean_srpm_dir $build_idx "$RPMBUILD_BASE/SRPMS" 1 fi if [ -d $RPMBUILD_BASE ]; then echo "rm -rf $RPMBUILD_BASE" \rm -rf "$RPMBUILD_BASE" fi echo "mkdir -p $WORK_BASE $SRPM_PATH $SPEC_PATH $SOURCES_PATH" mkdir -p "$WORK_BASE" && \ mkdir -p "$SRPM_PATH" && \ mkdir -p "$SPEC_PATH" && \ mkdir -p "$SOURCES_PATH" if [ $? -ne 0 ]; then echo "ERROR: $FUNCNAME (${LINENO}): Failed to create directories under: $WORK_BASE" fi \cp -L -f -v $SPECS_BASE/*.spec $SPEC_PATH/ if [ $? -ne 0 ]; then echo "ERROR: $FUNCNAME (${LINENO}): Failed to copy spec files from '$SPECS_BASE' to '$SPEC_PATH'" fi # # build # $MAKE_SRPM if [ $? -ne 0 ]; then echo "ERROR: $FUNCNAME (${LINENO}): script failed '$MAKE_SRPM'" echo "$TARGET_FOUND" >> $MY_WORKSPACE/tmp/SRPM_FAILED_REBUILD_LIST_${build_idx} exit 1 fi # # Find age of youngest input file. # We will apply this as the creation/modification timestamp of the src.rpm we produce. # AGE=$(find $PKG_BASE -type f -exec stat --format '%Y' "{}" \; | grep -v '[/][.]git$' | grep -v '[/][.]git[/]' | sort -nr | head -n 1) if [ -f $PKG_BASE/$DATA ]; then AGE2=$( cd $PKG_BASE srpm_source_build_data "$DATA" "$SRC_BUILD_TYPE_SPEC" "$SPEC" PATH_LIST="" if [ "x$SRC_DIR" != "x" ]; then if [ -d "$SRC_DIR" ]; then PATH_LIST="$PATH_LIST $SRC_DIR" fi fi if [ "x$COPY_LIST" != "x" ]; then PATH_LIST="$PATH_LIST $COPY_LIST" fi if [ "x$COPY_LIST_TO_TAR" != "x" ]; then PATH_LIST="$PATH_LIST $COPY_LIST_TO_TAR" fi if [ "x$PATH_LIST" == "x" ]; then echo "0" else AGE2=$(find $PATH_LIST -type f -exec stat --format '%Y' "{}" \; | grep -v '[/][.]git$' | grep -v '[/][.]git[/]' | sort -nr | head -n 1) echo "$AGE2" fi ) if [ $AGE2 -gt $AGE ]; then AGE=$AGE2 fi fi TS=$(date -d @$AGE +%Y-%m-%dT%H:%M:%S) for s in $(find $SRPM_PATH -name '*.src.rpm'); do \cp -L -f $s $SRPM_OUT/ ss=$(basename $s) touch $SRPM_OUT/$ss --date=$TS mkdir -p $SOURCES_DIR/$ss BIG_FLAG_FILE="$SOURCES_DIR/$ss/BIG" SLOW_FLAG_FILE="$SOURCES_DIR/$ss/SLOW" if [ $BUILD_IS_BIG -gt 0 ]; then echo $BUILD_IS_BIG > $BIG_FLAG_FILE else if [ -f $BIG_FLAG_FILE ]; then \rm -f $BIG_FLAG_FILE fi fi if [ $BUILD_IS_SLOW -gt 0 ]; then echo $BUILD_IS_SLOW > $SLOW_FLAG_FILE else if [ -f $SLOW_FLAG_FILE ]; then \rm -f $SLOW_FLAG_FILE fi fi \rm -f -v "$REFERENCE_MD5" \mv -v "$INPUT_FILES_MD5" "$REFERENCE_MD5" local SPEC_DIR=$(spec_cache_dir_from_srpm $SRPM_OUT/$ss) if [ -d $SPEC_DIR/BUILDS_VR ]; then for f in $(ls -1 $SPEC_DIR/BUILDS_VR); do for r in $(find $RPM_DIR -name "$f*rpm" 2>> /dev/null); do \rm -f -v $r done done fi local RESULT_DIR=$(result_dir_from_srpm $SRPM_OUT/$ss) if [ -d $RESULT_DIR ]; then echo "rm -rf $RESULT_DIR" \rm -rf $RESULT_DIR fi done echo "$TARGET_FOUND" >> $MY_WORKSPACE/tmp/SRPM_REBUILT_LIST_${build_idx} echo "===== Build complete for '$TARGET_FOUND' =====" echo fi fi return 0 } ( echo "$CMDLINE" if [ -L $BUILD_ROOT/repo ]; then REPO_DEST=$(readlink $BUILD_ROOT/repo) if [ "$REPO_DEST" != "$SRC_ROOT" ]; then echo "Error: MY_REPO changed since last build" echo " old path: $REPO_DEST" echo " new path: $SRC_ROOT" echo "Please run '$ME --clean' if you want to compile from a new source tree" exit 1 fi fi if [ ! -L $BUILD_ROOT/repo ]; then ln -s $SRC_ROOT $BUILD_ROOT/repo fi ALL=0 UNRESOLVED_TARGETS="" if [ "x$TARGETS" == "x" ]; then echo "make: all" ALL=1 else echo "make: $TARGETS" UNRESOLVED_TARGETS="$TARGETS" fi workers=0 max_workers=$MAX_WORKERS declare -A build_env init_build_env () { local i=0 local stop=$((max_workers-1)) for i in $(seq 0 $stop); do build_env[$i]='Idle' done } init_build_env get_idle_build_env () { local i=0 local stop=$((max_workers-1)) if [ $stop -ge 255 ]; then stop=254 fi for i in $(seq 0 $stop); do if [ ${build_env[$i]} == 'Idle' ]; then build_env[$i]='Busy' return $i fi done return 255 } set_build_env_pid () { local idx=$1 local val=$2 build_env[$idx]=$val } release_build_env () { local idx=$1 build_env[$idx]='Idle' } reaper () { local reaped=0 local last_reaped=-1 local i=0 local stop=$((max_workers-1)) local p=0 local ret=0 if [ $stop -ge 255 ]; then stop=254 fi while [ $reaped -gt $last_reaped ]; do last_reaped=$reaped for i in $(seq 0 $stop); do p=${build_env[$i]} if [ "$p" == "Idle" ] || [ "$p" == "Busy" ]; then continue fi # echo "test $i $p" kill -0 $p &> /dev/null if [ $? -ne 0 ]; then wait $p ret=$? workers=$((workers-1)) reaped=$((reaped+1)) release_build_env $i if [ $ret -ne 0 ]; then VERB="build" if [ $EDIT_FLAG -eq 1 ]; then VERB="edit" if [ $CLEAN_FLAG -eq 1 ]; then VERB="edit clean" fi else if [ $CLEAN_FLAG -eq 1 ]; then VERB="clean" fi fi sleep 1 echo "ERROR: $FUNCNAME (${LINENO}): Failed to $VERB src.rpm from source at 'b$i'" cat "$LOG_DIR/$i" >> $LOG_DIR/errors echo "ERROR: $FUNCNAME (${LINENO}): Failed to $VERB src.rpm from source at 'b$i'" >> $LOG_DIR/errors echo "" >> $LOG_DIR/errors STOP_SCHEDULING=1 fi fi done done return $reaped } # Set up files to collect parallel build results ... mkdir -p $MY_WORKSPACE/tmp fn="$MY_WORKSPACE/tmp/UNRESOLVED_TARGETS_merge" if [ -f $fn ]; then \rm -f $fn fi for n in $UNRESOLVED_TARGETS; do echo $n >> $fn; done if [ -f $fn ]; then sort $fn > $MY_WORKSPACE/tmp/UNRESOLVED_TARGETS else \rm -f -v $MY_WORKSPACE/tmp/UNRESOLVED_TARGETS touch $MY_WORKSPACE/tmp/UNRESOLVED_TARGETS fi for i in $(seq 0 $((max_workers-1))); do for fn in $MY_WORKSPACE/tmp/SRPM_REBUILT_LIST_$i $MY_WORKSPACE/tmp/SRPM_FAILED_REBUILD_LIST_$i $MY_WORKSPACE/tmp/UNRESOLVED_TARGETS_$i; do if [ -f $fn ]; then \rm -f -v $fn fi done \cp $MY_WORKSPACE/tmp/UNRESOLVED_TARGETS $MY_WORKSPACE/tmp/UNRESOLVED_TARGETS_$i done # create a build info if [ $CLEAN_FLAG -eq 0 ] && [ $EDIT_FLAG -eq 0 ] && [ $NO_BUILD_INFO -eq 0 ]; then set_build_info fi # Build src.rpm's LOG_DIR=$(mktemp -d $MY_WORKSPACE/tmp/$USER-$ME-log-XXXXXX) if [ "x$LOG_DIR" == "x" ]; then echo "failed to create temporary directory" exit 1; fi for GIT_ROOT in $GIT_LIST; do export GIT_BASE="$GIT_ROOT" if [ $STOP_SCHEDULING -eq 1 ]; then break; fi if echo "$GIT_ROOT" | grep do-not-build; then continue fi for p in $(cat $GIT_ROOT/$PKG_DIRS_FILE 2>> /dev/null); do if [ $STOP_SCHEDULING -eq 1 ]; then break; fi src_dir="$GIT_ROOT/$p" if [ -d $src_dir ]; then if [ -d $src_dir/${DISTRO} ]; then rel_dir=$(echo $src_dir | sed "s:^$SRC_BASE::") work_dir="$BUILD_INPUTS$rel_dir" # Free up a worker while [ $workers -ge $max_workers ]; do reaper reaped=$? if [ $reaped -eq 0 ]; then sleep 0.1 fi done workers=$((workers+1)) get_idle_build_env b=$? if [ $b -ge 255 ]; then echo "get_idle_build_env failed to find a free slot" exit 1 fi PREFIX="b$b" ( build_dir $b $src_dir $work_dir 2>&1 | sed "s#^#${PREFIX}: #" | tee $LOG_DIR/$b; exit ${PIPESTATUS[0]} ) & pp=$! set_build_env_pid $b $pp else echo "ERROR: $FUNCNAME (${LINENO}): Failed to find 'centos' in '$p', found in file '$GIT_ROOT/$PKG_DIRS_FILE'" fi else echo "ERROR: $FUNCNAME (${LINENO}): Bad path '$p' in file '$GIT_ROOT/$PKG_DIRS_FILE'" fi done done # Wait for remaining workers to exit while [ $workers -gt 0 ]; do reaper reaped=$? if [ $reaped -eq 0 ]; then sleep 0.1 fi done if [ $STOP_SCHEDULING -eq 1 ]; then echo "============ Build failed =============" if [ -f $LOG_DIR/errors ]; then cat $LOG_DIR/errors fi \rm -rf $LOG_DIR exit 1 fi \rm -rf $LOG_DIR # Transfer results from files back into variables SRPM_REBUILT_LIST=$((for i in $(seq 0 $((max_workers-1))); do fn=$MY_WORKSPACE/tmp/SRPM_REBUILT_LIST_$i if [ -f $fn ]; then cat $fn | tr '\n' ' ' fi done) | sed 's/ $//') SRPM_FAILED_REBUILD_LIST=$((for i in $(seq 0 $((max_workers-1))); do fn=$MY_WORKSPACE/tmp/SRPM_FAILED_REBUILD_LIST_$i if [ -f $fn ]; then cat $fn | tr '\n' ' ' fi done) | sed 's/ $//') UNRESOLVED_TARGETS=$(for i in $(seq 0 $((max_workers-1))); do if [ -f $MY_WORKSPACE/tmp/UNRESOLVED_TARGETS_$i ]; then comm -1 -2 $MY_WORKSPACE/tmp/UNRESOLVED_TARGETS $MY_WORKSPACE/tmp/UNRESOLVED_TARGETS_$i > $MY_WORKSPACE/tmp/UNRESOLVED_TARGETS_merge \mv $MY_WORKSPACE/tmp/UNRESOLVED_TARGETS_merge $MY_WORKSPACE/tmp/UNRESOLVED_TARGETS fi done cat $MY_WORKSPACE/tmp/UNRESOLVED_TARGETS | tr '\n' ' ' | sed 's/ $//') \rm -rf $MY_WORKSPACE/tmp/SRPM_REBUILT_LIST_* $MY_WORKSPACE/tmp/SRPM_FAILED_REBUILD_LIST_* $MY_WORKSPACE/tmp/UNRESOLVED_TARGETS* 2>> /dev/null # Try to find and clean orphaned and discontinued .src.rpm's if [ $ALL -eq 1 ]; then echo echo "Auditing for obsolete srpms" AUDIT_DIR=$(mktemp -d $MY_WORKSPACE/tmp/$USER-$ME-audit-XXXXXX) if [ $? -eq 0 ] && [ "x$AUDIT_DIR" != "x" ]; then for GIT_ROOT in $GIT_LIST; do if echo "$GIT_ROOT" | grep -q do-not-build; then continue fi for p in $(cat $GIT_ROOT/$PKG_DIRS_FILE 2>> /dev/null); do ( src_dir="$GIT_ROOT/$p" if [ -d $src_dir ]; then if [ -d $src_dir/$DISTRO ]; then for f in $(find $src_dir/${DISTRO} -name '*.spec' | sort -V); do NAME=$(spec_find_tag Name "$f" 2>> /dev/null) if [ $? -eq 0 ]; then touch "$AUDIT_DIR/$NAME" fi done if [ -f $src_dir/$SRPM_LIST_PATH ]; then for p in $(grep -v '^#' $src_dir/$SRPM_LIST_PATH | grep -v '^$'); do ORIG_SRPM_PATH="" # absolute path source rpms echo "$p" | grep "^/" >/dev/null && ORIG_SRPM_PATH=$p if [ "${ORIG_SRPM_PATH}x" == "x" ]; then # handle repo: definitions echo "$p" | grep "^repo:" >/dev/null && ORIG_SRPM_PATH=$(echo $p | sed "s%^repo:%$REPO_DOWNLOADS_ROOT/%") fi if [ "${ORIG_SRPM_PATH}x" == "x" ]; then # handle repo: definitions echo "$p" | grep "^3rd_party:" >/dev/null && ORIG_SRPM_PATH=$(echo $p | sed "s%^3rd_party:%$THIRD_PARTY_ROOT/%") fi if [ "${ORIG_SRPM_PATH}x" == "x" ]; then # handle mirror: definitions echo "$p" | grep "^mirror:" >/dev/null && ORIG_SRPM_PATH=$(echo $p | sed "s%^mirror:%$MIRROR_ROOT/%" | sed "s#CentOS/tis-r3-CentOS/kilo/##" | sed "s#CentOS/tis-r3-CentOS/mitaka/##") fi if [ "${ORIG_SRPM_PATH}x" == "x" ]; then # we haven't found a valid prefix yet, so assume it's a legacy # file (mirror: interpretation) ORIG_SRPM_PATH="$MIRROR_ROOT/$p" fi if [ -f $ORIG_SRPM_PATH ]; then NAME=$(rpm -q --queryformat '%{NAME}\n' -p $ORIG_SRPM_PATH 2>> /dev/null) if [ $? -eq 0 ]; then touch "$AUDIT_DIR/$NAME" fi fi done fi fi fi ) & done done echo "waiting" wait echo "Auditing for obsolete srpms Phase 2" for r in $(find $SRPM_OUT -name '*.src.rpm' | sort -V); do ( NAME=$(rpm -q --queryformat '%{NAME}\n' -p $r 2>> /dev/null) ALT_NAME=$(echo $NAME | sed "s#-$BUILD_TYPE\$##") FOUND=0 if [[ -f "$AUDIT_DIR/$NAME" || ( "$BUILD_TYPE" != "std" && -f "$AUDIT_DIR/$ALT_NAME" ) ]]; then FOUND=1 fi if [ $FOUND -eq 0 ]; then for INPUT_DIR in $(find $BUILD_INPUTS -name $NAME | sort -V); do if [ -d "$INPUT_DIR/rpmbuild/SRPMS" ]; then clean_srpm_dir $build_idx "$INPUT_DIR/rpmbuild/SRPMS" 0 fi if [ -d $INPUT_DIR ]; then echo "rm -rf $r" \rm -rf $r fi done if [ -f $r ]; then \rm -f -v $r fi fi ) & done echo "waiting" wait \rm -rf "$AUDIT_DIR" fi echo "Auditing for obsolete srpms done" fi if [ $CLEAN_FLAG -eq 1 ]; then if [ $ALL -eq 1 ]; then \rm -rf $BUILD_INPUTS \rm -rf $SOURCE_OUT/*.src.rpm fi fi if [ $EDIT_FLAG -ne 1 ]; then echo "==== Update repodata =====" mkdir -p $SRPM_OUT/repodata for d in $(find -L $SRPM_OUT -type d -name repodata); do (cd $d/.. \rm -rf repodata $CREATEREPO $(pwd) create_lst $(pwd) ) done echo "==== Update repodata complete =====" fi FINAL_RC=0 if [ $CLEAN_FLAG -eq 0 ] && [ $EDIT_FLAG -eq 0 ]; then echo "" if [ "$SRPM_FAILED_REBUILD_LIST" != "" ]; then N=$(echo "$SRPM_FAILED_REBUILD_LIST" | wc -w) echo "Failed to build $N packages:" echo " $SRPM_FAILED_REBUILD_LIST" FINAL_RC=1 fi if [ "$SRPM_REBUILT_LIST" != "" ]; then N=$(echo "$SRPM_REBUILT_LIST" | wc -w) echo "Successfully built $N packages:" echo " $SRPM_REBUILT_LIST" echo "" echo "Compiled src.rpm's can be found here: $SRPM_OUT" fi if [ "$SRPM_FAILED_REBUILD_LIST" == "" ] && [ "$SRPM_REBUILT_LIST" == "" ]; then echo "No packages required a rebuild" fi fi if [ "$UNRESOLVED_TARGETS" != "" ]; then echo "" echo "ERROR: $FUNCNAME (${LINENO}): failed to resolve build targets: $UNRESOLVED_TARGETS" FINAL_RC=1 fi exit $FINAL_RC ) 2>&1 | stdbuf -o0 awk '{ print strftime("%H:%M:%S"), $0; fflush(); }' | tee $(date "+$MY_WORKSPACE/build-srpms-parallel_%Y-%m-%d_%H-%M-%S.log") ; exit ${PIPESTATUS[0]}