From 7178c668dd69c551fd58f5ebaf584f75ae765961 Mon Sep 17 00:00:00 2001 From: xumia <59720581+xumia@users.noreply.github.com> Date: Mon, 14 Mar 2022 11:20:20 +0800 Subject: [PATCH] [Build]: Fix installing dpkg packages in parallel issue (#10175) Why I did it Fix the debian packages installing in parallel issue. Add apt hook command to support apt to print no version control info. --- src/sonic-build-hooks/hooks/apt | 5 ++ src/sonic-build-hooks/hooks/apt-get | 39 ++++------ .../scripts/buildinfo_base.sh | 74 +++++++++++++++++++ 3 files changed, 92 insertions(+), 26 deletions(-) create mode 100755 src/sonic-build-hooks/hooks/apt diff --git a/src/sonic-build-hooks/hooks/apt b/src/sonic-build-hooks/hooks/apt new file mode 100755 index 0000000000..f4b0f97287 --- /dev/null +++ b/src/sonic-build-hooks/hooks/apt @@ -0,0 +1,5 @@ +#!/bin/bash + +. /usr/local/share/buildinfo/scripts/buildinfo_base.sh + +APT_REAL_COMMAND=$(get_command apt) $(dirname "$0")/apt-get "$@" diff --git a/src/sonic-build-hooks/hooks/apt-get b/src/sonic-build-hooks/hooks/apt-get index 9ae50a1186..f1f789542b 100755 --- a/src/sonic-build-hooks/hooks/apt-get +++ b/src/sonic-build-hooks/hooks/apt-get @@ -3,36 +3,23 @@ INSTALL= . /usr/local/share/buildinfo/scripts/buildinfo_base.sh -REAL_COMMAND=$(get_command apt-get) +REAL_COMMAND=$APT_REAL_COMMAND +[ -z "$REAL_COMMAND" ] && REAL_COMMAND=$(get_command apt-get) if [ -z "$REAL_COMMAND" ]; then echo "The command apt-get does not exist." 1>&2 exit 1 fi -VERSION_FILE="/usr/local/share/buildinfo/versions/versions-deb" -if [ "$ENABLE_VERSION_CONTROL_DEB" == "y" ]; then - for para in $@ - do - if [[ "$para" != -* ]]; then - continue - fi - if [ ! -z "$INSTALL" ]; then - if [[ "$para" == *=* ]]; then - continue - elif [[ "$para" == *=* ]]; then - continue - else - package=$para - if ! grep -q "^${package}=" $VERSION_FILE; then - echo "The version of the package ${package} is not specified." - exit 1 - fi - fi - elif [[ "$para" == "install" ]]; then - INSTALL=y - fi - done +INSTALL=$(check_apt_install) +COMMAND_INFO="Locked by command: $REAL_COMMAND $@" +if [ "$INSTALL" == y ]; then + check_apt_version + lock_result=$(acquire_apt_installation_lock "$COMMAND_INFO" ) + $REAL_COMMAND "$@" + command_result=$? + [ "$lock_result" == y ] && release_apt_installation_lock + exit $command_result +else + $REAL_COMMAND "$@" fi - -$REAL_COMMAND "$@" diff --git a/src/sonic-build-hooks/scripts/buildinfo_base.sh b/src/sonic-build-hooks/scripts/buildinfo_base.sh index d46ffec183..22ab3da4e9 100755 --- a/src/sonic-build-hooks/scripts/buildinfo_base.sh +++ b/src/sonic-build-hooks/scripts/buildinfo_base.sh @@ -12,6 +12,7 @@ VERSION_DEB_PREFERENCE=$BUILDINFO_PATH/versions/01-versions-deb WEB_VERSION_FILE=$VERSION_PATH/versions-web BUILD_WEB_VERSION_FILE=$BUILD_VERSION_PATH/versions-web REPR_MIRROR_URL_PATTERN='http:\/\/packages.trafficmanager.net\/debian' +DPKG_INSTALLTION_LOCK_FILE=/tmp/.dpkg_installation.lock . $BUILDINFO_PATH/config/buildinfo.config @@ -182,6 +183,79 @@ run_pip_command() return $result } +# Check if the command is to install the debian packages +# The apt/apt-get command format: apt/apt-get [options] {update|install} +check_apt_install() +{ + for para in "$@" + do + if [[ "$para" == -* ]]; then + continue + fi + + if [[ "$para" == "install" ]]; then + echo y + fi + + break + done +} + +# Print warning message if a debian package version not specified when debian version control enabled. +check_apt_version() +{ + VERSION_FILE="/usr/local/share/buildinfo/versions/versions-deb" + local install=$(check_apt_install "$@") + if [ "$ENABLE_VERSION_CONTROL_DEB" == "y" ] && [ "$install" == "y" ]; then + for para in "$@" + do + if [[ "$para" == -* ]]; then + continue + fi + + if [[ "$para" == *=* ]]; then + continue + else + package=$para + if ! grep -q "^${package}=" $VERSION_FILE; then + echo "Warning: the version of the package ${package} is not specified." 1>&2 + fi + fi + done + fi +} + +acquire_apt_installation_lock() +{ + local result=n + local wait_in_second=10 + local count=60 + local info="$1" + for ((i=1; i<=$count; i++)); do + if [ -f $DPKG_INSTALLTION_LOCK_FILE ]; then + local lock_info=$(cat $DPKG_INSTALLTION_LOCK_FILE || true) + echo "Waiting dpkg lock for $wait_in_second, $i/$count, info: $lock_info" 1>&2 + sleep $wait_in_second + else + # Create file in an atomic operation + if (set -o noclobber; echo "$info">$DPKG_INSTALLTION_LOCK_FILE) &>/dev/null; then + result=y + break + else + echo "Failed to creat lock, Waiting dpkg lock for $wait_in_second, $i/$count, info: $lock_info" 1>&2 + sleep $wait_in_second + fi + fi + done + + echo $result +} + +release_apt_installation_lock() +{ + rm -f $DPKG_INSTALLTION_LOCK_FILE +} + ENABLE_VERSION_CONTROL_DEB=$(check_version_control "deb") ENABLE_VERSION_CONTROL_PY2=$(check_version_control "py2") ENABLE_VERSION_CONTROL_PY3=$(check_version_control "py3")