Added tempest images

Sem-Ver: feature
Change-Id: I9fea644a8fc021cb21bd7ff14af2d581e1d193ee
diff --git a/images/master.yml b/images/master.yml
new file mode 100644
index 0000000..1801720
--- /dev/null
+++ b/images/master.yml
@@ -0,0 +1,26 @@
+# 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.
+
+registry: us-docker.pkg.dev/vexxhost-infra/openstack
+
+projects:
+  tempest:
+    branch: master
+    revision: 44dac69eb77d78a0de8e68e63617099249345578
+    tag: 30.1.0-0
+    pip_packages:
+      - keystone-tempest-plugin
+      - cinder-tempest-plugin
+      - neutron-tempest-plugin
+      - heat-tempest-plugin
\ No newline at end of file
diff --git a/releasenotes/notes/add-tempest-images-07a34f3e521ffee5.yaml b/releasenotes/notes/add-tempest-images-07a34f3e521ffee5.yaml
new file mode 100644
index 0000000..7cd427e
--- /dev/null
+++ b/releasenotes/notes/add-tempest-images-07a34f3e521ffee5.yaml
@@ -0,0 +1,3 @@
+---
+features:
+  - Added tempest images built from the master branch.
diff --git a/zuul.d/images-master.yaml b/zuul.d/images-master.yaml
new file mode 100644
index 0000000..3e9346d
--- /dev/null
+++ b/zuul.d/images-master.yaml
@@ -0,0 +1,99 @@
+# 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.
+
+- job:
+    name: ansible-collection-atmosphere-build-images-master
+    parent: ansible-collection-atmosphere-build-images
+    abstract: true
+    dependencies: &image_dependencies
+      - name: ansible-collection-atmosphere-buildset-registry
+        soft: false
+      - name: ansible-collection-atmosphere-merge-wheels-master
+        soft: true
+    requires: &image_requires
+      - ansible-collection-atmosphere-wheels-master
+    files: &image_files
+      - images/master.yml
+    vars: &image_vars
+      openstack_release: master
+
+- job:
+    name: ansible-collection-atmosphere-build-images-master-amd64
+    parent: ansible-collection-atmosphere-build-images-master
+    nodeset: ubuntu-focal
+
+- job:
+    name: ansible-collection-atmosphere-build-images-master-aarch64
+    parent: ansible-collection-atmosphere-build-images-master
+    nodeset: ubuntu-focal-arm64
+
+- job:
+    name: ansible-collection-atmosphere-build-images-manifest-master
+    parent: ansible-collection-atmosphere-build-images-manifest
+    dependencies:
+      - name: ansible-collection-atmosphere-buildset-registry
+        soft: false
+      - name: ansible-collection-atmosphere-build-images-master-amd64
+        soft: false
+      - name: ansible-collection-atmosphere-build-images-master-aarch64
+        soft: false
+    files: *image_files
+    vars: &manifest_vars
+      openstack_release: master
+
+
+- job:
+    name: ansible-collection-atmosphere-upload-images-master
+    parent: ansible-collection-atmosphere-upload-images
+    abstract: true
+    dependencies: *image_dependencies
+    requires: *image_requires
+    files: *image_files
+    vars: *image_vars
+
+- job:
+    name: ansible-collection-atmosphere-upload-images-master-amd64
+    parent: ansible-collection-atmosphere-upload-images-master
+    nodeset: ubuntu-focal
+
+- job:
+    name: ansible-collection-atmosphere-upload-images-master-aarch64
+    parent: ansible-collection-atmosphere-upload-images-master
+    nodeset: ubuntu-focal-arm64
+
+- job:
+    name: ansible-collection-atmosphere-upload-images-manifest-master
+    parent: ansible-collection-atmosphere-upload-images-manifest
+    dependencies:
+      - name: ansible-collection-atmosphere-buildset-registry
+        soft: false
+      - name: ansible-collection-atmosphere-upload-images-master-amd64
+        soft: false
+      - name: ansible-collection-atmosphere-upload-images-master-aarch64
+        soft: false
+    files: *image_files
+    vars: *manifest_vars
+
+
+- project:
+    check:
+      jobs:
+        - ansible-collection-atmosphere-build-images-master-amd64
+        - ansible-collection-atmosphere-build-images-master-aarch64
+        - ansible-collection-atmosphere-build-images-manifest-master
+    gate:
+      jobs:
+        - ansible-collection-atmosphere-upload-images-master-amd64
+        - ansible-collection-atmosphere-upload-images-master-aarch64
+        - ansible-collection-atmosphere-upload-images-manifest-master
\ No newline at end of file
diff --git a/zuul.d/images.yaml b/zuul.d/images.yaml
new file mode 100644
index 0000000..c487221
--- /dev/null
+++ b/zuul.d/images.yaml
@@ -0,0 +1,56 @@
+# 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.
+
+- job:
+    name: ansible-collection-atmosphere-buildset-registry
+    parent: opendev-buildset-registry
+
+- job:
+    name: ansible-collection-atmosphere-build-images
+    parent: opendev-build-docker-image
+    abstract: true
+    required-projects:
+      - openstack/loci
+    pre-run:
+      - zuul.d/playbooks/ansible-collection-atmosphere-build-images/pre-run.yml
+    run:
+      - zuul.d/playbooks/ansible-collection-atmosphere-build-images/run.yml
+
+- job:
+    name: ansible-collection-atmosphere-upload-images
+    parent: ansible-collection-atmosphere-build-images
+    abstract: true
+    secrets:
+      name: docker_credentials
+      secret: gar-credentials
+      pass-to-parent: true
+
+- job:
+    name: ansible-collection-atmosphere-build-images-manifest
+    pre-run:
+      - zuul.d/playbooks/ansible-collection-atmosphere-build-images-manifest/pre-run.yml
+    run:
+      - zuul.d/playbooks/ansible-collection-atmosphere-build-images-manifest/run.yml
+
+- job:
+    name: ansible-collection-atmosphere-upload-images-manifest
+    parent: ansible-collection-atmosphere-build-images-manifest
+
+- project:
+    check:
+      jobs:
+        - ansible-collection-atmosphere-buildset-registry
+    gate:
+      jobs:
+        - ansible-collection-atmosphere-buildset-registry
diff --git a/zuul.d/playbooks/ansible-collection-atmosphere-build-images-manifest/pre-run.yml b/zuul.d/playbooks/ansible-collection-atmosphere-build-images-manifest/pre-run.yml
new file mode 100644
index 0000000..f390d11
--- /dev/null
+++ b/zuul.d/playbooks/ansible-collection-atmosphere-build-images-manifest/pre-run.yml
@@ -0,0 +1,18 @@
+# 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.
+
+- hosts: all
+  roles:
+    - ensure-podman
+    - use-buildset-registry
\ No newline at end of file
diff --git a/zuul.d/playbooks/ansible-collection-atmosphere-build-images-manifest/run.yml b/zuul.d/playbooks/ansible-collection-atmosphere-build-images-manifest/run.yml
new file mode 100644
index 0000000..2ded2c2
--- /dev/null
+++ b/zuul.d/playbooks/ansible-collection-atmosphere-build-images-manifest/run.yml
@@ -0,0 +1,40 @@
+# 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.
+
+- hosts: all
+  tasks:
+    - name: Include manifest file with all the image information
+      ansible.builtin.include_vars:
+        file: "../../../images/{{ openstack_release }}.yml"
+        name: image_manifest
+
+    - name: Create manifest for every project built
+      command:
+        podman manifest create {{ item | basename }}:{{ image_manifest['projects'][item.rsplit('/')[-1]]['tag'] }}
+      loop: "{{ zuul.artifacts | selectattr('metadata.repository', 'defined') | map(attribute='metadata.repository') | sort | unique }}"
+
+    - name: Add image to their manifest
+      command:
+        podman manifest add
+          --arch {{ (item.metadata.arch == "aarch64") | ternary("arm64", "amd64") }}
+          {{ item.metadata.project }}:{{ image_manifest['projects'][item.metadata.project]['tag'] }}
+          {{ item.url }}
+      loop: "{{ zuul.artifacts | selectattr('metadata.type', 'defined') | selectattr('metadata.type', 'equalto', 'image') | list }}"
+
+    - name: Push manifests to buildset registry
+      command:
+        podman manifest push
+          {{ item | basename }}:{{ image_manifest['projects'][item.rsplit('/')[-1]]['tag'] }}
+          {{ item }}:{{ image_manifest['projects'][item.rsplit('/')[-1]]['tag'] }}
+      loop: "{{ zuul.artifacts | selectattr('metadata.repository', 'defined') | map(attribute='metadata.repository') | sort | unique }}"
diff --git a/zuul.d/playbooks/ansible-collection-atmosphere-build-images/pre-run.yml b/zuul.d/playbooks/ansible-collection-atmosphere-build-images/pre-run.yml
new file mode 100644
index 0000000..1032b4c
--- /dev/null
+++ b/zuul.d/playbooks/ansible-collection-atmosphere-build-images/pre-run.yml
@@ -0,0 +1,17 @@
+# 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.
+
+- hosts: all
+  roles:
+    - ensure-pip
diff --git a/zuul.d/playbooks/ansible-collection-atmosphere-build-images/run.yml b/zuul.d/playbooks/ansible-collection-atmosphere-build-images/run.yml
new file mode 100644
index 0000000..7f879cf
--- /dev/null
+++ b/zuul.d/playbooks/ansible-collection-atmosphere-build-images/run.yml
@@ -0,0 +1,130 @@
+# 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.
+
+- hosts: all
+  tasks:
+    - name: Include manifest file with all the image information
+      ansible.builtin.include_vars:
+        file: "../../../images/{{ openstack_release }}.yml"
+        name: image_manifest
+
+    - name: Check if the image is already built
+      ansible.builtin.command:
+        docker manifest inspect {{ image_manifest.registry }}/{{ item.key }}:{{ item.value.tag }}
+      register: _docker_manifest_inspect
+      with_dict: "{{ image_manifest.projects }}"
+      loop_control:
+        label: "{{ item.key }}"
+      # NOTE(mnaser): We want to mark the task as "changed" if we have to do
+      #               any work (i.e if the image is not already built).
+      failed_when: false
+      changed_when: _docker_manifest_inspect.rc != 0
+
+    - name: Fail the job if all the images are already built
+      ansible.builtin.fail:
+        msg: All the images are already built, did you forget to bump the tag?
+      when: _docker_manifest_inspect is not changed
+
+    - name: Generate a fact with the list of projects to be built
+      ansible.builtin.set_fact:
+        images_to_build: "{{ _docker_manifest_inspect.results | select('changed') | list | map(attribute='item.key') | list }}"
+
+    - name: Clone projects that need to be built
+      ansible.builtin.git:
+        repo: "https://opendev.org/openstack/{{ item }}"
+        dest: "/tmp/{{ item }}"
+        version: "{{ image_manifest['projects'][item]['revision'] }}"
+      loop: "{{ images_to_build }}"
+
+    - name: Generate the PBR version for the projects
+      ansible.builtin.shell:
+        /usr/bin/python3 setup.py --version
+      args:
+        chdir: "/tmp/{{ item }}"
+      environment:
+        PYTHONWARNINGS: "ignore:Unverified HTTPS request"
+      register: _pbr_version
+      loop: "{{ images_to_build }}"
+
+    - name: Assert that the PBR version exists in the tag
+      ansible.builtin.assert:
+        that: item.stdout.strip() in image_manifest['projects'][item.item].tag
+      loop: "{{ _pbr_version.results }}"
+      loop_control:
+        label: "{{ item.item }}"
+
+    - name: Set fact for wheels tarball from artifacts
+      ansible.builtin.set_fact:
+        wheels_path: "{{ item.url }}"
+      loop: "{{ (zuul.artifacts | default([])) | selectattr('metadata.type', 'defined') | selectattr('metadata.type', 'equalto', 'wheels') | list }}"
+
+    - name: Set the fact for wheels path to default if none is detected
+      ansible.builtin.set_fact:
+        wheels_path: "https://tarballs.opendev.org/vexxhost/ansible-collection-atmosphere/ansible-collection-atmosphere-wheels-{{ openstack_release }}-master.tar.gz"
+      when: wheels_path is not defined
+
+    - name: Build the images
+      ansible.builtin.include_role:
+        name: build-docker-image
+      register: _build_docker_image
+      loop: "{{ images_to_build }}"
+      vars:
+        zuul_work_dir: "{{ zuul.projects['opendev.org/openstack/loci'].src_dir }}"
+        docker_registry: "{{ image_manifest.registry }}"
+        docker_images:
+          - context: .
+            repository: "{{ item }}"
+            tags:
+              - "{{ image_manifest['projects'][item]['tag'] }}-{{ ansible_architecture }}"
+            build_args:
+              # TODO(mnaser): build base image
+              - FROM="ubuntu:focal"
+              - PROJECT="{{ item }}"
+              - PROJECT_REF="{{ image_manifest['projects'][item]['revision'] }}"
+              - PROJECT_RELEASE="{{ openstack_release }}"
+              - WHEELS="{{ wheels_path }}"
+              - PROFILES="{{ image_manifest['projects'][item].get('profies', []) | join(' ') }}"
+              - PIP_PACKAGES="{{ image_manifest['projects'][item].get('pip_packages', []) | join(' ') }}"
+              - DIST_PACKAGES="{{ image_manifest['projects'][item].get('dist_packages', []) | join(' ') }}"
+
+    - name: Upload the images
+      ansible.builtin.include_role:
+        name: upload-docker-image
+      register: _build_docker_image
+      when: zuul.job is search("upload")
+      loop: "{{ images_to_build }}"
+      vars:
+        zuul_work_dir: "{{ zuul.projects['opendev.org/openstack/loci'].src_dir }}"
+        docker_registry: "{{ image_manifest.registry }}"
+        docker_images:
+          - context: .
+            repository: "{{ item }}"
+            tags:
+              - "{{ image_manifest['projects'][item]['tag'] }}-{{ ansible_architecture }}"
+
+    - name: Return artifacts to Zuul
+      zuul_return:
+        data:
+          zuul:
+            artifacts:
+              - name: "{{ item }} ({{ ansible_architecture }})"
+                url: "docker://{{ _docker_registry }}/{{ item }}:{{ image_manifest['projects'][item]['tag'] }}-{{ ansible_architecture }}"
+                metadata:
+                  type: image
+                  repository: "docker://{{ _docker_registry }}/{{ item }}"
+                  project: "{{ item }}"
+                  arch: "{{ ansible_architecture }}"
+      vars:
+        _docker_registry: "{{ (docker_registry is defined) | ternary(docker_registry, 'zuul-jobs.buildset-registry:5000') }}"
+      loop: "{{ _build_docker_image.results | map(attribute='item') | list }}"
diff --git a/zuul.d/secrets.yaml b/zuul.d/secrets.yaml
new file mode 100644
index 0000000..348b2ab
--- /dev/null
+++ b/zuul.d/secrets.yaml
@@ -0,0 +1,89 @@
+# 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.
+
+- secret:
+    name: gar-credentials
+    data:
+      username: _json_key_base64
+      password: !encrypted/pkcs1-oaep
+        - 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
\ No newline at end of file