Skip to content

Commit 4cbdef9

Browse files
garloffmbuechsedepressiveRobot
authored
Add os_purpose field. (#970)
Also add a link to OpenStack specs for os_distro and explain why we need it. This is patch 1 from several. It adds this os_purpose field as *recommended*. As it does not break certification, this can be done in the existing v1 of the scs-0102 standard. I suggest we discuss this one first until we are aligned. In parallel, I'd like to prepare a blog article that serves as user guide how to select images in a portable way without relying on the name. We can reference it in tne implementation notes. We should also enhance the image-manager input to carry this field soon. In a future patch, we create a v2 of scs-0102 which *requires* the os_purpose field. The naming in scs-0102 is already a recommendation only, so that can remain. scs-0104 will need a new version then, as it does use the recommended names as mandatory for the mandatory images. Signed-off-by: Kurt Garloff <[email protected]> Signed-off-by: Marvin Frommhold <[email protected]> Signed-off-by: Matthias Büchse <[email protected]> Co-authored-by: Matthias Büchse <[email protected]> Co-authored-by: Marvin Frommhold <[email protected]>
1 parent 9dadf5a commit 4cbdef9

File tree

3 files changed

+62
-14
lines changed

3 files changed

+62
-14
lines changed

Standards/scs-0102-v1-image-metadata.md

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ status: Stable
66
track: IaaS
77
replaces: Image-Metadata-Spec.md
88
description: |
9-
The SCS-0102 Image Metadata Standard outlines how to categorize and manage metadata for cloud-based operating
9+
This is version 1.1 of the SCS-0102 Image Metadata Standard.
10+
It outlines how to categorize and manage metadata for cloud-based operating
1011
system images to ensure usability and clarity. The standard encompasses naming conventions, technical requirements,
1112
image handling protocols including updating and origin, and licensing/support details. These guidelines ensure
1213
that users can understand, access, and utilize OS images effectively, with clear information on features, updates,
@@ -65,14 +66,51 @@ The following property is recommended:
6566

6667
- `hypervisor_type`
6768

69+
The values for `architecture` and `os_distro` and `hypervisor_type` (the latter only if specified) values
70+
must follow the [OpenStack specifications](https://docs.openstack.org/glance/2025.1/admin/useful-image-properties.html).
71+
The `os_version` string should be numeric if the distribution uses numbers, the pair `os_distro` `os_version` should
72+
for example be `ubuntu` `24.04` for Ubuntu Noble Numbat 24.04[.x] LTS.
73+
74+
To allow the distinction between general purpose images (which should come from upstream with at most some
75+
targeted adjustments as required by the cloud such as e.g. drivers) and images that are purpose-built, we
76+
recommend an additional field:
77+
78+
- `os_purpose`
79+
80+
The following values are allowed
81+
82+
| `os_purpose` value | Intention |
83+
|--------------------|-----------------------------------------------------------|
84+
| `generic` | A general purpose image, (mostly) vanilla from upstream |
85+
| `minimal` | A much more barebones general purpose image |
86+
| `k8snode` | Node image built for k8s with CRI and kubelet |
87+
| `gpu` | Image with GPU drivers e.g. for HPC or AI |
88+
| `network` | Network appliance (firewall, router, loadbalancer, ...) |
89+
| `custom` | None of the above |
90+
91+
Note that no other values are currently allowed and `custom` should be used in case
92+
of doubt. Talk to the SCS standardization bodies if you'd like to see this list extended which is
93+
likely the case if you fall back to `custom`.
94+
95+
The usage of standardized `os_distro`, `os_version`, `architecture`, and `os_purpose` help cloud users to create
96+
automation that works across clouds without requiring image names to be standardized.
97+
98+
_Uniqueness requirement_: whenever there are two images that have `os_hidden=False`, `visibility=public`,
99+
and that coincide in all three fields `os_distro`, `os_version`, and `architecture`, then only one of them may
100+
have `os_purpose=generic`. In other words, users who search visible public images for a generic OS
101+
of a certain distro, version, and architecture will not get more than one result.
102+
103+
Note: Expect this field to become mandatory in v2 of this standard sooner rather than later.
104+
68105
The following further properties are recommended (if the features are supported):
69106

70107
- `hw_rng_model`
71108
- `os_secure_boot`, `hw_firmware_type`
72109
- `hw_watchdog_action`, `hw_mem_encryption`, `hw_pmu`, `hw_video_ram`, `hw_vif_multiqueue_enabled`
73110

74111
The `trait:XXX=required` property can be used to indicate that certain virtual hardware
75-
features `XXX` are required.
112+
features `XXX` are required which may be advertised in matching
113+
[flavor extra specs](https://docs.openstack.org/nova/latest/user/flavors.html#extra-specs).
76114

77115
## Image handling
78116

@@ -239,3 +277,11 @@ A boolean property that is not present is considered to be `false`.
239277
contact for issues with this image. Note that this field must only be set if the
240278
service provider does provide support for this image included in the image/flavor
241279
pricing (but it might be provided by a contracted 3rd party, e.g. the OS vendor).
280+
281+
### Version history
282+
283+
- Version 1.0 has existed without notable changes since June 2021.
284+
- Version 1.1 was created in preparation for a new major version 2.0 and has the following additional recommendations:
285+
- Reference OpenStack image spec for standard values of `os_distro`, `architecture` and `hypervisor_type`.
286+
- Recommendation on `os_version` to be a version number (if such a value exists).
287+
- Recommended field `os_purpose`.

Tests/iaas/openstack_test.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
from scs_0102_image_metadata.image_metadata import \
2525
compute_scs_0102_prop_architecture, compute_scs_0102_prop_hash_algo, compute_scs_0102_prop_min_disk, \
2626
compute_scs_0102_prop_min_ram, compute_scs_0102_prop_os_version, compute_scs_0102_prop_os_distro, \
27+
compute_scs_0102_prop_os_purpose, \
2728
compute_scs_0102_prop_hw_disk_bus, compute_scs_0102_prop_hypervisor_type, compute_scs_0102_prop_hw_rng_model, \
2829
compute_scs_0102_prop_image_build_date, compute_scs_0102_prop_image_original_user, \
2930
compute_scs_0102_prop_image_source, compute_scs_0102_prop_image_description, \
@@ -90,6 +91,7 @@ def make_container(cloud):
9091
c.add_function('scs_0102_prop_min_ram', lambda c: compute_scs_0102_prop_min_ram(c.images))
9192
c.add_function('scs_0102_prop_os_version', lambda c: compute_scs_0102_prop_os_version(c.images))
9293
c.add_function('scs_0102_prop_os_distro', lambda c: compute_scs_0102_prop_os_distro(c.images))
94+
c.add_function('scs_0102_prop_os_purpose', lambda c: compute_scs_0102_prop_os_purpose(c.images))
9395
c.add_function('scs_0102_prop_hw_disk_bus', lambda c: compute_scs_0102_prop_hw_disk_bus(c.images))
9496
c.add_function('scs_0102_prop_hypervisor_type', lambda c: compute_scs_0102_prop_hypervisor_type(c.images))
9597
c.add_function('scs_0102_prop_hw_rng_model', lambda c: compute_scs_0102_prop_hw_rng_model(c.images))

Tests/iaas/scs_0102_image_metadata/image_metadata.py

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@
1212
HW_DISK_BUSES = ("virtio", "scsi", None) # FIXME why None?
1313
HYPERVISOR_TYPES = ("qemu", "kvm", "xen", "hyper-v", "esxi", None)
1414
HW_RNG_MODELS = ("virtio", None)
15-
# Just for nice formatting of image naming hints -- otherwise we capitalize the 1st letter
16-
OS_LIST = ("CentOS", "AlmaLinux", "Windows Server", "RHEL", "SLES", "openSUSE")
15+
OS_PURPOSES = ("generic", "minimal", "k8snode", "gpu", "network", "custom")
1716
# Auxiliary mapping for `freq2secs` (note that values are rounded up a bit on purpose)
1817
FREQ_TO_SEC = {
1918
"never": 0,
@@ -31,15 +30,6 @@
3130
KIB, MIB, GIB = (1024 ** n for n in (1, 2, 3))
3231

3332

34-
def recommended_name(nm, os_list=OS_LIST):
35-
"""Return capitalized name"""
36-
for osnm in os_list:
37-
osln = len(osnm)
38-
if nm[:osln].casefold() == osnm.casefold():
39-
return osnm + nm[osln:]
40-
return nm[0].upper() + nm[1:]
41-
42-
4333
def is_url(stg):
4434
"""Is string stg a URL?"""
4535
idx = stg.find("://")
@@ -156,6 +146,7 @@ def compute_scs_0102_prop_os_version(images):
156146
# NOTE currently we are content when the property is not empty, but we could be more strict,
157147
# because the standard was recently edited to refer to the OpenStack docs, which prescribe
158148
# certain values for common operating systems.
149+
# - os_version not matching regexp r'[0-9\.]*' (should be a numeric version no)
159150
offenders = [img for img in images if not img.os_version]
160151
_log_error('property os_version not set', offenders)
161152
return not offenders
@@ -164,11 +155,20 @@ def compute_scs_0102_prop_os_version(images):
164155
def compute_scs_0102_prop_os_distro(images):
165156
"""This test ensures that each image has a proper value for the property `os_distro`."""
166157
# NOTE see note in `compute_scs_0102_prop_os_version`
158+
# - os_distro not being all-lowercase (they all should be acc. to
159+
# https://docs.openstack.org/glance/2025.1/admin/useful-image-properties.html
167160
offenders = [img for img in images if not img.os_distro]
168161
_log_error('property os_distro not set', offenders)
169162
return not offenders
170163

171164

165+
def compute_scs_0102_prop_os_purpose(images, os_purposes=OS_PURPOSES):
166+
"""This test ensures that each image has a proper value for the property `os_distro`."""
167+
offenders = [img for img in images if img.properties.get('os_purpose') not in os_purposes]
168+
_log_error('property os_purpose not set or not correct', offenders)
169+
return not offenders
170+
171+
172172
def compute_scs_0102_prop_hw_disk_bus(images, hw_disk_buses=HW_DISK_BUSES):
173173
"""This test ensures that each image has a proper value for the property `hw_disk_bus`."""
174174
offenders = [img for img in images if img.hw_disk_bus not in hw_disk_buses]
@@ -227,7 +227,7 @@ def compute_scs_0102_prop_image_source(images):
227227
img
228228
for img in images
229229
if img.properties.get('image_source') != 'private'
230-
if not is_url(img.properties.get('image_source'))
230+
if not is_url(img.properties.get('image_source', ''))
231231
]
232232
_log_error('property image_source INVALID (url or "private")', offenders)
233233
return not offenders

0 commit comments

Comments
 (0)