diff --git a/releasenotes/notes/glance-image-owner-1a0fa44cce1e6ed9.yaml b/releasenotes/notes/glance-image-owner-1a0fa44cce1e6ed9.yaml new file mode 100644 index 0000000000..9640a369d1 --- /dev/null +++ b/releasenotes/notes/glance-image-owner-1a0fa44cce1e6ed9.yaml @@ -0,0 +1,6 @@ +--- +features: + - | + Allow each declarative Glance image to specify an owner project and domain. + Ownership is reconciled through the Atmosphere common image role together + with image properties and visibility. diff --git a/roles/glance/README.md b/roles/glance/README.md index 70fcbeef91..914b6d2276 100644 --- a/roles/glance/README.md +++ b/roles/glance/README.md @@ -1 +1,33 @@ # `glance` + +Images in `glance_images` can declare `owner` and `owner_domain`. The role +passes both values to `atmosphere.common.glance_image`, which resolves the +project and reconciles image ownership. Omit both keys to preserve the default +upload project. + +Use either `url`, or a digest-pinned OCI source with `oci_reference`, +`oci_path`, and `oci_sha512`. OCI artifacts are extracted and checksum-verified +by `atmosphere.common.glance_image` before upload. + +```yaml +glance_images: + - name: trusted-image + url: https://images.example.invalid/trusted-image.raw + disk_format: raw + container_format: bare + is_public: true + owner: service + owner_domain: service + properties: + os_distro: ubuntu +``` + +```yaml +glance_images: + - name: trusted-oci-image + oci_reference: docker.io/example/image@sha256: + oci_path: /images/image.qcow2 + oci_sha512: + disk_format: qcow2 + container_format: bare +``` diff --git a/roles/glance/tasks/main.yml b/roles/glance/tasks/main.yml index 19c3f9616f..81ffb377ed 100644 --- a/roles/glance/tasks/main.yml +++ b/roles/glance/tasks/main.yml @@ -42,12 +42,19 @@ loop: "{{ glance_images }}" vars: glance_image_name: "{{ item.name }}" - glance_image_url: "{{ item.url }}" + glance_image_url: "{{ item.url | default('') }}" + glance_image_oci_reference: "{{ item.oci_reference | default('') }}" + glance_image_oci_path: "{{ item.oci_path | default('') }}" + glance_image_oci_sha512: "{{ item.oci_sha512 | default('') }}" + glance_image_oci_architecture: "{{ item.oci_architecture | default('amd64') }}" + glance_image_oci_authfile: "{{ item.oci_authfile | default('') }}" 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({}) }}" + glance_image_owner: "{{ item.owner | default(omit) }}" + glance_image_owner_domain: "{{ item.owner_domain | 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/vars_test.go b/roles/glance/vars_test.go index 65821917ad..fd920e0aff 100644 --- a/roles/glance/vars_test.go +++ b/roles/glance/vars_test.go @@ -16,6 +16,9 @@ var ( //go:embed vars/main.yml varsFile []byte vars Vars + + //go:embed tasks/main.yml + tasksFile []byte ) type Vars struct { @@ -38,8 +41,8 @@ func TestHelmValues(t *testing.T) { // for the actual template. Like: // {{ tuple "heat_api" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" }} vars.HelmValues.Pod.PriorityClass = map[string]string{ - "db_sync": "high-priority", - "glance_api": "high-priority", + "db_sync": "high-priority", + "glance_api": "high-priority", "glance_tests": "high-priority", } // (rlin): Before you add any new runtime class here. @@ -48,8 +51,8 @@ func TestHelmValues(t *testing.T) { // for the actual template. Like: // {{ tuple "heat_api" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" }} vars.HelmValues.Pod.RuntimeClass = map[string]string{ - "db_sync": "kata-clh", - "glance_api": "kata-clh", + "db_sync": "kata-clh", + "glance_api": "kata-clh", "glance_tests": "kata-clh", } vals, err := openstack_helm.CoalescedHelmValues("../../charts/glance", &vars.HelmValues) @@ -59,3 +62,17 @@ func TestHelmValues(t *testing.T) { testutils.TestAllPodsHaveRuntimeClass(t, vals) testutils.TestAllPodsHavePriorityClass(t, vals) } + +func TestImageConfigurationIsForwarded(t *testing.T) { + for _, expected := range []string{ + `glance_image_oci_reference: "{{ item.oci_reference | default('') }}"`, + `glance_image_oci_path: "{{ item.oci_path | default('') }}"`, + `glance_image_oci_sha512: "{{ item.oci_sha512 | default('') }}"`, + `glance_image_oci_architecture: "{{ item.oci_architecture | default('amd64') }}"`, + `glance_image_oci_authfile: "{{ item.oci_authfile | default('') }}"`, + `glance_image_owner: "{{ item.owner | default(omit) }}"`, + `glance_image_owner_domain: "{{ item.owner_domain | default(omit) }}"`, + } { + require.Contains(t, string(tasksFile), expected) + } +}