Browse Source

cli_image: do not require Docker when using CRI-O

Use atomic to copy the CLI binaries to the host.

Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
Giuseppe Scrivano 7 years ago
parent
commit
2ea7c0d02d

+ 50 - 14
roles/openshift_cli/library/openshift_container_binary_sync.py

@@ -24,23 +24,51 @@ class BinarySyncError(Exception):
         self.msg = msg
 
 
-# pylint: disable=too-few-public-methods
+# pylint: disable=too-few-public-methods,too-many-instance-attributes
 class BinarySyncer(object):
     """
     Syncs the openshift, oc, oadm, and kubectl binaries/symlinks out of
     a container onto the host system.
     """
 
-    def __init__(self, module, image, tag):
+    def __init__(self, module, image, tag, backend):
         self.module = module
         self.changed = False
         self.output = []
         self.bin_dir = '/usr/local/bin'
         self.image = image
         self.tag = tag
+        self.backend = backend
         self.temp_dir = None  # TBD
 
     def sync(self):
+        if self.backend == 'atomic':
+            return self._sync_atomic()
+
+        return self._sync_docker()
+
+    def _sync_atomic(self):
+        self.temp_dir = tempfile.mkdtemp()
+        temp_dir_mount = tempfile.mkdtemp()
+        try:
+            image_spec = '%s:%s' % (self.image, self.tag)
+            rc, stdout, stderr = self.module.run_command(['atomic', 'mount',
+                                                          '--storage', "ostree",
+                                                          image_spec, temp_dir_mount])
+            if rc:
+                raise BinarySyncError("Error mounting image. stdout=%s, stderr=%s" %
+                                      (stdout, stderr))
+            for i in ["openshift", "oc"]:
+                src_file = os.path.join(temp_dir_mount, "usr/bin", i)
+                shutil.copy(src_file, self.temp_dir)
+
+            self._sync_binaries()
+        finally:
+            self.module.run_command(['atomic', 'umount', temp_dir_mount])
+            shutil.rmtree(temp_dir_mount)
+            shutil.rmtree(self.temp_dir)
+
+    def _sync_docker(self):
         container_name = "openshift-cli-%s" % random.randint(1, 100000)
         rc, stdout, stderr = self.module.run_command(['docker', 'create', '--name',
                                                       container_name, '%s:%s' % (self.image, self.tag)])
@@ -64,21 +92,24 @@ class BinarySyncer(object):
                 raise BinarySyncError("Error copying file from docker container: stdout=%s, stderr=%s" %
                                       (stdout, stderr))
 
-            self._sync_binary('openshift')
-
-            # In older versions, oc was a symlink to openshift:
-            if os.path.islink(os.path.join(self.temp_dir, 'oc')):
-                self._sync_symlink('oc', 'openshift')
-            else:
-                self._sync_binary('oc')
-
-            # Ensure correct symlinks created:
-            self._sync_symlink('kubectl', 'openshift')
-            self._sync_symlink('oadm', 'openshift')
+            self._sync_binaries()
         finally:
             shutil.rmtree(self.temp_dir)
             self.module.run_command(['docker', 'rm', container_name])
 
+    def _sync_binaries(self):
+        self._sync_binary('openshift')
+
+        # In older versions, oc was a symlink to openshift:
+        if os.path.islink(os.path.join(self.temp_dir, 'oc')):
+            self._sync_symlink('oc', 'openshift')
+        else:
+            self._sync_binary('oc')
+
+        # Ensure correct symlinks created:
+        self._sync_symlink('kubectl', 'openshift')
+        self._sync_symlink('oadm', 'openshift')
+
     def _sync_symlink(self, binary_name, link_to):
         """ Ensure the given binary name exists and links to the expected binary. """
 
@@ -112,14 +143,19 @@ def main():
         argument_spec=dict(
             image=dict(required=True),
             tag=dict(required=True),
+            backend=dict(required=True),
         ),
         supports_check_mode=True
     )
 
     image = module.params['image']
     tag = module.params['tag']
+    backend = module.params['backend']
+
+    if backend not in ["docker", "atomic"]:
+        module.fail_json(msg="unknown backend")
 
-    binary_syncer = BinarySyncer(module, image, tag)
+    binary_syncer = BinarySyncer(module, image, tag, backend)
 
     try:
         binary_syncer.sync()

+ 33 - 11
roles/openshift_cli/tasks/main.yml

@@ -1,20 +1,42 @@
 ---
+- set_fact:
+    l_use_crio: "{{ openshift_docker_use_crio | default(false) }}"
+
 - name: Install clients
   package: name={{ openshift.common.service_type }}-clients state=present
   when: not openshift.common.is_containerized | bool
 
-- name: Pull CLI Image
-  command: >
-    docker pull {{ openshift.common.cli_image }}:{{ openshift_image_tag }}
-  register: pull_result
-  changed_when: "'Downloaded newer image' in pull_result.stdout"
-  when: openshift.common.is_containerized | bool
+- block:
+  - name: Pull CLI Image
+    command: >
+      docker pull {{ openshift.common.cli_image }}:{{ openshift_image_tag }}
+    register: pull_result
+    changed_when: "'Downloaded newer image' in pull_result.stdout"
+
+  - name: Copy client binaries/symlinks out of CLI image for use on the host
+    openshift_container_binary_sync:
+      image: "{{ openshift.common.cli_image }}"
+      tag: "{{ openshift_image_tag }}"
+      backend: "docker"
+  when:
+  - openshift.common.is_containerized | bool
+  - not l_use_crio
+
+- block:
+  - name: Pull CLI Image
+    command: >
+      atomic pull --storage ostree {{ openshift.common.system_images_registry }}/{{ openshift.common.cli_image }}:{{ openshift_image_tag }}
+    register: pull_result
+    changed_when: "'Pulling layer' in pull_result.stdout"
 
-- name: Copy client binaries/symlinks out of CLI image for use on the host
-  openshift_container_binary_sync:
-    image: "{{ openshift.common.cli_image }}"
-    tag: "{{ openshift_image_tag }}"
-  when: openshift.common.is_containerized | bool
+  - name: Copy client binaries/symlinks out of CLI image for use on the host
+    openshift_container_binary_sync:
+      image: "{{ openshift.common.system_images_registry }}/{{ openshift.common.cli_image }}"
+      tag: "{{ openshift_image_tag }}"
+      backend: "atomic"
+  when:
+  - openshift.common.is_containerized | bool
+  - l_use_crio
 
 - name: Reload facts to pick up installed OpenShift version
   openshift_facts: