From 9d8a83314b9da22de1fe93d4e6fd666183f26cea Mon Sep 17 00:00:00 2001
From: Cristian Calin <6627509+cristicalin@users.noreply.github.com>
Date: Fri, 3 Dec 2021 22:20:35 +0200
Subject: [PATCH] containerd: add hashes for 1.5.8 and 1.4.12 and make 1.5.8
 the new default (#8239)

* containerd: add hashes for 1.5.8 and 1.4.12 and make 1.5.8 the new default

* containerd: make nerdctl mandatory for container_manager = containerd

* nerdctl: bump to version 0.14.0

* containerd: use nerdctl for image manipulation

* OpenSuSE: install basic nerdctl dependencies
---
 README.md                                     |  2 +-
 .../bootstrap-os/tasks/bootstrap-opensuse.yml |  9 +++++
 .../container-engine/containerd/meta/main.yml |  1 +
 .../containerd/molecule/default/prepare.yml   | 19 +++++++++-
 .../molecule/default/tests/test_default.py    | 36 ++++++++++++++++++-
 roles/download/defaults/main.yml              | 16 ++++++---
 roles/download/tasks/main.yml                 |  1 -
 roles/download/tasks/prep_download.yml        |  8 ++---
 roles/download/tasks/set_container_facts.yml  |  4 +--
 roles/kubespray-defaults/defaults/main.yaml   |  5 +--
 10 files changed, 82 insertions(+), 19 deletions(-)

diff --git a/README.md b/README.md
index ffcace439..9f2e18c3e 100644
--- a/README.md
+++ b/README.md
@@ -134,7 +134,7 @@ Note: Upstart/SysV init based OS types are not supported.
   - [kubernetes](https://github.com/kubernetes/kubernetes) v1.22.4
   - [etcd](https://github.com/coreos/etcd) v3.5.0
   - [docker](https://www.docker.com/) v20.10 (see note)
-  - [containerd](https://containerd.io/) v1.4.9
+  - [containerd](https://containerd.io/) v1.5.8
   - [cri-o](http://cri-o.io/) v1.22 (experimental: see [CRI-O Note](docs/cri-o.md). Only on fedora, ubuntu and centos based OS)
 - Network Plugin
   - [cni-plugins](https://github.com/containernetworking/plugins) v0.9.1
diff --git a/roles/bootstrap-os/tasks/bootstrap-opensuse.yml b/roles/bootstrap-os/tasks/bootstrap-opensuse.yml
index b30581120..c036c21f6 100644
--- a/roles/bootstrap-os/tasks/bootstrap-opensuse.yml
+++ b/roles/bootstrap-os/tasks/bootstrap-opensuse.yml
@@ -59,3 +59,12 @@
     state: present
     update_cache: true
   become: true
+
+# Nerdctl needs some basic packages to get an environment up
+- name: Install basic dependencies
+  zypper:
+    name:
+      - iptables
+      - apparmor-parser
+    state: present
+  become: true
diff --git a/roles/container-engine/containerd/meta/main.yml b/roles/container-engine/containerd/meta/main.yml
index 562956772..41c5b6a97 100644
--- a/roles/container-engine/containerd/meta/main.yml
+++ b/roles/container-engine/containerd/meta/main.yml
@@ -3,3 +3,4 @@ dependencies:
   - role: container-engine/containerd-common
   - role: container-engine/runc
   - role: container-engine/crictl
+  - role: container-engine/nerdctl
diff --git a/roles/container-engine/containerd/molecule/default/prepare.yml b/roles/container-engine/containerd/molecule/default/prepare.yml
index aef05228d..100673cb4 100644
--- a/roles/container-engine/containerd/molecule/default/prepare.yml
+++ b/roles/container-engine/containerd/molecule/default/prepare.yml
@@ -8,4 +8,21 @@
   roles:
     - role: kubespray-defaults
     - role: bootstrap-os
-    - { role: kubernetes/preinstall, tags: ["bootstrap-os"] }
+    - role: kubernetes/preinstall
+    - role: adduser
+      user: "{{ addusers.kube }}"
+  tasks:
+    - include_tasks: "../../../../download/tasks/download_file.yml"
+      vars:
+        download: "{{ download_defaults | combine(downloads.cni) }}"
+
+- name: Prepare CNI
+  hosts: all
+  gather_facts: False
+  become: true
+  vars:
+    ignore_assert_errors: true
+    kube_network_plugin: cni
+  roles:
+    - role: kubespray-defaults
+    - role: network_plugin/cni
diff --git a/roles/container-engine/containerd/molecule/default/tests/test_default.py b/roles/container-engine/containerd/molecule/default/tests/test_default.py
index 523408be6..e1d915179 100644
--- a/roles/container-engine/containerd/molecule/default/tests/test_default.py
+++ b/roles/container-engine/containerd/molecule/default/tests/test_default.py
@@ -1,4 +1,5 @@
 import os
+import pytest
 
 import testinfra.utils.ansible_runner
 
@@ -12,10 +13,43 @@ def test_service(host):
     assert svc.is_enabled
 
 
-def test_run(host):
+def test_version(host):
     crictl = "/usr/local/bin/crictl"
     path = "unix:///var/run/containerd/containerd.sock"
     with host.sudo():
         cmd = host.command(crictl + " --runtime-endpoint " + path + " version")
     assert cmd.rc == 0
     assert "RuntimeName:  containerd" in cmd.stdout
+
+
+@pytest.mark.parametrize('image, dest', [
+    ('quay.io/kubespray/hello-world:latest', '/tmp/hello-world.tar')
+])
+def test_image_pull_save_load(host, image, dest):
+    nerdctl = "/usr/local/bin/nerdctl"
+    dest_file = host.file(dest)
+
+    with host.sudo():
+        pull_cmd = host.command(nerdctl + " pull " + image)
+    assert pull_cmd.rc ==0
+
+    with host.sudo():
+        save_cmd = host.command(nerdctl + " save -o " + dest + " " + image)
+    assert save_cmd.rc == 0
+    assert dest_file.exists
+
+    with host.sudo():
+        load_cmd = host.command(nerdctl + " load < " + dest)
+    assert load_cmd.rc == 0
+
+
+@pytest.mark.parametrize('image', [
+    ('quay.io/kubespray/hello-world:latest')
+])
+def test_run(host, image):
+    nerdctl = "/usr/local/bin/nerdctl"
+
+    with host.sudo():
+        cmd = host.command(nerdctl + " -n k8s.io run " + image)
+    assert cmd.rc == 0
+    assert "Hello from Docker" in cmd.stdout
diff --git a/roles/download/defaults/main.yml b/roles/download/defaults/main.yml
index 06aece6ec..b2c4a47d0 100644
--- a/roles/download/defaults/main.yml
+++ b/roles/download/defaults/main.yml
@@ -88,7 +88,7 @@ kube_ovn_version: "v1.8.1"
 kube_router_version: "v1.3.2"
 multus_version: "v3.8"
 helm_version: "v3.7.1"
-nerdctl_version: "0.12.1"
+nerdctl_version: "0.14.0"
 krew_version: "v0.4.2"
 
 # Get kubernetes major version (i.e. 1.17.4 => 1.17)
@@ -521,28 +521,34 @@ gvisor_containerd_shim_binary_checksums:
 
 nerdctl_archive_checksums:
   arm:
-    0.12.1: 64d6cfdbf9e0ac6eb47d86f05452d36d5c31471bdc31c027fe3a23edfae0d64c
+    0.14.0: b85b6813935d4a9f93af9fb1104cdefeb06edfcfc7e25507c32f503f222dfd5f
   arm64:
-    0.12.1: 991c1b9ff842ac2546f22ca8842eaaa0d0e20d2fa8e9c1746c40443a6ce24430
+    0.14.0: bf00613a4d0c400e916e7ee6afdf043b9251e492527c6746ad7553cb2c646cc8
   amd64:
-    0.12.1: 868dc5997c3edb0bd06f75012e71c2b15ee0885b83bad191fbe2a1d6d5f4f2ac
+    0.14.0: 4d3a2e9ecb9efd278313483e85e34e45605f4f8e61805480de440f69a298a649
 
 containerd_archive_checksums:
   arm:
     1.4.9: 0
     1.4.11: 0
+    1.4.12: 0
     1.5.5: 0
     1.5.7: 0
+    1.5.8: 0
   arm64:
     1.4.9: 0
     1.4.11: 0
+    1.4.12: 0
     1.5.5: 0
     1.5.7: 0
+    1.5.8: 0
   amd64:
     1.4.9: 346f88ad5b973960ff81b5539d4177af5941ec2e4703b479ca9a6081ff1d023b
     1.4.11: 80c47ec5ce2cd91a15204b5f5b534892ca653e75f3fba0c451ca326bca45fb00
+    1.4.12: 26bb35ee8a2467029ca450352112ba3a0d2b8bf6b70bf040f62d91f3c501736c
     1.5.5: 8efc527ffb772a82021800f0151374a3113ed2439922497ff08f2596a70f10f1
     1.5.7: 109fc95b86382065ea668005c376360ddcd8c4ec413e7abe220ae9f461e0e173
+    1.5.8: feeda3f563edf0294e33b6c4b89bd7dbe0ee182ca61a2f9b8c3de2766bcbc99b
 
 etcd_binary_checksum: "{{ etcd_binary_checksums[image_arch] }}"
 cni_binary_checksum: "{{ cni_binary_checksums[image_arch] }}"
@@ -908,7 +914,7 @@ downloads:
 
   nerdctl:
     file: true
-    enabled: "{{ nerdctl_enabled }}"
+    enabled: "{{ container_manager == 'containerd' }}"
     version: "{{ nerdctl_version }}"
     dest: "{{ local_release_dir }}/nerdctl-{{ nerdctl_version }}-linux-{{ image_arch }}.tar.gz"
     sha256: "{{ nerdctl_archive_checksum }}"
diff --git a/roles/download/tasks/main.yml b/roles/download/tasks/main.yml
index 48b592050..94e9d03aa 100644
--- a/roles/download/tasks/main.yml
+++ b/roles/download/tasks/main.yml
@@ -20,7 +20,6 @@
   when:
     - not skip_downloads|default(false)
     - container_manager in ['containerd']
-    - nerdctl_enabled
 
 - name: download | Get kubeadm binary and list of required images
   include_tasks: prep_kubeadm_images.yml
diff --git a/roles/download/tasks/prep_download.yml b/roles/download/tasks/prep_download.yml
index 73d72cf25..e84a516dc 100644
--- a/roles/download/tasks/prep_download.yml
+++ b/roles/download/tasks/prep_download.yml
@@ -15,8 +15,8 @@
 
 - name: prep_download | Set image pull/info command for containerd
   set_fact:
-    image_info_command: "{{ bin_dir }}/ctr -n k8s.io images ls | awk '/application/ {print $1}' | grep -v ^sha | tr '\n' ','"
-    image_pull_command: "{{ bin_dir }}/ctr -n k8s.io images pull --platform linux/{{ image_arch }}"
+    image_info_command: "{{ bin_dir }}/nerdctl -n k8s.io images --format '{% raw %}{{ '{{' }} .Repository {{ '}}' }}:{{ '{{' }} .Tag {{ '}}' }}{% endraw %}' 2>/dev/null | grep -v ^:$ | tr '\n' ','"
+    image_pull_command: "{{ bin_dir }}/nerdctl -n k8s.io pull"
   when: container_manager == 'containerd'
 
 - name: prep_download | Set image pull/info command for crio
@@ -33,8 +33,8 @@
 
 - name: prep_download | Set image pull/info command for containerd on localhost
   set_fact:
-    image_info_command_on_localhost: "{{ bin_dir }}/ctr -n k8s.io images ls | awk '/application/ {print $1}' | grep -v ^sha | tr '\n' ','"
-    image_pull_command_on_localhost: "{{ bin_dir }}/ctr -n k8s.io images pull --platform linux/{{ image_arch }}"
+    image_info_command_on_localhost: "{{ bin_dir }}/nerdctl -n k8s.io images --format '{% raw %}{{ '{{' }} .Repository {{ '}}' }}:{{ '{{' }} .Tag {{ '}}' }}{% endraw %}' 2>/dev/null | grep -v ^:$ | tr '\n' ','"
+    image_pull_command_on_localhost: "{{ bin_dir }}/nerdctl -n k8s.io pull"
   when: container_manager_on_localhost == 'containerd'
 
 - name: prep_download | Set image pull/info command for crio on localhost
diff --git a/roles/download/tasks/set_container_facts.yml b/roles/download/tasks/set_container_facts.yml
index 20c178300..5890e6c82 100644
--- a/roles/download/tasks/set_container_facts.yml
+++ b/roles/download/tasks/set_container_facts.yml
@@ -29,8 +29,8 @@
 
 - name: Set image save/load command for containerd
   set_fact:
-    image_save_command: "{{ containerd_bin_dir }}/ctr -n k8s.io image export --platform linux/{{ image_arch }} {{ image_path_final }} {{ image_reponame }}"
-    image_load_command: "{{ containerd_bin_dir }}/ctr -n k8s.io image import --base-name {{ download.repo }} {{ image_path_final }}"
+    image_save_command: "{{ bin_dir }}/nerdctl -n k8s.io image save -o {{ image_path_final }} {{ image_reponame }}"
+    image_load_command: "{{ bin_dir }}/nerdctl -n k8s.io image load < {{ image_path_final }}"
   when: container_manager == 'containerd'
 
 - name: Set image save/load command for crio
diff --git a/roles/kubespray-defaults/defaults/main.yaml b/roles/kubespray-defaults/defaults/main.yaml
index 77d3e01de..658dc65fc 100644
--- a/roles/kubespray-defaults/defaults/main.yaml
+++ b/roles/kubespray-defaults/defaults/main.yaml
@@ -336,7 +336,7 @@ docker_plugins: []
 etcd_kubeadm_enabled: false
 
 # Containerd options - thse are relevant when container_manager == 'containerd'
-containerd_version: 1.4.11
+containerd_version: 1.5.8
 containerd_use_systemd_cgroup: true
 
 # Docker options - this is relevant when container_manager == 'docker'
@@ -387,9 +387,6 @@ expand_persistent_volumes: false
 metallb_enabled: false
 argocd_enabled: false
 
-# containerd official CLI tool
-nerdctl_enabled: false
-
 ## When OpenStack is used, Cinder version can be explicitly specified if autodetection fails (Fixed in 1.9: https://github.com/kubernetes/kubernetes/issues/50461)
 # openstack_blockstorage_version: "v1/v2/auto (default)"
 openstack_blockstorage_ignore_volume_az: "{{ volume_cross_zone_attachment | default('false') }}"
-- 
GitLab