blob: 7d5c46fc63666f86ceba1cbc6a0014186d1a5a05 [file]
#!/usr/bin/env bash
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
set -euo pipefail
usage() {
cat <<'USAGE'
Usage: scripts/ci/apt-install.sh [apt-get install flags] <package>...
Install Debian packages behind a bounded `apt-get update`.
GitHub runners intermittently lose egress to azure.archive.ubuntu.com. apt
falls back through /etc/apt/apt-mirrors.txt and can then wedge fetching the
package indices with no output and no timeout of its own, so the job sits
dead until it burns the whole `timeout-minutes` budget. apt's own
Acquire::*::Timeout does not bound this - the observed stalls ran for half an
hour past the 120s default - so both phases are capped externally instead.
The install runs even when every update attempt failed, so a stale but
present index set is not fatal.
Environment:
APT_UPDATE_TIMEOUT Seconds allowed per update attempt (default: 120)
APT_UPDATE_ATTEMPTS Update attempts before giving up (default: 3)
APT_INSTALL_TIMEOUT Seconds allowed for the install (default: 600)
USAGE
}
case "${1:-}" in
-h|--help)
usage
exit 0
;;
"")
usage >&2
exit 1
;;
esac
timeout_seconds="${APT_UPDATE_TIMEOUT:-120}"
attempts="${APT_UPDATE_ATTEMPTS:-3}"
install_timeout="${APT_INSTALL_TIMEOUT:-600}"
for attempt in $(seq 1 "${attempts}"); do
if sudo timeout --kill-after=10 "${timeout_seconds}" apt-get \
-o Acquire::Retries=2 \
-o Acquire::http::Timeout=15 \
-o Acquire::https::Timeout=15 \
update; then
break
fi
echo "::warning::apt-get update attempt ${attempt}/${attempts} timed out or failed"
if [ "${attempt}" -lt "${attempts}" ]; then
sleep 5
fi
done
# Generous cap: a healthy install of the heaviest package set here takes well
# under a minute, and killing dpkg mid-configure leaves a broken package DB.
if ! sudo timeout --kill-after=10 "${install_timeout}" apt-get install -y "$@"; then
echo "::error::apt-get install exceeded ${install_timeout}s or failed"
exit 1
fi