1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
|
#! /bin/bash
#
# usage:
# tag2upload-fetch-inputs <setting>=<value> ...
#
# Fetches the git objects (tags etc) from the forge.
#
# ATTENTION! This program lives is in the tag2upload builder image,
# but is called by dgit-repos-server on the tag2upload oracle.
# Maintain compatibility and attend to deployment order.
# See dgit-infra-notes-scripts/services-diagram.pdf.
#
# settings:
#
# tag name of the tag (not including refs/tags/)
# upstream_tag name of the upstream tag or ''
#
# optional settings:
#
# bpd defaults to ../bpd
#
# Exit status
#
# Nonretriable errors:
#
# 3 missing at least one tag
# 4 the repository does not appear to exist (HTTP 4XX)
# 16 other nonretriable failure
#
# any other (not specially handled)
#
# Retriable errors:
#
# 75 Temporary failure accessing forge via git or direct https.
# (EX_TEMPFAIL from sysexits.h)
# We rely on nothing exiting 75 (EX_TEMPFAIL) when it doesn't mean it
set -eu -o pipefail
shopt -s inherit_errexit # #514862, wtf
us="$(basename "$0")"
sharedir="${0%/*}" ###substituted###
. "$sharedir"/dgit-functions.sh
parse-args-settings "$@"
fetch=(git fetch origin --no-tags)
need-fetch-tag () {
local tag="$1"
local refname="refs/tags/$tag"
git check-ref-format "$refname" \
|| fail "git check-ref-format $tag failed, status $?"
fetch+=("$refname:$refname")
need_refs+=("$refname")
}
need-fetch-tag "$s_tag"
if [ "x$s_upstream_tag" != x ]; then
need-fetch-tag "$s_upstream_tag"
fi
set +e
x "${fetch[@]}" >&2
rc=$?
set -e
if [ $rc != 0 ]; then
report "git fetch from forge failed, status $rc, diagnosing..."
# See what happens if we try to access the repo via https
url=$(git config remote.origin.url)
x curl --head -L \
-w '%{response_code}\n' >../fetch-code \
-o /dev/null \
-- "$url" \
|| tempfail "http fetch failed, exit status $?"
# OK we did an HTTP GET, but what was the HTTP status code?
read <../fetch-code fetch_code || fail 'curl did not write response_code!'
report "http fetch of repository gave HTTP status code $fetch_code"
case "$fetch_code" in
200) ;;
4*) exit 4 ;;
5*) exit 75 ;;
*) exit 16 ;;
esac
# Try to use git-ls-remote to see if the ref is nonexistent
x git ls-remote origin "${need_refs[@]}" >../ls-remote \
|| tempfail "git ls-remote of repository failed, status $?"
# git-ls-remote is completely bananas: it gives all refs
# whose tail matches the search patterns!
perl -we <../ls-remote '
use Carp;
while (<STDIN>) {
chomp && s/^\w+\t// or confess;
$found{$_}++;
}
@bad = grep { !$found{$_} } @ARGV;
exit 0 if !@bad;
foreach (@bad) {
$m = "missing ref: $_\n";
print $m or die $!;
print STDERR $m or die $!;
}
exit 3;
' "${need_refs[@]}"
tempfail 'repo accessible, refs exist, but git fetch failed'
fi
exit 0
|