From 2ea7c0d02d7bc10b3bb6313b13c3bbf37ca4a67c Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Wed, 26 Jul 2017 17:59:44 +0200 Subject: 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 --- .../library/openshift_container_binary_sync.py | 64 +++++++++++++++++----- roles/openshift_cli/tasks/main.yml | 44 +++++++++++---- 2 files changed, 83 insertions(+), 25 deletions(-) (limited to 'roles/openshift_cli') diff --git a/roles/openshift_cli/library/openshift_container_binary_sync.py b/roles/openshift_cli/library/openshift_container_binary_sync.py index 57ac16602..c47203211 100644 --- a/roles/openshift_cli/library/openshift_container_binary_sync.py +++ b/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() diff --git a/roles/openshift_cli/tasks/main.yml b/roles/openshift_cli/tasks/main.yml index 07a00189c..c716a0860 100644 --- a/roles/openshift_cli/tasks/main.yml +++ b/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: -- cgit v1.2.3