From a16d55707c10a368b5aa2f9b7e595751978c3b04 Mon Sep 17 00:00:00 2001 From: Stepan Andrushko Date: Thu, 24 May 2018 13:13:40 +0300 Subject: Add virtual image generation to install script Update install.yaml with image generation: nsb and normal. JIRA: YARDSTICK-1198 Change-Id: I3b8773e9b3b9890ae8623bb6536d05f1151d84a8 Signed-off-by: Stepan Andrushko --- ansible/group_vars/all.yml | 8 +- ansible/install-inventory.ini | 15 +- ansible/install.yaml | 50 ++++- ansible/roles/add_custom_repos/tasks/main.yml | 2 +- .../tasks/cloudimg_modify_normal.yml | 56 ++++++ .../tasks/cloudimg_modify_nsb.yml | 104 +++++++++++ ansible/roles/build_yardstick_image/tasks/main.yml | 14 ++ .../build_yardstick_image/tasks/post_build.yml | 46 +++++ .../build_yardstick_image/tasks/pre_build.yml | 202 +++++++++++++++++++++ ansible/roles/build_yardstick_image/vars/main.yml | 31 ++++ ansible/roles/download_dpdk/defaults/main.yml | 2 +- ansible/roles/install_civetweb/defaults/main.yml | 7 +- .../install_image_dependencies/tasks/main.yml | 2 +- 13 files changed, 513 insertions(+), 26 deletions(-) create mode 100644 ansible/roles/build_yardstick_image/tasks/cloudimg_modify_normal.yml create mode 100644 ansible/roles/build_yardstick_image/tasks/cloudimg_modify_nsb.yml create mode 100644 ansible/roles/build_yardstick_image/tasks/main.yml create mode 100644 ansible/roles/build_yardstick_image/tasks/post_build.yml create mode 100644 ansible/roles/build_yardstick_image/tasks/pre_build.yml create mode 100644 ansible/roles/build_yardstick_image/vars/main.yml diff --git a/ansible/group_vars/all.yml b/ansible/group_vars/all.yml index 359968277..9f5293272 100644 --- a/ansible/group_vars/all.yml +++ b/ansible/group_vars/all.yml @@ -1,9 +1,15 @@ --- target_os: "Ubuntu" YARD_IMG_ARCH: "amd64" +IMG_PROPERTY: "normal" clone_dest: /opt/tempT release: xenial normal_image_file: "{{ workspace }}/yardstick-image.img" nsb_image_file: "{{ workspace }}/yardstick-nsb-image.img" ubuntu_image_file: /tmp/workspace/yardstick/yardstick-trusty-server.raw -proxy_env: {} +proxy_env: + PATH: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/root/bin + http_proxy: "{{ lookup('env', 'http_proxy') }}" + https_proxy: "{{ lookup('env', 'https_proxy') }}" + ftp_proxy: "{{ lookup('env', 'ftp_proxy') }}" + no_proxy: "{{ lookup('env', 'no_proxy') }}" diff --git a/ansible/install-inventory.ini b/ansible/install-inventory.ini index 6aa9905bd..e15a2e96a 100644 --- a/ansible/install-inventory.ini +++ b/ansible/install-inventory.ini @@ -1,7 +1,6 @@ # the group of systems on which to install yardstick # by default just localhost [jumphost] -#yardstickvm1 ansible_user=ubuntu ansible_ssh_pass=password ansible_connection=local localhost ansible_connection=local # section below is only due backward compatibility. @@ -10,14 +9,10 @@ localhost ansible_connection=local jumphost [yardstick-standalone] -#yardstickvm2 ansible_host=192.168.2.51 ansible_user=ubuntu ansible_ssh_pass=password ansible_connection=ssh -# uncomment hosts below if you would to test yardstick-standalone/sriov scenarios -#yardstick-standalone-node ansible_host=192.168.1.2 -#yardstick-standalone-node-2 ansible_host=192.168.1.3 +# standalone-node ansible_host=192.168.2.51 ansible_user=ubuntu ansible_ssh_pass=password ansible_connection=ssh [yardstick-baremetal] -#yardstickvm3 ansible_host=192.168.2.52 ansible_user=ubuntu ansible_ssh_pass=password ansible_connection=ssh -# hostname ansible_host=192.168.1.2 +# baremetal-node ansible_host=192.168.2.52 ansible_user=ubuntu ansible_ssh_pass=password ansible_connection=ssh [all:vars] arch_amd64=amd64 @@ -25,6 +20,6 @@ arch_arm64=arm64 inst_mode_container=container inst_mode_baremetal=baremetal ubuntu_archive={"amd64": "http://archive.ubuntu.com/ubuntu/", "arm64": "http://ports.ubuntu.com/ubuntu-ports/"} -# uncomment credentials below for yardstick-standalone -#ansible_user=root -#ansible_pass=root +# Uncomment credentials below if needed +# ansible_user=root +# ansible_pass=root diff --git a/ansible/install.yaml b/ansible/install.yaml index ae9f8587f..fa8419b53 100644 --- a/ansible/install.yaml +++ b/ansible/install.yaml @@ -50,23 +50,18 @@ - shell: uwsgi -i /etc/yardstick/yardstick.ini when: installation_mode != inst_mode_container -- name: Prepare baremetal and standalone server(s) + +- name: Prepare baremetal and standalone servers hosts: yardstick-baremetal,yardstick-standalone become: yes - vars: - YARD_IMG_ARCH: "{{ arch_amd64 }}" - environment: - proxy_env: - http_proxy: "{{ lookup('env', 'http_proxy') }}" - https_proxy: "{{ lookup('env', 'https_proxy') }}" - ftp_proxy: "{{ lookup('env', 'ftp_proxy') }}" - no_proxy: "{{ lookup('env', 'no_proxy') }}" + environment: "{{ proxy_env }}" roles: - add_custom_repos - role: set_package_installer_proxy when: proxy_env is defined and proxy_env # can't update grub in chroot/docker + # ?? - enable_iommu_on_boot - enable_hugepages_on_boot # needed for collectd plugins - increase_open_file_limits @@ -98,3 +93,40 @@ - install_pmu_tools - download_collectd - install_collectd + + +- hosts: jumphost + become: yes + vars: + img_prop_item: "{{ IMG_PROPERTY }}" + img_arch: "{{ YARD_IMG_ARCH }}" + + tasks: + - name: Include pre-build + include_role: + name: build_yardstick_image + tasks_from: pre_build.yml + + +- hosts: chroot_image + connection: chroot + become: yes + vars: + img_property: "{{ IMG_PROPERTY }}" + environment: "{{ proxy_env }}" + + tasks: + - name: Include image build + include_role: + name: build_yardstick_image + tasks_from: "cloudimg_modify_{{ img_property }}.yml" + + +- hosts: jumphost + become: yes + + tasks: + - name: Include post-build + include_role: + name: build_yardstick_image + tasks_from: post_build.yml diff --git a/ansible/roles/add_custom_repos/tasks/main.yml b/ansible/roles/add_custom_repos/tasks/main.yml index 7341ad07d..b1dfd542d 100644 --- a/ansible/roles/add_custom_repos/tasks/main.yml +++ b/ansible/roles/add_custom_repos/tasks/main.yml @@ -12,5 +12,5 @@ # See the License for the specific language governing permissions and # limitations under the License. --- -- include: "{{ target_os|lower }}.yml" +- include_tasks: "{{ target_os|lower }}.yml" diff --git a/ansible/roles/build_yardstick_image/tasks/cloudimg_modify_normal.yml b/ansible/roles/build_yardstick_image/tasks/cloudimg_modify_normal.yml new file mode 100644 index 000000000..435b43856 --- /dev/null +++ b/ansible/roles/build_yardstick_image/tasks/cloudimg_modify_normal.yml @@ -0,0 +1,56 @@ +# Copyright (c) 2018 Intel Corporation. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +--- +- debug: + msg: "chrooted in {{ inventory_hostname }}" + +- debug: + var: proxy_env + verbosity: 2 + +- include_role: + name: "{{ role_item }}" + with_items: + - reset_resolv_conf + - add_custom_repos + - modify_cloud_config + loop_control: + loop_var: role_item + +- include_role: + name: set_package_installer_proxy + when: proxy_env is defined and proxy_env + +- include_role: + name: install_image_dependencies + +- include_vars: roles/download_unixbench/defaults/main.yml + when: unixbench_dest is undefined + +- include_vars: roles/download_ramspeed/defaults/main.yml + when: ramspeed_dest is undefined + +- include_role: + name: "{{ role_item }}" + with_items: + - download_l2fwd + - download_unixbench + - install_unixbench + - download_ramspeed + - install_ramspeed + - download_cachestat + loop_control: + loop_var: role_item + + environment: "{{ proxy_env }}" diff --git a/ansible/roles/build_yardstick_image/tasks/cloudimg_modify_nsb.yml b/ansible/roles/build_yardstick_image/tasks/cloudimg_modify_nsb.yml new file mode 100644 index 000000000..9a70ff39a --- /dev/null +++ b/ansible/roles/build_yardstick_image/tasks/cloudimg_modify_nsb.yml @@ -0,0 +1,104 @@ +# Copyright (c) 2018 Intel Corporation. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +--- +- debug: + msg: "chrooted in {{ inventory_hostname }}" + +- debug: + var: proxy_env + verbosity: 2 + +- debug: msg="play_hosts={{play_hosts}}" + +- include_role: + name: "{{ role_item }}" + with_items: + - reset_resolv_conf + - add_custom_repos + - modify_cloud_config + loop_control: + loop_var: role_item + +- include_role: + name: set_package_installer_proxy + when: proxy_env is defined and proxy_env + +- include_vars: roles/install_dpdk/vars/main.yml + when: dpdk_make_arch is undefined + +- include_vars: roles/download_dpdk/defaults/main.yml + when: dpdk_version is undefined + +- include_vars: roles/download_trex/defaults/main.yml + when: trex_unarchive is undefined + +- include_vars: roles/download_civetweb/defaults/main.yml + when: civetweb_dest is undefined + +- include_role: + name: "{{ role_item }}" + with_items: + - install_image_dependencies + - enable_hugepages_on_boot # can't update grub in chroot/docker + - increase_open_file_limits # needed for collectd plugins + - download_dpdk + - install_dpdk + - download_trex + - install_trex + - download_pktgen + - install_pktgen + - download_civetweb + - install_civetweb + - download_samplevnfs + loop_control: + loop_var: role_item + environment: "{{ proxy_env }}" + +- include_vars: roles/install_dpdk/defaults/main.yml + when: INSTALL_BIN_PATH is undefined + +- include_vars: roles/download_samplevnfs/defaults/main.yml + when: samplevnf_dest is undefined +- set_fact: + samplevnf_path: "{{ samplevnf_dest }}" +- include_role: + name: install_samplevnf + with_items: + - PROX + - UDP_Replay + - ACL + - FW + - CGNAPT + loop_control: + loop_var: vnf_name + +- include_vars: roles/download_drivers/defaults/main.yml + when: i40evf_path is undefined + +- include_role: + name: "{{ role_item }}" + with_items: + - install_dpdk_shared # build shared DPDK for collectd only, required DPDK downloaded already + - install_rabbitmq + - download_intel_cmt_cat + - install_intel_cmt_cat + - download_pmu_tools + - install_pmu_tools + - download_collectd + - install_collectd + - download_drivers + - install_drivers + loop_control: + loop_var: role_item + environment: "{{ proxy_env }}" diff --git a/ansible/roles/build_yardstick_image/tasks/main.yml b/ansible/roles/build_yardstick_image/tasks/main.yml new file mode 100644 index 000000000..e21cbb766 --- /dev/null +++ b/ansible/roles/build_yardstick_image/tasks/main.yml @@ -0,0 +1,14 @@ +# Copyright (c) 2018 Intel Corporation. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +--- diff --git a/ansible/roles/build_yardstick_image/tasks/post_build.yml b/ansible/roles/build_yardstick_image/tasks/post_build.yml new file mode 100644 index 000000000..c6888f8df --- /dev/null +++ b/ansible/roles/build_yardstick_image/tasks/post_build.yml @@ -0,0 +1,46 @@ +# Copyright (c) 2018 Intel Corporation. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +--- +- name: convert image to image file + command: qemu-img convert -c -o compat=0.10 -O qcow2 {{ raw_imgfile }} {{ imgfile }} + +# Post build yardstick image +- group_by: + key: image_builder + +- name: remove ubuntu policy-rc.d workaround + file: + path: "{{ mountdir }}/usr/sbin/policy-rc.d" + state: absent + when: "target_os == 'Ubuntu'" + +- name: cleanup fake tmp fstab + file: + path: "{{ fake_fstab }}" + state: absent + +- mount: + name: "{{ mountdir }}/proc" + state: unmounted + +- mount: + name: "{{ mountdir }}" + state: unmounted + +- name: kpartx -dv to delete all image partition device nodes + command: kpartx -dv "{{ raw_imgfile }}" + ignore_errors: true + +- debug: + msg: "yardstick image = {{ imgfile }}" diff --git a/ansible/roles/build_yardstick_image/tasks/pre_build.yml b/ansible/roles/build_yardstick_image/tasks/pre_build.yml new file mode 100644 index 000000000..2dae38060 --- /dev/null +++ b/ansible/roles/build_yardstick_image/tasks/pre_build.yml @@ -0,0 +1,202 @@ +# Copyright (c) 2018 Intel Corporation. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +--- +- name: Group + group_by: + key: image_builder + +- package: name=parted state=present + environment: "{{ proxy_env }}" + +- package: name=kpartx state=present + environment: "{{ proxy_env }}" + +- package: name="{{ growpart_package[ansible_os_family] }}" state=present + environment: "{{ proxy_env }}" + +- set_fact: + imgfile: "{{ normal_image_file }}" + when: img_prop_item == "normal" + +- set_fact: + imgfile: "{{ nsb_image_file }}" + when: img_prop_item == "nsb" + +- set_fact: + mountdir: "{{ lookup('env', 'mountdir')|default('/mnt/yardstick', true) }}" + raw_imgfile: "{{ workspace }}/{{ raw_imgfile_basename }}" + +# cleanup non-lxd +- name: unmount all old mount points + mount: + name: "{{ item }}" + state: unmounted + with_items: + # order matters + - "{{ mountdir }}/proc" + - "{{ mountdir }}" + - "/mnt/{{ release }}" + +- name: kpartx -dv to delete all image partition device nodes + command: kpartx -dv "{{ raw_imgfile }}" + ignore_errors: true + +- name: Debug dump loop devices + command: losetup -a + ignore_errors: true + +- name: delete loop devices for image file + # use this because kpartx -dv will fail if raw_imgfile was delete + # but in theory we could have deleted file still attached to loopback device? + # use grep because of // and awk + shell: losetup -O NAME,BACK-FILE | grep "{{ raw_imgfile_basename }}" | awk '{ print $1 }' | xargs -l1 losetup -v -d + ignore_errors: true + +- name: Debug dump loop devices again + command: losetup -a + ignore_errors: true + +- name: delete {{ raw_imgfile }} + file: + path: "{{ raw_imgfile }}" + state: absent + +# common +- name: remove {{ mountdir }} + file: + path: "{{ mountdir }}" + state: absent + +# download-common +- name: remove {{ workspace }} + file: + path: "{{ workspace }}" + state: directory + +- name: "fetch {{ image_url }} and verify " + fetch_url_and_verify: + url: "{{ image_url }}" + sha256url: "{{ sha256sums_url }}" + dest: "{{ image_dest }}" + +- name: convert image to raw + command: "qemu-img convert {{ image_dest }} {{ raw_imgfile }}" + +- name: resize image to allow for more VNFs + command: "qemu-img resize -f raw {{ raw_imgfile }} +2G" + +- name: resize parition to allow for more VNFs + # use growpart because maybe it handles GPT better than parted + command: growpart {{ raw_imgfile }} 1 + +- name: create mknod devices in chroot + command: "mknod -m 0660 /dev/loop{{ item }} b 7 {{ item }}" + args: + creates: "/dev/loop{{ item }}" + with_sequence: start=0 end=9 + tags: mknod_devices + +- name: find first partition device + command: kpartx -l "{{ raw_imgfile }}" + register: kpartx_res + +- set_fact: + image_first_partition: "{{ kpartx_res.stdout_lines[0].split()[0] }}" + +- set_fact: + # assume / is the first partition + image_first_partition_device: "/dev/mapper/{{ image_first_partition }}" + +- name: use kpartx to create device nodes for the raw image loop device + # operate on the loop device to avoid /dev namespace missing devices + command: kpartx -avs "{{ raw_imgfile }}" + +- name: parted dump raw image + command: parted "{{ raw_imgfile }}" print + register: parted_res + +- debug: + var: parted_res + verbosity: 2 + +- name: use blkid to find filesystem type of first partition device + command: blkid -o value -s TYPE {{ image_first_partition_device }} + register: blkid_res + +- set_fact: + image_fs_type: "{{ blkid_res.stdout.strip() }}" + +- fail: + msg: "We only support ext4 image filesystems because we have to resize" + when: image_fs_type != "ext4" + +- name: fsck the image filesystem + command: "e2fsck -y -f {{ image_first_partition_device }}" + +- name: resize filesystem to full partition size + command: resize2fs {{ image_first_partition_device }} + +- name: fsck the image filesystem + command: "e2fsck -y -f {{ image_first_partition_device }}" + +- name: make tmp disposable fstab + command: mktemp --tmpdir fake_fstab.XXXXXXXXXX + register: mktemp_res + +- set_fact: + fake_fstab: "{{ mktemp_res.stdout.strip() }}" + +- name: mount first parition on image device + mount: + src: "{{ image_first_partition_device }}" + name: "{{ mountdir }}" + # fstype is required + fstype: "{{ image_fs_type }}" + # !!!!!!! this is required otherwise we add entries to /etc/fstab + # and prevent the system from booting + fstab: "{{ fake_fstab }}" + state: mounted + +- name: mount chroot /proc + mount: + src: none + name: "{{ mountdir }}/proc" + fstype: proc + # !!!!!!! this is required otherwise we add entries to /etc/fstab + # and prevent the system from booting + fstab: "{{ fake_fstab }}" + state: mounted + +- name: if arm copy qemu-aarch64-static into chroot + copy: + src: /usr/bin/qemu-aarch64-static + dest: "{{ mountdir }}/usr/bin" + when: img_arch == arch_arm64 + +- name: create ubuntu policy-rc.d workaround + copy: + content: "{{ '#!/bin/sh\nexit 101\n' }}" + dest: "{{ mountdir }}/usr/sbin/policy-rc.d" + mode: 0755 + when: "target_os == 'Ubuntu'" + +- name: add chroot as host + add_host: + name: "{{ mountdir }}" + groups: chroot_image,image_builder + connection: chroot + ansible_python_interpreter: /usr/bin/python3 + # set this host variable here + nameserver_ip: "{{ ansible_dns.nameservers[0] }}" + image_type: vm diff --git a/ansible/roles/build_yardstick_image/vars/main.yml b/ansible/roles/build_yardstick_image/vars/main.yml new file mode 100644 index 000000000..6728e5afb --- /dev/null +++ b/ansible/roles/build_yardstick_image/vars/main.yml @@ -0,0 +1,31 @@ +# Copyright (c) 2018 Intel Corporation. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +--- +boot_modes: + 'amd64': disk1 + 'arm64': uefi1 +boot_mode: "{{ boot_modes[YARD_IMG_ARCH] }}" +image_filename: "{{ release }}-server-cloudimg-{{ YARD_IMG_ARCH }}-{{ boot_mode }}.img" +image_path: "{{ release }}/current/{{ image_filename }}" +host: "{{ lookup('env', 'HOST')|default('cloud-images.ubuntu.com', true)}}" +image_url: "{{ lookup('env', 'IMAGE_URL')|default('https://' ~ host ~ '/' ~ image_path, true) }}" +image_dest: "{{ workspace }}/{{ image_filename }}" +sha256sums_path: "{{ release }}/current/SHA256SUMS" +sha256sums_filename: "{{ sha256sums_path|basename }}" +sha256sums_url: "{{ lookup('env', 'SHA256SUMS_URL')|default('https://' ~ host ~ '/' ~ sha256sums_path, true) }}" +workspace: "{{ lookup('env', 'workspace')|default('/tmp/workspace/yardstick', true) }}" +raw_imgfile_basename: "yardstick-{{ release }}-server.raw" +growpart_package: + RedHat: cloud-utils-growpart + Debian: cloud-guest-utils diff --git a/ansible/roles/download_dpdk/defaults/main.yml b/ansible/roles/download_dpdk/defaults/main.yml index 885eebf03..83711881b 100644 --- a/ansible/roles/download_dpdk/defaults/main.yml +++ b/ansible/roles/download_dpdk/defaults/main.yml @@ -1,5 +1,5 @@ --- -dpdk_version: "17.02.1" +dpdk_version: "17.05" dpdk_url: "http://fast.dpdk.org/rel/dpdk-{{ dpdk_version }}.tar.xz" dpdk_file: "{{ dpdk_url|basename }}" dpdk_unarchive: "{{ dpdk_file|regex_replace('[.]tar[.]xz$', '') }}" diff --git a/ansible/roles/install_civetweb/defaults/main.yml b/ansible/roles/install_civetweb/defaults/main.yml index ed5ab27f2..c97403688 100644 --- a/ansible/roles/install_civetweb/defaults/main.yml +++ b/ansible/roles/install_civetweb/defaults/main.yml @@ -15,8 +15,9 @@ civetweb_dest: "{{ clone_dest }}/civetweb" civetweb_build_dependencies: Debian: - - libjson-c-dev=0.11-4ubuntu2 - - libjson0 - - libjson0-dev +# - libjson-c-dev=0.11-4ubuntu2 +# - libjson0 +# - libjson0-dev - libssl-dev + - libjson-c-dev RedHat: diff --git a/ansible/roles/install_image_dependencies/tasks/main.yml b/ansible/roles/install_image_dependencies/tasks/main.yml index ffd30f33e..4e55339c2 100644 --- a/ansible/roles/install_image_dependencies/tasks/main.yml +++ b/ansible/roles/install_image_dependencies/tasks/main.yml @@ -19,5 +19,5 @@ action: "{{ ansible_pkg_mgr }} name={{ item }} state=latest update_cache=yes" register: pkg_mgr_results retries: "{{ pkg_mgr_retries }}" - until: pkg_mgr_results|success + until: pkg_mgr_results is success with_items: "{{ install_dependencies[ansible_os_family] }}" -- cgit 1.2.3-korg