This is an automated email from the ASF dual-hosted git repository.

potiuk pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git


The following commit(s) were added to refs/heads/main by this push:
     new a8184e4  Stop using docker manifest to check for image presence 
(#17883)
a8184e4 is described below

commit a8184e42ce9d9b7f6b409f07c1e2da0138352ef3
Author: Jarek Potiuk <[email protected]>
AuthorDate: Tue Sep 21 11:46:20 2021 +0200

    Stop using docker manifest to check for image presence (#17883)
    
    We need to set the "experimental" flag in CI in order to use
    `docker manifest` command to check for presence of the images
    in ghcr.io. In order to use them we need to enable experimental
    features via ~/.docker/config.json.
    
    Sometimes, very rarely, we had the case that the config file
    got broken and the problem turned out to be that we tried
    to do this experimental replacement in parallel by several
    running "wait image" commands (:facepalm: here for myself)
    that were apparenlty overriding the same config.json
    at the same time in non-atomic way, which (very rarely)
    led to corrupted file.
    
    However for quite some time we pulled the image immediately
    after it was available, in order to verify the image,
    so rather than checking if the image
    is there via manifest, we can simply pull the image
    and effect will be the same - if it fails, the image is not
    there, if it has been pulled - we can immediately verify
    it. We do not need experimental flag at all for that
    so no messing around with .docker/config.json is needed
    at all.
---
 scripts/ci/images/ci_prepare_ci_image_on_ci.sh     |  3 +-
 scripts/ci/images/ci_prepare_prod_image_on_ci.sh   |  3 +-
 scripts/ci/images/ci_push_ci_images.sh             |  2 +
 scripts/ci/images/ci_push_production_images.sh     |  2 +
 .../images/ci_wait_for_and_verify_all_ci_images.sh |  5 +-
 .../ci_wait_for_and_verify_all_prod_images.sh      |  4 +-
 .../ci/images/ci_wait_for_and_verify_ci_image.sh   | 15 +---
 .../ci/images/ci_wait_for_and_verify_prod_image.sh | 16 +---
 scripts/ci/libraries/_build_images.sh              | 95 ++++++----------------
 scripts/ci/libraries/_initialization.sh            |  3 -
 scripts/ci/libraries/_push_pull_remove_images.sh   | 38 +++++----
 scripts/ci/tools/free_space.sh                     |  4 +
 12 files changed, 67 insertions(+), 123 deletions(-)

diff --git a/scripts/ci/images/ci_prepare_ci_image_on_ci.sh 
b/scripts/ci/images/ci_prepare_ci_image_on_ci.sh
index d0d4aac..8fe9299 100755
--- a/scripts/ci/images/ci_prepare_ci_image_on_ci.sh
+++ b/scripts/ci/images/ci_prepare_ci_image_on_ci.sh
@@ -31,7 +31,8 @@ function build_ci_image_on_ci() {
         # Pretend that the image was build. We already have image with the 
right sources baked in!
         # so all the checksums are assumed to be correct
         md5sum::calculate_md5sum_for_all_files
-        build_images::wait_for_image_tag "${AIRFLOW_CI_IMAGE}" 
":${GITHUB_REGISTRY_PULL_IMAGE_TAG}"
+        local 
image_name_with_tag="${AIRFLOW_CI_IMAGE}:${GITHUB_REGISTRY_PULL_IMAGE_TAG}"
+        push_pull_remove_images::wait_for_image "${image_name_with_tag}"
         md5sum::update_all_md5_with_group
     else
         build_images::rebuild_ci_image_if_needed
diff --git a/scripts/ci/images/ci_prepare_prod_image_on_ci.sh 
b/scripts/ci/images/ci_prepare_prod_image_on_ci.sh
index 8027d78..0aea3c7 100755
--- a/scripts/ci/images/ci_prepare_prod_image_on_ci.sh
+++ b/scripts/ci/images/ci_prepare_prod_image_on_ci.sh
@@ -32,7 +32,8 @@ function build_prod_images_on_ci() {
     build_images::prepare_prod_build
 
     if [[ ${GITHUB_REGISTRY_WAIT_FOR_IMAGE} == "true" ]]; then
-        build_images::wait_for_image_tag "${AIRFLOW_PROD_IMAGE}" 
":${GITHUB_REGISTRY_PULL_IMAGE_TAG}"
+        local 
image_name_with_tag="${AIRFLOW_PROD_IMAGE}:${GITHUB_REGISTRY_PULL_IMAGE_TAG}"
+        push_pull_remove_images::wait_for_image "${image_name_with_tag}"
     else
         build_images::build_prod_images_from_locally_built_airflow_packages
     fi
diff --git a/scripts/ci/images/ci_push_ci_images.sh 
b/scripts/ci/images/ci_push_ci_images.sh
index 5bd5eb3..6e232fa 100755
--- a/scripts/ci/images/ci_push_ci_images.sh
+++ b/scripts/ci/images/ci_push_ci_images.sh
@@ -20,4 +20,6 @@
 
 build_images::prepare_ci_build
 
+build_images::login_to_docker_registry
+
 push_pull_remove_images::push_ci_images_to_github
diff --git a/scripts/ci/images/ci_push_production_images.sh 
b/scripts/ci/images/ci_push_production_images.sh
index 43e14d3..7e0e0ea 100755
--- a/scripts/ci/images/ci_push_production_images.sh
+++ b/scripts/ci/images/ci_push_production_images.sh
@@ -20,4 +20,6 @@
 
 build_images::prepare_prod_build
 
+build_images::login_to_docker_registry
+
 push_pull_remove_images::push_prod_images_to_github
diff --git a/scripts/ci/images/ci_wait_for_and_verify_all_ci_images.sh 
b/scripts/ci/images/ci_wait_for_and_verify_all_ci_images.sh
index 39dfe8f..cb45c1f 100755
--- a/scripts/ci/images/ci_wait_for_and_verify_all_ci_images.sh
+++ b/scripts/ci/images/ci_wait_for_and_verify_all_ci_images.sh
@@ -25,7 +25,7 @@ source "${LIBRARIES_DIR}/_all_libs.sh"
 
 initialization::set_output_color_variables
 
-PARALLEL_TAIL_LENGTH=5
+export PARALLEL_TAIL_LENGTH=5
 
 parallel::make_sure_gnu_parallel_is_installed
 
@@ -35,11 +35,12 @@ echo
 echo "${COLOR_BLUE}Waiting for all CI images to appear${COLOR_RESET}"
 echo
 
-
 parallel::initialize_monitoring
 
 parallel::monitor_progress
 
+build_images::login_to_docker_registry
+
 # shellcheck disable=SC2086
 parallel --results "${PARALLEL_MONITORED_DIR}" \
     "$( dirname "${BASH_SOURCE[0]}" )/ci_wait_for_and_verify_ci_image.sh" ::: \
diff --git a/scripts/ci/images/ci_wait_for_and_verify_all_prod_images.sh 
b/scripts/ci/images/ci_wait_for_and_verify_all_prod_images.sh
index 6786a31..5df66a3 100755
--- a/scripts/ci/images/ci_wait_for_and_verify_all_prod_images.sh
+++ b/scripts/ci/images/ci_wait_for_and_verify_all_prod_images.sh
@@ -25,7 +25,7 @@ source "${LIBRARIES_DIR}/_all_libs.sh"
 
 initialization::set_output_color_variables
 
-PARALLEL_TAIL_LENGTH=5
+export PARALLEL_TAIL_LENGTH=5
 
 parallel::make_sure_gnu_parallel_is_installed
 
@@ -39,6 +39,8 @@ parallel::initialize_monitoring
 
 parallel::monitor_progress
 
+build_images::login_to_docker_registry
+
 # shellcheck disable=SC2086
 parallel --results "${PARALLEL_MONITORED_DIR}" \
     "$( dirname "${BASH_SOURCE[0]}" )/ci_wait_for_and_verify_prod_image.sh" 
::: \
diff --git a/scripts/ci/images/ci_wait_for_and_verify_ci_image.sh 
b/scripts/ci/images/ci_wait_for_and_verify_ci_image.sh
index 1d52f69..bc5034a 100755
--- a/scripts/ci/images/ci_wait_for_and_verify_ci_image.sh
+++ b/scripts/ci/images/ci_wait_for_and_verify_ci_image.sh
@@ -30,22 +30,9 @@ shift
 
 image_name_with_tag="${AIRFLOW_CI_IMAGE}:${GITHUB_REGISTRY_PULL_IMAGE_TAG}"
 
-function pull_ci_image() {
-    start_end::group_start "Pulling image: ${IMAGE_AVAILABLE}"
-    push_pull_remove_images::pull_image_if_not_present_or_forced 
"${IMAGE_AVAILABLE}"
-    start_end::group_end
-}
-
-start_end::group_start "Configure Docker Registry"
-build_images::configure_docker_registry
-start_end::group_end
-
-start_end::group_start "Waiting for ${image_name_with_tag}"
-push_pull_remove_images::wait_for_image "${image_name_with_tag}"
 build_images::prepare_ci_build
-start_end::group_end
 
-pull_ci_image
+push_pull_remove_images::wait_for_image "${image_name_with_tag}"
 
 if [[ ${VERIFY_IMAGE=} != "false" ]]; then
     verify_image::verify_ci_image "${image_name_with_tag}"
diff --git a/scripts/ci/images/ci_wait_for_and_verify_prod_image.sh 
b/scripts/ci/images/ci_wait_for_and_verify_prod_image.sh
index aae05ae..bc2f80f 100755
--- a/scripts/ci/images/ci_wait_for_and_verify_prod_image.sh
+++ b/scripts/ci/images/ci_wait_for_and_verify_prod_image.sh
@@ -30,22 +30,8 @@ shift
 
 image_name_with_tag="${AIRFLOW_PROD_IMAGE}:${GITHUB_REGISTRY_PULL_IMAGE_TAG}"
 
-function pull_prod_image() {
-    start_end::group_start  "Pulling image: ${IMAGE_AVAILABLE}"
-    push_pull_remove_images::pull_image_if_not_present_or_forced 
"${IMAGE_AVAILABLE}"
-    start_end::group_end
-}
-
-start_end::group_start "Configure Docker Registry"
-build_images::configure_docker_registry
-start_end::group_end
-
-start_end::group_start "Waiting for ${image_name_with_tag}"
-push_pull_remove_images::wait_for_image "${image_name_with_tag}"
 build_images::prepare_prod_build
-start_end::group_end
-
-pull_prod_image
+push_pull_remove_images::wait_for_image "${image_name_with_tag}"
 
 if [[ ${VERIFY_IMAGE=} != "false" ]]; then
     verify_image::verify_prod_image "${image_name_with_tag}"
diff --git a/scripts/ci/libraries/_build_images.sh 
b/scripts/ci/libraries/_build_images.sh
index 157fb64..e94c0b2 100644
--- a/scripts/ci/libraries/_build_images.sh
+++ b/scripts/ci/libraries/_build_images.sh
@@ -374,7 +374,7 @@ function build_images::get_docker_cache_image_names() {
     export PYTHON_BASE_IMAGE="python:${PYTHON_MAJOR_MINOR_VERSION}-slim-buster"
 
     local image_name
-    
image_name="${GITHUB_REGISTRY}/$(build_images::get_github_container_registry_image_prefix)"
+    
image_name="ghcr.io/$(build_images::get_github_container_registry_image_prefix)"
 
     # Example:
     #  ghcr.io/apache/airflow/main/python:3.8-slim-buster
@@ -412,36 +412,33 @@ function build_images::get_docker_cache_image_names() {
 }
 
 # If GitHub Registry is used, login to the registry using GITHUB_USERNAME and
-# GITHUB_TOKEN. In case Personal Access token is not set, skip logging in
-# Also enable experimental features of docker (we need `docker manifest` 
command)
-function build_images::configure_docker_registry() {
-    local token="${GITHUB_TOKEN}"
-    if [[ -z "${token}" ]]; then
-        verbosity::print_info
-        verbosity::print_info "Skip logging in to GitHub Registry. No Token 
available!"
-        verbosity::print_info
-    elif [[ ${AIRFLOW_LOGIN_TO_GITHUB_REGISTRY=} != "true" ]]; then
-        verbosity::print_info
-        verbosity::print_info "Skip logging in to GitHub Registry. 
AIRFLOW_LOGIN_TO_GITHUB_REGISTRY != true"
-        verbosity::print_info
-    elif [[ -n "${token}" ]]; then
-        echo "${token}" | docker_v login \
-            --username "${GITHUB_USERNAME:-apache}" \
-            --password-stdin \
-            "${GITHUB_REGISTRY}"
-    else
-        verbosity::print_info "Skip Login to GitHub Registry 
${GITHUB_REGISTRY} as token is missing"
-    fi
-    if [[ ${CI} == "true" ]]; then
-        # we only need that on CI in order to run "docker manifest" when we 
check if remote image exists
-        # See function push_pull_remove_images::check_image_manifest()
-        local new_config
-        new_config=$(jq '.experimental = "enabled"' 
"${HOME}/.docker/config.json" || true)
-        if [[ ${new_config} != "" ]]; then
-            echo "${new_config}" > "${HOME}/.docker/config.json"
+# GITHUB_TOKEN. We only need to login to docker registry on CI and only when 
we push
+# images. All other images we pull from docker registry are public and we do 
not need
+# to login there.
+function build_images::login_to_docker_registry() {
+    if [[ "${CI}" == "true" ]]; then
+        start_end::group_start "Configure Docker Registry"
+        local token="${GITHUB_TOKEN}"
+        if [[ -z "${token}" ]]; then
+            verbosity::print_info
+            verbosity::print_info "Skip logging in to GitHub Registry. No 
Token available!"
+            verbosity::print_info
+        elif [[ ${AIRFLOW_LOGIN_TO_GITHUB_REGISTRY=} != "true" ]]; then
+            verbosity::print_info
+            verbosity::print_info "Skip logging in to GitHub Registry. 
AIRFLOW_LOGIN_TO_GITHUB_REGISTRY != true"
+            verbosity::print_info
+        elif [[ -n "${token}" ]]; then
+            # logout from the repository first - so that we do not keep us 
logged in if the token
+            # already expired (which can happen if we have a long build 
running)
+            docker_v logout "ghcr.io"
+            # The login might succeed or not - in some cases, when we pull 
public images in forked
+            # repos it might fail, but the pulls will continue to work
+            echo "${token}" | docker_v login \
+                --username "${GITHUB_USERNAME:-apache}" \
+                --password-stdin \
+                "ghcr.io" || true
         else
-            echo "${COLOR_YELLOW}Could not set experimental flag in 
${HOME}/.docker/config.json ${COLOR_RESET}"
-            echo "${COLOR_YELLOW}docker manifest command will likely not 
work${COLOR_RESET}"
+            verbosity::print_info "Skip Login to GitHub Container Registry as 
token is missing"
         fi
     fi
 }
@@ -457,7 +454,6 @@ function build_images::prepare_ci_build() {
     export AIRFLOW_EXTRAS="${AIRFLOW_EXTRAS:="${DEFAULT_CI_EXTRAS}"}"
     readonly AIRFLOW_EXTRAS
 
-    build_images::configure_docker_registry
     sanity_checks::go_to_airflow_sources
     permissions::fix_group_permissions
 }
@@ -754,7 +750,6 @@ function build_images::prepare_prod_build() {
     export AIRFLOW_EXTRAS="${AIRFLOW_EXTRAS:="${DEFAULT_PROD_EXTRAS}"}"
     readonly AIRFLOW_EXTRAS
 
-    build_images::configure_docker_registry
     AIRFLOW_BRANCH_FOR_PYPI_PRELOADING="${BRANCH_NAME}"
     sanity_checks::go_to_airflow_sources
 }
@@ -897,42 +892,6 @@ function build_images::tag_image() {
     done
 }
 
-# Waits for image tag to appear in GitHub Registry, pulls it and tags with the 
target tag
-# Parameters:
-#  $1 - image name to wait for
-#  $2 - fallback image to wait for
-#  $3, $4, ... - target tags to tag the image with
-function build_images::wait_for_image_tag() {
-
-    local image_name="${1}"
-    local image_suffix="${2}"
-    shift 2
-
-    local image_to_wait_for="${image_name}${image_suffix}"
-    start_end::group_start "Wait for image tag ${image_to_wait_for}"
-    while true; do
-        set +e
-        echo "${COLOR_BLUE}Docker pull ${image_to_wait_for} ${COLOR_RESET}" 
>"${OUTPUT_LOG}"
-        docker_v pull "${image_to_wait_for}" >>"${OUTPUT_LOG}" 2>&1
-        set -e
-        local image_hash
-        echo "${COLOR_BLUE} Docker images -q 
${image_to_wait_for}${COLOR_RESET}" >>"${OUTPUT_LOG}"
-        image_hash="$(docker images -q "${image_to_wait_for}" 
2>>"${OUTPUT_LOG}" || true)"
-        if [[ -z "${image_hash}" ]]; then
-            echo
-            echo "The image ${image_to_wait_for} is not yet available. No 
local hash for the image"
-            echo
-            echo "Last log:"
-            cat "${OUTPUT_LOG}" || true
-            echo
-        else
-            build_images::tag_image "${image_to_wait_for}" 
"${image_name}:latest" "${@}"
-            break
-        fi
-    done
-    start_end::group_end
-}
-
 # We use pulled docker image cache by default for CI images to speed up the 
builds
 # and local to speed up iteration on kerberos tests
 function build_images::determine_docker_cache_strategy() {
diff --git a/scripts/ci/libraries/_initialization.sh 
b/scripts/ci/libraries/_initialization.sh
index 3a8aa3f..026795e 100644
--- a/scripts/ci/libraries/_initialization.sh
+++ b/scripts/ci/libraries/_initialization.sh
@@ -558,8 +558,6 @@ function initialization::initialize_git_variables() {
 }
 
 function initialization::initialize_github_variables() {
-    # Defaults for interacting with GitHub
-    export GITHUB_REGISTRY="ghcr.io"
     export 
GITHUB_REGISTRY_WAIT_FOR_IMAGE=${GITHUB_REGISTRY_WAIT_FOR_IMAGE:="false"}
     export 
GITHUB_REGISTRY_PULL_IMAGE_TAG=${GITHUB_REGISTRY_PULL_IMAGE_TAG:="latest"}
     export 
GITHUB_REGISTRY_PUSH_IMAGE_TAG=${GITHUB_REGISTRY_PUSH_IMAGE_TAG:="latest"}
@@ -843,7 +841,6 @@ function initialization::make_constants_read_only() {
     readonly ADDITIONAL_RUNTIME_APT_DEPS
     readonly ADDITIONAL_RUNTIME_APT_ENV
 
-    readonly GITHUB_REGISTRY
     readonly GITHUB_REGISTRY_WAIT_FOR_IMAGE
     readonly GITHUB_REGISTRY_PULL_IMAGE_TAG
     readonly GITHUB_REGISTRY_PUSH_IMAGE_TAG
diff --git a/scripts/ci/libraries/_push_pull_remove_images.sh 
b/scripts/ci/libraries/_push_pull_remove_images.sh
index 750b2eb..51611ae 100644
--- a/scripts/ci/libraries/_push_pull_remove_images.sh
+++ b/scripts/ci/libraries/_push_pull_remove_images.sh
@@ -62,7 +62,7 @@ function 
push_pull_remove_images::pull_image_if_not_present_or_forced() {
         echo
         echo "Pulling the image ${image_to_pull}"
         echo
-        docker_v pull "${image_to_pull}"
+        docker pull "${image_to_pull}"
     fi
 }
 
@@ -262,32 +262,34 @@ function 
push_pull_remove_images::push_prod_images_to_github () {
     fi
 }
 
-# waits for an image to be available in GitHub Container Registry. Should be 
run with `set +e`
-function push_pull_remove_images::check_image_manifest() {
-    local image_to_wait_for="${1}"
-    echo "GitHub Container Registry: checking for ${image_to_wait_for} via 
docker manifest inspect!"
-    docker_v manifest inspect "${image_to_wait_for}"
-    local res=$?
-    if [[ ${res} == "0" ]]; then
-        echo  "Image: ${image_to_wait_for} found in Container Registry: 
${COLOR_GREEN}OK.${COLOR_RESET}"
-        return 0
-    else
-        echo "${COLOR_YELLOW}Still waiting. Not found!${COLOR_RESET}"
-        return 1
-    fi
-}
 
 # waits for an image to be available in the GitHub registry
 function push_pull_remove_images::wait_for_image() {
+    # Maximum number of tries 100 = we try for max. 100 minutes.
+    local MAX_TRIES=100
     set +e
     echo " Waiting for github registry image: $1"
+    local count=0
     while true
     do
-        if push_pull_remove_images::check_image_manifest "$1"; then
-            export IMAGE_AVAILABLE="$1"
+        if push_pull_remove_images::pull_image_if_not_present_or_forced "$1"; 
then
             break
         fi
-        sleep 30
+        if [[ ${count} == "${MAX_TRIES}" ]]; then
+            echo "${COLOR_RED}Giving up after ${MAX_TRIES}!${COLOR_RESET}"
+            echo "If there were delays with building the image, maintainers 
could potentially restart the build when the images are ready!"
+            echo "Or you can run 'git commit --amend' and then push the PR 
again with 'git push --force-with-lease' to re-trigger the build."
+            return 1
+        fi
+        echo "${COLOR_YELLOW}Failed to pull the image for ${count} time. 
Sleeping!${COLOR_RESET}"
+        sleep 60
+        count=$((count + 1))
     done
     set -e
 }
+
+function push_pull_remove_images::pull_image() {
+    start_end::group_start  "Pulling image: $1"
+    push_pull_remove_images::pull_image_if_not_present_or_forced "$1"
+    start_end::group_end
+}
diff --git a/scripts/ci/tools/free_space.sh b/scripts/ci/tools/free_space.sh
index d89172d..4767d60 100755
--- a/scripts/ci/tools/free_space.sh
+++ b/scripts/ci/tools/free_space.sh
@@ -30,3 +30,7 @@ docker_v system prune --all --force --volumes
 
 echo "${COLOR_BLUE}Free disk space  ${COLOR_RESET}"
 df -h
+
+# always logout from the docker registry - this is necessary as we can have an 
expired token from
+# previous job!.
+docker_v logout "ghcr.io"

Reply via email to