Uploaded image for project: 'Ansible Automation Platform RFEs'
  1. Ansible Automation Platform RFEs
  2. AAPRFE-2615

Enable "Skip Image Copy If Image Already Exists in Private Automation Hub" Behavior

XMLWordPrintable

    • Icon: Feature Request Feature Request
    • Resolution: Unresolved
    • Icon: Normal Normal
    • None
    • 2.5, 2.6
    • hub, platform-installer
    • None
    • False
    • Hide

      None

      Show
      None
    • False

      1. What is the nature and description of the request?

      The customer is requesting a new feature for the Ansible Automation Platform (AAP) installer — specifically for the image copy/push workflow involving Skopeo and Private Automation Hub (PAH).

      Current behavior:

        • During installation, AAP always executes skopeo copy for each execution environment (EE) listed.
        • The installer does not check whether the image already exists in PAH.
        • As a result, the installer attempts to re-copy/re-push all images every time, even if:
          • The image already exists in PAH
          • The customer uses custom EE images already loaded into PAH

      Requested enhancement:

        • Add logic that skips the image copy step if the image already exists in Private Automation Hub.
        • The installer should behave intelligently and avoid redundant copying.
      1. Why does the customer need this? (List the business requirements here)

      The customer needs this enhancement for the following reasons:

        1. Reduce installation failures
          • Failures in the copy process (e.g., due to proxy, CDN restrictions, or network filtering) should not affect images that already exist locally.
          • Their custom EE images were impacted even though they should not need syncing from any external registry.
            • Private Automation Hub is designed to operate fully offline, especially in secure environments.
            • If images already exist, trying to copy from external sources is unnecessary and introduces risk.
        1. Increase installation efficiency
          • Copying large container images is slow and resource-intensive.
          • Skipping already-present images saves bandwidth, time, and storage.
        1. Prevent corruption of local custom EE images
          • The installer's forced re-copy logic caused partially written images, resulting in broken blobs (404 errors).
          • Avoiding unnecessary copying prevents corruption from incomplete transfers.
      1. How would you like to achieve this? (List the functional requirements here)

      To meet the above business needs, the customer requests:

      1. Pre-copy validation logic
        • Before running skopeo copy, the installer should check if the image (name + tag) already exists in Private Automation Hub.
        • Validation method could include:
          • Manifest digest comparison
          • Tag existence check via PAH API
          • Local hash/digest lookup in Pulp
      1. Conditional behavior
        • If the target image exists and is identical → Skip copy
        • If it does not exist or differs → Proceed with skopeo copy
            •  
        1. Idempotency
          • Allow repeated installer runs without breaking existing images in PAH.
          • Prevent partially written or corrupted blobs.

      $ cat collections/ansible_collections/ansible/automation_platform_installer/roles/misc/tasks/setup_ee_images.yml 

      The failing snippet is as follows:

      ~~~~

      • block:
            - name: Ensure skopeo exists
              dnf:
                name: skopeo
                state: present
              register: installed_skopeo

          - name: Set list of images to upload for controller and execution nodes
            set_fact:
              _images_to_upload: '{{ ee_images }}'
            when: inventory_hostname in groups.get('automationcontroller', []) | union(groups.get('execution_nodes', []))

          - name: Set list of images to upload for hub
            set_fact:
              _images_to_upload: '{{ ee_images | union(de_images) | union(extra_images) }}'
            when: inventory_hostname in groups.get('automationhub', [])

          - name: Set list of images to upload for EDA
            set_fact:
              _images_to_upload: '{{ de_images }}'
            when: inventory_hostname in _automationedacontroller_web_hosts

          - name: Set up images
            block:
              - name: Set source registry credential (username)
                set_fact:
                  src_registry_creds: "--src-creds '{{ registry_username }}'"
                when:
                  - registry_username | default('') | length
                  - not registry_password | default('') | length

              - name: Set source registry credential (username and password)
                set_fact:
                  src_registry_creds: "--src-creds '{{ registry_username }}:{{ registry_password }}'"
                when:
                  - registry_username | default('') | length
                  - registry_password | default('') | length
                no_log: "{{ _no_log }}"

              - name: Push images to Automation Hub registry
                command: skopeo copy \
                           --retry-times 5 \
                           {{ src_registry_creds | default('') }} --src-tls-verify={{ _registry_verify_ssl | default(true) | bool }} \
                           --dest-creds '{{ _automationgateway_admin_username }}:{{ automationgateway_admin_password }}' --dest-tls-verify=false \
                           docker://{{ _ee_image_base }}{{ item }}:latest \
                           docker://{{ _automationgateway_main_netloc }}/{{ item }}:latest
                environment:
                  HTTP_PROXY: "{{ http_proxy | default('') }}"
                  HTTPS_PROXY: "{{ https_proxy | default('') }}"
                  NO_PROXY: "{{ no_proxy | default('') }}"
                register: _push_ee_result
                ignore_errors: true
                no_log: "{{ _no_log }}"
                with_items: '{{ _images_to_upload }}'

              - name: Catch error when not all images are processed
                set_fact:
                  _image_push_error: "{{ _image_push_error | default([]) + [_push_ee_result.msg] }}"
                when: _push_ee_result.results is not defined

              - name: Parse error messages
                set_fact:
                  _image_push_error: "{{ _image_push_error | default([]) + [item.stderr] }}"
                with_items: "{{ _push_ee_result.results }}"
                no_log: "{{ _no_log }}"
                when: item | default({}) is failed

            when:
              - inventory_hostname in groups['automationhub'] | default([])
              - not bundle_install | default(false) | bool

          - name: Set up images (bundle)
            include_tasks: push_bundle_ee_image.yml
            with_items: '{{ _images_to_upload }}'
            when: bundle_install | default(false) | bool

          - name: Parse error messages
            set_fact:
              _image_push_error_messages: "{{ _image_push_error | default([]) + _bundle_image_push_error | default([]) }}"
            no_log: "{{ _no_log }}"

          - name: Ensure images are pushed
            fail:
              msg: "Failed to push image(s), reason: {{ _image_push_error_messages }}"
            when: _image_push_error_messages | default([]) | length

        always:
          - name: Remove skopeo if added by installer
            dnf:
              name: skopeo
              state: absent
              autoremove: true
            when: installed_skopeo is changed
      ~~~~

              Unassigned Unassigned
              rhn-support-apaygavh Abhishek Paygavhan
              Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

                Created:
                Updated: