fix: add image conversion
diff --git a/molecule/default/group_vars/all/molecule.yml b/molecule/default/group_vars/all/molecule.yml
index 7b122e0..db8ff71 100644
--- a/molecule/default/group_vars/all/molecule.yml
+++ b/molecule/default/group_vars/all/molecule.yml
@@ -2,8 +2,7 @@
glance_images:
- name: cirros
- source_url: https://object-storage.public.mtl1.vexxhost.net/swift/v1/a91f106f55e64246babde7402c21b87a/cirros/
- image_file: cirros-0.6.0-x86_64-disk.raw
+ url: http://download.cirros-cloud.net/0.6.1/cirros-0.6.1-x86_64-disk.img
min_disk: 1
disk_format: raw
container_format: bare
diff --git a/roles/glance/tasks/main.yml b/roles/glance/tasks/main.yml
index 92b9f14..f3ff7d5 100644
--- a/roles/glance/tasks/main.yml
+++ b/roles/glance/tasks/main.yml
@@ -54,46 +54,17 @@
openstack_helm_ingress_annotations: "{{ _glance_ingress_annotations | combine(glance_ingress_annotations) }}"
- name: Create images
- when: glance_images | length > 0
- block:
- - name: Wait until image service ready
- kubernetes.core.k8s_info:
- api_version: apps/v1
- kind: Deployment
- name: glance-api
- namespace: openstack
- wait_sleep: 10
- wait_timeout: 600
- wait: true
- wait_condition:
- type: Available
- status: true
-
- - name: Download images
- ansible.builtin.get_url:
- url: "{{ item.source_url | regex_replace('\\/$', '') }}/{{ item.image_file }}"
- dest: "/tmp/{{ item.image_file }}"
- mode: "0600"
- loop: "{{ glance_images }}"
-
- - name: Upload images
- openstack.cloud.image:
- cloud: atmosphere
- name: "{{ item.name }}"
- state: present
- filename: "/tmp/{{ item.image_file }}"
- min_disk: "{{ item.min_disk | default(omit) }}"
- min_ram: "{{ item.min_ram | default(omit) }}"
- container_format: "{{ item.container_format | default(omit) }}"
- disk_format: "{{ item.disk_format | default(omit) }}"
- properties: "{{ item.properties | default(omit) }}"
- kernel: "{{ item.kernel | default(omit) }}"
- ramdisk: "{{ item.ramdisk | default(omit) }}"
- is_public: "{{ item.is_public | default(omit) }}"
- loop: "{{ glance_images }}"
- # NOTE(mnaser): This often fails since the SSL certificates are not
- # ready yet. We need to wait for them to be ready.
- retries: 60
- delay: 5
- register: _result
- until: _result is not failed
+ ansible.builtin.include_role:
+ name: glance_image
+ loop: "{{ glance_images }}"
+ vars:
+ glance_image_name: "{{ item.name }}"
+ glance_image_url: "{{ item.url }}"
+ glance_image_min_disk: "{{ item.min_disk | default(omit) }}"
+ glance_image_min_ram: "{{ item.min_ram | default(omit) }}"
+ glance_image_container_format: "{{ item.container_format | default(omit) }}"
+ glance_image_disk_format: "{{ item.disk_format | default(omit) }}"
+ glance_image_properties: "{{ item.properties | default(omit) }}"
+ glance_image_kernel: "{{ item.kernel | default(omit) }}"
+ glance_image_ramdisk: "{{ item.ramdisk | default(omit) }}"
+ glance_image_is_public: "{{ item.is_public | default(omit) }}"
diff --git a/roles/glance_image/README.md b/roles/glance_image/README.md
new file mode 100644
index 0000000..f014107
--- /dev/null
+++ b/roles/glance_image/README.md
@@ -0,0 +1 @@
+# `glance_image`
diff --git a/roles/glance_image/meta/main.yml b/roles/glance_image/meta/main.yml
new file mode 100644
index 0000000..1fbcf19
--- /dev/null
+++ b/roles/glance_image/meta/main.yml
@@ -0,0 +1,29 @@
+# Copyright (c) 2022 VEXXHOST, Inc.
+#
+# 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.
+
+galaxy_info:
+ author: VEXXHOST, Inc.
+ description: Ansible role for managing OpenStack Glance images
+ license: Apache-2.0
+ min_ansible_version: 5.5.0
+ standalone: false
+ platforms:
+ - name: Ubuntu
+ versions:
+ - focal
+
+dependencies:
+ - role: defaults
+ - role: qemu_utils
+ - role: openstacksdk
diff --git a/roles/glance_image/tasks/main.yml b/roles/glance_image/tasks/main.yml
new file mode 100644
index 0000000..d1c0486
--- /dev/null
+++ b/roles/glance_image/tasks/main.yml
@@ -0,0 +1,91 @@
+# Copyright (c) 2023 VEXXHOST, Inc.
+#
+# 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: Check if image exists
+ run_once: true
+ openstack.cloud.image_info:
+ cloud: atmosphere
+ image: "{{ glance_image_name }}"
+ register: _image_info
+
+- name: Download image and upload into Glance
+ run_once: true
+ when: _image_info.openstack_image == None
+ block:
+ - name: Generate temporary work directory
+ ansible.builtin.tempfile:
+ state: directory
+ register: _workdir
+
+ - name: Download image
+ ansible.builtin.get_url:
+ url: "{{ glance_image_url }}"
+ dest: "{{ _workdir.path }}/{{ glance_image_url | basename }}"
+ mode: 0600
+ register: _get_url
+
+ - name: Get image format
+ changed_when: false
+ ansible.builtin.shell: |
+ set -o pipefail
+ qemu-img info {{ _get_url.dest }} | grep -i "file format" | awk '{ print $3 }'
+ args:
+ executable: /bin/bash
+ register: _image_format
+
+ - name: Convert file to target disk format
+ when: _image_format.stdout != glance_image_disk_format
+ ansible.builtin.command:
+ qemu-img convert -O {{ glance_image_disk_format }} {{ _get_url.dest }} {{ _get_url.dest }}.converted
+
+ - name: Wait until image service ready
+ kubernetes.core.k8s_info:
+ api_version: apps/v1
+ kind: Deployment
+ name: glance-api
+ namespace: openstack
+ wait_sleep: 1
+ wait_timeout: 600
+ wait: true
+ wait_condition:
+ type: Available
+ status: true
+
+ - name: Upload image into Glance
+ openstack.cloud.image:
+ cloud: atmosphere
+ name: "{{ glance_image_name }}"
+ filename: "{{ _get_url.dest }}{% if _image_format.stdout != glance_image_disk_format %}.converted{% endif %}"
+ min_disk: "{{ glance_image_min_disk | default(omit) }}"
+ min_ram: "{{ glance_image_min_ram | default(omit) }}"
+ container_format: "{{ glance_image_container_format | default(omit) }}"
+ disk_format: "{{ glance_image_disk_format | default(omit) }}"
+ properties: "{{ glance_image_properties | default(omit) }}"
+ kernel: "{{ glance_image_kernel | default(omit) }}"
+ ramdisk: "{{ glance_image_ramdisk | default(omit) }}"
+ is_public: "{{ glance_image_is_public | default(omit) }}"
+ tags: "{{ glance_image_tags | default(omit) }}"
+ wait: true
+ timeout: 600
+ # NOTE(mnaser): This often fails since the SSL certificates are not
+ # ready yet. We need to wait for them to be ready.
+ retries: 60
+ delay: 5
+ register: _result
+ until: _result is not failed
+ always:
+ - name: Remove work directory
+ ansible.builtin.file:
+ path: "{{ _workdir.path }}"
+ state: absent
diff --git a/roles/magnum/defaults/main.yml b/roles/magnum/defaults/main.yml
index f4cc1d4..35ba3ae 100644
--- a/roles/magnum/defaults/main.yml
+++ b/roles/magnum/defaults/main.yml
@@ -24,19 +24,12 @@
magnum_registry_ingress_annotations: {}
# List of images to load into OpenStack for Magnum
+magnum_image_container_format: bare
+magnum_image_disk_format: raw
magnum_images:
- name: ubuntu-2004-v1.23.13
- source_url: https://object-storage.public.mtl1.vexxhost.net/swift/v1/a91f106f55e64246babde7402c21b87a/magnum-capi/
- image_file: ubuntu-2004-v1.23.13.qcow2
- disk_format: qcow2
- container_format: bare
+ url: https://object-storage.public.mtl1.vexxhost.net/swift/v1/a91f106f55e64246babde7402c21b87a/magnum-capi/ubuntu-2004-v1.23.13.qcow2
- name: ubuntu-2004-v1.24.7
- source_url: https://object-storage.public.mtl1.vexxhost.net/swift/v1/a91f106f55e64246babde7402c21b87a/magnum-capi/
- image_file: ubuntu-2004-v1.24.7.qcow2
- disk_format: qcow2
- container_format: bare
+ url: https://object-storage.public.mtl1.vexxhost.net/swift/v1/a91f106f55e64246babde7402c21b87a/magnum-capi/ubuntu-2004-v1.24.7.qcow2
- name: ubuntu-2004-v1.25.3
- source_url: https://object-storage.public.mtl1.vexxhost.net/swift/v1/a91f106f55e64246babde7402c21b87a/magnum-capi/
- image_file: ubuntu-2004-v1.25.3.qcow2
- disk_format: qcow2
- container_format: bare
+ url: https://object-storage.public.mtl1.vexxhost.net/swift/v1/a91f106f55e64246babde7402c21b87a/magnum-capi/ubuntu-2004-v1.25.3.qcow2
diff --git a/roles/magnum/tasks/main.yml b/roles/magnum/tasks/main.yml
index 201aca5..ea6b181 100644
--- a/roles/magnum/tasks/main.yml
+++ b/roles/magnum/tasks/main.yml
@@ -197,43 +197,12 @@
openstack_helm_ingress_service_port: 5000
openstack_helm_ingress_annotations: "{{ _magnum_registry_ingress_annotations | combine(magnum_registry_ingress_annotations) }}"
-- name: Create k8s images
- when: magnum_images | length > 0
- block:
- - name: Wait until image service ready
- kubernetes.core.k8s_info:
- api_version: apps/v1
- kind: Deployment
- name: glance-api
- namespace: openstack
- wait_sleep: 10
- wait_timeout: 600
- wait: true
- wait_condition:
- type: Available
- status: true
-
- - name: Download images
- ansible.builtin.get_url:
- url: "{{ item.source_url | regex_replace('\\/$', '') }}/{{ item.image_file }}"
- dest: "/tmp/{{ item.image_file }}"
- mode: "0600"
- loop: "{{ magnum_images }}"
-
- - name: Upload images
- openstack.cloud.image:
- cloud: atmosphere
- name: "{{ item.name }}"
- state: present
- filename: "/tmp/{{ item.image_file }}"
- container_format: "{{ item.container_format | default(omit) }}"
- disk_format: "{{ item.disk_format | default(omit) }}"
- properties:
- os_distro: ubuntu-focal
- loop: "{{ magnum_images }}"
- # NOTE(mnaser): This often fails since the SSL certificates are not
- # ready yet. We need to wait for them to be ready.
- retries: 60
- delay: 5
- register: _result
- until: _result is not failed
+- name: Upload images
+ ansible.builtin.include_role:
+ name: glance_image
+ loop: "{{ magnum_images }}"
+ vars:
+ glance_image_name: "{{ item.name }}"
+ glance_image_url: "{{ item.url }}"
+ glance_image_container_format: "{{ magnum_image_container_format }}"
+ glance_image_disk_format: "{{ magnum_image_disk_format }}"
diff --git a/roles/octavia/defaults/main.yml b/roles/octavia/defaults/main.yml
index 7aa9366..b3e588b 100644
--- a/roles/octavia/defaults/main.yml
+++ b/roles/octavia/defaults/main.yml
@@ -29,4 +29,9 @@
octavia_management_subnet_cidr: "172.24.0.0/22"
# Octavia amphora image url
-octavia_amphora_image_url: "https://tarballs.opendev.org/openstack/octavia/test-images/test-only-amphora-x64-haproxy-ubuntu-focal.qcow2"
+octavia_amphora_image_name: amphora-x64-haproxy
+octavia_amphora_image_url: https://tarballs.opendev.org/openstack/octavia/test-images/test-only-amphora-x64-haproxy-ubuntu-focal.qcow2
+octavia_amphora_image_container_format: bare
+octavia_amphora_image_disk_format: raw
+octavia_amphora_image_tags:
+ - amphora
diff --git a/roles/octavia/tasks/main.yml b/roles/octavia/tasks/main.yml
index 7ccbd0a..a28dede 100644
--- a/roles/octavia/tasks/main.yml
+++ b/roles/octavia/tasks/main.yml
@@ -133,21 +133,20 @@
is_public: false
register: _octavia_amphora_flavor
-- name: Download amphora image
- ansible.builtin.get_url:
- url: "{{ octavia_amphora_image_url }}"
- dest: "/tmp/{{ octavia_amphora_image_url | basename }}"
- mode: 0644
+- name: Upload Amphora image
+ ansible.builtin.include_role:
+ name: glance_image
+ vars:
+ glance_image_name: "{{ octavia_amphora_image_name }}"
+ glance_image_url: "{{ octavia_amphora_image_url }}"
+ glance_image_container_format: "{{ octavia_amphora_image_container_format }}"
+ glance_image_disk_format: "{{ octavia_amphora_image_disk_format }}"
+ glance_image_tags: "{{ octavia_amphora_image_tags }}"
-- name: Upload images
- openstack.cloud.image:
+- name: Get Amphora image information
+ openstack.cloud.image_info:
cloud: atmosphere
- name: "amphora-x64-haproxy"
- filename: "/tmp/{{ octavia_amphora_image_url | basename }}"
- container_format: "bare"
- disk_format: "qcow2"
- tags:
- - "amphora"
+ image: "{{ octavia_amphora_image_name }}"
register: _octavia_amphora_image
- name: Create CAs & Issuers
diff --git a/roles/octavia/vars/main.yml b/roles/octavia/vars/main.yml
index af3c061..be4639f 100644
--- a/roles/octavia/vars/main.yml
+++ b/roles/octavia/vars/main.yml
@@ -92,7 +92,7 @@
controller_worker:
amp_boot_network_list: "{{ _octavia_management_network.id }}"
amp_flavor_id: "{{ _octavia_amphora_flavor.id }}"
- amp_image_owner_id: "{{ _octavia_amphora_image.image.owner }}"
+ amp_image_owner_id: "{{ _octavia_amphora_image.openstack_image.owner }}"
amp_secgroup_list: "{{ _octavia_amphora_sg.id }}"
amp_ssh_key_name: null
client_ca: /etc/octavia/certs/client/ca.crt
diff --git a/roles/qemu_utils/README.md b/roles/qemu_utils/README.md
new file mode 100644
index 0000000..f78bb7a
--- /dev/null
+++ b/roles/qemu_utils/README.md
@@ -0,0 +1 @@
+# `qemu-utils`
diff --git a/roles/qemu_utils/meta/main.yml b/roles/qemu_utils/meta/main.yml
new file mode 100644
index 0000000..3558d4e
--- /dev/null
+++ b/roles/qemu_utils/meta/main.yml
@@ -0,0 +1,24 @@
+# Copyright (c) 2022 VEXXHOST, Inc.
+#
+# 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.
+
+galaxy_info:
+ author: VEXXHOST, Inc.
+ description: Install QEMU utilities
+ license: Apache-2.0
+ min_ansible_version: 5.5.0
+ standalone: false
+ platforms:
+ - name: Ubuntu
+ versions:
+ - focal
diff --git a/roles/qemu_utils/tasks/main.yml b/roles/qemu_utils/tasks/main.yml
new file mode 100644
index 0000000..ac3b65f
--- /dev/null
+++ b/roles/qemu_utils/tasks/main.yml
@@ -0,0 +1,18 @@
+# Copyright (c) 2023 VEXXHOST, Inc.
+#
+# 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: Install packages
+ ansible.builtin.apt:
+ name: qemu-utils
+ state: present