diff --git a/roles/download/tasks/download_container.yml b/roles/download/tasks/download_container.yml index 5e67fe8c5..1f2a070ae 100644 --- a/roles/download/tasks/download_container.yml +++ b/roles/download/tasks/download_container.yml @@ -15,11 +15,6 @@ tags: - facts - - name: Download_container | Prepare container download - include_tasks: check_pull_required.yml - when: - - not download_always_pull - - debug: # noqa name[missing] msg: "Pull {{ image_reponame }} required is: {{ pull_required }}" diff --git a/roles/download/tasks/main.yml b/roles/download/tasks/main.yml index 93f8bb55a..d29c6f934 100644 --- a/roles/download/tasks/main.yml +++ b/roles/download/tasks/main.yml @@ -16,6 +16,19 @@ - download - upload +# The image_info_command depends on the Container Runtime and will output something like the following: +# {"Digest":"sha256:847423221ed040798e47df36450edce5581ed642cd087ccb210532764da38b23","Repository":"quay.io/coreos/etcd","Tag":"v3.5.12"} +# {"Digest":"sha256:34fc87c4a60c0b3ba3b3608871f4494de8072c02808a4151953068f2d7c87743","Repository":"flannel/flannel","Tag":"latest"} +- name: Download | Generate a list of information about the images on a node # noqa command-instead-of-shell - image_info_command for crio contains a pipe, therefore requiring shell + shell: "{{ image_info_command }}" + register: node_images + changed_when: false + check_mode: no + +- name: Show node images + debug: + msg: "{{ node_images.stdout }}" + - name: Download | Download files / images include_tasks: "{{ include_file }}" loop: "{{ downloads | combine(kubeadm_images) | dict2items }}" @@ -26,5 +39,9 @@ - not skip_downloads | default(false) - download.enabled - item.value.enabled - - (not (item.value.container | default(false))) or (item.value.container and download_container) + - (not (item.value.container | default(false))) or (item.value.container and download_container and (not ((node_images.stdout_lines | map('from_json') | selectattr('Repository', 'equalto', (item.value.repo | regex_replace('^docker\.io/(library/)?', ''))) | selectattr('Tag', 'equalto', item.value.tag) | list | length > 0) or (node_images.stdout_lines | map('from_json') | selectattr('Digest', 'equalto', 'sha256:' ~ (item.value.sha256 | default(None))) | list | length > 0)) or download_always_pull)) - (download_run_once and inventory_hostname == download_delegate) or (group_names | intersect(download.groups) | length) + +- name: Show downloads + debug: + msg: "{{ downloads }}" diff --git a/roles/download/vars/main.yml b/roles/download/vars/main.yml new file mode 100644 index 000000000..fc49bd64d --- /dev/null +++ b/roles/download/vars/main.yml @@ -0,0 +1,19 @@ +--- +docker_image_pull_command: "{{ docker_bin_dir }}/docker pull" +docker_image_info_command: "docker images --format='{\"Digest\":\"{{ '{{' }}.Digest{{ '}}' }}\",\"Repository\":\"{{ '{{' }}.Repository{{ '}}' }}\",\"Tag\":\"{{ '{{' }}.Tag{{ '}}' }}\"}'" +nerdctl_image_info_command: "nerdctl images --format='{\"Digest\":\"{{ '{{' }}.Digest{{ '}}' }}\",\"Repository\":\"{{ '{{' }}.Repository{{ '}}' }}\",\"Tag\":\"{{ '{{' }}.Tag{{ '}}' }}\"}'" +# Using the ctr instead of nerdctl to workdaround the https://github.com/kubernetes-sigs/kubespray/issues/10670 +nerdctl_image_pull_command: "{{ bin_dir }}/ctr -n k8s.io images pull{% if containerd_registries_mirrors is defined %} --hosts-dir {{ containerd_cfg_dir }}/certs.d{%- endif -%}" +crictl_image_info_command: "crictl images --output json | jq -cMr '.images[] | {Digest: (.repoDigests[0] | split(\"@\") | .[1]), Repository: (.repoTags[0] | split(\":\") | .[0] | gsub(\"^docker.io/\"; \"\") | gsub(\"^library/\"; \"\")), Tag: (.repoTags[0] | split(\":\") | .[1])}'" +crictl_image_pull_command: "{{ bin_dir }}/crictl pull" + +image_command_tool: "{%- if container_manager == 'containerd' -%}nerdctl{%- elif container_manager == 'crio' -%}crictl{%- else -%}{{ container_manager }}{%- endif -%}" +image_command_tool_on_localhost: "{{ image_command_tool }}" + +# Example output for image_info_command: +# {"Digest":"sha256:847423221ed040798e47df36450edce5581ed642cd087ccb210532764da38b23","Repository":"quay.io/coreos/etcd","Tag":"v3.5.12"} +# {"Digest":"sha256:34fc87c4a60c0b3ba3b3608871f4494de8072c02808a4151953068f2d7c87743","Repository":"flannel/flannel","Tag":"latest"} +image_pull_command: "{{ lookup('vars', image_command_tool + '_image_pull_command') }}" +image_info_command: "{{ lookup('vars', image_command_tool + '_image_info_command') }}" +image_pull_command_on_localhost: "{{ lookup('vars', image_command_tool_on_localhost + '_image_pull_command') }}" +image_info_command_on_localhost: "{{ lookup('vars', image_command_tool_on_localhost + '_image_info_command') }}" diff --git a/roles/kubespray-defaults/defaults/main/download.yml b/roles/kubespray-defaults/defaults/main/download.yml index 8c3954c80..6e8cf7ba4 100644 --- a/roles/kubespray-defaults/defaults/main/download.yml +++ b/roles/kubespray-defaults/defaults/main/download.yml @@ -53,23 +53,6 @@ download_delegate: "{% if download_localhost %}localhost{% else %}{{ groups['kub # Allow control the times of download retries for files and containers download_retries: 4 -# The docker_image_info_command might seems weird but we are using raw/endraw and `{{ `{{` }}` to manage the double jinja2 processing -docker_image_pull_command: "{{ docker_bin_dir }}/docker pull" -docker_image_info_command: "{{ docker_bin_dir }}/docker images -q | xargs -i {{ '{{' }} docker_bin_dir }}/docker inspect -f {% raw %}'{{ '{{' }} if .RepoTags }}{{ '{{' }} join .RepoTags \",\" }}{{ '{{' }} end }}{{ '{{' }} if .RepoDigests }},{{ '{{' }} join .RepoDigests \",\" }}{{ '{{' }} end }}' {% endraw %} {} | tr '\n' ','" -nerdctl_image_info_command: "{{ bin_dir }}/nerdctl -n k8s.io images --format '{% raw %}{{ .Repository }}:{{ .Tag }}{% endraw %}' 2>/dev/null | grep -v ^:$ | tr '\n' ','" -# Using the ctr instead of nerdctl to workdaround the https://github.com/kubernetes-sigs/kubespray/issues/10670 -nerdctl_image_pull_command: "{{ bin_dir }}/ctr -n k8s.io images pull{% if containerd_registries_mirrors is defined %} --hosts-dir {{ containerd_cfg_dir }}/certs.d{%- endif -%}" -crictl_image_info_command: "{{ bin_dir }}/crictl images --verbose | awk -F ': ' '/RepoTags|RepoDigests/ {print $2}' | tr '\n' ','" -crictl_image_pull_command: "{{ bin_dir }}/crictl pull" - -image_command_tool: "{%- if container_manager == 'containerd' -%}nerdctl{%- elif container_manager == 'crio' -%}crictl{%- else -%}{{ container_manager }}{%- endif -%}" -image_command_tool_on_localhost: "{{ image_command_tool }}" - -image_pull_command: "{{ lookup('vars', image_command_tool + '_image_pull_command') }}" -image_info_command: "{{ lookup('vars', image_command_tool + '_image_info_command') }}" -image_pull_command_on_localhost: "{{ lookup('vars', image_command_tool_on_localhost + '_image_pull_command') }}" -image_info_command_on_localhost: "{{ lookup('vars', image_command_tool_on_localhost + '_image_info_command') }}" - # Arch of Docker images and needed packages image_arch: "{{ host_architecture | default('amd64') }}"