Signed-off-by: Cristian Ariza <dev@cristianrz.com>
| ... | ... |
@@ -24,7 +24,9 @@ usage() {
|
| 24 | 24 |
dir="$1" # dir for building tar in |
| 25 | 25 |
shift || usage 1 >&2 |
| 26 | 26 |
|
| 27 |
-[ $# -gt 0 -a "$dir" ] || usage 2 >&2 |
|
| 27 |
+if ! [ $# -gt 0 ] && [ "$dir" ]; then |
|
| 28 |
+ usage 2 >&2 |
|
| 29 |
+fi |
|
| 28 | 30 |
mkdir -p "$dir" |
| 29 | 31 |
|
| 30 | 32 |
# hacky workarounds for Bash 3 support (no associative arrays) |
| ... | ... |
@@ -37,7 +39,7 @@ doNotGenerateManifestJson= |
| 37 | 37 |
# bash v4 on Windows CI requires CRLF separator |
| 38 | 38 |
newlineIFS=$'\n' |
| 39 | 39 |
if [ "$(go env GOHOSTOS)" = 'windows' ]; then |
| 40 |
- major=$(echo ${BASH_VERSION%%[^0.9]} | cut -d. -f1)
|
|
| 40 |
+ major=$(echo "${BASH_VERSION%%[^0.9]}" | cut -d. -f1)
|
|
| 41 | 41 |
if [ "$major" -ge 4 ]; then |
| 42 | 42 |
newlineIFS=$'\r\n' |
| 43 | 43 |
fi |
| ... | ... |
@@ -59,7 +61,8 @@ fetch_blob() {
|
| 59 | 59 |
shift |
| 60 | 60 |
local curlArgs=("$@")
|
| 61 | 61 |
|
| 62 |
- local curlHeaders="$( |
|
| 62 |
+ local curlHeaders |
|
| 63 |
+ curlHeaders="$( |
|
| 63 | 64 |
curl -S "${curlArgs[@]}" \
|
| 64 | 65 |
-H "Authorization: Bearer $token" \ |
| 65 | 66 |
"$registryBase/v2/$image/blobs/$digest" \ |
| ... | ... |
@@ -70,7 +73,8 @@ fetch_blob() {
|
| 70 | 70 |
if grep -qE "^HTTP/[0-9].[0-9] 3" <<< "$curlHeaders"; then |
| 71 | 71 |
rm -f "$targetFile" |
| 72 | 72 |
|
| 73 |
- local blobRedirect="$(echo "$curlHeaders" | awk -F ': ' 'tolower($1) == "location" { print $2; exit }')"
|
|
| 73 |
+ local blobRedirect |
|
| 74 |
+ blobRedirect="$(echo "$curlHeaders" | awk -F ': ' 'tolower($1) == "location" { print $2; exit }')"
|
|
| 74 | 75 |
if [ -z "$blobRedirect" ]; then |
| 75 | 76 |
echo >&2 "error: failed fetching '$image' blob '$digest'" |
| 76 | 77 |
echo "$curlHeaders" | head -1 >&2 |
| ... | ... |
@@ -88,15 +92,18 @@ handle_single_manifest_v2() {
|
| 88 | 88 |
local manifestJson="$1" |
| 89 | 89 |
shift |
| 90 | 90 |
|
| 91 |
- local configDigest="$(echo "$manifestJson" | jq --raw-output '.config.digest')" |
|
| 91 |
+ local configDigest |
|
| 92 |
+ configDigest="$(echo "$manifestJson" | jq --raw-output '.config.digest')" |
|
| 92 | 93 |
local imageId="${configDigest#*:}" # strip off "sha256:"
|
| 93 | 94 |
|
| 94 | 95 |
local configFile="$imageId.json" |
| 95 | 96 |
fetch_blob "$token" "$image" "$configDigest" "$dir/$configFile" -s |
| 96 | 97 |
|
| 97 |
- local layersFs="$(echo "$manifestJson" | jq --raw-output --compact-output '.layers[]')" |
|
| 98 |
+ local layersFs |
|
| 99 |
+ layersFs="$(echo "$manifestJson" | jq --raw-output --compact-output '.layers[]')" |
|
| 98 | 100 |
local IFS="$newlineIFS" |
| 99 |
- local layers=($layersFs) |
|
| 101 |
+ local layers |
|
| 102 |
+ mapfile -t layers <<< "$layersFs" |
|
| 100 | 103 |
unset IFS |
| 101 | 104 |
|
| 102 | 105 |
echo "Downloading '$imageIdentifier' (${#layers[@]} layers)..."
|
| ... | ... |
@@ -105,8 +112,10 @@ handle_single_manifest_v2() {
|
| 105 | 105 |
for i in "${!layers[@]}"; do
|
| 106 | 106 |
local layerMeta="${layers[$i]}"
|
| 107 | 107 |
|
| 108 |
- local layerMediaType="$(echo "$layerMeta" | jq --raw-output '.mediaType')" |
|
| 109 |
- local layerDigest="$(echo "$layerMeta" | jq --raw-output '.digest')" |
|
| 108 |
+ local layerMediaType |
|
| 109 |
+ layerMediaType="$(echo "$layerMeta" | jq --raw-output '.mediaType')" |
|
| 110 |
+ local layerDigest |
|
| 111 |
+ layerDigest="$(echo "$layerMeta" | jq --raw-output '.digest')" |
|
| 110 | 112 |
|
| 111 | 113 |
# save the previous layer's ID |
| 112 | 114 |
local parentId="$layerId" |
| ... | ... |
@@ -118,8 +127,10 @@ handle_single_manifest_v2() {
|
| 118 | 118 |
echo '1.0' > "$dir/$layerId/VERSION" |
| 119 | 119 |
|
| 120 | 120 |
if [ ! -s "$dir/$layerId/json" ]; then |
| 121 |
- local parentJson="$(printf ', parent: "%s"' "$parentId")" |
|
| 122 |
- local addJson="$(printf '{ id: "%s"%s }' "$layerId" "${parentId:+$parentJson}")"
|
|
| 121 |
+ local parentJson |
|
| 122 |
+ parentJson="$(printf ', parent: "%s"' "$parentId")" |
|
| 123 |
+ local addJson |
|
| 124 |
+ addJson="$(printf '{ id: "%s"%s }' "$layerId" "${parentId:+$parentJson}")"
|
|
| 123 | 125 |
# this starter JSON is taken directly from Docker's own "docker save" output for unimportant layers |
| 124 | 126 |
jq "$addJson + ." > "$dir/$layerId/json" <<- 'EOJSON' |
| 125 | 127 |
{
|
| ... | ... |
@@ -159,7 +170,8 @@ handle_single_manifest_v2() {
|
| 159 | 159 |
echo "skipping existing ${layerId:0:12}"
|
| 160 | 160 |
continue |
| 161 | 161 |
fi |
| 162 |
- local token="$(curl -fsSL "$authBase/token?service=$authService&scope=repository:$image:pull" | jq --raw-output '.token')" |
|
| 162 |
+ local token |
|
| 163 |
+ token="$(curl -fsSL "$authBase/token?service=$authService&scope=repository:$image:pull" | jq --raw-output '.token')" |
|
| 163 | 164 |
fetch_blob "$token" "$image" "$layerDigest" "$dir/$layerTar" --progress-bar |
| 164 | 165 |
;; |
| 165 | 166 |
|
| ... | ... |
@@ -174,10 +186,12 @@ handle_single_manifest_v2() {
|
| 174 | 174 |
imageId="$layerId" |
| 175 | 175 |
|
| 176 | 176 |
# munge the top layer image manifest to have the appropriate image configuration for older daemons |
| 177 |
- local imageOldConfig="$(jq --raw-output --compact-output '{ id: .id } + if .parent then { parent: .parent } else {} end' "$dir/$imageId/json")"
|
|
| 177 |
+ local imageOldConfig |
|
| 178 |
+ imageOldConfig="$(jq --raw-output --compact-output '{ id: .id } + if .parent then { parent: .parent } else {} end' "$dir/$imageId/json")"
|
|
| 178 | 179 |
jq --raw-output "$imageOldConfig + del(.history, .rootfs)" "$dir/$configFile" > "$dir/$imageId/json" |
| 179 | 180 |
|
| 180 |
- local manifestJsonEntry="$( |
|
| 181 |
+ local manifestJsonEntry |
|
| 182 |
+ manifestJsonEntry="$( |
|
| 181 | 183 |
echo '{}' | jq --raw-output '. + {
|
| 182 | 184 |
Config: "'"$configFile"'", |
| 183 | 185 |
RepoTags: ["'"${image#library\/}:$tag"'"],
|
| ... | ... |
@@ -232,7 +246,7 @@ while [ $# -gt 0 ]; do |
| 232 | 232 |
application/vnd.docker.distribution.manifest.list.v2+json) |
| 233 | 233 |
layersFs="$(echo "$manifestJson" | jq --raw-output --compact-output '.manifests[]')" |
| 234 | 234 |
IFS="$newlineIFS" |
| 235 |
- layers=($layersFs) |
|
| 235 |
+ mapfile -t layers <<< "$layersFs" |
|
| 236 | 236 |
unset IFS |
| 237 | 237 |
|
| 238 | 238 |
found="" |
| ... | ... |
@@ -278,7 +292,7 @@ while [ $# -gt 0 ]; do |
| 278 | 278 |
|
| 279 | 279 |
layersFs="$(echo "$manifestJson" | jq --raw-output '.fsLayers | .[] | .blobSum')" |
| 280 | 280 |
IFS="$newlineIFS" |
| 281 |
- layers=($layersFs) |
|
| 281 |
+ mapfile -t layers <<< "$layersFs" |
|
| 282 | 282 |
unset IFS |
| 283 | 283 |
|
| 284 | 284 |
history="$(echo "$manifestJson" | jq '.history | [.[] | .v1Compatibility]')" |