#!/bin/bash # # Copyright (c) 2018 Wind River Systems, Inc. # # SPDX-License-Identifier: Apache-2.0 # # # Build first src.rpms, then rpms, from source, or from a downloaded tarball # or src.rpm plus our additional patches. # # This program is a wrapper around build-srpms-parallel and build-rpms-parallel # BUILD_PKGS_PARALLEL_DIR="$(dirname "$(readlink -f "${BASH_SOURCE[0]}" )" )" source "${BUILD_PKGS_PARALLEL_DIR}/git-utils.sh" source "${BUILD_PKGS_PARALLEL_DIR}/spec-utils" usage () { echo "" echo "Usage: " echo " Create source and Binary rpms:" echo " Build optimizations (--no-descendants, --no-required, --no-build-info," echo " --no-autoclean, --no-build-avoidance) are not recommended for the first build" echo " after a clone/pull, nor the final build prior to creating an iso or patch," echo " but can be used for intermediate builds." echo " i.e. while debugging compilation failures." echo " build-pkgs-parallel [--layer] [--build-avoidance | --no-build-avoidance] [--no-descendants] [--no-required] [--no-build-info] [--no-autoclean] [--careful] [--formal] [ list of package names ]" echo "" echo " Test build dependencies of a package:" echo " Note: A full build of all packages should preceed the dependency test build" echo " build-pkgs-parallel --dep-test " echo "" echo " Delete source rpms, and the directories associated with it's creation:" echo " Note: does not clean an edit environment" echo " build-pkgs-parallel --clean [--build-avoidance | --no-build-avoidance] [ 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 " build-pkgs-parallel --edit [--no-meta-patch] [ list of package names ]" echo "" echo " Delete an edit environment" echo " build-pkgs-parallel --edit --clean [ list of package names ]" echo "" echo " This help page" echo " build-pkgs-parallel [--help]" echo "" } HELP=0 CLEAN_FLAG=0 EDIT_FLAG=0 APPEND_LOG_FLAG=0 BUILD_AVOIDANCE_FLAG=0 STD_BUILD=1 RT_BUILD=1 INSTALLER_BUILD=0 CONTAINERS_BUILD=0 DEP_TEST_FLAG=0 export BUILD_AVOIDANCE_URL="" # For backward compatibility. Old repo location or new? CENTOS_REPO=${MY_REPO}/centos-repo if [ ! -d ${CENTOS_REPO} ]; then CENTOS_REPO=${MY_REPO}/cgcs-centos-repo if [ ! -d ${CENTOS_REPO} ]; then echo "ERROR: directory ${MY_REPO}/centos-repo not found." exit 1 fi fi # read the options TEMP=$(getopt -o h --long parallel,rt,std,installer,containers,layer:,edit,build-avoidance,no-build-avoidance,build-avoidance-dir:,build-avoidance-host:,build-avoidance-user:,build-avoidance-day:,no-meta-patch,no-descendants,no-required,no-build-info,no-autoclean,formal,careful,help,clean,dep-test,append-log -n 'build-pkgs-parallel' -- "$@") if [ $? -ne 0 ]; then usage exit 1 fi eval set -- "$TEMP" # extract options and their arguments into variables. EXTRA_ARGS_COMMON="" EXTRA_ARGS_SRPM="" EXTRA_ARGS_RPM="" export BUILD_AVOIDANCE_OVERRIDE_DIR="" export BUILD_AVOIDANCE_OVERRIDE_HOST="" export BUILD_AVOIDANCE_OVERRIDE_USR="" export BUILD_AVOIDANCE_DAY="" while true ; do case "$1" in --append-log) APPEND_LOG_FLAG=1 ; shift ;; --build-avoidance) BUILD_AVOIDANCE_FLAG=1 ; shift ;; --no-build-avoidance) BUILD_AVOIDANCE_FLAG=0 ; shift ;; --build-avoidance-dir) BUILD_AVOIDANCE_OVERRIDE_DIR=$2; shift 2 ;; --build-avoidance-host) BUILD_AVOIDANCE_OVERRIDE_HOST=$2; shift 2 ;; --build-avoidance-user) BUILD_AVOIDANCE_OVERRIDE_USR=$2; shift 2 ;; --build-avoidance-day) BUILD_AVOIDANCE_DAY=$2; shift 2 ;; --no-descendants) EXTRA_ARGS_COMMON+=" --no-descendants" ; shift ;; --formal) EXTRA_ARGS_COMMON+=" --formal" ; shift ;; --careful) EXTRA_ARGS_RPM+=" --careful" ; shift ;; --layer) EXTRA_ARGS_COMMON+=" --layer=$2"; shift 2 ;; --no-required) EXTRA_ARGS_RPM+=" --no-required" ; shift ;; --no-build-info) EXTRA_ARGS_COMMON+=" --no-build-info" ; shift ;; --no-autoclean) EXTRA_ARGS_RPM+=" --no-autoclean" ; shift ;; --no-meta-patch) EXTRA_ARGS_SRPM+=" --no-meta-patch" ; shift ;; -h|--help) HELP=1 ; shift ;; --clean) CLEAN_FLAG=1 ; shift ;; --dep-test) DEP_TEST_FLAG=1; EXTRA_ARGS_RPM+=" --dep-test"; shift ;; --edit) EDIT_FLAG=1 ; EXTRA_ARGS_SRPM+=" --edit"; shift ;; --rt) STD_BUILD=0 ; shift ;; --std) RT_BUILD=0 ; shift ;; --installer) INSTALLER_BUILD=1 ; STD_BUILD=0 ; RT_BUILD=0 ; shift ;; --containers) INSTALLER_BUILD=0 ; STD_BUILD=0 ; RT_BUILD=0 ; CONTAINERS_BUILD=1 ; shift ;; --parallel) shift ;; --) shift ; break ;; *) usage; exit 1 ;; esac done if [ $HELP -eq 1 ]; then usage exit 0 fi # Don't source until after BUILD_AVOIDANCE_OVERRIDE_* variables are set. source "${BUILD_PKGS_PARALLEL_DIR}/build-avoidance-utils.sh" function my_exit() { build-rpms-parallel --std --tmpfs-clean build-rpms-parallel --rt --tmpfs-clean } function my_sigint() { echo "build-pkgs-parallel sigint" pkill -SIGABRT -P $BASHPID &> /dev/null echo "build-pkgs-parallel waiting" wait echo "build-pkgs-parallel wait complete" } function my_sighup() { echo "build-pkgs-parallel sighup" pkill -SIGABRT -P $BASHPID &> /dev/null echo "build-pkgs-parallel waiting" wait echo "build-pkgs-parallel wait complete" } function my_sigabrt() { echo "build-pkgs-parallel sigabrt" pkill -SIGABRT -P $BASHPID &> /dev/null echo "build-pkgs-parallel waiting" wait echo "build-pkgs-parallel wait complete" } function my_sigterm() { echo "build-pkgs-parallel sigterm" pkill -SIGABRT -P $BASHPID &> /dev/null echo "build-pkgs-parallel waiting" wait echo "build-pkgs-parallel wait complete" } trap my_exit EXIT trap my_sigint INT trap my_sighup HUP trap my_sigabrt ABRT trap my_sigterm TERM # Note: For ease of parsing, a TARGETS list always begins and ends # with a space. An empty target list consistes of two spaces. TARGETS=" $@ " EMPTY_TARGETS=" " TARGETS_STD="$EMPTY_TARGETS" TARGETS_RT="$EMPTY_TARGETS" TARGETS_INSTALLER="$EMPTY_TARGETS" TARGETS_CONTAINERS="$EMPTY_TARGETS" TARGETS_MISC="$EMPTY_TARGETS" find_targets () { local centos_pkg_dirs=$1 local d="" local d2="" local g="" local x="" local name="" local path="" local RESULT="$EMPTY_TARGETS" local FOUND=0 for d in $GIT_LIST; do if [ -f $d/$centos_pkg_dirs ]; then for d2 in $(grep -v '^#' $d/$centos_pkg_dirs); do name="" if [ -f $d/$d2/centos/srpm_path ]; then path=$(cat $d/$d2/centos/srpm_path | head -n 1 | \ sed -e "s#^mirror:CentOS/tis-r3-CentOS/mitaka#${CENTOS_REPO}#" \ -e "s#^mirror:#${CENTOS_REPO}/#" \ -e "s#^repo:#$MY_REPO/#" \ -e "s#^3rd_party:#$MY_REPO/cgcs-3rd-party-repo/#" \ -e "s#^Source/#${CENTOS_REPO}/Source/#") name=$(rpm -q --qf='%{NAME}' --nosignature -p $path) else path=$(find $d/$d2/centos/ -name '*.spec' | head -n 1) if [[ ( -z "$path" ) && ( -f $d/$d2/centos/spec_path ) ]]; then path=$(find $MY_REPO/$(cat $d/$d2/centos/spec_path) -maxdepth 1 -name '*.spec' | head -n 1) fi if [ "$path" != "" ]; then name=$(spec_find_tag Name "$path" 2>> /dev/null) fi fi if [ "$name" != "" ]; then if [ "$BUILD_TYPE" == "rt" ]; then FOUND=0 for x in $TARGETS; do if [ "${x: -3}" == "-rt" ]; then if [ "${name}" == "$x" ] || [ "${name}-rt" == "${x}" ]; then RESULT+="$x " FOUND=1 break fi fi done if [ $FOUND -eq 0 ]; then for x in $TARGETS; do if [ "${name}" == "${x}-rt" ]; then RESULT+="$x-rt " FOUND=1 break else if [ "${name}" == "$x" ] || [ "${name}-rt" == "${x}" ]; then RESULT+="$x " FOUND=1 break fi fi done fi else for x in $TARGETS; do if [ "${name}" == "$x" ]; then RESULT+="$x " FOUND=1 break fi done fi fi done fi done echo "$RESULT" return 0 } if [ $EDIT_FLAG -eq 1 ] || [ "$TARGETS" != "$EMPTY_TARGETS" ]; then BUILD_AVOIDANCE_FLAG=0 fi echo "BUILD_AVOIDANCE_FLAG=$BUILD_AVOIDANCE_FLAG" echo "CLEAN_FLAG=$CLEAN_FLAG" echo "EDIT_FLAG=$EDIT_FLAG" if [ "$TARGETS" != "$EMPTY_TARGETS" ]; then TARGETS_STD="$(find_targets centos_pkg_dirs)" BUILD_TYPE_SAVE="$BUILD_TYPE" BUILD_TYPE="rt" TARGETS_RT="$(find_targets centos_pkg_dirs_rt)" BUILD_TYPE="installer" TARGETS_INSTALLER="$(find_targets centos_pkg_dirs_installer)" BUILD_TYPE="containers" TARGETS_CONTAINERS="$(find_targets centos_pkg_dirs_containers)" BUILD_TYPE="$BUILD_TYPE_SAVE" echo "TARGETS_STD=$TARGETS_STD" echo "TARGETS_RT=$TARGETS_RT" echo "TARGETS_INSTALLER=$TARGETS_INSTALLER" echo "TARGETS_CONTAINERS=$TARGETS_CONTAINERS" for x in $TARGETS; do if [[ $TARGETS_STD == *" $x "* ]] then echo "found $x" >> /dev/null; else if [[ $TARGETS_RT == *" $x "* ]] then echo "found $x" >> /dev/null; else if [[ $TARGETS_INSTALLER == *" $x "* ]] then echo "found $x" >> /dev/null; INSTALLER_BUILD=1 else if [[ $TARGETS_CONTAINERS == *" $x "* ]] then echo "found $x" >> /dev/null; CONTAINERS_BUILD=1 else TARGETS_MISC+="$x " fi fi fi fi done fi echo "EXTRA_ARGS_COMMON='$EXTRA_ARGS_COMMON'" echo "EXTRA_ARGS_SRPM='$EXTRA_ARGS_SRPM'" echo "EXTRA_ARGS_RPM='$EXTRA_ARGS_RPM'" echo "TARGETS='$TARGETS'" echo "TARGETS_STD='$TARGETS_STD'" echo "TARGETS_RT='$TARGETS_RT'" echo "TARGETS_INSTALLER='$TARGETS_INSTALLER'" echo "TARGETS_CONTAINERS='$TARGETS_CONTAINERS'" echo "TARGETS_MISC='$TARGETS_MISC'" if [ $CLEAN_FLAG -eq 1 ]; then if [ "$TARGETS" == "$EMPTY_TARGETS" ] && [ $BUILD_AVOIDANCE_FLAG -eq 1 ] ; then build_avoidance_clean fi if [ $STD_BUILD -eq 1 ]; then if [ "$TARGETS" == "$EMPTY_TARGETS" ] || [ "$TARGETS_STD" != "$EMPTY_TARGETS" ] || [ "$TARGETS_MISC" != "$EMPTY_TARGETS" ]; then if [ $EDIT_FLAG -ne 1 ]; then echo "${BUILD_PKGS_PARALLEL_DIR}/build-rpms-parallel --std --clean $EXTRA_ARGS_COMMON $EXTRA_ARGS_RPM $TARGETS_STD $TARGETS_MISC" ${BUILD_PKGS_PARALLEL_DIR}/build-rpms-parallel --std --clean $EXTRA_ARGS_COMMON $EXTRA_ARGS_RPM $TARGETS_STD $TARGETS_MISC || exit 1 fi fi if [ "$TARGETS" == "$EMPTY_TARGETS" ] || [ "$TARGETS_STD" != "$EMPTY_TARGETS" ] || [ "$TARGETS_MISC" != "$EMPTY_TARGETS" ]; then echo "${BUILD_PKGS_PARALLEL_DIR}/build-srpms-parallel --std --clean $EXTRA_ARGS_COMMON $EXTRA_ARGS_SRPM $TARGETS_STD $TARGETS_MISC" ${BUILD_PKGS_PARALLEL_DIR}/build-srpms-parallel --std --clean $EXTRA_ARGS_COMMON $EXTRA_ARGS_SRPM $TARGETS_STD $TARGETS_MISC || exit 1 fi fi if [ $RT_BUILD -eq 1 ]; then if [ "$TARGETS" == "$EMPTY_TARGETS" ] || [ "$TARGETS_RT" != "$EMPTY_TARGETS" ] || [ "$TARGETS_MISC" != "$EMPTY_TARGETS" ]; then if [ $EDIT_FLAG -ne 1 ]; then echo "${BUILD_PKGS_PARALLEL_DIR}/build-rpms-parallel --rt --clean $EXTRA_ARGS_COMMON $EXTRA_ARGS_RPM $TARGETS_RT $TARGETS_MISC" ${BUILD_PKGS_PARALLEL_DIR}/build-rpms-parallel --rt --clean $EXTRA_ARGS_COMMON $EXTRA_ARGS_RPM $TARGETS_RT $TARGETS_MISC || exit 1 fi fi if [ "$TARGETS" == "$EMPTY_TARGETS" ] || [ "$TARGETS_RT" != "$EMPTY_TARGETS" ] || [ "$TARGETS_MISC" != "$EMPTY_TARGETS" ]; then echo "${BUILD_PKGS_PARALLEL_DIR}/build-srpms-parallel --rt --clean $EXTRA_ARGS_COMMON $EXTRA_ARGS_SRPM $TARGETS_RT $TARGETS_MISC" ${BUILD_PKGS_PARALLEL_DIR}/build-srpms-parallel --rt --clean $EXTRA_ARGS_COMMON $EXTRA_ARGS_SRPM $TARGETS_RT $TARGETS_MISC || exit 1 fi fi if [ $INSTALLER_BUILD -eq 1 ]; then if [ "$TARGETS" == "$EMPTY_TARGETS" ] || [ "$TARGETS_INSTALLER" != "$EMPTY_TARGETS" ]; then if [ $EDIT_FLAG -ne 1 ]; then echo "${BUILD_PKGS_PARALLEL_DIR}/build-rpms-parallel --installer --clean $EXTRA_ARGS_COMMON $EXTRA_ARGS_RPM $TARGETS_INSTALLER" ${BUILD_PKGS_PARALLEL_DIR}/build-rpms-parallel --installer --clean $EXTRA_ARGS_COMMON $EXTRA_ARGS_RPM $TARGETS_INSTALLER || exit 1 fi fi if [ "$TARGETS" == "$EMPTY_TARGETS" ] || [ "$TARGETS_INSTALLER" != "$EMPTY_TARGETS" ]; then echo "${BUILD_PKGS_PARALLEL_DIR}/build-srpms-parallel --installer --clean $EXTRA_ARGS_COMMON $EXTRA_ARGS_SRPM $TARGETS_INSTALLER" ${BUILD_PKGS_PARALLEL_DIR}/build-srpms-parallel --installer --clean $EXTRA_ARGS_COMMON $EXTRA_ARGS_SRPM $TARGETS_INSTALLER || exit 1 fi fi if [ $CONTAINERS_BUILD -eq 1 ]; then if [ "$TARGETS" == "$EMPTY_TARGETS" ] || [ "$TARGETS_CONTAINERS" != "$EMPTY_TARGETS" ]; then if [ $EDIT_FLAG -ne 1 ]; then echo "${BUILD_PKGS_PARALLEL_DIR}/build-rpms-parallel --containers --clean $EXTRA_ARGS_COMMON $EXTRA_ARGS_RPM $TARGETS_CONTAINERS" ${BUILD_PKGS_PARALLEL_DIR}/build-rpms-parallel --containers --clean $EXTRA_ARGS_COMMON $EXTRA_ARGS_RPM $TARGETS_CONTAINERS || exit 1 fi fi if [ "$TARGETS" == "$EMPTY_TARGETS" ] || [ "$TARGETS_CONTAINERS" != "$EMPTY_TARGETS" ]; then echo "${BUILD_PKGS_PARALLEL_DIR}/build-srpms-parallel --containers --clean $EXTRA_ARGS_COMMON $EXTRA_ARGS_SRPM $TARGETS_CONTAINERS" ${BUILD_PKGS_PARALLEL_DIR}/build-srpms-parallel --containers --clean $EXTRA_ARGS_COMMON $EXTRA_ARGS_SRPM $TARGETS_CONTAINERS || exit 1 fi fi exit $? fi function launch_build() { local build_type=$1 shift local logfile=$MY_WORKSPACE/build-$build_type.log local rc local targets if [ "$build_type" == "std" ]; then targets="$TARGETS_STD $TARGETS_MISC" else if [ "$build_type" == "rt" ]; then targets="$TARGETS_RT $TARGETS_MISC" else if [ "$build_type" == "installer" ]; then targets="$TARGETS_INSTALLER $TARGETS_MISC" else if [ "$build_type" == "containers" ]; then targets="$TARGETS_CONTAINERS $TARGETS_MISC" else targets="$TARGETS" fi fi fi fi echo "Launching $build_type build, logging to $logfile" if [ $APPEND_LOG_FLAG -eq 0 ] && [ -f $logfile ]; then \rm $logfile fi echo -e "\n######## $(date): Launching build-srpms-parallel --$build_type $EXTRA_ARGS $@\n" | tee --append $logfile if [ $BUILD_AVOIDANCE_FLAG -eq 1 ]; then # Build Avoidance requested. Get URL of a usable context, if any. export BUILD_AVOIDANCE_URL=$(get_build_avoidance_context $build_type) fi echo "BUILD_AVOIDANCE_URL=$BUILD_AVOIDANCE_URL" | tee --append $logfile if [ "x$BUILD_AVOIDANCE_URL" != "x" ]; then echo "build_avoidance $build_type" | tee --append $logfile build_avoidance $build_type 2>&1 | tee --append $logfile fi # No clean flag, call build-srpms-parallel followed by build-rpms-parallel echo "${BUILD_PKGS_PARALLEL_DIR}/build-srpms-parallel --$build_type $EXTRA_ARGS_COMMON $EXTRA_ARGS_SRPM $targets" | tee --append $logfile ${BUILD_PKGS_PARALLEL_DIR}/build-srpms-parallel --$build_type $EXTRA_ARGS_COMMON $EXTRA_ARGS_SRPM $targets 2>&1 | tee --append $logfile rc=${PIPESTATUS[0]} if [ $rc -eq 0 ]; then echo -e "\n######## $(date): build-srpm-parallel --$build_type was successful" | tee --append $logfile else echo -e "\n######## $(date): build-srpm-parallel --$build_type failed with rc=$rc" | tee --append $logfile echo -e "\n$(date): build-srpm-parallel --$build_type failed with rc=$rc" exit $rc fi if [ $EDIT_FLAG -ne 1 ]; then echo -e "\n######## $(date): Launching build-rpms-parallel --$build_type $EXTRA_ARGS $@\n" | tee --append $logfile echo "${BUILD_PKGS_PARALLEL_DIR}/build-rpms-parallel --$build_type $EXTRA_ARGS_COMMON $EXTRA_ARGS_RPM $targets" | tee --append $logfile ${BUILD_PKGS_PARALLEL_DIR}/build-rpms-parallel --$build_type $EXTRA_ARGS_COMMON $EXTRA_ARGS_RPM $targets 2>&1 | tee --append $logfile rc=${PIPESTATUS[0]} if [ $rc -eq 0 ]; then echo -e "\n######## $(date): build-rpm-parallel --$build_type was successful" | tee --append $logfile else echo -e "\n######## $(date): build-rpm-parallel --$build_type failed with rc=$rc" | tee --append $logfile echo -e "\n$(date): build-rpm-parallel --$build_type failed with rc=$rc" exit $rc fi fi echo -e "\n$(date): $build_type complete\n" #exit $rc } function progbar() { while :; do for s in / - \\ \|; do printf "\r$s" sleep .5 done done } # Create $MY_WORKSPACE if it doesn't exist already mkdir -p "${MY_WORKSPACE}" if [ $? -ne 0 ]; then echo "Failed to create directory '${MY_WORKSPACE}'" exit 1 fi echo "Capture build context" git_context > "${MY_WORKSPACE}/CONTEXT" if [ $STD_BUILD -eq 1 ]; then if [ "$TARGETS" == "$EMPTY_TARGETS" ] || [ "$TARGETS_STD" != "$EMPTY_TARGETS" ] || [ "$TARGETS_MISC" != "$EMPTY_TARGETS" ]; then launch_build std else echo "Skipping 'std' build, no valid targets in list: '$TARGETS'" fi else echo "Skipping 'std' build" fi if [ $RT_BUILD -eq 1 ]; then if [ "$TARGETS" == "$EMPTY_TARGETS" ] || [ "$TARGETS_RT" != "$EMPTY_TARGETS" ] || [ "$TARGETS_MISC" != "$EMPTY_TARGETS" ]; then launch_build rt else echo "Skipping 'rt' build, no valid targets in list: $TARGETS" fi else echo "Skipping 'rt' build" fi if [ $INSTALLER_BUILD -eq 1 ]; then if [ "$TARGETS" == "$EMPTY_TARGETS" ] || [ "$TARGETS_INSTALLER" != "$EMPTY_TARGETS" ] || [ "$TARGETS_MISC" != "$EMPTY_TARGETS" ]; then launch_build installer else echo "Skipping 'installer' build, no valid targets in list: $TARGETS" fi else echo "Skipping 'installer' build" fi if [ $CONTAINERS_BUILD -eq 1 ]; then if [ "$TARGETS" == "$EMPTY_TARGETS" ] || [ "$TARGETS_CONTAINERS" != "$EMPTY_TARGETS" ] || [ "$TARGETS_MISC" != "$EMPTY_TARGETS" ]; then launch_build containers else echo "Skipping 'containers' build, no valid targets in list: $TARGETS" fi else echo "Skipping 'containers' build" fi # Make sure REFERENCE_BUILD is set to something if [ -z $REFERENCE_BUILD ]; then REFERENCE_BUILD=0 fi if [ $REFERENCE_BUILD -eq 1 ]; then echo "Saving reference context" build_avoidance_save_reference_context fi echo "All builds were successful" exit 0