From 0906155548ba607aec6cdf5f15991cb76d7fa59b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20B=C3=BCchse?= Date: Thu, 29 Jun 2023 21:43:55 +0200 Subject: [PATCH 01/17] Attempt at decoupling standard flavors from flavor naming MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Matthias Büchse --- Standards/scs-0100-v4-flavor-naming.md | 524 ++++++++++++++++++++++ Standards/scs-0103-v1-standard-flavors.md | 127 ++++++ 2 files changed, 651 insertions(+) create mode 100644 Standards/scs-0100-v4-flavor-naming.md create mode 100644 Standards/scs-0103-v1-standard-flavors.md diff --git a/Standards/scs-0100-v4-flavor-naming.md b/Standards/scs-0100-v4-flavor-naming.md new file mode 100644 index 000000000..0af3bb5c7 --- /dev/null +++ b/Standards/scs-0100-v4-flavor-naming.md @@ -0,0 +1,524 @@ +--- +title: SCS Flavor Naming Standard +type: Standard +status: Draft +track: IaaS +replaces: scs-0100-v3-flavor-naming.md +--- + +## Introduction + +This is the standard v4.0 for SCS Release 5. +Note that we intend to only extend it (so it's always backwards compatible), +but try to avoid changing in incompatible ways. +(See at the end for the v1 to v2 transition where we have not met that +goal, but at least managed to have a 1:1 relationship between v1 and v2 names.) + +## Motivation + +In OpenStack environments there is a need to define different flavors for instances. +The flavors are pre-defined by the operator, the customer can not change these. +OpenStack providers thus typically offer a large selection of flavors. + +While flavors can be discovered (`openstack flavor list`), it is helpful for users (DevOps teams), +to have + +- A naming scheme that is used across all SCS flavors, so flavor names have the same meaning everywhere. +- Have a guaranteed set of flavors available on all SCS clouds, so these do not need to be discovered. + +While not all details will be encoded in the name, the key features should be obvious: +Number of vCPUs, RAM, Root Disk. +Extra features are important as well: There will be flavors with GPU support, fast disks for databases, +memory-heavy applications, and other useful aspects of an instance. + +It may also be important to make the CPU generation clearly recognizable, as this is always a topic in +discussions with customers. + +Note that not all relevant properties of flavors can be discovered; creating a specification +to address this is a separate but related effort to the name standardization. +Commonly used infrastructure-as-code tools do not provide a way to use discoverability +features to express something like "I want a flavor with 2 vCPUs, 8GiB of RAM, a local +20GB SSD disk and Infiniband support but I don't care whether it's AMD or intel" in a +reasonable manner. Using flavor names to express this will thus continue to be useful +and we don't expect the need for standardization of flavor names to go away until +the commonly used IaC tools work on a higher abstraction layer than they currently do. + +## Design Considerations + +### Type of information included + +From discussions of our operators with their customers we learned that +the following characteristics are important in a flavor description: + +| Type | Description | +| :---------------- | :----------------------------------------------------- | +| Generation | CPU Generation | +| Number of CPU | Number of vCPUs - suffixed by L,V,T,C (see below) | +| Amount of RAM | Amount of memory available for the VM | +| Performance Class | Ability to label high-performance CPUs, disks, network | +| CPU Type | X86-intel, X86-amd, ARM, RISC-V, Generic | +| "bms" | Bare Metal System (no virtualization/hypervisor) | + +This list is likely not comprehensive and will grow over time. + +Rather than using random names `s5a.medium` and assigning a discrete set of properties +to them, we wanted to come up with a scheme that allows to systematically derive +names from properties and vice versa. The scheme allows for short names (by not +encoding all details) as well as very detailed longer names. + +## Complete Proposal for systematic flavor naming + +| Prefix | CPUs & Suffix | RAM[GiB] | optional: Disk[GB]&type | opt: extensions | +| ------ | ----------------- | ------------------ | ----------------------------- | ----------------| +| `SCS-` | N`L/V/T/C`\[`i`\] | `-`N\[`u`\]\[`o`\] | \[`-`\[M`x`\]N\[`n/s/l/p`\]\] | \[`_`EXT\] | + +Note that N and M are placeholders for numbers here. +The optional fields are denoted in brackets (and have opt: in the header. +See below for extensions. + +Note that all letters are case-sensitive. + +Typical flavor names look like `SCS-4V-16-50` for a flavor with 4vCPUs (with limited +oversubscription), 16GiB RAM and a 50GB disk (of unspecified type). + +## Proposal Details + +### [REQUIRED] CPU Suffixes + +Next to the number of vCPUs, these vCPUs need to be characterized ti describe their nature. + +| Suffix | Meaning | +| ------ | ----------------------------- | +| C | dedicated Core | +| T | dedicated Thread (SMT) | +| V | vCPU (oversubscribed) | +| L | vCPU (heavily oversubscribed) | + +#### Baseline + +Note that vCPU oversubscription for a `V` vCPU should be implemented such, that we +can guarantee _at least 20% of a core in >99% of the time_; this can be achieved by +limiting vCPU oversubscription to 5x per core (or 3x per thread when SMT/HT is enabled) +or by more advanced workload management logic. Otherwise `L` (low performance) instead +of `V` must be used. The >99% is measured over a month (1% is 7.2h/month). + +Note that CPUs should use latest microcode to protect against CPU vulnerabilities (Spectre, Meltdown, L1TF, etc.). +Microcode must be updated within less than a month of a new release; for CVSS scores above 8, +providers should do it in less than a week. +The provider should enable at least all mitigations that are enabled by default in the Linux kernel and the +KVM hypervisor. CPUs that are susceptible to L1TF (intel x86 pre Cascade Lake) should switch off hyperthreading +OR (in the future) use core scheduling implementations that are deemed to be secure by the SCS security team. + +If microcode updates needed for mitigation are lacking for longer than a month, default kernel/hypervisor +mitigations are disabled or hyperthreading is enabled despite the CPU being susceptible to L1TF, the +flavors must declare themselves insecure with the `i` suffix (see below). + +#### Higher oversubscription + +Must be indicated with a `L` vCPU type (low performance for > 5x/core or > 3x/thread oversubscription and +the lack of workload management that would prevent worst case performance <20% in more than 7.2h per month). + +#### Insufficient microcode + +Not using these mitigations must be indicated by an additional `i` suffix for insecure +(weak protection against CPU vulns through insufficient microcode, lack of disabled hyperthreading +on L1TF susceptible CPUs w/o effective core scheduling or disabled protections on the host/hypervisor). + +#### Examples + +- SCS-**2C**-4-10n +- SCS-**2T**-4-10n +- SCS-**2V**-4-10n +- SCS-**2L**-4-10n +- SCS-**2Li**-4-10n +- ~~SCS-**2**-\*\*4-10n~~ <- CPU suffix missing +- ~~SCS-**2iT**-4-10n~~ <- This order is forbidden + +### [REQUIRED] Memory + +#### Baseline + +Cloud providers should use ECC memory. +Memory oversubscription should not be used. +It is allowed to specify half GiBs (e.g. 3.5), though this is should not be done for larger memory sizes (>= 10GiB). + +#### No ECC + +If no ECC is used, the `u` suffix must indicate this. + +#### Enabled Oversubscription + +If memory is oversubscribed, you must expose this with the `o` suffix. + +#### Examples + +- SCS-2C-**4**-10n +- SCS-2C-**3.5**-10n +- SCS-2C-**4u**-10n +- SCS-2C-**4o**-10n +- SCS-2C-**4uo**-10n +- ~~SCS-2C-**4ou**-10n~~ <- This order is forbidden + +### [OPTIONAL] Disk sizes and types + +Disk sizes (in GB) should use sizes 5, 10, 20, 50, 100, 200, 500, 1000. + +| Disk type | Meaning | +| --------- | ------------------------------------ | +| n | Network shared storage (ceph/cinder) | +| h | Local disk (HDD: SATA/SAS class) | +| s | Local SSD disk | +| p | Local high-perf NVMe | + +#### Baseline + +Note that disk type might be omitted — the user then can not take any assumptions +on what storage is provided for the root disk (that the image gets provisioned to). + +It does make sense for `n` to be requested explicitly to allow for smooth live migration. +`h` typically provides latency advantages vs `n` (but not necessarily bandwidth and +also is more likely to fail), `s` and `p` are for applications that need low +latency (high IOPS) and bandwidth disk I/O. `n` storage is expected to survive +single-disk and single-node failure. + +For specific requirements on the SSD and NVMe disks regarding IOPS and +power-loss protection, refer to Decision Record [scs-0110-ssd-flavors](https://github.com/SovereignCloudStack/standards/blob/main/Standards/scs-0110-v1-ssd-flavors.md). + +If the disk size is left out, the cloud is expected to allocate a disk (network or local) +that is large enough to fit the root file system (`min_disk` in image). This automatic +allocation is indicated with `-` without a disk size. +If the `-` is left out completely, the user must create a boot volume manually and +tell the instance to boot from it or use the +[`block_device_mapping_v2`](https://docs.openstack.org/api-ref/compute/?expanded=create-server-detail#create-server) +mechanism explicitly to create the boot volume from an image. + +#### Multi-provisioned Disk + +The disk size can be prefixed with `Mx prefix`, where M is an integer specifying that the disk +is provisioned M times. Multiple disks provided this way should be independent storage media, +so users can expect some level of parallelism and independence. + +#### Examples + +- SCS-2C-4-**10n** +- SCS-2C-4-**10s** +- SCS-2C-4-**10s**\_bms_z3 +- SCS-2C-4-**3x10s** <- Cloud creates three 10GB SSDs +- SCS-2C-4-**3x10s**\_bms_z3 +- SCS-2C-4-**10** <- Cloud decides disk type +- SCS-2C-4-**10**\_bms_z3 +- SCS-2C-4-**n** <- Cloud decides disk size (min_disk from image or larger) +- SCS-2C-4-**n**\_bms_3 +- SCS-2C-4- <- Cloud decides disk type and size +- SCS-2C-4-\_bms_z3 +- SCS-2C-4-\_bms_z3h_GNa-64_ib +- SCS-2C-4-\_ib +- SCS-2C-4 <- You need to specify a boot volume yourself (boot from volume, or use `block_device_mapping_v2`) +- SCS-2C-4_bms_z3 +- SCS-2C-4-3x- <- Cloud decides disk type and size and creates three of them (FIXME: Is this useful?) +- SCS-2C-4-3xs <- Cloud decides size and creates three local SSD volumes (FIXME: useful?) +- SCS-2C-4-3x10 <- Cloud decides type and creates three 10GB volumes +- ~~SCS-2C-4-**1.5n**~~ <- You must not specify disk sizes which are not in full GiBs + +## Naming policy compliance + +To be certified as an SCS compliant x86-64 IaaS platform, you must offer all standard mandatory SCS +flavors according to the previous section. (We may define a mechanism that allows exceptions to be +granted in a way that makes this very transparent and visible to clients.) + +You are allowed to understate your performance; you may implement a SCS-1V-1-5 flavor with +a flavor that actually implements SCS-1T-1-5n (i.e. you dedicate a dedicated hyperthread instead +of higher oversubscription) or even SCS-1C-1.5-8s (1 dedicated core, 50% more RAM and a 8GiB SSD). +Or you may offer the (v3 mandatory) `SCS-2V-4-20s` with a `SCS-2V-4-20p` (using a local NVMe +instead of an SSD). + +Flavor names indicating certain capabilities must _at least_ provide these, otherwise they +are in violation of the SCS specification and prevent SCS compliance. + +We expect all cloud providers to offer the short, less specific flavor names (such as SCS-8V-32-100). +Larger providers that offer more details (using the extension below) are expected to still also +offer the short variants for usability and easier portability, even beyond the mandated flavors. + +You must be very careful to expose low vCPU guarantees (`L` instead of `V`), insecure +hyperthreading/microcode `i`, non-ECC-RAM `u`, memory oversubscription `o`. Note that omitting these qualifiers +is _overstating_ your security, reliability or performance properties and may be reason for +clients to feel betrayed or claim damages. This would prevent SCS compliance and certification; +in extreme cases, the SCS project might be forced to work with public statements. + +You may offer additional `SCS-` flavors, following the naming scheme and rules outlined here. + +You may offer additional flavors, not following above scheme and not starting with `SCS-` + +You must not offer flavors with the `SCS-` prefix which do not follow this naming scheme. + +You must not extend the SCS naming scheme with your own extensions; you are encouraged however +to suggest extensions that we can discuss and add to the official scheme. + +## Validation + +There is a script in [`flavor-name-check.py`](https://github.com/SovereignCloudStack/standards/blob/main/Tests/iaas/flavor-naming/flavor-name-check.py) +which can be used to decode, validate and construct flavor names. +[`flavor-name-describe.py`](https://github.com/SovereignCloudStack/standards/blob/main/Tests/iaas/flavor-naming/flavor-name-describe.py) outputs a human-readable decoding of the SCS flavor names. +These scripts must stay in sync with the specification text. + +Ensure you have your OpenStack tooling (`python3-openstackclient`, `OS_CLOUD`) setup and call +`tools/flavor-name-check.py -c $(openstack flavor list -f value -c Name)` to get a report +on the flavor list compliance of the cloud environment. + +The script `flavor-names-openstack.py` talks to the OpenStack API of the +cloud specified by the `OS_CLOUD` environment and queries properties and checks +the names for standards compliance and completeness w.r.t. the mandatory +flavor list. It goes beyond the above example in checking that the discoverable +features of flavors (vCPUs, RAM, Disk) match what the flavor names claim. +This is used for SCS-compatible compliance testing. + +## Extensions + +Extensions provide a possibility for providers that offer a very differentiated set +of flavors to indicate hypervisors, support for hardware/nested virtualization, +CPU types and generations, high-frequency models, GPU support and GPU types as +well as Infiniband support. (More extensions may be appended in the future.) + +Using the systematic naming approach ensures that two providers that offer flavors +with the same specific features will use the same name for them, thus simplifying +life for their customers when consuming these flavors. + +Note that there is no need to indicate all details and extra features this way. +Flavors may always perform better or have more features than indicated in a name. +Underperformance (CPU suffices `L` or `i` or memory suffices `o` and `u`) on the other +hand MUST be indicated in the name; this happens rarely in practice. + +For smaller providers, the ability to e.g. differentiate between an AMD Milan and an intel +IceLake and exposed the slightly different feature set to customers and have slightly +different price points is often not worth the extra effort. This is because having +this extra differentiation causes fragmentation of the machines (host aggregates) +that can offer these flavors, thus resulting in a lower utilization (as the capacity +management will need to have a certain amount of headroom per machine pool to avoid +running out of capacity). + +Note that it is possible for providers to register both the generic short names and the +longer, more detailed names and allow them to use the same set of machines (host aggregates). +Note that machines (hypervisors) can be part of more than one host aggregate. + +The extensions have the format: + +\[`_`hyp\]\[`_hwv`\]\[`_`\[arch\[N\]\[`h`\]\[`_`\[`G/g`\]X\[N\]\[`-`M\[`h`\]\]\]\[`_ib`\] + +Remember that letters are case-sensitive. +In case you wonder: Feature indicators are capitalized, modifiers are lower case. +(An exception is the uppercase `_G` for a pass-through GPU vs. lowercase `_g` for vGPU.) + +### [OPTIONAL] Hypervisor + +The _default Hypervisor_ is assumed to be `KVM`. Clouds, that offer different hypervisors +or Bare Metal Systems should indicate the Hypervisor according to the following table: + +| hyp | Meaning | +| --- | ----------------- | +| kvm | KVM | +| xen | Xen | +| vmw | VMware | +| hyv | Hyper-V | +| bms | Bare Metal System | + +#### Examples + +- SCS-2C-4-10n +- SCS-2C-4-10n\_**bms** +- SCS-2C-4-10n\_**bms**\_z3h + +### [OPTIONAL] Hardware virtualization / Nested virtualization + +If the instances that are created with this flavor support hardware-accelerated +virtualization, this can be reflected with the `_hwv` flag (after the optional +Hypervisor flag). On x86, this means that in the instance, the CPU flag vmx (intel) +or svm (AMD) is available. This will be the case on Bare Metal flavors on almost +all non-ancient x86 CPUs or if your virtualization hypervisor is configured to +support nested virtualization. +Flavors without the `_hwv` flag may or may not support hardware virtualization (as we +recommend enabling nesting, but don't require flavor names to reflect all +capabilities. Flavors may over-deliver ...) + +#### Examples + +- SCS-2C-4-10 <- may or may not support HW virtualization in VMs +- SCS-2C-4-10_kvm_**hwv** <- kvm with enabled nested virtualization +- SCS-2C-4-10\_**hwv** <- not recommended, but allowed +- SCS-2C-4-10\_bms\_**hwv** <- better: bare metal with HW virt support (VMX on intel, SVM on AMD, ...) +- ~~SCS-2C-4-10\_**hwv**\_xen~~ <- illegal, wrong ordering + +### [OPTIONAL] CPU Architecture Details + +Arch details provide more details on the specific CPU: + +- Vendor +- Generation +- Frequency + +#### Generation and Vendor + +The generations are vendor specific and can be left out. +Not specifying arch means that we have a generic CPU (**x86-64**). +The letters `i`, `z`, `a` and `r` specify the vendors Intel, +AMD (`z` like in Zen), ARM v8+, RISC-V. + +| Generation | i (Intel x86-64) | z (AMD x86-64) |  a (AArch64) | r (RISC-V) | +| ---------- | ---------------- | -------------- | ------------------ | ---------- | +| 0 | pre Skylake | pre Zen | pre Cortex A76 | TBD | +| 1 | Skylake | Zen-1 (Naples) | A76/NeoN1 class | TBD | +| 2 | Cascade Lake | Zen-2 (Rome) | A78/x1/NeoV1 class | TBD | +| 3 | Ice Lake | Zen-3 (Milan) | A71x/NeoN2 (ARMv9) | TBD | +| 4 | Sapphire Rapids | Zen-4 (Genoa) | | TBD | + +It is recommended to leave out the `0` when specifying the old generation; this will +help the parser tool, which assumes 0 for an unspecified value and does leave it +out when generating the name for comparison. In other words: 0 has a meaning of +"rather old or unspecified". + +#### Frequency Suffixes + +| Suffix | Meaning | +| ------ | ----------------- | +| h | >2.75GHz all-core | +| hh | >3.25GHz all-core | +| hhh | >3.75GHz all-core | + +#### Examples + +- SCS-2C-4-10n +- SCS-2C-4-10n\_**z** +- SCS-2C-4-10n\_**z3** +- SCS-2C-4-10n\_**z3h** +- SCS-2C-4-10n\_**z3hh** +- SCS-2C-4-10n_bms_**z** +- SCS-2C-4-10n_bms_**z3** +- SCS-2C-4-10n_bms_**z3** +- SCS-2C-4-10n_bms_**z3h** +- SCS-2C-4-10n_bms_**z3hh** <- Bare Metal, Intel Ice Lake with > 3.25GHz all core freq + +### [OPTIONAL] GPU support + +`_G`X\[N\]\[`-`M\[`h`\]\] indicates a Pass-Through GPU from vendor X of gen N with M compute units / SMs / EUs exposed. +`_g`X\[N\]\[`-`M\[`h`\]\] indicates a vGPU from vendor X of gen N with M compute units / SMs / EUs assigned. + +Note that the vendor letter X is mandatory, generation and compute units are optional. + +| GPU | Vendor | +| --- | ------ | +| N | nVidia | +| A | AMD | +| I | Intel | + +For nVidia, the generation N can be f=Fermi, k=Kepler, m=Maxwell, p=Pascal, v=Volta, t=turing, a=Ampere, l=Ada Lovelace, ..., +for AMD GCN-x=0.x, RDNA1=1, RDNA2=2, RDNA3=3, for intel Gen9=0.9, Xe(12.1)=1, ... +(Note: This may need further work to properly reflect what's out there.) + +The optional `h` suffix to the compute unit count indicates high-performance (e.g. high freq or special +high bandwidth gfx memory such as HBM); +`h` can be duplicated for even higher performance. + +### [OPTIONAL] Infiniband + +`_ib` indicates Infiniband networking. + +More extensions may be forthcoming and appended in a later revision of this spec. + +Extensions need to be specified in the above mentioned order. + +### Naming options advice + +Note that we expect most clouds to prefer short flavor names, +not indicating CPU details or hypervisor types. See above list +of standard flavors to get a feeling. + +However, more successful providers will often need to differentiate their +offerings in response to customer demand and allow customers to request +flavors with specific detailed properties. The goal of this proposal is to avoid +providers to invent their own names and then refer customers to (currently +incompletely standardized) `extra_specs` +or worse a non-machine-readable service descriptions to find out the details. + +So a cloud provider might well evolve from offering `SCS-8T-16-50` to offering +`SCS-8T-16-50n`, `SCS-8T-16-50n_i2` and `SCS-8T-16-50n_z2` to specify that he +is using network disks and offer a choice b/w intel Cascade-Lake and AMD Rome. +We would expect the cloud provider to still offer the generic flavor +`SCS-8T-16-50` and allow the scheduler (placement service) to pick both more +specific types (or just one if e.g. capacity management considerations suggest +so). Providers in such cases should ensure that the price of a requested +flavor does not depend on the scheduler decisions. + +We are looking into the [metadefs](https://docs.openstack.org/image-guide/introduction.html#metadata-definition-metadefs-service) +mechanism and [extra_specs](https://docs.openstack.org/api-guide/compute/extra_specs_and_properties.html) +to allow customers to ask for specific flavor properties without the need to +encode all these flavor details into the flavor name, so the optional pieces +may not be needed much. However, there must be a way to request flavor +properties without encoding the need into an image — the indirection via +an image is considered broken by the SCS team. + +## Proposal Examples + +| Example | Decoding | +| ------------------------- | ---------------------------------------------------------------------------------------------- | +| SCS-2C-4-10n | 2 dedicated cores (x86-64), 4GiB RAM, 10GB network disk | +| SCS-8Ti-32-50p_i1 | 8 dedicated hyperthreads (insecure), Skylake, 32GiB RAM, 50GB local NVMe | +| SCS-1L-1u-5 | 1 vCPU (heavily oversubscribed), 1GiB Ram (no ECC), 5GB disk (unspecific) | +| SCS-16T-64-200s_GNa-64_ib | 16 dedicated threads, 64GiB RAM, 200GB local SSD, Infiniband, 64 Passthrough nVidia Ampere SMs | +| SCS-4C-16-2x200p_a1 | 4 dedicated Arm64 cores (A76 class), 16GiB RAM, 2x200GB local NVMe drives | +| SCS-1V-0.5 | 1 vCPU, 0.5GiB RAM, no disk (boot from cinder volume) | + +## Previous standard versions + +Previous versions up to [version 3](scs-0100-v3-flavor-naming.md) contained the list of +mandatory/recommended flavors, which has been moved to +[a standard of its own](scs-0103-v1-standard-flavors.md). + +[Version 1 of the standard](scs-0100-v1-flavor-naming.md) +used a slightly different naming syntax while the logic was exactly the same. +What is a `-` in v2 used to be a `:`; `_` used to be `-`. The reason for +the change was certain Kubernetes tools using the flavor names as labels. +Labels however are subject to stricter naming rules and in particular don't +allow for a `:`. See [PR #190](https://github.com/SovereignCloudStack/standards/issues/190) +for a discussion. + +Version 1 flavor names can be translated to v2 using the following transformation: + +```shell +NAMEV2=$(echo "$NAMEV1" | sed -e 's/\-/_/g' -e 's/:/-/g' -e 's/^SCS_/SCS-/') +``` + +and the way back can be done with + +```shell +NAMEV1=$(echo "$NAMEV2" | sed -e 's/\-/:/g' -e 's/_/-/g' -e 's/^SCS:/SCS-/') +``` + +Considerations for how providers can ensure a smooth transition for their customers +from v1 to v2 are written in a separate document. + +For the time being, the validation tools still accept the old names with a warning +(despite the unchanged `SCS-` prefix) unless you pass option `-2` to them. They will +however not count v1 flavors towards fulfilling the needs against the corresponding +v2 mandatory flavor list unless you pass the option `-1`. +In other words: An IaaS infrastructure with the 26 +v1 mandatory flavors will produce 26 warnings (for using old flavors) and 26 +errors (for missing the 26 mandatory v2 flavors) unless you pass `-1` in which +case no errors and no warnings will be produced. Registering the 26 mandatory +v2 flavor names in addition will result in passing the test with only 26 +warnings — unless you specify `-2`. If you do and want to pass you'll need +to remove the old v1 names or rename them to no longer start with `SCS-`. + +## Beyond SCS + +The Gaia-X provider working group which could have created a superseding standard +does no longer exist. + +However, we have been reaching out to the OpenStack Public Cloud SIG and the ALASCA +members to seek further alignment. + +Getting upstream OpenStack support for flavor aliases would provide more flexibility +and ease migrations between providers, also providers that don't offer the SCS- +flavors. + +We also would like to see upstream `extra_specs` standardizing the discoverability of some +properties exposed via the SCS names and work on IaC tooling (terraform ...) +to make use of these when selecting a flavor. diff --git a/Standards/scs-0103-v1-standard-flavors.md b/Standards/scs-0103-v1-standard-flavors.md new file mode 100644 index 000000000..1f73233d2 --- /dev/null +++ b/Standards/scs-0103-v1-standard-flavors.md @@ -0,0 +1,127 @@ +--- +title: SCS Standard Flavors +type: Standard +status: Draft +track: IaaS +--- + +## Introduction + +## Motivation + +In OpenStack environments there is a need to define different flavors for instances. +The flavors are pre-defined by the operator, the customer can not change these. +OpenStack providers thus typically offer a large selection of flavors. + +While flavors can be discovered (`openstack flavor list`), it is helpful for users (DevOps teams), +to have a guaranteed set of flavors available on all SCS clouds, so these need not be discovered. + +## Standard SCS flavors + +These are flavors that must exist on standard SCS clouds (x86-64). + +### Mandatory + +| Recommended name | vCPUs | vCPU type | RAM [GiB] | Root disk [GB] | Disk type | +| ---------------- | ------ | ------------- | ---------- | --------------- | ---------- | +| SCS-1V-4 | 1 | shared core | 4 | | | +| SCS-2V-8 | 2 | shared core | 8 | | | +| SCS-4V-16 | 4 | shared core | 16 | | | +| SCS-4V-16-100s | 4 | shared core | 16 | 100 | ssd | +| SCS-8V-32 | 8 | shared core | 32 | | | +| SCS-1V-2 | 1 | shared core | 2 | | | +| SCS-2V-4 | 2 | shared core | 4 | | | +| SCS-2V-4-20s | 2 | shared core | 4 | 20 | ssd | +| SCS-4V-8 | 4 | shared core | 8 | | | +| SCS-8V-16 | 8 | shared core | 16 | | | +| SCS-16V-32 | 16 | shared core | 32 | | | +| SCS-1V-8 | 1 | shared core | 8 | | | +| SCS-2V-16 | 2 | shared core | 16 | | | +| SCS-4V-32 | 4 | shared core | 32 | | | +| SCS-1L-1 | 1 | crowded core | 1 | | | + +### Recommended + +| Recommended name | vCPUs | vCPU type | RAM [GiB] | Root disk [GB] | Disk type | +| ---------------- | ------ | ------------- | ---------- | --------------- | ---------- | +| SCS-1V-4-10 | 1 | shared core | 4 | 10 | (any) | +| SCS-2V-8-20 | 2 | shared core | 8 | 20 | (any) | +| SCS-4V-16-50 | 4 | shared core | 16 | 50 | (any) | +| SCS-8V-32-100 | 8 | shared core | 32 | 100 | (any) | +| SCS-1V-2-5 | 1 | shared core | 2 | 5 | (any) | +| SCS-2V-4-10 | 2 | shared core | 4 | 10 | (any) | +| SCS-4V-8-20 | 4 | shared core | 8 | 20 | (any) | +| SCS-8V-16-50 | 8 | shared core | 16 | 50 | (any) | +| SCS-16V-32-100 | 16 | shared core | 32 | 100 | (any) | +| SCS-1V-8-20 | 1 | shared core | 8 | 20 | (any) | +| SCS-2V-16-50 | 2 | shared core | 16 | 50 | (any) | +| SCS-4V-32-100 | 4 | shared core | 32 | 100 | (any) | +| SCS-1L-1-5 | 1 | crowded core | 1 | 5 | (any) | + +### Guarantees and properties + +The following guarantees must be met: + +- A "shared core" means _at least 20% of a core in >99% of the time_, measured over the + course of one month (1% is 7,2 h/month). +- A disk of type "ssd" must support 1000 _sequential_ IOPS per VM and it must be equipped + with power-loss protection; see [scs-0110-v1-ssd-flavors](./scs-0110-v1-ssd-flavors.md). + +The following properties must be set (in the `extra_specs`): + +- `scs:name-v4` to the recommended name, +- `scs:vCPU-type` to `shared-core` or `crowded-core`, reflecting the vCPU type, +- `scs:disk0-type` not set if no disk is provided, otherwise set to `ssd` or some other + value, reflecting the disk type. + +### Remarks + +We expect the most used vCPU:RAM[GiB] ratio to be 1:4. + +Note that all vCPUs of SCS standard flavors are oversubscribed — the smallest `1L-1` +flavor allows for heavy oversubscription (note the `L`), and thus can be offered very +cheaply — imagine jump hosts ... + +The design allows for small clouds (with CPUs with 16 Threads, 64GiB RAM +compute hosts) to offer all flavors. + +Except for the two flavors with SSD root volume, disks types are not specified +(and expected to be network disks (Ceph/Cinder) or local SATA/SAS disks typically). + +We only included a limited variation of disk sizes — this reflects that +for the standard networked cinder +disks, you can pass `block_device_mapping_v2` on server (VM) creation to +allocate a boot disk of any size you desire. We have scaled the few +recommended disk sizes with the amount of RAM. For each flavor there is +also one _without_ a pre-attached disk — these are meant to be used +to boot from a volume (either created beforehand or allocated on-the-fly +with `block_device_mapping_v2`, e.g. +`openstack server create --flavor SCS-1V-2 --block-device-mapping sda=IMGUUID:image:12:true` +to create a bootable 12G cinder volume from image `IMGUUID` that gets tied to the VM +instance life cycle.) + +## Validation + +The script `flavor-names-openstack.py` talks to the OpenStack API of the +cloud specified by the `OS_CLOUD` environment and queries properties and checks +the names for standards compliance and completeness w.r.t. the mandatory +flavor list. It goes beyond the above example in checking that the discoverable +features of flavors (vCPUs, RAM, Disk) match what the flavor names claim. +This is used for SCS-compatible compliance testing. + +## Operational tooling + +The [openstack-flavor-manager](https://github.com/osism/openstack-flavor-manager) is able to +create all standard, mandatory SCS flavors for you. It takes input that can be generated by +`flavor-manager-input.py`. + +## Previous standard versions + +The list of standard flavors used to be part of the flavor naming standard up until +[version 3](scs-0100-v3-flavor-naming.md). + +Note that the flavors with fixed size root disks have all moved to Recommended +with said version. This means that they are not a certification requirement any longer, +but we still recommend implementing these for backwards compatibility reasons. +Also in that version, two flavors with SSD+ root disks have been added, as defined in +[scs-0110-v1-ssd-flavors.md](scs-0110-v1-ssd-flavors.md) From c8abfd67b7a768aacb945d3ed1a3529bdfb7b0e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20B=C3=BCchse?= Date: Fri, 30 Jun 2023 13:45:18 +0200 Subject: [PATCH 02/17] made ssd flavors recommended (maybe even remove them entirely) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Matthias Büchse --- Standards/scs-0100-v4-flavor-naming.md | 5 +---- Standards/scs-0103-v1-standard-flavors.md | 15 ++++++++++----- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/Standards/scs-0100-v4-flavor-naming.md b/Standards/scs-0100-v4-flavor-naming.md index 0af3bb5c7..5c669f7d1 100644 --- a/Standards/scs-0100-v4-flavor-naming.md +++ b/Standards/scs-0100-v4-flavor-naming.md @@ -21,10 +21,7 @@ The flavors are pre-defined by the operator, the customer can not change these. OpenStack providers thus typically offer a large selection of flavors. While flavors can be discovered (`openstack flavor list`), it is helpful for users (DevOps teams), -to have - -- A naming scheme that is used across all SCS flavors, so flavor names have the same meaning everywhere. -- Have a guaranteed set of flavors available on all SCS clouds, so these do not need to be discovered. +to have a naming scheme that is used across all SCS flavors, so flavor names have the same meaning everywhere. While not all details will be encoded in the name, the key features should be obvious: Number of vCPUs, RAM, Root Disk. diff --git a/Standards/scs-0103-v1-standard-flavors.md b/Standards/scs-0103-v1-standard-flavors.md index 1f73233d2..63b1567e0 100644 --- a/Standards/scs-0103-v1-standard-flavors.md +++ b/Standards/scs-0103-v1-standard-flavors.md @@ -27,11 +27,9 @@ These are flavors that must exist on standard SCS clouds (x86-64). | SCS-1V-4 | 1 | shared core | 4 | | | | SCS-2V-8 | 2 | shared core | 8 | | | | SCS-4V-16 | 4 | shared core | 16 | | | -| SCS-4V-16-100s | 4 | shared core | 16 | 100 | ssd | | SCS-8V-32 | 8 | shared core | 32 | | | | SCS-1V-2 | 1 | shared core | 2 | | | | SCS-2V-4 | 2 | shared core | 4 | | | -| SCS-2V-4-20s | 2 | shared core | 4 | 20 | ssd | | SCS-4V-8 | 4 | shared core | 8 | | | | SCS-8V-16 | 8 | shared core | 16 | | | | SCS-16V-32 | 16 | shared core | 32 | | | @@ -47,9 +45,11 @@ These are flavors that must exist on standard SCS clouds (x86-64). | SCS-1V-4-10 | 1 | shared core | 4 | 10 | (any) | | SCS-2V-8-20 | 2 | shared core | 8 | 20 | (any) | | SCS-4V-16-50 | 4 | shared core | 16 | 50 | (any) | +| SCS-4V-16-100s | 4 | shared core | 16 | 100 | ssd | | SCS-8V-32-100 | 8 | shared core | 32 | 100 | (any) | | SCS-1V-2-5 | 1 | shared core | 2 | 5 | (any) | | SCS-2V-4-10 | 2 | shared core | 4 | 10 | (any) | +| SCS-2V-4-20s | 2 | shared core | 4 | 20 | ssd | | SCS-4V-8-20 | 4 | shared core | 8 | 20 | (any) | | SCS-8V-16-50 | 8 | shared core | 16 | 50 | (any) | | SCS-16V-32-100 | 16 | shared core | 32 | 100 | (any) | @@ -118,10 +118,15 @@ create all standard, mandatory SCS flavors for you. It takes input that can be g ## Previous standard versions The list of standard flavors used to be part of the flavor naming standard up until -[version 3](scs-0100-v3-flavor-naming.md). +[version 3](scs-0100-v3-flavor-naming.md). The following changes have been made to +the list in comparison with said standard: +* two flavors with ssds have been relegated to recommended status, +* the flavor names have been turned into recommendations, and +* the properties have been introduced in order to help discoverability. Note that the flavors with fixed size root disks have all moved to Recommended -with said version. This means that they are not a certification requirement any longer, +with [scs-0100-v3](scs-0100-v3-flavor-naming.md). +This means that they are not a certification requirement any longer, but we still recommend implementing these for backwards compatibility reasons. -Also in that version, two flavors with SSD+ root disks have been added, as defined in +Also in that standard, two flavors with SSD+ root disks have been added, as defined in [scs-0110-v1-ssd-flavors.md](scs-0110-v1-ssd-flavors.md) From e0a369b2c895bd1859a3834a99399d3eff261b60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20B=C3=BCchse?= Date: Fri, 30 Jun 2023 17:38:43 +0200 Subject: [PATCH 03/17] First shot at conformance test for the newly split-up standards MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Matthias Büchse --- Tests/iaas/scs-0100-v4-flavors.yaml | 5 + Tests/iaas/scs-0103-v1-flavors.yaml | 136 ++++++++++++++ .../standard-flavors/flavors-openstack.py | 175 ++++++++++++++++++ Tests/testing/scs-compatible-test.yaml | 30 ++- 4 files changed, 342 insertions(+), 4 deletions(-) create mode 100644 Tests/iaas/scs-0100-v4-flavors.yaml create mode 100644 Tests/iaas/scs-0103-v1-flavors.yaml create mode 100644 Tests/iaas/standard-flavors/flavors-openstack.py diff --git a/Tests/iaas/scs-0100-v4-flavors.yaml b/Tests/iaas/scs-0100-v4-flavors.yaml new file mode 100644 index 000000000..c5bffdc0e --- /dev/null +++ b/Tests/iaas/scs-0100-v4-flavors.yaml @@ -0,0 +1,5 @@ +SCS-Spec: + # Empty lists so flavor-names-openstack.py only checks the names for scs-0100. + # The list of flavors will be checked with flavors-openstack.py for scs-0103. + MandatoryFlavors: + RecommendedFlavors: diff --git a/Tests/iaas/scs-0103-v1-flavors.yaml b/Tests/iaas/scs-0103-v1-flavors.yaml new file mode 100644 index 000000000..9407c62cc --- /dev/null +++ b/Tests/iaas/scs-0103-v1-flavors.yaml @@ -0,0 +1,136 @@ +meta: + name_key: scs:name-v4 +flavor_groups: + - status: mandatory + list: + - name: SCS-1V-4 + cpus: 1 + cpu-type: shared-core + ram: 4 + - name: SCS-2V-8 + cpus: 2 + cpu-type: shared-core + ram: 8 + - name: SCS-4V-16 + cpus: 4 + cpu-type: shared-core + ram: 16 + - name: SCS-8V-32 + cpus: 8 + cpu-type: shared-core + ram: 32 + - name: SCS-1V-2 + cpus: 1 + cpu-type: shared-core + ram: 2 + - name: SCS-2V-4 + cpus: 2 + cpu-type: shared-core + ram: 4 + - name: SCS-4V-8 + cpus: 4 + cpu-type: shared-core + ram: 8 + - name: SCS-8V-16 + cpus: 8 + cpu-type: shared-core + ram: 16 + - name: SCS-16V-32 + cpus: 16 + cpu-type: shared-core + ram: 32 + - name: SCS-1V-8 + cpus: 1 + cpu-type: shared-core + ram: 8 + - name: SCS-2V-16 + cpus: 2 + cpu-type: shared-core + ram: 16 + - name: SCS-4V-32 + cpus: 4 + cpu-type: shared-core + ram: 32 + - name: SCS-1L-1 + cpus: 1 + cpu-type: crowded-core + ram: 1 + - status: recommended + list: + - name: SCS-1V-4-10 + cpus: 1 + cpu-type: shared-core + ram: 4 + disk: 10 + - name: SCS-2V-8-20 + cpus: 2 + cpu-type: shared-core + ram: 8 + disk: 20 + - name: SCS-4V-16-50 + cpus: 4 + cpu-type: shared-core + ram: 16 + disk: 50 + - name: SCS-4V-16-100s + cpus: 4 + cpu-type: shared-core + ram: 16 + disk: 100 + disk0-type: ssd + - name: SCS-8V-32-100 + cpus: 8 + cpu-type: shared-core + ram: 32 + disk: 100 + - name: SCS-1V-2-5 + cpus: 1 + cpu-type: shared-core + ram: 2 + disk: 5 + - name: SCS-2V-4-10 + cpus: 2 + cpu-type: shared-core + ram: 4 + disk: 10 + - name: SCS-2V-4-20s + cpus: 2 + cpu-type: shared-core + ram: 4 + disk: 20 + disk0-type: ssd + - name: SCS-4V-8-20 + cpus: 4 + cpu-type: shared-core + ram: 8 + disk: 20 + - name: SCS-8V-16-50 + cpus: 8 + cpu-type: shared-core + ram: 16 + disk: 50 + - name: SCS-16V-32-100 + cpus: 16 + cpu-type: shared-core + ram: 32 + disk: 100 + - name: SCS-1V-8-20 + cpus: 1 + cpu-type: shared-core + ram: 8 + disk: 20 + - name: SCS-2V-16-50 + cpus: 2 + cpu-type: shared-core + ram: 16 + disk: 50 + - name: SCS-4V-32-100 + cpus: 4 + cpu-type: shared-core + ram: 32 + disk: 100 + - name: SCS-1L-1-5 + cpus: 1 + cpu-type: crowded-core + ram: 1 + disk: 5 diff --git a/Tests/iaas/standard-flavors/flavors-openstack.py b/Tests/iaas/standard-flavors/flavors-openstack.py new file mode 100644 index 000000000..d50947812 --- /dev/null +++ b/Tests/iaas/standard-flavors/flavors-openstack.py @@ -0,0 +1,175 @@ +#!/usr/bin/env python3 +"""Standard flavors checker for OpenStack + +Check given cloud for conformance with SCS standard regarding standard flavors, +to be found under /Standards/scs-0103-v1-standard-flavors.md + +The respective list of flavors is defined in a corresponding yaml file; this script +expects the path of such a file as its only positional argument. + +Return code is 0 precisely when it could be verified that the standard is satisfied. +Otherwise the return code is the number of errors that occurred (up to 127 due to OS +restrictions); for further information, see the log messages on various channels: + CRITICAL for problems preventing the test to complete, + ERROR for violations of requirements, + INFO for violations of recommendations, + DEBUG for background information and problems that don't hinder the test. +""" +from collections import Counter +import getopt +import logging +import os +import re +import sys +import tempfile +import time +import warnings + +import openstack +import openstack.cloud +import yaml + + +logger = logging.getLogger(__name__) + + +def print_usage(file=sys.stderr): + """Help output""" + print("""Usage: flavors-openstack.py [options] YAML +This tool checks the flavors according to the SCS Standard 0103 "Standard Flavors". +Arguments: + YAML path to the file containing the flavor definitions corresponding to the version + of the standard to be tested +Options: + [-c/--os-cloud OS_CLOUD] sets cloud environment (default from OS_CLOUD env) + [-d/--debug] enables DEBUG logging channel +""", end='', file=file) + + +class CountingHandler(logging.Handler): + def __init__(self, level=logging.NOTSET): + super().__init__(level=level) + self.bylevel = Counter() + + def handle(self, record): + self.bylevel[record.levelno] += 1 + + +def main(argv): + # configure logging, disable verbose library logging + logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.INFO) + openstack.enable_logging(debug=False) + # count the number of log records per level (used for summary and return code) + counting_handler = CountingHandler(level=logging.INFO) + logger.addHandler(counting_handler) + + try: + opts, args = getopt.gnu_getopt(argv, "c:hd", ["os-cloud=", "help", "debug"]) + except getopt.GetoptError as exc: + logger.critical(f"{exc}") + print_usage() + return 1 + + if len(args) != 1: + logger.critical("Missing YAML argument, or too many arguments") + print_usage() + return 1 + + yaml_path = args[0] + cloud = os.environ.get("OS_CLOUD") + for opt in opts: + if opt[0] == "-h" or opt[0] == "--help": + print_usage() + return 0 + if opt[0] == "-c" or opt[0] == "--os-cloud": + cloud = opt[1] + if opt[0] == "-d" or opt[0] == "--debug": + logging.getLogger().setLevel(logging.DEBUG) + + if not cloud: + logger.critical("You need to have OS_CLOUD set or pass --os-cloud=CLOUD.") + return 1 + + try: + with open(yaml_path, "rb") as fileobj: + flavor_spec_data = yaml.safe_load(fileobj) + except Exception as e: + logger.critical(f"Unable to load '{yaml_path}': {e!r}") + logger.debug("Exception info", exc_info=True) + return 1 + + if 'meta' not in flavor_spec_data or 'name_key' not in flavor_spec_data['meta']: + logger.critical("Flavor definition missing 'meta' field or field incomplete") + return 1 + + if 'flavor_groups' not in flavor_spec_data: + logger.critical("Flavor definition missing 'flavor_groups' field") + + name_key = flavor_spec_data['meta']['name_key'] + # compute union of all flavor groups, copying group info (mainly "status") to each flavor + # check if the spec is complete while we are at it + flavor_specs = [] + for flavor_group in flavor_spec_data['flavor_groups']: + group_info = dict(flavor_group) + group_info.pop('list') + missing = {'status'} - set(group_info) + if missing: + logging.critical(f"Flavor group missing attributes: {', '.join(missing)}") + return 1 + for flavor_spec in flavor_group['list']: + missing = {'name', 'cpus', 'ram'} - set(flavor_spec) + if missing: + logging.critical(f"Flavor spec missing attributes: {', '.join(missing)}") + return 1 + flavor_specs.append({"_group": group_info, **flavor_spec}) + + try: + logger.debug(f"Fetching flavors from cloud '{cloud}'") + with openstack.connect(cloud=cloud, timeout=32) as conn: + present_flavors = conn.list_flavors(get_extra=True) + by_name = { + flavor.extra_specs[name_key]: flavor + for flavor in present_flavors + if name_key in flavor.extra_specs + } + + logger.debug(f"Checking {len(flavor_specs)} flavor specs against {len(present_flavors)} flavors") + for flavor_spec in flavor_specs: + flavor = by_name.get(flavor_spec['name']) + if not flavor: + status = flavor_spec['_group']['status'] + level = {"mandatory": logging.ERROR}.get(status, logging.INFO) + logger.log(level, f"Missing {status} flavor '{flavor_spec['name']}'") + continue + # check that flavor matches flavor_spec + # name and corresponding extra_spec do match, because that's how we found the flavor in the first place... + # cpu, ram, and disk should match, and they should match precisely for discoverability + if flavor.vcpus != flavor_spec['cpus']: + logger.error(f"Flavor '{flavor.name}' violating CPU constraint: {flavor.vcpus} != {flavor_spec['cpus']}") + if flavor.ram != 1024 * flavor_spec['ram']: + logger.error(f"Flavor '{flavor.name}' violating RAM constraint: {flavor.ram} != {1024 * flavor_spec['ram']}") + if flavor.disk != flavor_spec.get('disk', 0): + logger.error(f"Flavor '{flavor.name}' violating disk constraint: {flavor.disk} != {flavor_spec.get('disk', 0)}") + # other fields besides name, cpu, ram, and disk should also match + report = [ + f"{key}: {es_value!r} should be {value!r}" + for key, value, es_value in [ + (key, value, flavor.extra_specs.get(f"scs:{key}")) + for key, value in flavor_spec.items() + if key not in ('_group', 'name', 'cpus', 'ram', 'disk') + ] + if value != es_value + ] + if report: + logger.error(f"Flavor '{flavor.name}' violating property constraints: {'; '.join(report)}") + except BaseException as e: + logger.critical(f"{e!r}") + logger.debug("Exception info", exc_info=True) + + c = counting_handler.bylevel + logger.debug(f"Total critical / error / info: {c[logging.CRITICAL]} / {c[logging.ERROR]} / {c[logging.INFO]}") + return min(127, c[logging.CRITICAL] + c[logging.ERROR]) # cap at 127 due to OS restrictions + + +if __name__ == "__main__": + sys.exit(main(sys.argv[1:])) diff --git a/Tests/testing/scs-compatible-test.yaml b/Tests/testing/scs-compatible-test.yaml index e712705b6..9499dd89e 100644 --- a/Tests/testing/scs-compatible-test.yaml +++ b/Tests/testing/scs-compatible-test.yaml @@ -1,15 +1,37 @@ name: SCS Compatible url: https://raw.githubusercontent.com/SovereignCloudStack/standards/main/Tests/scs-compatible.yaml iaas: + - version: v4 + standards: + - name: Standard flavors + url: https://raw.githubusercontent.com/SovereignCloudStack/standards/main/Standards/scs-0103-v1-standard-flavors.md + check_tools: + - executable: ./iaas/standard-flavors/flavors-openstack.py + args: "./iaas/scs-0103-v1-flavors.yaml" + - name: Flavor naming + url: https://raw.githubusercontent.com/SovereignCloudStack/standards/main/Standards/scs-0100-v4-flavor-naming.md + check_tools: + - executable: ./iaas/flavor-naming/flavor-names-openstack.py + args: "--mand=./iaas/scs-0100-v4-flavors.yaml" + - name: Image metadata + url: https://raw.githubusercontent.com/SovereignCloudStack/standards/main/Standards/scs-0102-v1-image-metadata.md + check_tools: + - executable: ./iaas/image-metadata/image-md-check.py + args: -v + - name: OpenStack Powered Compute v2022.11 + url: https://opendev.org/openinfra/interop/src/branch/master/guidelines/2022.11.json + condition: mandatory + # Unfortunately, no wrapper to run refstack yet, needs to be added - version: v3 - stabilized_at: 2023-08-01 - # obsoleted_at: 2024-10-30 + stabilized_at: 2023-06-15 + obsoleted_at: 2024-04-30 standards: - name: Flavor naming url: https://raw.githubusercontent.com/SovereignCloudStack/standards/main/Standards/scs-0100-v3-flavor-naming.md check_tools: - executable: ./iaas/flavor-naming/flavor-names-openstack.py - args: "--v3 --v2plus" + args: "--v3" + # Note: "--v3 --v2plus" would outlaw the v1 flavor names. Don't do this yet. - name: Image metadata url: https://raw.githubusercontent.com/SovereignCloudStack/standards/main/Standards/scs-0102-v1-image-metadata.md check_tools: @@ -18,7 +40,7 @@ iaas: - name: OpenStack Powered Compute v2022.11 url: https://opendev.org/openinfra/interop/src/branch/master/guidelines/2022.11.json condition: mandatory - # Unfortunately, no wrapper to run refstack yet, needs to be added - version: v3 + # Unfortunately, no wrapper to run refstack yet, needs to be added - version: v2 stabilized_at: 2023-03-20 obsoleted_at: 2024-04-30 From d07520dbec0367a27512013d6255a8fee39fbffe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20B=C3=BCchse?= Date: Fri, 30 Jun 2023 17:40:27 +0200 Subject: [PATCH 04/17] Appease flake8 by removing unused imports MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Matthias Büchse --- Tests/iaas/standard-flavors/flavors-openstack.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Tests/iaas/standard-flavors/flavors-openstack.py b/Tests/iaas/standard-flavors/flavors-openstack.py index d50947812..f017c99b3 100644 --- a/Tests/iaas/standard-flavors/flavors-openstack.py +++ b/Tests/iaas/standard-flavors/flavors-openstack.py @@ -19,11 +19,7 @@ import getopt import logging import os -import re import sys -import tempfile -import time -import warnings import openstack import openstack.cloud From 06f1c768de89b6cff558a5389fdf3e3c72f5a90b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20B=C3=BCchse?= Date: Fri, 30 Jun 2023 17:47:37 +0200 Subject: [PATCH 05/17] Fix scs-0100-v4-flavors.yaml (empty lists) as well as mode for flavors-openstack.py (executable) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Matthias Büchse --- Tests/iaas/scs-0100-v4-flavors.yaml | 4 ++-- Tests/iaas/standard-flavors/flavors-openstack.py | 0 2 files changed, 2 insertions(+), 2 deletions(-) mode change 100644 => 100755 Tests/iaas/standard-flavors/flavors-openstack.py diff --git a/Tests/iaas/scs-0100-v4-flavors.yaml b/Tests/iaas/scs-0100-v4-flavors.yaml index c5bffdc0e..a481a9cda 100644 --- a/Tests/iaas/scs-0100-v4-flavors.yaml +++ b/Tests/iaas/scs-0100-v4-flavors.yaml @@ -1,5 +1,5 @@ SCS-Spec: # Empty lists so flavor-names-openstack.py only checks the names for scs-0100. # The list of flavors will be checked with flavors-openstack.py for scs-0103. - MandatoryFlavors: - RecommendedFlavors: + MandatoryFlavors: [] + RecommendedFlavors: [] diff --git a/Tests/iaas/standard-flavors/flavors-openstack.py b/Tests/iaas/standard-flavors/flavors-openstack.py old mode 100644 new mode 100755 From 99fba75b045f8139499306420bde5166d431a8ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20B=C3=BCchse?= Date: Mon, 3 Jul 2023 19:34:14 +0200 Subject: [PATCH 06/17] Appeased markdown-lint; harmonized extra-spec key with script: scs:cpu-type instead of scs:vCPU-type MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Matthias Büchse --- Standards/scs-0103-v1-standard-flavors.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Standards/scs-0103-v1-standard-flavors.md b/Standards/scs-0103-v1-standard-flavors.md index 63b1567e0..6df717314 100644 --- a/Standards/scs-0103-v1-standard-flavors.md +++ b/Standards/scs-0103-v1-standard-flavors.md @@ -70,7 +70,7 @@ The following guarantees must be met: The following properties must be set (in the `extra_specs`): - `scs:name-v4` to the recommended name, -- `scs:vCPU-type` to `shared-core` or `crowded-core`, reflecting the vCPU type, +- `scs:cpu-type` to `shared-core` or `crowded-core`, reflecting the vCPU type, - `scs:disk0-type` not set if no disk is provided, otherwise set to `ssd` or some other value, reflecting the disk type. @@ -120,9 +120,10 @@ create all standard, mandatory SCS flavors for you. It takes input that can be g The list of standard flavors used to be part of the flavor naming standard up until [version 3](scs-0100-v3-flavor-naming.md). The following changes have been made to the list in comparison with said standard: -* two flavors with ssds have been relegated to recommended status, -* the flavor names have been turned into recommendations, and -* the properties have been introduced in order to help discoverability. + +- two flavors with ssds have been relegated to recommended status, +- the flavor names have been turned into recommendations, and +- the properties have been introduced in order to help discoverability. Note that the flavors with fixed size root disks have all moved to Recommended with [scs-0100-v3](scs-0100-v3-flavor-naming.md). From 85497d9abe85b6928d93d9c9f449b0df5d93f414 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20B=C3=BCchse?= Date: Wed, 5 Jul 2023 09:59:09 +0200 Subject: [PATCH 07/17] Adjusted/amended Conformance Tests sections according to scs-0001-v1. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Matthias Büchse --- Standards/scs-0100-v4-flavor-naming.md | 6 +++--- Standards/scs-0103-v1-standard-flavors.md | 17 +++++++++-------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/Standards/scs-0100-v4-flavor-naming.md b/Standards/scs-0100-v4-flavor-naming.md index 5c669f7d1..1c6bfafef 100644 --- a/Standards/scs-0100-v4-flavor-naming.md +++ b/Standards/scs-0100-v4-flavor-naming.md @@ -251,7 +251,7 @@ You must not offer flavors with the `SCS-` prefix which do not follow this namin You must not extend the SCS naming scheme with your own extensions; you are encouraged however to suggest extensions that we can discuss and add to the official scheme. -## Validation +## Conformance Tests There is a script in [`flavor-name-check.py`](https://github.com/SovereignCloudStack/standards/blob/main/Tests/iaas/flavor-naming/flavor-name-check.py) which can be used to decode, validate and construct flavor names. @@ -264,8 +264,8 @@ on the flavor list compliance of the cloud environment. The script `flavor-names-openstack.py` talks to the OpenStack API of the cloud specified by the `OS_CLOUD` environment and queries properties and checks -the names for standards compliance and completeness w.r.t. the mandatory -flavor list. It goes beyond the above example in checking that the discoverable +the names for standards compliance. +It goes beyond the above example in checking that the discoverable features of flavors (vCPUs, RAM, Disk) match what the flavor names claim. This is used for SCS-compatible compliance testing. diff --git a/Standards/scs-0103-v1-standard-flavors.md b/Standards/scs-0103-v1-standard-flavors.md index 6df717314..143b13112 100644 --- a/Standards/scs-0103-v1-standard-flavors.md +++ b/Standards/scs-0103-v1-standard-flavors.md @@ -100,14 +100,15 @@ with `block_device_mapping_v2`, e.g. to create a bootable 12G cinder volume from image `IMGUUID` that gets tied to the VM instance life cycle.) -## Validation - -The script `flavor-names-openstack.py` talks to the OpenStack API of the -cloud specified by the `OS_CLOUD` environment and queries properties and checks -the names for standards compliance and completeness w.r.t. the mandatory -flavor list. It goes beyond the above example in checking that the discoverable -features of flavors (vCPUs, RAM, Disk) match what the flavor names claim. -This is used for SCS-compatible compliance testing. +## Conformance Tests + +The script `flavors-openstack.py` will read the lists of mandatory and recommended flavors +from a yaml file provided as command-line argument, connect to an OpenStack installation, +and check whether the flavors are present and their extra specs are correct. Missing +flavors will be reported on various logging channels: error for mandatory, info for +recommended flavors. Incorrect extra specs will be reported as error in any case. +The return code will be non-zero if the test could not be performed or if any error was +reported. ## Operational tooling From 7a4a2f1041d69f5ee37887189b73e6b7bd0956ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20B=C3=BCchse?= Date: Tue, 8 Aug 2023 11:48:56 +0200 Subject: [PATCH 08/17] Make properties a first-class subject of this standard MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Any flavor that carries any of these must also have the corresponding semantics, otherwise no discoverability Signed-off-by: Matthias Büchse --- Standards/scs-0103-v1-standard-flavors.md | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/Standards/scs-0103-v1-standard-flavors.md b/Standards/scs-0103-v1-standard-flavors.md index 143b13112..fa8d88987 100644 --- a/Standards/scs-0103-v1-standard-flavors.md +++ b/Standards/scs-0103-v1-standard-flavors.md @@ -1,5 +1,5 @@ --- -title: SCS Standard Flavors +title: SCS Standard Flavors and Properties type: Standard status: Draft track: IaaS @@ -16,6 +16,18 @@ OpenStack providers thus typically offer a large selection of flavors. While flavors can be discovered (`openstack flavor list`), it is helpful for users (DevOps teams), to have a guaranteed set of flavors available on all SCS clouds, so these need not be discovered. +## Properties (extra specs) + +The following extra specs are recognized, together with the respective semantics: + +- `scs:cpu-type=shared-core` means that _at least 20% of a core in >99% of the time_, + measured over the course of one month (1% is 7,2 h/month). +- `scs:diskN-type=ssd` (where `N` is a nonnegative integer, usually `0`) means that the + root disk `N` must support 1000 _sequential_ IOPS per VM and it must be equipped with + power-loss protection; see [scs-0110-v1-ssd-flavors](./scs-0110-v1-ssd-flavors.md). + +Whenever ANY of these are present on ANY flavor, the corresponding semantics must be satisfied. + ## Standard SCS flavors These are flavors that must exist on standard SCS clouds (x86-64). @@ -60,13 +72,6 @@ These are flavors that must exist on standard SCS clouds (x86-64). ### Guarantees and properties -The following guarantees must be met: - -- A "shared core" means _at least 20% of a core in >99% of the time_, measured over the - course of one month (1% is 7,2 h/month). -- A disk of type "ssd" must support 1000 _sequential_ IOPS per VM and it must be equipped - with power-loss protection; see [scs-0110-v1-ssd-flavors](./scs-0110-v1-ssd-flavors.md). - The following properties must be set (in the `extra_specs`): - `scs:name-v4` to the recommended name, From acb3c96869cc51f0e02b5a84646bdb645bd781a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20B=C3=BCchse?= Date: Tue, 8 Aug 2023 11:54:03 +0200 Subject: [PATCH 09/17] SSD flavors are mandatory (revert b7d655ab6dd07dd769e73b255e53ff5ae3695c5c) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Matthias Büchse --- Standards/scs-0103-v1-standard-flavors.md | 5 ++--- Tests/iaas/scs-0103-v1-flavors.yaml | 24 +++++++++++------------ 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/Standards/scs-0103-v1-standard-flavors.md b/Standards/scs-0103-v1-standard-flavors.md index fa8d88987..69a965d74 100644 --- a/Standards/scs-0103-v1-standard-flavors.md +++ b/Standards/scs-0103-v1-standard-flavors.md @@ -39,9 +39,11 @@ These are flavors that must exist on standard SCS clouds (x86-64). | SCS-1V-4 | 1 | shared core | 4 | | | | SCS-2V-8 | 2 | shared core | 8 | | | | SCS-4V-16 | 4 | shared core | 16 | | | +| SCS-4V-16-100s | 4 | shared core | 16 | 100 | ssd | | SCS-8V-32 | 8 | shared core | 32 | | | | SCS-1V-2 | 1 | shared core | 2 | | | | SCS-2V-4 | 2 | shared core | 4 | | | +| SCS-2V-4-20s | 2 | shared core | 4 | 20 | ssd | | SCS-4V-8 | 4 | shared core | 8 | | | | SCS-8V-16 | 8 | shared core | 16 | | | | SCS-16V-32 | 16 | shared core | 32 | | | @@ -57,11 +59,9 @@ These are flavors that must exist on standard SCS clouds (x86-64). | SCS-1V-4-10 | 1 | shared core | 4 | 10 | (any) | | SCS-2V-8-20 | 2 | shared core | 8 | 20 | (any) | | SCS-4V-16-50 | 4 | shared core | 16 | 50 | (any) | -| SCS-4V-16-100s | 4 | shared core | 16 | 100 | ssd | | SCS-8V-32-100 | 8 | shared core | 32 | 100 | (any) | | SCS-1V-2-5 | 1 | shared core | 2 | 5 | (any) | | SCS-2V-4-10 | 2 | shared core | 4 | 10 | (any) | -| SCS-2V-4-20s | 2 | shared core | 4 | 20 | ssd | | SCS-4V-8-20 | 4 | shared core | 8 | 20 | (any) | | SCS-8V-16-50 | 8 | shared core | 16 | 50 | (any) | | SCS-16V-32-100 | 16 | shared core | 32 | 100 | (any) | @@ -127,7 +127,6 @@ The list of standard flavors used to be part of the flavor naming standard up un [version 3](scs-0100-v3-flavor-naming.md). The following changes have been made to the list in comparison with said standard: -- two flavors with ssds have been relegated to recommended status, - the flavor names have been turned into recommendations, and - the properties have been introduced in order to help discoverability. diff --git a/Tests/iaas/scs-0103-v1-flavors.yaml b/Tests/iaas/scs-0103-v1-flavors.yaml index 9407c62cc..0c09fed7d 100644 --- a/Tests/iaas/scs-0103-v1-flavors.yaml +++ b/Tests/iaas/scs-0103-v1-flavors.yaml @@ -15,6 +15,12 @@ flavor_groups: cpus: 4 cpu-type: shared-core ram: 16 + - name: SCS-4V-16-100s + cpus: 4 + cpu-type: shared-core + ram: 16 + disk: 100 + disk0-type: ssd - name: SCS-8V-32 cpus: 8 cpu-type: shared-core @@ -27,6 +33,12 @@ flavor_groups: cpus: 2 cpu-type: shared-core ram: 4 + - name: SCS-2V-4-20s + cpus: 2 + cpu-type: shared-core + ram: 4 + disk: 20 + disk0-type: ssd - name: SCS-4V-8 cpus: 4 cpu-type: shared-core @@ -72,12 +84,6 @@ flavor_groups: cpu-type: shared-core ram: 16 disk: 50 - - name: SCS-4V-16-100s - cpus: 4 - cpu-type: shared-core - ram: 16 - disk: 100 - disk0-type: ssd - name: SCS-8V-32-100 cpus: 8 cpu-type: shared-core @@ -93,12 +99,6 @@ flavor_groups: cpu-type: shared-core ram: 4 disk: 10 - - name: SCS-2V-4-20s - cpus: 2 - cpu-type: shared-core - ram: 4 - disk: 20 - disk0-type: ssd - name: SCS-4V-8-20 cpus: 4 cpu-type: shared-core From a970f05eab8fd1aaa18a202f5d7d9647c529ad41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20B=C3=BCchse?= Date: Tue, 8 Aug 2023 11:55:23 +0200 Subject: [PATCH 10/17] Rename scs:name-v4 to v2 because the naming scheme has not changed since v2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Matthias Büchse --- Standards/scs-0103-v1-standard-flavors.md | 2 +- Tests/iaas/scs-0103-v1-flavors.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Standards/scs-0103-v1-standard-flavors.md b/Standards/scs-0103-v1-standard-flavors.md index 69a965d74..93d00f3ba 100644 --- a/Standards/scs-0103-v1-standard-flavors.md +++ b/Standards/scs-0103-v1-standard-flavors.md @@ -74,7 +74,7 @@ These are flavors that must exist on standard SCS clouds (x86-64). The following properties must be set (in the `extra_specs`): -- `scs:name-v4` to the recommended name, +- `scs:name-v2` to the recommended name, - `scs:cpu-type` to `shared-core` or `crowded-core`, reflecting the vCPU type, - `scs:disk0-type` not set if no disk is provided, otherwise set to `ssd` or some other value, reflecting the disk type. diff --git a/Tests/iaas/scs-0103-v1-flavors.yaml b/Tests/iaas/scs-0103-v1-flavors.yaml index 0c09fed7d..c977c24c6 100644 --- a/Tests/iaas/scs-0103-v1-flavors.yaml +++ b/Tests/iaas/scs-0103-v1-flavors.yaml @@ -1,5 +1,5 @@ meta: - name_key: scs:name-v4 + name_key: scs:name-v2 flavor_groups: - status: mandatory list: From 407386abe9ca5fc96fef88d4150f1c9e25cc41cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20B=C3=BCchse?= Date: Tue, 8 Aug 2023 12:01:33 +0200 Subject: [PATCH 11/17] Make requirements more precise, enhance discoverability MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Matthias Büchse --- Standards/scs-0103-v1-standard-flavors.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Standards/scs-0103-v1-standard-flavors.md b/Standards/scs-0103-v1-standard-flavors.md index 93d00f3ba..5b2a0b2fb 100644 --- a/Standards/scs-0103-v1-standard-flavors.md +++ b/Standards/scs-0103-v1-standard-flavors.md @@ -20,6 +20,8 @@ to have a guaranteed set of flavors available on all SCS clouds, so these need n The following extra specs are recognized, together with the respective semantics: +- `scs:name-v2=NAME` (where `NAME` is some string) means that the flavor is one of the + standard SCS flavors, and the requirements of Section "Standard SCS flavors" below apply. - `scs:cpu-type=shared-core` means that _at least 20% of a core in >99% of the time_, measured over the course of one month (1% is 7,2 h/month). - `scs:diskN-type=ssd` (where `N` is a nonnegative integer, usually `0`) means that the @@ -72,7 +74,10 @@ These are flavors that must exist on standard SCS clouds (x86-64). ### Guarantees and properties -The following properties must be set (in the `extra_specs`): +The figures given in the table (number of CPUs, amount of RAM, root disk size) must match +precisely the corresponding figures in the flavor. + +In addition, the following properties must be set (in the `extra_specs`): - `scs:name-v2` to the recommended name, - `scs:cpu-type` to `shared-core` or `crowded-core`, reflecting the vCPU type, From 69ac212c242e458fce2a0f4563eaddbcf58d6be9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20B=C3=BCchse?= Date: Tue, 15 Aug 2023 10:55:36 +0200 Subject: [PATCH 12/17] Change scs-0100-v3 in place because the change doesn't render any implementation unconformant MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Matthias Büchse --- Standards/scs-0100-v3-flavor-naming.md | 73 +-- Standards/scs-0100-v4-flavor-naming.md | 521 ------------------ ...-flavors.yaml => scs-0100-v3-flavors.yaml} | 0 Tests/testing/scs-compatible-test.yaml | 4 +- 4 files changed, 11 insertions(+), 587 deletions(-) delete mode 100644 Standards/scs-0100-v4-flavor-naming.md rename Tests/iaas/{scs-0100-v4-flavors.yaml => scs-0100-v3-flavors.yaml} (100%) diff --git a/Standards/scs-0100-v3-flavor-naming.md b/Standards/scs-0100-v3-flavor-naming.md index 636c730f0..4d4447ac7 100644 --- a/Standards/scs-0100-v3-flavor-naming.md +++ b/Standards/scs-0100-v3-flavor-naming.md @@ -9,7 +9,7 @@ replaces: scs-0100-v2-flavor-naming.md ## Introduction -This is the standard v3.0 for SCS Release 5. +This is the standard v3.1 for SCS Release 5. Note that we intend to only extend it (so it's always backwards compatible), but try to avoid changing in incompatible ways. (See at the end for the v1 to v2 transition where we have not met that @@ -22,10 +22,7 @@ The flavors are pre-defined by the operator, the customer can not change these. OpenStack providers thus typically offer a large selection of flavors. While flavors can be discovered (`openstack flavor list`), it is helpful for users (DevOps teams), -to have - -- A naming scheme that is used across all SCS flavors, so flavor names have the same meaning everywhere. -- Have a guaranteed set of flavors available on all SCS clouds, so these do not need to be discovered. +to have a naming scheme that is used across all SCS flavors, so flavor names have the same meaning everywhere. While not all details will be encoded in the name, the key features should be obvious: Number of vCPUs, RAM, Root Disk. @@ -226,56 +223,6 @@ so users can expect some level of parallelism and independence. - SCS-2C-4-3x10 <- Cloud decides type and creates three 10GB volumes - ~~SCS-2C-4-**1.5n**~~ <- You must not specify disk sizes which are not in full GiBs -## Standard SCS flavors - -These are flavors that must exist on standard SCS clouds (x86-64). - -We recommend disk sizes to be 5, 10, 20, 50, 100, 200, 500, 1000GB, 2000GB. -We expect the most used vCPU:Mem[GiB] ratio to be 1:4. - -| vCPU:RAM ratio | Mandatory Flavors | Recommended Flavors | -| -------------- | ------------------------- | ------------------- | -| 1:4 | SCS-1V-4 | SCS-1V-4-10 | -| 2:8 | SCS-2V-8 | SCS-2V-8-20 | -| 4:16 | SCS-4V-16, SCS-4V-16-100s | SCS-4V-16-50 | -| 8:32 | SCS-8V-32 | SCS-8V-32-100 | -| 1:2 | SCS-1V-2 | SCS-1V-2-5 | -| 2:4 | SCS-2V-4, SCS-2V-4-20s | SCS-2V-4-10 | -| 4:8 | SCS-4V-8 | SCS-4V-8-20 | -| 8:16 | SCS-8V-16 | SCS-8V-16-50 | -| 16:32 | SCS-16V-32 | SCS-16V-32-100 | -| 1:8 | SCS-1V-8 | SCS-1V-8-20 | -| 2:16 | SCS-2V-16 | SCS-2V-16-50 | -| 4:32 | SCS-4V-32 | SCS-4V-32-100 | -| 1:1 | SCS-1L-1 | SCS-1L-1-5 | - -Note that all vCPUs of SCS standard flavors are oversubscribed — the smallest `1L-1` -flavor allows for heavy oversubscription (note the `L`), and thus can be offered very -cheaply — imagine jump hosts ... - -The design allows for small clouds (with CPUs with 16 Threads, 64GiB RAM -compute hosts) to offer all flavors. - -Note that the flavors with fixed size root disks have all moved to Recommended -in version 3 of the standard. This means that they are not a certification requirement any longer, -but we still recommend implementing these for backwards compatibility reasons. -Disks types are not specified (and expected to be n or h typically). - -However, two flavors with SSD+ root disks have been added in v3, as defined in -[scs-0110-v1-ssd-flavors.md](https://github.com/SovereignCloudStack/standards/blob/main/Standards/scs-0110-v1-ssd-flavors.md) - -Note: Compared to previous drafts, we have heavily reduced the variations -on disk sizes — this reflects that for the standard networked cinder -disks, you can pass `block_device_mapping_v2` on server (VM) creation to -allocate a boot disk of any size you desire. We have scaled the few -recommended disk sizes with the amount of RAM. For each flavor there is -also one _without_ a pre-attached disk — these are meant to be used -to boot from a volume (either created beforehand or allocated on-the-fly -with `block_device_mapping_v2`, e.g. -`openstack server create --flavor SCS-1V:2 --block-device-mapping sda=IMGUUID:image:12:true` -to create a bootable 12G cinder volume from image `IMGUUID` that gets tied to the VM -instance life cycle.) - ## Naming policy compliance You are allowed to understate your performance; you may implement a SCS-1V-1-5 flavor with @@ -306,7 +253,7 @@ You must not offer flavors with the `SCS-` prefix which do not follow this namin You must not extend the SCS naming scheme with your own extensions; you are encouraged however to suggest extensions that we can discuss and add to the official scheme. -## Validation +## Conformance Tests There is a script in [`flavor-name-check.py`](https://github.com/SovereignCloudStack/standards/blob/main/Tests/iaas/flavor-naming/flavor-name-check.py) which can be used to decode, validate and construct flavor names. @@ -319,17 +266,11 @@ on the flavor list compliance of the cloud environment. The script `flavor-names-openstack.py` talks to the OpenStack API of the cloud specified by the `OS_CLOUD` environment and queries properties and checks -the names for standards compliance and completeness w.r.t. the mandatory -flavor list. It goes beyond the above example in checking that the discoverable +the names for standards compliance. +It goes beyond the above example in checking that the discoverable features of flavors (vCPUs, RAM, Disk) match what the flavor names claim. This is used for SCS-compatible compliance testing. -## Operational tooling - -The [openstack-flavor-manager](https://github.com/osism/openstack-flavor-manager) is able to -create all standard, mandatory SCS flavors for you. It takes input that can be generated by -`flavor-manager-input.py`. - ## Extensions Extensions provide a possibility for providers that offer a very differentiated set @@ -526,6 +467,10 @@ an image is considered broken by the SCS team. ## Previous standard versions +Previous versions up to version 3.0 contained the list of +mandatory/recommended flavors, which has been moved to +[a standard of its own](scs-0103-v1-standard-flavors.md). + [Version 1 of the standard](scs-0100-v1-flavor-naming.md) used a slightly different naming syntax while the logic was exactly the same. What is a `-` in v2 used to be a `:`; `_` used to be `-`. The reason for diff --git a/Standards/scs-0100-v4-flavor-naming.md b/Standards/scs-0100-v4-flavor-naming.md deleted file mode 100644 index 1c6bfafef..000000000 --- a/Standards/scs-0100-v4-flavor-naming.md +++ /dev/null @@ -1,521 +0,0 @@ ---- -title: SCS Flavor Naming Standard -type: Standard -status: Draft -track: IaaS -replaces: scs-0100-v3-flavor-naming.md ---- - -## Introduction - -This is the standard v4.0 for SCS Release 5. -Note that we intend to only extend it (so it's always backwards compatible), -but try to avoid changing in incompatible ways. -(See at the end for the v1 to v2 transition where we have not met that -goal, but at least managed to have a 1:1 relationship between v1 and v2 names.) - -## Motivation - -In OpenStack environments there is a need to define different flavors for instances. -The flavors are pre-defined by the operator, the customer can not change these. -OpenStack providers thus typically offer a large selection of flavors. - -While flavors can be discovered (`openstack flavor list`), it is helpful for users (DevOps teams), -to have a naming scheme that is used across all SCS flavors, so flavor names have the same meaning everywhere. - -While not all details will be encoded in the name, the key features should be obvious: -Number of vCPUs, RAM, Root Disk. -Extra features are important as well: There will be flavors with GPU support, fast disks for databases, -memory-heavy applications, and other useful aspects of an instance. - -It may also be important to make the CPU generation clearly recognizable, as this is always a topic in -discussions with customers. - -Note that not all relevant properties of flavors can be discovered; creating a specification -to address this is a separate but related effort to the name standardization. -Commonly used infrastructure-as-code tools do not provide a way to use discoverability -features to express something like "I want a flavor with 2 vCPUs, 8GiB of RAM, a local -20GB SSD disk and Infiniband support but I don't care whether it's AMD or intel" in a -reasonable manner. Using flavor names to express this will thus continue to be useful -and we don't expect the need for standardization of flavor names to go away until -the commonly used IaC tools work on a higher abstraction layer than they currently do. - -## Design Considerations - -### Type of information included - -From discussions of our operators with their customers we learned that -the following characteristics are important in a flavor description: - -| Type | Description | -| :---------------- | :----------------------------------------------------- | -| Generation | CPU Generation | -| Number of CPU | Number of vCPUs - suffixed by L,V,T,C (see below) | -| Amount of RAM | Amount of memory available for the VM | -| Performance Class | Ability to label high-performance CPUs, disks, network | -| CPU Type | X86-intel, X86-amd, ARM, RISC-V, Generic | -| "bms" | Bare Metal System (no virtualization/hypervisor) | - -This list is likely not comprehensive and will grow over time. - -Rather than using random names `s5a.medium` and assigning a discrete set of properties -to them, we wanted to come up with a scheme that allows to systematically derive -names from properties and vice versa. The scheme allows for short names (by not -encoding all details) as well as very detailed longer names. - -## Complete Proposal for systematic flavor naming - -| Prefix | CPUs & Suffix | RAM[GiB] | optional: Disk[GB]&type | opt: extensions | -| ------ | ----------------- | ------------------ | ----------------------------- | ----------------| -| `SCS-` | N`L/V/T/C`\[`i`\] | `-`N\[`u`\]\[`o`\] | \[`-`\[M`x`\]N\[`n/s/l/p`\]\] | \[`_`EXT\] | - -Note that N and M are placeholders for numbers here. -The optional fields are denoted in brackets (and have opt: in the header. -See below for extensions. - -Note that all letters are case-sensitive. - -Typical flavor names look like `SCS-4V-16-50` for a flavor with 4vCPUs (with limited -oversubscription), 16GiB RAM and a 50GB disk (of unspecified type). - -## Proposal Details - -### [REQUIRED] CPU Suffixes - -Next to the number of vCPUs, these vCPUs need to be characterized ti describe their nature. - -| Suffix | Meaning | -| ------ | ----------------------------- | -| C | dedicated Core | -| T | dedicated Thread (SMT) | -| V | vCPU (oversubscribed) | -| L | vCPU (heavily oversubscribed) | - -#### Baseline - -Note that vCPU oversubscription for a `V` vCPU should be implemented such, that we -can guarantee _at least 20% of a core in >99% of the time_; this can be achieved by -limiting vCPU oversubscription to 5x per core (or 3x per thread when SMT/HT is enabled) -or by more advanced workload management logic. Otherwise `L` (low performance) instead -of `V` must be used. The >99% is measured over a month (1% is 7.2h/month). - -Note that CPUs should use latest microcode to protect against CPU vulnerabilities (Spectre, Meltdown, L1TF, etc.). -Microcode must be updated within less than a month of a new release; for CVSS scores above 8, -providers should do it in less than a week. -The provider should enable at least all mitigations that are enabled by default in the Linux kernel and the -KVM hypervisor. CPUs that are susceptible to L1TF (intel x86 pre Cascade Lake) should switch off hyperthreading -OR (in the future) use core scheduling implementations that are deemed to be secure by the SCS security team. - -If microcode updates needed for mitigation are lacking for longer than a month, default kernel/hypervisor -mitigations are disabled or hyperthreading is enabled despite the CPU being susceptible to L1TF, the -flavors must declare themselves insecure with the `i` suffix (see below). - -#### Higher oversubscription - -Must be indicated with a `L` vCPU type (low performance for > 5x/core or > 3x/thread oversubscription and -the lack of workload management that would prevent worst case performance <20% in more than 7.2h per month). - -#### Insufficient microcode - -Not using these mitigations must be indicated by an additional `i` suffix for insecure -(weak protection against CPU vulns through insufficient microcode, lack of disabled hyperthreading -on L1TF susceptible CPUs w/o effective core scheduling or disabled protections on the host/hypervisor). - -#### Examples - -- SCS-**2C**-4-10n -- SCS-**2T**-4-10n -- SCS-**2V**-4-10n -- SCS-**2L**-4-10n -- SCS-**2Li**-4-10n -- ~~SCS-**2**-\*\*4-10n~~ <- CPU suffix missing -- ~~SCS-**2iT**-4-10n~~ <- This order is forbidden - -### [REQUIRED] Memory - -#### Baseline - -Cloud providers should use ECC memory. -Memory oversubscription should not be used. -It is allowed to specify half GiBs (e.g. 3.5), though this is should not be done for larger memory sizes (>= 10GiB). - -#### No ECC - -If no ECC is used, the `u` suffix must indicate this. - -#### Enabled Oversubscription - -If memory is oversubscribed, you must expose this with the `o` suffix. - -#### Examples - -- SCS-2C-**4**-10n -- SCS-2C-**3.5**-10n -- SCS-2C-**4u**-10n -- SCS-2C-**4o**-10n -- SCS-2C-**4uo**-10n -- ~~SCS-2C-**4ou**-10n~~ <- This order is forbidden - -### [OPTIONAL] Disk sizes and types - -Disk sizes (in GB) should use sizes 5, 10, 20, 50, 100, 200, 500, 1000. - -| Disk type | Meaning | -| --------- | ------------------------------------ | -| n | Network shared storage (ceph/cinder) | -| h | Local disk (HDD: SATA/SAS class) | -| s | Local SSD disk | -| p | Local high-perf NVMe | - -#### Baseline - -Note that disk type might be omitted — the user then can not take any assumptions -on what storage is provided for the root disk (that the image gets provisioned to). - -It does make sense for `n` to be requested explicitly to allow for smooth live migration. -`h` typically provides latency advantages vs `n` (but not necessarily bandwidth and -also is more likely to fail), `s` and `p` are for applications that need low -latency (high IOPS) and bandwidth disk I/O. `n` storage is expected to survive -single-disk and single-node failure. - -For specific requirements on the SSD and NVMe disks regarding IOPS and -power-loss protection, refer to Decision Record [scs-0110-ssd-flavors](https://github.com/SovereignCloudStack/standards/blob/main/Standards/scs-0110-v1-ssd-flavors.md). - -If the disk size is left out, the cloud is expected to allocate a disk (network or local) -that is large enough to fit the root file system (`min_disk` in image). This automatic -allocation is indicated with `-` without a disk size. -If the `-` is left out completely, the user must create a boot volume manually and -tell the instance to boot from it or use the -[`block_device_mapping_v2`](https://docs.openstack.org/api-ref/compute/?expanded=create-server-detail#create-server) -mechanism explicitly to create the boot volume from an image. - -#### Multi-provisioned Disk - -The disk size can be prefixed with `Mx prefix`, where M is an integer specifying that the disk -is provisioned M times. Multiple disks provided this way should be independent storage media, -so users can expect some level of parallelism and independence. - -#### Examples - -- SCS-2C-4-**10n** -- SCS-2C-4-**10s** -- SCS-2C-4-**10s**\_bms_z3 -- SCS-2C-4-**3x10s** <- Cloud creates three 10GB SSDs -- SCS-2C-4-**3x10s**\_bms_z3 -- SCS-2C-4-**10** <- Cloud decides disk type -- SCS-2C-4-**10**\_bms_z3 -- SCS-2C-4-**n** <- Cloud decides disk size (min_disk from image or larger) -- SCS-2C-4-**n**\_bms_3 -- SCS-2C-4- <- Cloud decides disk type and size -- SCS-2C-4-\_bms_z3 -- SCS-2C-4-\_bms_z3h_GNa-64_ib -- SCS-2C-4-\_ib -- SCS-2C-4 <- You need to specify a boot volume yourself (boot from volume, or use `block_device_mapping_v2`) -- SCS-2C-4_bms_z3 -- SCS-2C-4-3x- <- Cloud decides disk type and size and creates three of them (FIXME: Is this useful?) -- SCS-2C-4-3xs <- Cloud decides size and creates three local SSD volumes (FIXME: useful?) -- SCS-2C-4-3x10 <- Cloud decides type and creates three 10GB volumes -- ~~SCS-2C-4-**1.5n**~~ <- You must not specify disk sizes which are not in full GiBs - -## Naming policy compliance - -To be certified as an SCS compliant x86-64 IaaS platform, you must offer all standard mandatory SCS -flavors according to the previous section. (We may define a mechanism that allows exceptions to be -granted in a way that makes this very transparent and visible to clients.) - -You are allowed to understate your performance; you may implement a SCS-1V-1-5 flavor with -a flavor that actually implements SCS-1T-1-5n (i.e. you dedicate a dedicated hyperthread instead -of higher oversubscription) or even SCS-1C-1.5-8s (1 dedicated core, 50% more RAM and a 8GiB SSD). -Or you may offer the (v3 mandatory) `SCS-2V-4-20s` with a `SCS-2V-4-20p` (using a local NVMe -instead of an SSD). - -Flavor names indicating certain capabilities must _at least_ provide these, otherwise they -are in violation of the SCS specification and prevent SCS compliance. - -We expect all cloud providers to offer the short, less specific flavor names (such as SCS-8V-32-100). -Larger providers that offer more details (using the extension below) are expected to still also -offer the short variants for usability and easier portability, even beyond the mandated flavors. - -You must be very careful to expose low vCPU guarantees (`L` instead of `V`), insecure -hyperthreading/microcode `i`, non-ECC-RAM `u`, memory oversubscription `o`. Note that omitting these qualifiers -is _overstating_ your security, reliability or performance properties and may be reason for -clients to feel betrayed or claim damages. This would prevent SCS compliance and certification; -in extreme cases, the SCS project might be forced to work with public statements. - -You may offer additional `SCS-` flavors, following the naming scheme and rules outlined here. - -You may offer additional flavors, not following above scheme and not starting with `SCS-` - -You must not offer flavors with the `SCS-` prefix which do not follow this naming scheme. - -You must not extend the SCS naming scheme with your own extensions; you are encouraged however -to suggest extensions that we can discuss and add to the official scheme. - -## Conformance Tests - -There is a script in [`flavor-name-check.py`](https://github.com/SovereignCloudStack/standards/blob/main/Tests/iaas/flavor-naming/flavor-name-check.py) -which can be used to decode, validate and construct flavor names. -[`flavor-name-describe.py`](https://github.com/SovereignCloudStack/standards/blob/main/Tests/iaas/flavor-naming/flavor-name-describe.py) outputs a human-readable decoding of the SCS flavor names. -These scripts must stay in sync with the specification text. - -Ensure you have your OpenStack tooling (`python3-openstackclient`, `OS_CLOUD`) setup and call -`tools/flavor-name-check.py -c $(openstack flavor list -f value -c Name)` to get a report -on the flavor list compliance of the cloud environment. - -The script `flavor-names-openstack.py` talks to the OpenStack API of the -cloud specified by the `OS_CLOUD` environment and queries properties and checks -the names for standards compliance. -It goes beyond the above example in checking that the discoverable -features of flavors (vCPUs, RAM, Disk) match what the flavor names claim. -This is used for SCS-compatible compliance testing. - -## Extensions - -Extensions provide a possibility for providers that offer a very differentiated set -of flavors to indicate hypervisors, support for hardware/nested virtualization, -CPU types and generations, high-frequency models, GPU support and GPU types as -well as Infiniband support. (More extensions may be appended in the future.) - -Using the systematic naming approach ensures that two providers that offer flavors -with the same specific features will use the same name for them, thus simplifying -life for their customers when consuming these flavors. - -Note that there is no need to indicate all details and extra features this way. -Flavors may always perform better or have more features than indicated in a name. -Underperformance (CPU suffices `L` or `i` or memory suffices `o` and `u`) on the other -hand MUST be indicated in the name; this happens rarely in practice. - -For smaller providers, the ability to e.g. differentiate between an AMD Milan and an intel -IceLake and exposed the slightly different feature set to customers and have slightly -different price points is often not worth the extra effort. This is because having -this extra differentiation causes fragmentation of the machines (host aggregates) -that can offer these flavors, thus resulting in a lower utilization (as the capacity -management will need to have a certain amount of headroom per machine pool to avoid -running out of capacity). - -Note that it is possible for providers to register both the generic short names and the -longer, more detailed names and allow them to use the same set of machines (host aggregates). -Note that machines (hypervisors) can be part of more than one host aggregate. - -The extensions have the format: - -\[`_`hyp\]\[`_hwv`\]\[`_`\[arch\[N\]\[`h`\]\[`_`\[`G/g`\]X\[N\]\[`-`M\[`h`\]\]\]\[`_ib`\] - -Remember that letters are case-sensitive. -In case you wonder: Feature indicators are capitalized, modifiers are lower case. -(An exception is the uppercase `_G` for a pass-through GPU vs. lowercase `_g` for vGPU.) - -### [OPTIONAL] Hypervisor - -The _default Hypervisor_ is assumed to be `KVM`. Clouds, that offer different hypervisors -or Bare Metal Systems should indicate the Hypervisor according to the following table: - -| hyp | Meaning | -| --- | ----------------- | -| kvm | KVM | -| xen | Xen | -| vmw | VMware | -| hyv | Hyper-V | -| bms | Bare Metal System | - -#### Examples - -- SCS-2C-4-10n -- SCS-2C-4-10n\_**bms** -- SCS-2C-4-10n\_**bms**\_z3h - -### [OPTIONAL] Hardware virtualization / Nested virtualization - -If the instances that are created with this flavor support hardware-accelerated -virtualization, this can be reflected with the `_hwv` flag (after the optional -Hypervisor flag). On x86, this means that in the instance, the CPU flag vmx (intel) -or svm (AMD) is available. This will be the case on Bare Metal flavors on almost -all non-ancient x86 CPUs or if your virtualization hypervisor is configured to -support nested virtualization. -Flavors without the `_hwv` flag may or may not support hardware virtualization (as we -recommend enabling nesting, but don't require flavor names to reflect all -capabilities. Flavors may over-deliver ...) - -#### Examples - -- SCS-2C-4-10 <- may or may not support HW virtualization in VMs -- SCS-2C-4-10_kvm_**hwv** <- kvm with enabled nested virtualization -- SCS-2C-4-10\_**hwv** <- not recommended, but allowed -- SCS-2C-4-10\_bms\_**hwv** <- better: bare metal with HW virt support (VMX on intel, SVM on AMD, ...) -- ~~SCS-2C-4-10\_**hwv**\_xen~~ <- illegal, wrong ordering - -### [OPTIONAL] CPU Architecture Details - -Arch details provide more details on the specific CPU: - -- Vendor -- Generation -- Frequency - -#### Generation and Vendor - -The generations are vendor specific and can be left out. -Not specifying arch means that we have a generic CPU (**x86-64**). -The letters `i`, `z`, `a` and `r` specify the vendors Intel, -AMD (`z` like in Zen), ARM v8+, RISC-V. - -| Generation | i (Intel x86-64) | z (AMD x86-64) |  a (AArch64) | r (RISC-V) | -| ---------- | ---------------- | -------------- | ------------------ | ---------- | -| 0 | pre Skylake | pre Zen | pre Cortex A76 | TBD | -| 1 | Skylake | Zen-1 (Naples) | A76/NeoN1 class | TBD | -| 2 | Cascade Lake | Zen-2 (Rome) | A78/x1/NeoV1 class | TBD | -| 3 | Ice Lake | Zen-3 (Milan) | A71x/NeoN2 (ARMv9) | TBD | -| 4 | Sapphire Rapids | Zen-4 (Genoa) | | TBD | - -It is recommended to leave out the `0` when specifying the old generation; this will -help the parser tool, which assumes 0 for an unspecified value and does leave it -out when generating the name for comparison. In other words: 0 has a meaning of -"rather old or unspecified". - -#### Frequency Suffixes - -| Suffix | Meaning | -| ------ | ----------------- | -| h | >2.75GHz all-core | -| hh | >3.25GHz all-core | -| hhh | >3.75GHz all-core | - -#### Examples - -- SCS-2C-4-10n -- SCS-2C-4-10n\_**z** -- SCS-2C-4-10n\_**z3** -- SCS-2C-4-10n\_**z3h** -- SCS-2C-4-10n\_**z3hh** -- SCS-2C-4-10n_bms_**z** -- SCS-2C-4-10n_bms_**z3** -- SCS-2C-4-10n_bms_**z3** -- SCS-2C-4-10n_bms_**z3h** -- SCS-2C-4-10n_bms_**z3hh** <- Bare Metal, Intel Ice Lake with > 3.25GHz all core freq - -### [OPTIONAL] GPU support - -`_G`X\[N\]\[`-`M\[`h`\]\] indicates a Pass-Through GPU from vendor X of gen N with M compute units / SMs / EUs exposed. -`_g`X\[N\]\[`-`M\[`h`\]\] indicates a vGPU from vendor X of gen N with M compute units / SMs / EUs assigned. - -Note that the vendor letter X is mandatory, generation and compute units are optional. - -| GPU | Vendor | -| --- | ------ | -| N | nVidia | -| A | AMD | -| I | Intel | - -For nVidia, the generation N can be f=Fermi, k=Kepler, m=Maxwell, p=Pascal, v=Volta, t=turing, a=Ampere, l=Ada Lovelace, ..., -for AMD GCN-x=0.x, RDNA1=1, RDNA2=2, RDNA3=3, for intel Gen9=0.9, Xe(12.1)=1, ... -(Note: This may need further work to properly reflect what's out there.) - -The optional `h` suffix to the compute unit count indicates high-performance (e.g. high freq or special -high bandwidth gfx memory such as HBM); -`h` can be duplicated for even higher performance. - -### [OPTIONAL] Infiniband - -`_ib` indicates Infiniband networking. - -More extensions may be forthcoming and appended in a later revision of this spec. - -Extensions need to be specified in the above mentioned order. - -### Naming options advice - -Note that we expect most clouds to prefer short flavor names, -not indicating CPU details or hypervisor types. See above list -of standard flavors to get a feeling. - -However, more successful providers will often need to differentiate their -offerings in response to customer demand and allow customers to request -flavors with specific detailed properties. The goal of this proposal is to avoid -providers to invent their own names and then refer customers to (currently -incompletely standardized) `extra_specs` -or worse a non-machine-readable service descriptions to find out the details. - -So a cloud provider might well evolve from offering `SCS-8T-16-50` to offering -`SCS-8T-16-50n`, `SCS-8T-16-50n_i2` and `SCS-8T-16-50n_z2` to specify that he -is using network disks and offer a choice b/w intel Cascade-Lake and AMD Rome. -We would expect the cloud provider to still offer the generic flavor -`SCS-8T-16-50` and allow the scheduler (placement service) to pick both more -specific types (or just one if e.g. capacity management considerations suggest -so). Providers in such cases should ensure that the price of a requested -flavor does not depend on the scheduler decisions. - -We are looking into the [metadefs](https://docs.openstack.org/image-guide/introduction.html#metadata-definition-metadefs-service) -mechanism and [extra_specs](https://docs.openstack.org/api-guide/compute/extra_specs_and_properties.html) -to allow customers to ask for specific flavor properties without the need to -encode all these flavor details into the flavor name, so the optional pieces -may not be needed much. However, there must be a way to request flavor -properties without encoding the need into an image — the indirection via -an image is considered broken by the SCS team. - -## Proposal Examples - -| Example | Decoding | -| ------------------------- | ---------------------------------------------------------------------------------------------- | -| SCS-2C-4-10n | 2 dedicated cores (x86-64), 4GiB RAM, 10GB network disk | -| SCS-8Ti-32-50p_i1 | 8 dedicated hyperthreads (insecure), Skylake, 32GiB RAM, 50GB local NVMe | -| SCS-1L-1u-5 | 1 vCPU (heavily oversubscribed), 1GiB Ram (no ECC), 5GB disk (unspecific) | -| SCS-16T-64-200s_GNa-64_ib | 16 dedicated threads, 64GiB RAM, 200GB local SSD, Infiniband, 64 Passthrough nVidia Ampere SMs | -| SCS-4C-16-2x200p_a1 | 4 dedicated Arm64 cores (A76 class), 16GiB RAM, 2x200GB local NVMe drives | -| SCS-1V-0.5 | 1 vCPU, 0.5GiB RAM, no disk (boot from cinder volume) | - -## Previous standard versions - -Previous versions up to [version 3](scs-0100-v3-flavor-naming.md) contained the list of -mandatory/recommended flavors, which has been moved to -[a standard of its own](scs-0103-v1-standard-flavors.md). - -[Version 1 of the standard](scs-0100-v1-flavor-naming.md) -used a slightly different naming syntax while the logic was exactly the same. -What is a `-` in v2 used to be a `:`; `_` used to be `-`. The reason for -the change was certain Kubernetes tools using the flavor names as labels. -Labels however are subject to stricter naming rules and in particular don't -allow for a `:`. See [PR #190](https://github.com/SovereignCloudStack/standards/issues/190) -for a discussion. - -Version 1 flavor names can be translated to v2 using the following transformation: - -```shell -NAMEV2=$(echo "$NAMEV1" | sed -e 's/\-/_/g' -e 's/:/-/g' -e 's/^SCS_/SCS-/') -``` - -and the way back can be done with - -```shell -NAMEV1=$(echo "$NAMEV2" | sed -e 's/\-/:/g' -e 's/_/-/g' -e 's/^SCS:/SCS-/') -``` - -Considerations for how providers can ensure a smooth transition for their customers -from v1 to v2 are written in a separate document. - -For the time being, the validation tools still accept the old names with a warning -(despite the unchanged `SCS-` prefix) unless you pass option `-2` to them. They will -however not count v1 flavors towards fulfilling the needs against the corresponding -v2 mandatory flavor list unless you pass the option `-1`. -In other words: An IaaS infrastructure with the 26 -v1 mandatory flavors will produce 26 warnings (for using old flavors) and 26 -errors (for missing the 26 mandatory v2 flavors) unless you pass `-1` in which -case no errors and no warnings will be produced. Registering the 26 mandatory -v2 flavor names in addition will result in passing the test with only 26 -warnings — unless you specify `-2`. If you do and want to pass you'll need -to remove the old v1 names or rename them to no longer start with `SCS-`. - -## Beyond SCS - -The Gaia-X provider working group which could have created a superseding standard -does no longer exist. - -However, we have been reaching out to the OpenStack Public Cloud SIG and the ALASCA -members to seek further alignment. - -Getting upstream OpenStack support for flavor aliases would provide more flexibility -and ease migrations between providers, also providers that don't offer the SCS- -flavors. - -We also would like to see upstream `extra_specs` standardizing the discoverability of some -properties exposed via the SCS names and work on IaC tooling (terraform ...) -to make use of these when selecting a flavor. diff --git a/Tests/iaas/scs-0100-v4-flavors.yaml b/Tests/iaas/scs-0100-v3-flavors.yaml similarity index 100% rename from Tests/iaas/scs-0100-v4-flavors.yaml rename to Tests/iaas/scs-0100-v3-flavors.yaml diff --git a/Tests/testing/scs-compatible-test.yaml b/Tests/testing/scs-compatible-test.yaml index 9499dd89e..7652ef4c5 100644 --- a/Tests/testing/scs-compatible-test.yaml +++ b/Tests/testing/scs-compatible-test.yaml @@ -9,10 +9,10 @@ iaas: - executable: ./iaas/standard-flavors/flavors-openstack.py args: "./iaas/scs-0103-v1-flavors.yaml" - name: Flavor naming - url: https://raw.githubusercontent.com/SovereignCloudStack/standards/main/Standards/scs-0100-v4-flavor-naming.md + url: https://raw.githubusercontent.com/SovereignCloudStack/standards/main/Standards/scs-0100-v3-flavor-naming.md check_tools: - executable: ./iaas/flavor-naming/flavor-names-openstack.py - args: "--mand=./iaas/scs-0100-v4-flavors.yaml" + args: "--mand=./iaas/scs-0100-v3-flavors.yaml" - name: Image metadata url: https://raw.githubusercontent.com/SovereignCloudStack/standards/main/Standards/scs-0102-v1-image-metadata.md check_tools: From 96bfab4eaaeb402c77c9c0af3c1ca1b107e0aa60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20B=C3=BCchse?= Date: Tue, 15 Aug 2023 15:27:03 +0200 Subject: [PATCH 13/17] Tool to generate input for osism's flavor manager from this standard's yaml file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Matthias Büchse --- .../standard-flavors/flavor-manager-input.py | 86 +++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100755 Tests/iaas/standard-flavors/flavor-manager-input.py diff --git a/Tests/iaas/standard-flavors/flavor-manager-input.py b/Tests/iaas/standard-flavors/flavor-manager-input.py new file mode 100755 index 000000000..beec022ca --- /dev/null +++ b/Tests/iaas/standard-flavors/flavor-manager-input.py @@ -0,0 +1,86 @@ +#!/usr/bin/env python3 +""" +Convert yaml format from the one expected by flavors-openstack.py to the one expected +by osism's flavor manager, cf. https://github.com/osism/openstack-flavor-manager . + +The conversion is performed from stdin to stdout. +""" +import logging +import sys + +import yaml + + +logger = logging.getLogger(__name__) + + +def main(argv): + logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.INFO) + + # load the yaml, checking for sanity + try: + flavor_spec_data = yaml.safe_load(sys.stdin) + except Exception as e: + logger.critical(f"Unable to load: {e!r}") + logger.debug("Exception info", exc_info=True) + return 1 + + if 'meta' not in flavor_spec_data or 'name_key' not in flavor_spec_data['meta']: + logger.critical("Flavor definition missing 'meta' field or field incomplete") + return 1 + + if 'flavor_groups' not in flavor_spec_data: + logger.critical("Flavor definition missing 'flavor_groups' field") + + # boilerplate / scaffolding + result = yaml.safe_load(""" +reference: + - field: name + mandatory_prefix: SCS- + optional_prefix: SCSX- + - field: cpus + - field: ram + - field: disk + - field: public + default: true + - field: disabled + default: false +mandatory: [] +recommended: [] +""") + + # transfer the info into the result yaml, again checking for sanity + name_key = flavor_spec_data['meta']['name_key'] + for flavor_group in flavor_spec_data['flavor_groups']: + group_info = dict(flavor_group) + group_info.pop('list') + missing = {'status'} - set(group_info) + if missing: + logging.critical(f"Flavor group missing attributes: {', '.join(missing)}") + return 1 + group_info.pop('status') + result_list = result[flavor_group['status']] + for flavor_spec in flavor_group['list']: + missing = {'name', 'cpus', 'ram'} - set(flavor_spec) + if missing: + logging.critical(f"Flavor spec missing attributes: {', '.join(missing)}") + return 1 + flavor_spec = {**group_info, **flavor_spec} + extra_specs = {name_key: flavor_spec['name']} + extra_specs.update({ + f"scs:{key}": value + for key, value in flavor_spec.items() + if key not in ('name', 'cpus', 'ram', 'disk') + }) + flavor_spec = { + key: value + for key, value in flavor_spec.items() + if key in ('name', 'cpus', 'ram', 'disk') + } + result_list.append({**flavor_spec, **extra_specs}) + + print(yaml.dump(result, sort_keys=False)) + + +if __name__ == "__main__": + sys.exit(main(sys.argv[1:])) From 070db2c9223b4015b5c4151e1ccd099f221cc33d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20B=C3=BCchse?= Date: Thu, 17 Aug 2023 11:57:43 +0200 Subject: [PATCH 14/17] Include v1 names, make name handling more explicit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Matthias Büchse --- Tests/iaas/scs-0103-v1-flavors.yaml | 58 ++++++++++++++++++- .../standard-flavors/flavor-manager-input.py | 5 +- .../standard-flavors/flavors-openstack.py | 8 +-- 3 files changed, 63 insertions(+), 8 deletions(-) diff --git a/Tests/iaas/scs-0103-v1-flavors.yaml b/Tests/iaas/scs-0103-v1-flavors.yaml index c977c24c6..45c44b304 100644 --- a/Tests/iaas/scs-0103-v1-flavors.yaml +++ b/Tests/iaas/scs-0103-v1-flavors.yaml @@ -1,5 +1,5 @@ meta: - name_key: scs:name-v2 + name_key: name-v2 flavor_groups: - status: mandatory list: @@ -7,66 +7,96 @@ flavor_groups: cpus: 1 cpu-type: shared-core ram: 4 + name-v1: SCS-1V:4 + name-v2: SCS-1V-4 - name: SCS-2V-8 cpus: 2 cpu-type: shared-core ram: 8 + name-v1: SCS-2V:8 + name-v2: SCS-2V-8 - name: SCS-4V-16 cpus: 4 cpu-type: shared-core ram: 16 + name-v1: SCS-4V:16 + name-v2: SCS-4V-16 - name: SCS-4V-16-100s cpus: 4 cpu-type: shared-core ram: 16 disk: 100 disk0-type: ssd + name-v1: SCS-4V:16:100s + name-v2: SCS-4V-16-100s - name: SCS-8V-32 cpus: 8 cpu-type: shared-core ram: 32 + name-v1: SCS-8V:32 + name-v2: SCS-8V-32 - name: SCS-1V-2 cpus: 1 cpu-type: shared-core ram: 2 + name-v1: SCS-1V:2 + name-v2: SCS-1V-2 - name: SCS-2V-4 cpus: 2 cpu-type: shared-core ram: 4 + name-v1: SCS-2V:4 + name-v2: SCS-2V-4 - name: SCS-2V-4-20s cpus: 2 cpu-type: shared-core ram: 4 disk: 20 disk0-type: ssd + name-v1: SCS-2V:4:20s + name-v2: SCS-2V-4-20s - name: SCS-4V-8 cpus: 4 cpu-type: shared-core ram: 8 + name-v1: SCS-4V:8 + name-v2: SCS-4V-8 - name: SCS-8V-16 cpus: 8 cpu-type: shared-core ram: 16 + name-v1: SCS-8V:16 + name-v2: SCS-8V-16 - name: SCS-16V-32 cpus: 16 cpu-type: shared-core ram: 32 + name-v1: SCS-16V:32 + name-v2: SCS-16V-32 - name: SCS-1V-8 cpus: 1 cpu-type: shared-core ram: 8 + name-v1: SCS-1V:8 + name-v2: SCS-1V-8 - name: SCS-2V-16 cpus: 2 cpu-type: shared-core ram: 16 + name-v1: SCS-2V:16 + name-v2: SCS-2V-16 - name: SCS-4V-32 cpus: 4 cpu-type: shared-core ram: 32 + name-v1: SCS-4V:32 + name-v2: SCS-4V-32 - name: SCS-1L-1 cpus: 1 cpu-type: crowded-core ram: 1 + name-v1: SCS-1L:1 + name-v2: SCS-1L-1 - status: recommended list: - name: SCS-1V-4-10 @@ -74,63 +104,89 @@ flavor_groups: cpu-type: shared-core ram: 4 disk: 10 + name-v1: SCS-1V:4:10 + name-v2: SCS-1V-4-10 - name: SCS-2V-8-20 cpus: 2 cpu-type: shared-core ram: 8 disk: 20 + name-v1: SCS-2V:8:20 + name-v2: SCS-2V-8-20 - name: SCS-4V-16-50 cpus: 4 cpu-type: shared-core ram: 16 disk: 50 + name-v1: SCS-4V:16:50 + name-v2: SCS-4V-16-50 - name: SCS-8V-32-100 cpus: 8 cpu-type: shared-core ram: 32 disk: 100 + name-v1: SCS-8V:32:100 + name-v2: SCS-8V-32-100 - name: SCS-1V-2-5 cpus: 1 cpu-type: shared-core ram: 2 disk: 5 + name-v1: SCS-1V:2:5 + name-v2: SCS-1V-2-5 - name: SCS-2V-4-10 cpus: 2 cpu-type: shared-core ram: 4 disk: 10 + name-v1: SCS-2V:4:10 + name-v2: SCS-2V-4-10 - name: SCS-4V-8-20 cpus: 4 cpu-type: shared-core ram: 8 disk: 20 + name-v1: SCS-4V:8:20 + name-v2: SCS-4V-8-20 - name: SCS-8V-16-50 cpus: 8 cpu-type: shared-core ram: 16 disk: 50 + name-v1: SCS-8V:16:50 + name-v2: SCS-8V-16-50 - name: SCS-16V-32-100 cpus: 16 cpu-type: shared-core ram: 32 disk: 100 + name-v1: SCS-16V:32:100 + name-v2: SCS-16V-32-100 - name: SCS-1V-8-20 cpus: 1 cpu-type: shared-core ram: 8 disk: 20 + name-v1: SCS-1V:8:20 + name-v2: SCS-1V-8-20 - name: SCS-2V-16-50 cpus: 2 cpu-type: shared-core ram: 16 disk: 50 + name-v1: SCS-2V:16:50 + name-v2: SCS-2V-16-50 - name: SCS-4V-32-100 cpus: 4 cpu-type: shared-core ram: 32 disk: 100 + name-v1: SCS-4V:32:100 + name-v2: SCS-4V-32-100 - name: SCS-1L-1-5 cpus: 1 cpu-type: crowded-core ram: 1 disk: 5 + name-v1: SCS-1L:1:5 + name-v2: SCS-1L-1-5 diff --git a/Tests/iaas/standard-flavors/flavor-manager-input.py b/Tests/iaas/standard-flavors/flavor-manager-input.py index beec022ca..af6f345eb 100755 --- a/Tests/iaas/standard-flavors/flavor-manager-input.py +++ b/Tests/iaas/standard-flavors/flavor-manager-input.py @@ -66,12 +66,11 @@ def main(argv): logging.critical(f"Flavor spec missing attributes: {', '.join(missing)}") return 1 flavor_spec = {**group_info, **flavor_spec} - extra_specs = {name_key: flavor_spec['name']} - extra_specs.update({ + extra_specs = { f"scs:{key}": value for key, value in flavor_spec.items() if key not in ('name', 'cpus', 'ram', 'disk') - }) + } flavor_spec = { key: value for key, value in flavor_spec.items() diff --git a/Tests/iaas/standard-flavors/flavors-openstack.py b/Tests/iaas/standard-flavors/flavors-openstack.py index f017c99b3..c3a1d206d 100755 --- a/Tests/iaas/standard-flavors/flavors-openstack.py +++ b/Tests/iaas/standard-flavors/flavors-openstack.py @@ -102,6 +102,7 @@ def main(argv): logger.critical("Flavor definition missing 'flavor_groups' field") name_key = flavor_spec_data['meta']['name_key'] + es_name_key = f"scs:{name_key}" # compute union of all flavor groups, copying group info (mainly "status") to each flavor # check if the spec is complete while we are at it flavor_specs = [] @@ -124,21 +125,20 @@ def main(argv): with openstack.connect(cloud=cloud, timeout=32) as conn: present_flavors = conn.list_flavors(get_extra=True) by_name = { - flavor.extra_specs[name_key]: flavor + flavor.extra_specs[es_name_key]: flavor for flavor in present_flavors - if name_key in flavor.extra_specs + if es_name_key in flavor.extra_specs } logger.debug(f"Checking {len(flavor_specs)} flavor specs against {len(present_flavors)} flavors") for flavor_spec in flavor_specs: - flavor = by_name.get(flavor_spec['name']) + flavor = by_name.get(flavor_spec[name_key]) if not flavor: status = flavor_spec['_group']['status'] level = {"mandatory": logging.ERROR}.get(status, logging.INFO) logger.log(level, f"Missing {status} flavor '{flavor_spec['name']}'") continue # check that flavor matches flavor_spec - # name and corresponding extra_spec do match, because that's how we found the flavor in the first place... # cpu, ram, and disk should match, and they should match precisely for discoverability if flavor.vcpus != flavor_spec['cpus']: logger.error(f"Flavor '{flavor.name}' violating CPU constraint: {flavor.vcpus} != {flavor_spec['cpus']}") From f3ba0b0e83672d00e13e05457fbb0ad7156b0206 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20B=C3=BCchse?= Date: Thu, 17 Aug 2023 11:59:59 +0200 Subject: [PATCH 15/17] Include v1 names MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Matthias Büchse --- Standards/scs-0103-v1-standard-flavors.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Standards/scs-0103-v1-standard-flavors.md b/Standards/scs-0103-v1-standard-flavors.md index 5b2a0b2fb..d6970a24d 100644 --- a/Standards/scs-0103-v1-standard-flavors.md +++ b/Standards/scs-0103-v1-standard-flavors.md @@ -20,7 +20,8 @@ to have a guaranteed set of flavors available on all SCS clouds, so these need n The following extra specs are recognized, together with the respective semantics: -- `scs:name-v2=NAME` (where `NAME` is some string) means that the flavor is one of the +- `scs:name-vN=NAME` (where `N` is `1` or `2`, and `NAME` is some string) means that the + flavor is one of the standard SCS flavors, and the requirements of Section "Standard SCS flavors" below apply. - `scs:cpu-type=shared-core` means that _at least 20% of a core in >99% of the time_, measured over the course of one month (1% is 7,2 h/month). @@ -79,6 +80,7 @@ precisely the corresponding figures in the flavor. In addition, the following properties must be set (in the `extra_specs`): +- `scs:name-v1` to the recommended name, but with each dash AFTER the first one replaced by a colon, - `scs:name-v2` to the recommended name, - `scs:cpu-type` to `shared-core` or `crowded-core`, reflecting the vCPU type, - `scs:disk0-type` not set if no disk is provided, otherwise set to `ssd` or some other From 140adf75fa6e89ae61e4f08ffadb7b781b4b34e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20B=C3=BCchse?= Date: Thu, 17 Aug 2023 13:43:29 +0200 Subject: [PATCH 16/17] Appease flake8: remove unused variable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Matthias Büchse --- Tests/iaas/standard-flavors/flavor-manager-input.py | 1 - 1 file changed, 1 deletion(-) diff --git a/Tests/iaas/standard-flavors/flavor-manager-input.py b/Tests/iaas/standard-flavors/flavor-manager-input.py index af6f345eb..b8bb5da60 100755 --- a/Tests/iaas/standard-flavors/flavor-manager-input.py +++ b/Tests/iaas/standard-flavors/flavor-manager-input.py @@ -50,7 +50,6 @@ def main(argv): """) # transfer the info into the result yaml, again checking for sanity - name_key = flavor_spec_data['meta']['name_key'] for flavor_group in flavor_spec_data['flavor_groups']: group_info = dict(flavor_group) group_info.pop('list') From 632c5b5ebce16d49003a0088603343205a9e8969 Mon Sep 17 00:00:00 2001 From: Kurt Garloff Date: Wed, 30 Aug 2023 11:13:41 +0200 Subject: [PATCH 17/17] Added improvements to standard flavors. Define cpu-type and diskN-types and cross-reference flavor-naming. Mention live-migration consequence. Signed-off-by: Kurt Garloff --- Standards/scs-0103-v1-standard-flavors.md | 63 ++++++++++++----------- 1 file changed, 34 insertions(+), 29 deletions(-) diff --git a/Standards/scs-0103-v1-standard-flavors.md b/Standards/scs-0103-v1-standard-flavors.md index d6970a24d..098ef4dac 100644 --- a/Standards/scs-0103-v1-standard-flavors.md +++ b/Standards/scs-0103-v1-standard-flavors.md @@ -24,10 +24,15 @@ The following extra specs are recognized, together with the respective semantics flavor is one of the standard SCS flavors, and the requirements of Section "Standard SCS flavors" below apply. - `scs:cpu-type=shared-core` means that _at least 20% of a core in >99% of the time_, - measured over the course of one month (1% is 7,2 h/month). + measured over the course of one month (1% is 7,2 h/month). The `cpu-type=shared-core` + corresponds to the `V` cpu modifier in the [flavor-naming spec](./scs-0100-v3-flavor-naming.md), + other options are `crowded-core` (`L`), `dedicated-thread` (`T`) and `dedicated-core` (`C`). - `scs:diskN-type=ssd` (where `N` is a nonnegative integer, usually `0`) means that the root disk `N` must support 1000 _sequential_ IOPS per VM and it must be equipped with power-loss protection; see [scs-0110-v1-ssd-flavors](./scs-0110-v1-ssd-flavors.md). + The `disk`N`-type=ssd` setting corresponds to the `s` disk modifier, other options + are `nvme` (`p`), `hdd` (`h`) and `network` (`n`). Only flavors without disk and + those with `diskN-type=network` can be expected to support live-migration. Whenever ANY of these are present on ANY flavor, the corresponding semantics must be satisfied. @@ -39,39 +44,39 @@ These are flavors that must exist on standard SCS clouds (x86-64). | Recommended name | vCPUs | vCPU type | RAM [GiB] | Root disk [GB] | Disk type | | ---------------- | ------ | ------------- | ---------- | --------------- | ---------- | -| SCS-1V-4 | 1 | shared core | 4 | | | -| SCS-2V-8 | 2 | shared core | 8 | | | -| SCS-4V-16 | 4 | shared core | 16 | | | -| SCS-4V-16-100s | 4 | shared core | 16 | 100 | ssd | -| SCS-8V-32 | 8 | shared core | 32 | | | -| SCS-1V-2 | 1 | shared core | 2 | | | -| SCS-2V-4 | 2 | shared core | 4 | | | -| SCS-2V-4-20s | 2 | shared core | 4 | 20 | ssd | -| SCS-4V-8 | 4 | shared core | 8 | | | -| SCS-8V-16 | 8 | shared core | 16 | | | -| SCS-16V-32 | 16 | shared core | 32 | | | -| SCS-1V-8 | 1 | shared core | 8 | | | -| SCS-2V-16 | 2 | shared core | 16 | | | -| SCS-4V-32 | 4 | shared core | 32 | | | -| SCS-1L-1 | 1 | crowded core | 1 | | | +| SCS-1V-4 | 1 | shared-core | 4 | | | +| SCS-2V-8 | 2 | shared-core | 8 | | | +| SCS-4V-16 | 4 | shared-core | 16 | | | +| SCS-4V-16-100s | 4 | shared-core | 16 | 100 | ssd | +| SCS-8V-32 | 8 | shared-core | 32 | | | +| SCS-1V-2 | 1 | shared-core | 2 | | | +| SCS-2V-4 | 2 | shared-core | 4 | | | +| SCS-2V-4-20s | 2 | shared-core | 4 | 20 | ssd | +| SCS-4V-8 | 4 | shared-core | 8 | | | +| SCS-8V-16 | 8 | shared-core | 16 | | | +| SCS-16V-32 | 16 | shared-core | 32 | | | +| SCS-1V-8 | 1 | shared-core | 8 | | | +| SCS-2V-16 | 2 | shared-core | 16 | | | +| SCS-4V-32 | 4 | shared-core | 32 | | | +| SCS-1L-1 | 1 | crowded-core | 1 | | | ### Recommended | Recommended name | vCPUs | vCPU type | RAM [GiB] | Root disk [GB] | Disk type | | ---------------- | ------ | ------------- | ---------- | --------------- | ---------- | -| SCS-1V-4-10 | 1 | shared core | 4 | 10 | (any) | -| SCS-2V-8-20 | 2 | shared core | 8 | 20 | (any) | -| SCS-4V-16-50 | 4 | shared core | 16 | 50 | (any) | -| SCS-8V-32-100 | 8 | shared core | 32 | 100 | (any) | -| SCS-1V-2-5 | 1 | shared core | 2 | 5 | (any) | -| SCS-2V-4-10 | 2 | shared core | 4 | 10 | (any) | -| SCS-4V-8-20 | 4 | shared core | 8 | 20 | (any) | -| SCS-8V-16-50 | 8 | shared core | 16 | 50 | (any) | -| SCS-16V-32-100 | 16 | shared core | 32 | 100 | (any) | -| SCS-1V-8-20 | 1 | shared core | 8 | 20 | (any) | -| SCS-2V-16-50 | 2 | shared core | 16 | 50 | (any) | -| SCS-4V-32-100 | 4 | shared core | 32 | 100 | (any) | -| SCS-1L-1-5 | 1 | crowded core | 1 | 5 | (any) | +| SCS-1V-4-10 | 1 | shared-core | 4 | 10 | (any) | +| SCS-2V-8-20 | 2 | shared-core | 8 | 20 | (any) | +| SCS-4V-16-50 | 4 | shared-core | 16 | 50 | (any) | +| SCS-8V-32-100 | 8 | shared-core | 32 | 100 | (any) | +| SCS-1V-2-5 | 1 | shared-core | 2 | 5 | (any) | +| SCS-2V-4-10 | 2 | shared-core | 4 | 10 | (any) | +| SCS-4V-8-20 | 4 | shared-core | 8 | 20 | (any) | +| SCS-8V-16-50 | 8 | shared-core | 16 | 50 | (any) | +| SCS-16V-32-100 | 16 | shared-core | 32 | 100 | (any) | +| SCS-1V-8-20 | 1 | shared-core | 8 | 20 | (any) | +| SCS-2V-16-50 | 2 | shared-core | 16 | 50 | (any) | +| SCS-4V-32-100 | 4 | shared-core | 32 | 100 | (any) | +| SCS-1L-1-5 | 1 | crowded-core | 1 | 5 | (any) | ### Guarantees and properties