|
7 | 7 | # that doesn't have a clone of this repository, which is common when downloading a tarball onto a
|
8 | 8 | # fresh machine to validate it.
|
9 | 9 | #
|
| 10 | +# If env var 'azdo_build_pat' isn't detected, prompts to set it. The prompt is intended to help a |
| 11 | +# little bit by keeping the PAT off 'history' while also making multiple calls to the function |
| 12 | +# convenient. Be aware that the PAT is put into the current shell's env. |
| 13 | +# |
10 | 14 | # Usage: download_tarball <url>
|
11 | 15 | # url: the URL to download. Wrap it in single quotes to avoid issues with special chars.
|
| 16 | +# |
| 17 | +# Usage: name=<targz-path> download_tarball <url> |
| 18 | +# Downloads the tarball to a specific name/location. |
12 | 19 | download_tarball() {
|
13 | 20 | [ "${azdo_build_pat:-}" ] || read -p 'AzDO dnceng PAT with build read permission: ' -s azdo_build_pat
|
14 | 21 | (
|
15 | 22 | set -euo pipefail
|
16 | 23 | url=$1
|
17 |
| - temp_name=${temp_name:-tarball.tar.gz} |
| 24 | + name=${name:-tarball.tar.gz} |
18 | 25 |
|
19 | 26 | echo; echo 'Starting download...'
|
20 | 27 |
|
21 |
| - curl -o "$temp_name" -u "intentionally_blank:$azdo_build_pat" "$url" |
22 |
| - if tar -xf "$temp_name"; then |
| 28 | + # Sometimes tooling converts %-encoding back to spaces. AzDO doesn't like that (400 error), so |
| 29 | + # put the % back. (Full encoding might be better, but we just have spaces to deal with so far.) |
| 30 | + url=${url// /%20} |
| 31 | + |
| 32 | + curl -fSL -o "$name" -u "intentionally_blank:$azdo_build_pat" "$url" |
| 33 | + |
| 34 | + echo "Completed download: '$url' -> '$name'" |
| 35 | + ) |
| 36 | +} |
| 37 | + |
| 38 | +# Extract a tarball into the working directory. This includes a workaround for tarballs downloaded |
| 39 | +# from AzDO, which may have been double-compressed by the server. |
| 40 | +# |
| 41 | +# Usage: name=<tarball-path> extract_tarball |
| 42 | +extract_tarball() { |
| 43 | + ( |
| 44 | + set -euo pipefail |
| 45 | + |
| 46 | + if tar -xf "$name"; then |
23 | 47 | echo "Extracted using tar -xf"
|
24 | 48 | # Fall back to 'gunzip' as an intermediate to avoid problems found
|
25 | 49 | # decompressing archives with 'tar' when downloaded directly from AzDO.
|
26 | 50 | # AzDO seems to double-compress the tar.gz: https://superuser.com/a/841876
|
27 |
| - elif gunzip -d < "$temp_name" | tar -zx; then |
| 51 | + elif gunzip -d < "$name" | tar -zx; then |
28 | 52 | echo "Extracted using gunzip"
|
29 | 53 | else
|
30 |
| - echo "Failed to extract $temp_name" |
| 54 | + echo "Failed to extract $name" |
31 | 55 | exit 1
|
32 | 56 | fi
|
33 | 57 |
|
34 |
| - rm "$temp_name" |
35 |
| - echo 'Complete!' |
| 58 | + echo "Completed extracting: $name" |
| 59 | + ) |
| 60 | +} |
| 61 | + |
| 62 | +# Use download_tarball to download a tarball to a temporary file in the working dir, extract the |
| 63 | +# tar.gz in the working dir, and delete the temporary file. |
| 64 | +# |
| 65 | +# Usage: download_extract_tarball <url> |
| 66 | +# url: the URL to download. Wrap it in single quotes to avoid issues with special chars. |
| 67 | +download_extract_tarball() { |
| 68 | + ( |
| 69 | + set -euo pipefail |
| 70 | + |
| 71 | + url=$1 |
| 72 | + |
| 73 | + date_now_for_path=$(date +%Y-%m-%d_%H%M%S) |
| 74 | + export name=${name:-tarball-${date_now_for_path}.tar.gz} |
| 75 | + |
| 76 | + download_tarball "$url" |
| 77 | + extract_tarball |
| 78 | + |
| 79 | + rm "$name" |
| 80 | + echo "Completed download_extract_tarball." |
| 81 | + ) |
| 82 | +} |
| 83 | + |
| 84 | +# AzDO sometimes double-compresses tarballs unexpectedly, which can cause problems with |
| 85 | +# rename_inner_targz during the release process. This function extracts the tarball file with a |
| 86 | +# workaround and re-creates it. Uses a temporary dir in the working directory to store extracted |
| 87 | +# contents. The targz file must be in the working dir. |
| 88 | +# |
| 89 | +# Usage: fix_azdo_tarball <targz-file> |
| 90 | +fix_azdo_tarball() { |
| 91 | + ( |
| 92 | + set -euo pipefail |
| 93 | + |
| 94 | + tar=$1 |
| 95 | + tar_temp=${tar}-temp-extract |
| 96 | + |
| 97 | + set -x |
| 98 | + |
| 99 | + mkdir "$tar_temp" |
| 100 | + ( |
| 101 | + cd "$tar_temp" |
| 102 | + name="../$tar" extract_tarball |
| 103 | + rm "../$tar" |
| 104 | + |
| 105 | + tar --numeric-owner -zcf "../$tar" * |
| 106 | + ) |
| 107 | + rm -rf "$tar_temp" |
36 | 108 | )
|
37 | 109 | }
|
| 110 | + |
| 111 | +# Renames the inner top-level dir inside a tarball to something else. Creates a new tar.gz in the |
| 112 | +# working dir that matches the new inner top-level dir. The input tar.gz file must contain only a |
| 113 | +# single directory at its root. The working directory must not have any exiting files that match the |
| 114 | +# old inner dir name, target inner dir name, or output tarball name. |
| 115 | +# |
| 116 | +# This is only intended to be useful to manually create a nice-looking final source-build tarball to |
| 117 | +# upload to blob storage. We should instead have the build produce a nice name to begin with: |
| 118 | +# https://github.com/dotnet/source-build/issues/747 |
| 119 | +# |
| 120 | +# Usage: rename_tarball_inner_dir <targz-name> <target-name> |
| 121 | +# targz-name: The name of the tarball file. Includes extension. |
| 122 | +# target-name: |
| 123 | +# The desired name of the inner dir in the output tar.gz. The output tar.gz is named |
| 124 | +# {target-name}.tar.gz in the working directory. |
| 125 | +rename_tarball_inner_dir() { |
| 126 | + ( |
| 127 | + set -u |
| 128 | + |
| 129 | + tar=$1 |
| 130 | + target=$2 |
| 131 | + |
| 132 | + first=$(tar -ztf "$tar" | head -1) |
| 133 | + inner=${first%%/*} |
| 134 | + |
| 135 | + abort_if_exists "$inner" |
| 136 | + abort_if_exists "$target" |
| 137 | + abort_if_exists "$target.tar.gz" |
| 138 | + |
| 139 | + set -x |
| 140 | + |
| 141 | + tar -xf "$tar" |
| 142 | + mv "$inner" "$target" |
| 143 | + tar --numeric-owner -zcf "$target.tar.gz" "$target" |
| 144 | + rm -rf "$target" |
| 145 | + ) |
| 146 | +} |
| 147 | + |
| 148 | +# Renames the given targz so that its filename matches its top-level directory. The output tarball |
| 149 | +# ends up in the working dir. |
| 150 | +# |
| 151 | +# Usage: rename_targz_to_match_first_dir <targz-name> |
| 152 | +rename_targz_to_match_first_dir() { |
| 153 | + ( |
| 154 | + set -u |
| 155 | + |
| 156 | + tar=$1 |
| 157 | + first_file=$(tar -ztf "$tar" | head -1) |
| 158 | + first_dir=${first_file%%/*} |
| 159 | + tar_dest=${first_dir}.tar.gz |
| 160 | + |
| 161 | + abort_if_exists "$tar_dest" |
| 162 | + |
| 163 | + set -x |
| 164 | + mv "$tar" "$tar_dest" |
| 165 | + ) |
| 166 | +} |
| 167 | + |
| 168 | +abort_if_exists() { |
| 169 | + if [ -a "$1" ] |
| 170 | + then |
| 171 | + echo "Aborting: file exists: $1" |
| 172 | + exit 1 |
| 173 | + fi |
| 174 | +} |
0 commit comments