From 590dfadbe256482d41ed2ed910eb8ae8c578271c Mon Sep 17 00:00:00 2001 From: Bhargavi Gudi Date: Wed, 15 Apr 2026 20:24:16 +0530 Subject: [PATCH] Allow :ref suffix in additionalLayerStores path for stargz-store to support lazy image pulling Introduced LayerStorePath type for additionalLayerStores that allows paths ending with :ref (e.g., /var/lib/stargz-store/store:ref), while keeping StorePath unchanged for additionalImageStores and additionalArtifactStores. Fixes: https://issues.redhat.com/browse/OCPBUGS-83492 --- .../AdditionalStorageConfig.yaml | 52 ++- machineconfiguration/v1/types.go | 15 +- ...nerruntimeconfigs-CustomNoUpgrade.crd.yaml | 8 +- ...untimeconfigs-DevPreviewNoUpgrade.crd.yaml | 8 +- ...ntimeconfigs-TechPreviewNoUpgrade.crd.yaml | 8 +- .../AdditionalStorageConfig.yaml | 8 +- .../v1/zz_generated.swagger_doc_generated.go | 2 +- openapi/openapi.json | 301 +++++++++++++++++- ...nerruntimeconfigs-CustomNoUpgrade.crd.yaml | 8 +- ...untimeconfigs-DevPreviewNoUpgrade.crd.yaml | 8 +- ...ntimeconfigs-TechPreviewNoUpgrade.crd.yaml | 8 +- 11 files changed, 397 insertions(+), 29 deletions(-) diff --git a/machineconfiguration/v1/tests/containerruntimeconfigs.machineconfiguration.openshift.io/AdditionalStorageConfig.yaml b/machineconfiguration/v1/tests/containerruntimeconfigs.machineconfiguration.openshift.io/AdditionalStorageConfig.yaml index cb0ea8cbba2..fb95c24287e 100644 --- a/machineconfiguration/v1/tests/containerruntimeconfigs.machineconfiguration.openshift.io/AdditionalStorageConfig.yaml +++ b/machineconfiguration/v1/tests/containerruntimeconfigs.machineconfiguration.openshift.io/AdditionalStorageConfig.yaml @@ -26,6 +26,42 @@ tests: - path: /mnt/nydus-store - path: /opt/layer_store-v1.0 + - name: Should be able to create ContainerRuntimeConfig with additionalLayerStores using :ref suffix for stargz-store + initial: | + apiVersion: machineconfiguration.openshift.io/v1 + kind: ContainerRuntimeConfig + spec: + containerRuntimeConfig: + additionalLayerStores: + - path: /var/lib/stargz-store/store:ref + expected: | + apiVersion: machineconfiguration.openshift.io/v1 + kind: ContainerRuntimeConfig + spec: + containerRuntimeConfig: + additionalLayerStores: + - path: /var/lib/stargz-store/store:ref + + - name: Should be able to create ContainerRuntimeConfig with mixed additionalLayerStores paths (with and without :ref) + initial: | + apiVersion: machineconfiguration.openshift.io/v1 + kind: ContainerRuntimeConfig + spec: + containerRuntimeConfig: + additionalLayerStores: + - path: /var/lib/stargz-store/store:ref + - path: /mnt/nydus-store + - path: /opt/layer-store:ref + expected: | + apiVersion: machineconfiguration.openshift.io/v1 + kind: ContainerRuntimeConfig + spec: + containerRuntimeConfig: + additionalLayerStores: + - path: /var/lib/stargz-store/store:ref + - path: /mnt/nydus-store + - path: /opt/layer-store:ref + - name: Should fail if additionalLayerStores path is empty initial: | apiVersion: machineconfiguration.openshift.io/v1 @@ -44,7 +80,7 @@ tests: containerRuntimeConfig: additionalLayerStores: - path: var/lib/stargz-store - expectedError: "path must be absolute and contain only alphanumeric characters, '/', '.', '_', and '-'" + expectedError: "path must be absolute and contain only alphanumeric characters, '/', '.', '_', '-', and optionally end with ':ref'" - name: Should fail if additionalLayerStores path contains spaces initial: | @@ -54,7 +90,7 @@ tests: containerRuntimeConfig: additionalLayerStores: - path: /var/lib/stargz store - expectedError: "path must be absolute and contain only alphanumeric characters, '/', '.', '_', and '-'" + expectedError: "path must be absolute and contain only alphanumeric characters, '/', '.', '_', '-', and optionally end with ':ref'" - name: Should fail if additionalLayerStores path contains invalid characters initial: | @@ -64,7 +100,17 @@ tests: containerRuntimeConfig: additionalLayerStores: - path: /var/lib/stargz@store - expectedError: "path must be absolute and contain only alphanumeric characters, '/', '.', '_', and '-'" + expectedError: "path must be absolute and contain only alphanumeric characters, '/', '.', '_', '-', and optionally end with ':ref'" + + - name: Should fail if additionalLayerStores path contains colon with suffix other than :ref + initial: | + apiVersion: machineconfiguration.openshift.io/v1 + kind: ContainerRuntimeConfig + spec: + containerRuntimeConfig: + additionalLayerStores: + - path: /var/lib/stargz-store:other + expectedError: "path must be absolute and contain only alphanumeric characters, '/', '.', '_', '-', and optionally end with ':ref'" - name: Should fail if additionalLayerStores path is too long initial: | diff --git a/machineconfiguration/v1/types.go b/machineconfiguration/v1/types.go index 21615ee9aa4..7f040b063bf 100644 --- a/machineconfiguration/v1/types.go +++ b/machineconfiguration/v1/types.go @@ -976,6 +976,16 @@ const ( // +kubebuilder:validation:XValidation:rule="!self.contains('//')",message="path must not contain consecutive forward slashes" type StorePath string +// LayerStorePath is an absolute filesystem path used by additional layer store configurations. +// The path must be between 1 and 256 characters long, begin with a forward slash, and only contain +// the characters a-z, A-Z, 0-9, '/', '.', '_', '-', and may end with the ':ref' suffix for reference-based layer organization (e.g., stargz-store). +// Consecutive forward slashes are not permitted. +// +kubebuilder:validation:MinLength=1 +// +kubebuilder:validation:MaxLength=256 +// +kubebuilder:validation:XValidation:rule="self.matches('^/[a-zA-Z0-9/._-]+(:ref)?$')",message="path must be absolute and contain only alphanumeric characters, '/', '.', '_', '-', and optionally end with ':ref'" +// +kubebuilder:validation:XValidation:rule="!self.contains('//')",message="path must not contain consecutive forward slashes" +type LayerStorePath string + // AdditionalLayerStore defines a read-only storage location for Open Container Initiative (OCI) container image layers. type AdditionalLayerStore struct { // path specifies the absolute location of the additional layer store. @@ -983,10 +993,11 @@ type AdditionalLayerStore struct { // When a container image is requested, layers found at this location will be used instead of // retrieving from the registry. // The path is required and must be between 1 and 256 characters long, begin with a forward slash, - // and only contain the characters a-z, A-Z, 0-9, '/', '.', '_', and '-'. + // and only contain the characters a-z, A-Z, 0-9, '/', '.', '_', '-', and may end with the ':ref' suffix + // for reference-based layer organization (e.g., /var/lib/stargz-store/store:ref for stargz-store). // Consecutive forward slashes are not permitted. // +required - Path StorePath `json:"path,omitempty"` + Path LayerStorePath `json:"path,omitempty"` } // AdditionalImageStore defines an additional read-only storage location for Open Container Initiative (OCI) images. diff --git a/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_containerruntimeconfigs-CustomNoUpgrade.crd.yaml b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_containerruntimeconfigs-CustomNoUpgrade.crd.yaml index 68726d9ce15..8826beb7bb8 100644 --- a/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_containerruntimeconfigs-CustomNoUpgrade.crd.yaml +++ b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_containerruntimeconfigs-CustomNoUpgrade.crd.yaml @@ -163,15 +163,17 @@ spec: When a container image is requested, layers found at this location will be used instead of retrieving from the registry. The path is required and must be between 1 and 256 characters long, begin with a forward slash, - and only contain the characters a-z, A-Z, 0-9, '/', '.', '_', and '-'. + and only contain the characters a-z, A-Z, 0-9, '/', '.', '_', '-', and may end with the ':ref' suffix + for reference-based layer organization (e.g., /var/lib/stargz-store/store:ref for stargz-store). Consecutive forward slashes are not permitted. maxLength: 256 minLength: 1 type: string x-kubernetes-validations: - message: path must be absolute and contain only alphanumeric - characters, '/', '.', '_', and '-' - rule: self.matches('^/[a-zA-Z0-9/._-]+$') + characters, '/', '.', '_', '-', and optionally end with + ':ref' + rule: self.matches('^/[a-zA-Z0-9/._-]+(:ref)?$') - message: path must not contain consecutive forward slashes rule: '!self.contains(''//'')' required: diff --git a/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_containerruntimeconfigs-DevPreviewNoUpgrade.crd.yaml b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_containerruntimeconfigs-DevPreviewNoUpgrade.crd.yaml index 8d918545b29..c9fcd29f4de 100644 --- a/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_containerruntimeconfigs-DevPreviewNoUpgrade.crd.yaml +++ b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_containerruntimeconfigs-DevPreviewNoUpgrade.crd.yaml @@ -163,15 +163,17 @@ spec: When a container image is requested, layers found at this location will be used instead of retrieving from the registry. The path is required and must be between 1 and 256 characters long, begin with a forward slash, - and only contain the characters a-z, A-Z, 0-9, '/', '.', '_', and '-'. + and only contain the characters a-z, A-Z, 0-9, '/', '.', '_', '-', and may end with the ':ref' suffix + for reference-based layer organization (e.g., /var/lib/stargz-store/store:ref for stargz-store). Consecutive forward slashes are not permitted. maxLength: 256 minLength: 1 type: string x-kubernetes-validations: - message: path must be absolute and contain only alphanumeric - characters, '/', '.', '_', and '-' - rule: self.matches('^/[a-zA-Z0-9/._-]+$') + characters, '/', '.', '_', '-', and optionally end with + ':ref' + rule: self.matches('^/[a-zA-Z0-9/._-]+(:ref)?$') - message: path must not contain consecutive forward slashes rule: '!self.contains(''//'')' required: diff --git a/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_containerruntimeconfigs-TechPreviewNoUpgrade.crd.yaml b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_containerruntimeconfigs-TechPreviewNoUpgrade.crd.yaml index 27a0cb3c173..eac8c58b630 100644 --- a/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_containerruntimeconfigs-TechPreviewNoUpgrade.crd.yaml +++ b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_containerruntimeconfigs-TechPreviewNoUpgrade.crd.yaml @@ -163,15 +163,17 @@ spec: When a container image is requested, layers found at this location will be used instead of retrieving from the registry. The path is required and must be between 1 and 256 characters long, begin with a forward slash, - and only contain the characters a-z, A-Z, 0-9, '/', '.', '_', and '-'. + and only contain the characters a-z, A-Z, 0-9, '/', '.', '_', '-', and may end with the ':ref' suffix + for reference-based layer organization (e.g., /var/lib/stargz-store/store:ref for stargz-store). Consecutive forward slashes are not permitted. maxLength: 256 minLength: 1 type: string x-kubernetes-validations: - message: path must be absolute and contain only alphanumeric - characters, '/', '.', '_', and '-' - rule: self.matches('^/[a-zA-Z0-9/._-]+$') + characters, '/', '.', '_', '-', and optionally end with + ':ref' + rule: self.matches('^/[a-zA-Z0-9/._-]+(:ref)?$') - message: path must not contain consecutive forward slashes rule: '!self.contains(''//'')' required: diff --git a/machineconfiguration/v1/zz_generated.featuregated-crd-manifests/containerruntimeconfigs.machineconfiguration.openshift.io/AdditionalStorageConfig.yaml b/machineconfiguration/v1/zz_generated.featuregated-crd-manifests/containerruntimeconfigs.machineconfiguration.openshift.io/AdditionalStorageConfig.yaml index 6dfa85331f5..caaa317c2fb 100644 --- a/machineconfiguration/v1/zz_generated.featuregated-crd-manifests/containerruntimeconfigs.machineconfiguration.openshift.io/AdditionalStorageConfig.yaml +++ b/machineconfiguration/v1/zz_generated.featuregated-crd-manifests/containerruntimeconfigs.machineconfiguration.openshift.io/AdditionalStorageConfig.yaml @@ -163,15 +163,17 @@ spec: When a container image is requested, layers found at this location will be used instead of retrieving from the registry. The path is required and must be between 1 and 256 characters long, begin with a forward slash, - and only contain the characters a-z, A-Z, 0-9, '/', '.', '_', and '-'. + and only contain the characters a-z, A-Z, 0-9, '/', '.', '_', '-', and may end with the ':ref' suffix + for reference-based layer organization (e.g., /var/lib/stargz-store/store:ref for stargz-store). Consecutive forward slashes are not permitted. maxLength: 256 minLength: 1 type: string x-kubernetes-validations: - message: path must be absolute and contain only alphanumeric - characters, '/', '.', '_', and '-' - rule: self.matches('^/[a-zA-Z0-9/._-]+$') + characters, '/', '.', '_', '-', and optionally end with + ':ref' + rule: self.matches('^/[a-zA-Z0-9/._-]+(:ref)?$') - message: path must not contain consecutive forward slashes rule: '!self.contains(''//'')' required: diff --git a/machineconfiguration/v1/zz_generated.swagger_doc_generated.go b/machineconfiguration/v1/zz_generated.swagger_doc_generated.go index c286d4e2753..d43a8838f46 100644 --- a/machineconfiguration/v1/zz_generated.swagger_doc_generated.go +++ b/machineconfiguration/v1/zz_generated.swagger_doc_generated.go @@ -31,7 +31,7 @@ func (AdditionalImageStore) SwaggerDoc() map[string]string { var map_AdditionalLayerStore = map[string]string{ "": "AdditionalLayerStore defines a read-only storage location for Open Container Initiative (OCI) container image layers.", - "path": "path specifies the absolute location of the additional layer store. The path must exist on the node before configuration is applied. When a container image is requested, layers found at this location will be used instead of retrieving from the registry. The path is required and must be between 1 and 256 characters long, begin with a forward slash, and only contain the characters a-z, A-Z, 0-9, '/', '.', '_', and '-'. Consecutive forward slashes are not permitted.", + "path": "path specifies the absolute location of the additional layer store. The path must exist on the node before configuration is applied. When a container image is requested, layers found at this location will be used instead of retrieving from the registry. The path is required and must be between 1 and 256 characters long, begin with a forward slash, and only contain the characters a-z, A-Z, 0-9, '/', '.', '_', '-', and may end with the ':ref' suffix for reference-based layer organization (e.g., /var/lib/stargz-store/store:ref for stargz-store). Consecutive forward slashes are not permitted.", } func (AdditionalLayerStore) SwaggerDoc() map[string]string { diff --git a/openapi/openapi.json b/openapi/openapi.json index f3254cd59a4..c016ee3f41b 100644 --- a/openapi/openapi.json +++ b/openapi/openapi.json @@ -24188,6 +24188,11 @@ "default": {}, "$ref": "#/definitions/com.github.openshift.api.config.v1alpha1.TelemeterClientConfig" }, + "thanosQuerierConfig": { + "description": "thanosQuerierConfig is an optional field that can be used to configure the Thanos Querier component that runs in the openshift-monitoring namespace. The Thanos Querier provides a global query view by aggregating and deduplicating metrics from multiple Prometheus instances. When omitted, this means no opinion and the platform is left to choose a reasonable default, which is subject to change over time. The current default deploys the Thanos Querier on linux nodes with 5m CPU and 12Mi memory requests, and no custom tolerations or topology spread constraints. When set, at least one field must be specified within thanosQuerierConfig.", + "default": {}, + "$ref": "#/definitions/com.github.openshift.api.config.v1alpha1.ThanosQuerierConfig" + }, "userDefined": { "description": "userDefined set the deployment mode for user-defined monitoring in addition to the default platform monitoring. userDefined is optional. When omitted, this means no opinion and the platform is left to choose a reasonable default, which is subject to change over time. The current default value is `Disabled`.", "default": {}, @@ -24215,7 +24220,7 @@ "type": "string" }, "request": { - "description": "request is the minimum amount of the resource required (e.g. \"2Mi\", \"1Gi\"). This field is optional. When limit is specified, request cannot be greater than limit.", + "description": "request is the minimum amount of the resource required (e.g. \"2Mi\", \"1Gi\"). This field is optional. When limit is specified, request cannot be greater than limit. The value must be greater than 0 when specified.", "$ref": "#/definitions/Quantity.resource.api.pkg.apimachinery.k8s.io" } } @@ -25609,6 +25614,54 @@ } } }, + "com.github.openshift.api.config.v1alpha1.ThanosQuerierConfig": { + "description": "ThanosQuerierConfig provides configuration options for the Thanos Querier component that runs in the `openshift-monitoring` namespace. At least one field must be specified; an empty thanosQuerierConfig object is not allowed.", + "type": "object", + "properties": { + "nodeSelector": { + "description": "nodeSelector defines the nodes on which the Pods are scheduled. nodeSelector is optional.\n\nWhen omitted, this means the user has no opinion and the platform is left to choose reasonable defaults. These defaults are subject to change over time. The current default value is `kubernetes.io/os: linux`. When specified, nodeSelector must contain at least 1 entry and must not contain more than 10 entries.", + "type": "object", + "additionalProperties": { + "type": "string", + "default": "" + } + }, + "resources": { + "description": "resources defines the compute resource requests and limits for the Thanos Querier container. resources is optional.\n\nWhen omitted, this means the user has no opinion and the platform is left to choose reasonable defaults. These defaults are subject to change over time. Requests cannot exceed limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ This is a simplified API that maps to Kubernetes ResourceRequirements. The current default values are:\n resources:\n - name: cpu\n request: 5m\n - name: memory\n request: 12Mi\nMaximum length for this list is 5. Minimum length for this list is 1. Each resource name must be unique within this list.", + "type": "array", + "items": { + "default": {}, + "$ref": "#/definitions/com.github.openshift.api.config.v1alpha1.ContainerResource" + }, + "x-kubernetes-list-map-keys": [ + "name" + ], + "x-kubernetes-list-type": "map" + }, + "tolerations": { + "description": "tolerations defines tolerations for the pods. tolerations is optional.\n\nWhen omitted, this means the user has no opinion and the platform is left to choose reasonable defaults. These defaults are subject to change over time. Defaults are empty/unset. Maximum length for this list is 10. Minimum length for this list is 1.", + "type": "array", + "items": { + "default": {}, + "$ref": "#/definitions/Toleration.v1.core.api.k8s.io" + }, + "x-kubernetes-list-type": "atomic" + }, + "topologySpreadConstraints": { + "description": "topologySpreadConstraints defines rules for how Thanos Querier Pods should be distributed across topology domains such as zones, nodes, or other user-defined labels. topologySpreadConstraints is optional. This helps improve high availability and resource efficiency by avoiding placing too many replicas in the same failure domain.\n\nWhen omitted, this means no opinion and the platform is left to choose a default, which is subject to change over time. This field maps directly to the `topologySpreadConstraints` field in the Pod spec. Defaults are empty/unset. Maximum length for this list is 10. Minimum length for this list is 1. Entries must have unique topologyKey and whenUnsatisfiable pairs.", + "type": "array", + "items": { + "default": {}, + "$ref": "#/definitions/TopologySpreadConstraint.v1.core.api.k8s.io" + }, + "x-kubernetes-list-map-keys": [ + "topologyKey", + "whenUnsatisfiable" + ], + "x-kubernetes-list-type": "map" + } + } + }, "com.github.openshift.api.config.v1alpha1.UppercaseActionConfig": { "description": "UppercaseActionConfig configures the Uppercase action. Maps the concatenated source_labels to their upper case and writes to target_label. Requires Prometheus >= v2.36.0.", "type": "object", @@ -27087,6 +27140,250 @@ } } }, + "com.github.openshift.api.etcd.v1.PacemakerCluster": { + "description": "PacemakerCluster represents the current state of the pacemaker cluster as reported by the pcs status command. PacemakerCluster is a cluster-scoped singleton resource. The name of this instance is \"cluster\". This resource provides a view into the health and status of a pacemaker-managed cluster in Two Node OpenShift with Fencing deployments.\n\nCompatibility level 1: Stable within a major release for a minimum of 12 months or 3 minor releases (whichever is longer).", + "type": "object", + "required": [ + "metadata" + ], + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "metadata": { + "description": "metadata is the standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", + "default": {}, + "$ref": "#/definitions/ObjectMeta.v1.meta.apis.pkg.apimachinery.k8s.io" + }, + "status": { + "description": "status contains the actual pacemaker cluster status information collected from the cluster. The goal of this status is to be able to quickly identify if pacemaker is in a healthy state. In Two Node OpenShift with Fencing, a healthy pacemaker cluster has 2 nodes, both of which have healthy kubelet, etcd, and fencing resources. This field is optional on creation - the status collector populates it immediately after creating the resource via the status subresource.", + "default": {}, + "$ref": "#/definitions/com.github.openshift.api.etcd.v1.PacemakerClusterStatus" + } + } + }, + "com.github.openshift.api.etcd.v1.PacemakerClusterFencingAgentStatus": { + "description": "PacemakerClusterFencingAgentStatus represents the status of a fencing agent that can fence a node. Fencing agents are STONITH (Shoot The Other Node In The Head) devices used to isolate failed nodes. Unlike regular pacemaker resources, fencing agents are mapped to their target node (the node they can fence), not the node where their monitoring operations are scheduled.", + "type": "object", + "required": [ + "conditions", + "name", + "method" + ], + "properties": { + "conditions": { + "description": "conditions represent the observations of the fencing agent's current state. Known condition types are: \"Healthy\", \"InService\", \"Managed\", \"Enabled\", \"Operational\", \"Active\", \"Started\", \"Schedulable\". The \"Healthy\" condition is an aggregate that tracks the overall health of the fencing agent. The \"InService\" condition tracks whether the fencing agent is in service (not in maintenance mode). The \"Managed\" condition tracks whether the fencing agent is managed by pacemaker. The \"Enabled\" condition tracks whether the fencing agent is enabled. The \"Operational\" condition tracks whether the fencing agent is operational (not failed). The \"Active\" condition tracks whether the fencing agent is active (available to be used). The \"Started\" condition tracks whether the fencing agent is started. The \"Schedulable\" condition tracks whether the fencing agent is schedulable (not blocked). Each of these conditions is required, so the array must contain at least 8 items.", + "type": "array", + "items": { + "default": {}, + "$ref": "#/definitions/Condition.v1.meta.apis.pkg.apimachinery.k8s.io" + }, + "x-kubernetes-list-map-keys": [ + "type" + ], + "x-kubernetes-list-type": "map" + }, + "method": { + "description": "method is the fencing method used by this agent. Valid values are \"Redfish\" and \"IPMI\". Redfish is a standard RESTful API for server management. IPMI (Intelligent Platform Management Interface) is a hardware management interface.\n\nPossible enum values:\n - `\"IPMI\"` uses IPMI (Intelligent Platform Management Interface), a hardware management interface.\n - `\"Redfish\"` uses Redfish, a standard RESTful API for server management.", + "type": "string", + "enum": [ + "IPMI", + "Redfish" + ] + }, + "name": { + "description": "name is the unique identifier for this fencing agent (e.g., \"master-0_redfish\"). The name must be unique within the fencingAgents array for this node. It may contain alphanumeric characters, dots, hyphens, and underscores. Maximum length is 300 characters, providing headroom beyond the typical format of _ (253 for RFC 1123 node name + 1 underscore + type).", + "type": "string" + } + } + }, + "com.github.openshift.api.etcd.v1.PacemakerClusterList": { + "description": "PacemakerClusterList contains a list of PacemakerCluster objects. PacemakerCluster is a cluster-scoped singleton resource; only one instance named \"cluster\" may exist. This list type exists only to satisfy Kubernetes API conventions.\n\nCompatibility level 1: Stable within a major release for a minimum of 12 months or 3 minor releases (whichever is longer).", + "type": "object", + "required": [ + "items" + ], + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "items": { + "description": "items is a list of PacemakerCluster objects.", + "type": "array", + "items": { + "default": {}, + "$ref": "#/definitions/com.github.openshift.api.etcd.v1.PacemakerCluster" + } + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "metadata": { + "description": "metadata is the standard list's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", + "default": {}, + "$ref": "#/definitions/ListMeta.v1.meta.apis.pkg.apimachinery.k8s.io" + } + } + }, + "com.github.openshift.api.etcd.v1.PacemakerClusterNodeStatus": { + "description": "PacemakerClusterNodeStatus represents the status of a single node in the pacemaker cluster including the node's conditions and the health of critical resources running on that node.", + "type": "object", + "required": [ + "conditions", + "nodeName", + "addresses", + "resources", + "fencingAgents" + ], + "properties": { + "addresses": { + "description": "addresses is a list of IP addresses for the node. Pacemaker allows multiple IP addresses for Corosync communication between nodes. The first address in this list is used for IP-based peer URLs for etcd membership. Each address must be a valid global unicast IPv4 or IPv6 address in canonical form (e.g., \"192.168.1.1\" not \"192.168.001.001\", or \"2001:db8::1\" not \"2001:0db8::1\"). This excludes loopback, link-local, and multicast addresses.", + "type": "array", + "items": { + "default": {}, + "$ref": "#/definitions/com.github.openshift.api.etcd.v1.PacemakerNodeAddress" + }, + "x-kubernetes-list-type": "atomic" + }, + "conditions": { + "description": "conditions represent the observations of the node's current state. Known condition types are: \"Healthy\", \"Online\", \"InService\", \"Active\", \"Ready\", \"Clean\", \"Member\", \"FencingAvailable\", \"FencingHealthy\". The \"Healthy\" condition is an aggregate that tracks the overall health of the node. The \"Online\" condition tracks whether the node is online. The \"InService\" condition tracks whether the node is in service (not in maintenance mode). The \"Active\" condition tracks whether the node is active (not in standby mode). The \"Ready\" condition tracks whether the node is ready (not in a pending state). The \"Clean\" condition tracks whether the node is in a clean (status known) state. The \"Member\" condition tracks whether the node is a member of the cluster. The \"FencingAvailable\" condition tracks whether this node can be fenced by at least one healthy agent. The \"FencingHealthy\" condition tracks whether all fencing agents for this node are healthy. Each of these conditions is required, so the array must contain at least 9 items.", + "type": "array", + "items": { + "default": {}, + "$ref": "#/definitions/Condition.v1.meta.apis.pkg.apimachinery.k8s.io" + }, + "x-kubernetes-list-map-keys": [ + "type" + ], + "x-kubernetes-list-type": "map" + }, + "fencingAgents": { + "description": "fencingAgents contains the status of fencing agents that can fence this node. Unlike resources (which are scheduled to run on this node), fencing agents are mapped to the node they can fence (their target), not the node where monitoring operations run. Each fencing agent entry includes a unique name, fencing type, target node, and health conditions. A node is considered fence-capable if at least one fencing agent is healthy. A healthy node is expected to have at least 1 fencing agent, but the list may be empty when fencing agent discovery fails. Names must be unique within this array.", + "type": "array", + "items": { + "default": {}, + "$ref": "#/definitions/com.github.openshift.api.etcd.v1.PacemakerClusterFencingAgentStatus" + }, + "x-kubernetes-list-map-keys": [ + "name" + ], + "x-kubernetes-list-type": "map" + }, + "nodeName": { + "description": "nodeName is the name of the node. This is expected to match the Kubernetes node's name, which must be a lowercase RFC 1123 subdomain consisting of lowercase alphanumeric characters, '-' or '.', starting and ending with an alphanumeric character, and be at most 253 characters in length.", + "type": "string" + }, + "resources": { + "description": "resources contains the status of pacemaker resources scheduled on this node. Each resource entry includes the resource name and its health conditions. For Two Node OpenShift with Fencing, we track Kubelet and Etcd resources per node. Both resources are required to be present, so the array must contain at least 2 items. Valid resource names are \"Kubelet\" and \"Etcd\". Fencing agents are tracked separately in the fencingAgents field.", + "type": "array", + "items": { + "default": {}, + "$ref": "#/definitions/com.github.openshift.api.etcd.v1.PacemakerClusterResourceStatus" + }, + "x-kubernetes-list-map-keys": [ + "name" + ], + "x-kubernetes-list-type": "map" + } + } + }, + "com.github.openshift.api.etcd.v1.PacemakerClusterResourceStatus": { + "description": "PacemakerClusterResourceStatus represents the status of a pacemaker resource scheduled on a node. A pacemaker resource is a unit of work managed by pacemaker. In pacemaker terminology, resources are services or applications that pacemaker monitors, starts, stops, and moves between nodes to maintain high availability. For Two Node OpenShift with Fencing, we track two resources per node:\n - Kubelet (the Kubernetes node agent and a prerequisite for etcd)\n - Etcd (the distributed key-value store)\n\nFencing agents are tracked separately in the fencingAgents field because they are mapped to their target node (the node they can fence), not the node where monitoring operations are scheduled.", + "type": "object", + "required": [ + "conditions", + "name" + ], + "properties": { + "conditions": { + "description": "conditions represent the observations of the resource's current state. Known condition types are: \"Healthy\", \"InService\", \"Managed\", \"Enabled\", \"Operational\", \"Active\", \"Started\", \"Schedulable\". The \"Healthy\" condition is an aggregate that tracks the overall health of the resource. The \"InService\" condition tracks whether the resource is in service (not in maintenance mode). The \"Managed\" condition tracks whether the resource is managed by pacemaker. The \"Enabled\" condition tracks whether the resource is enabled. The \"Operational\" condition tracks whether the resource is operational (not failed). The \"Active\" condition tracks whether the resource is active (available to be used). The \"Started\" condition tracks whether the resource is started. The \"Schedulable\" condition tracks whether the resource is schedulable (not blocked). Each of these conditions is required, so the array must contain at least 8 items.", + "type": "array", + "items": { + "default": {}, + "$ref": "#/definitions/Condition.v1.meta.apis.pkg.apimachinery.k8s.io" + }, + "x-kubernetes-list-map-keys": [ + "type" + ], + "x-kubernetes-list-type": "map" + }, + "name": { + "description": "name is the name of the pacemaker resource. Valid values are \"Kubelet\" and \"Etcd\". The Kubelet resource is a prerequisite for etcd in Two Node OpenShift with Fencing deployments. The Etcd resource may temporarily transition to stopped during pacemaker quorum-recovery operations. Fencing agents are tracked separately in the node's fencingAgents field.\n\nPossible enum values:\n - `\"Etcd\"` is the etcd pacemaker resource. The etcd resource may temporarily transition to stopped during pacemaker quorum-recovery operations.\n - `\"Kubelet\"` is the kubelet pacemaker resource. The kubelet resource is a prerequisite for etcd in Two Node OpenShift with Fencing deployments.", + "type": "string", + "enum": [ + "Etcd", + "Kubelet" + ] + } + } + }, + "com.github.openshift.api.etcd.v1.PacemakerClusterStatus": { + "description": "PacemakerClusterStatus contains the actual pacemaker cluster status information. As part of validating the status object, we need to ensure that the lastUpdated timestamp may not be set to an earlier timestamp than the current value. The validation rule checks if oldSelf has lastUpdated before comparing, to handle the initial status creation case.", + "type": "object", + "required": [ + "conditions", + "lastUpdated", + "nodes" + ], + "properties": { + "conditions": { + "description": "conditions represent the observations of the pacemaker cluster's current state. Known condition types are: \"Healthy\", \"InService\", \"NodeCountAsExpected\". The \"Healthy\" condition is an aggregate that tracks the overall health of the cluster. The \"InService\" condition tracks whether the cluster is in service (not in maintenance mode). The \"NodeCountAsExpected\" condition tracks whether the expected number of nodes are present. Each of these conditions is required, so the array must contain at least 3 items.", + "type": "array", + "items": { + "default": {}, + "$ref": "#/definitions/Condition.v1.meta.apis.pkg.apimachinery.k8s.io" + }, + "x-kubernetes-list-map-keys": [ + "type" + ], + "x-kubernetes-list-type": "map" + }, + "lastUpdated": { + "description": "lastUpdated is the timestamp when this status was last updated. This is useful for identifying stale status reports. It must be a valid timestamp in RFC3339 format. Once set, this field cannot be removed and cannot be set to an earlier timestamp than the current value.", + "$ref": "#/definitions/Time.v1.meta.apis.pkg.apimachinery.k8s.io" + }, + "nodes": { + "description": "nodes provides detailed status for each control-plane node in the Pacemaker cluster. While Pacemaker supports up to 32 nodes, the limit is set to 5 (max OpenShift control-plane nodes). For Two Node OpenShift with Fencing, exactly 2 nodes are expected in a healthy cluster. An empty list indicates a catastrophic failure where Pacemaker reports no nodes.", + "type": "array", + "items": { + "default": {}, + "$ref": "#/definitions/com.github.openshift.api.etcd.v1.PacemakerClusterNodeStatus" + }, + "x-kubernetes-list-map-keys": [ + "nodeName" + ], + "x-kubernetes-list-type": "map" + } + } + }, + "com.github.openshift.api.etcd.v1.PacemakerNodeAddress": { + "description": "PacemakerNodeAddress contains information for a node's address. This is similar to corev1.NodeAddress but adds validation for IP addresses.", + "type": "object", + "required": [ + "type", + "address" + ], + "properties": { + "address": { + "description": "address is the node address. For InternalIP, this must be a valid global unicast IPv4 or IPv6 address in canonical form. Canonical form means the shortest standard representation (e.g., \"192.168.1.1\" not \"192.168.001.001\", or \"2001:db8::1\" not \"2001:0db8::1\"). Maximum length is 39 characters (full IPv6 address). Global unicast includes private/RFC1918 addresses but excludes loopback, link-local, and multicast.", + "type": "string" + }, + "type": { + "description": "type is the type of node address. Currently only \"InternalIP\" is supported.\n\nPossible enum values:\n - `\"InternalIP\"` is an internal IP address assigned to the node. This is typically the IP address used for intra-cluster communication.", + "type": "string", + "enum": [ + "InternalIP" + ] + } + } + }, "com.github.openshift.api.etcd.v1alpha1.PacemakerCluster": { "description": "PacemakerCluster represents the current state of the pacemaker cluster as reported by the pcs status command. PacemakerCluster is a cluster-scoped singleton resource. The name of this instance is \"cluster\". This resource provides a view into the health and status of a pacemaker-managed cluster in Two Node OpenShift with Fencing deployments.\n\nCompatibility level 4: No compatibility is provided, the API can change at any point for any reason. These capabilities should not be used by applications needing long term support.", "type": "object", @@ -27212,7 +27509,7 @@ "x-kubernetes-list-type": "map" }, "fencingAgents": { - "description": "fencingAgents contains the status of fencing agents that can fence this node. Unlike resources (which are scheduled to run on this node), fencing agents are mapped to the node they can fence (their target), not the node where monitoring operations run. Each fencing agent entry includes a unique name, fencing type, target node, and health conditions. A node is considered fence-capable if at least one fencing agent is healthy. Expected to have 1 fencing agent per node, but up to 8 are supported for redundancy. Names must be unique within this array.", + "description": "fencingAgents contains the status of fencing agents that can fence this node. Unlike resources (which are scheduled to run on this node), fencing agents are mapped to the node they can fence (their target), not the node where monitoring operations run. Each fencing agent entry includes a unique name, fencing type, target node, and health conditions. A node is considered fence-capable if at least one fencing agent is healthy. A healthy node is expected to have at least 1 fencing agent, but the list may be empty when fencing agent discovery fails. Names must be unique within this array.", "type": "array", "items": { "default": {}, diff --git a/payload-manifests/crds/0000_80_machine-config_01_containerruntimeconfigs-CustomNoUpgrade.crd.yaml b/payload-manifests/crds/0000_80_machine-config_01_containerruntimeconfigs-CustomNoUpgrade.crd.yaml index 68726d9ce15..8826beb7bb8 100644 --- a/payload-manifests/crds/0000_80_machine-config_01_containerruntimeconfigs-CustomNoUpgrade.crd.yaml +++ b/payload-manifests/crds/0000_80_machine-config_01_containerruntimeconfigs-CustomNoUpgrade.crd.yaml @@ -163,15 +163,17 @@ spec: When a container image is requested, layers found at this location will be used instead of retrieving from the registry. The path is required and must be between 1 and 256 characters long, begin with a forward slash, - and only contain the characters a-z, A-Z, 0-9, '/', '.', '_', and '-'. + and only contain the characters a-z, A-Z, 0-9, '/', '.', '_', '-', and may end with the ':ref' suffix + for reference-based layer organization (e.g., /var/lib/stargz-store/store:ref for stargz-store). Consecutive forward slashes are not permitted. maxLength: 256 minLength: 1 type: string x-kubernetes-validations: - message: path must be absolute and contain only alphanumeric - characters, '/', '.', '_', and '-' - rule: self.matches('^/[a-zA-Z0-9/._-]+$') + characters, '/', '.', '_', '-', and optionally end with + ':ref' + rule: self.matches('^/[a-zA-Z0-9/._-]+(:ref)?$') - message: path must not contain consecutive forward slashes rule: '!self.contains(''//'')' required: diff --git a/payload-manifests/crds/0000_80_machine-config_01_containerruntimeconfigs-DevPreviewNoUpgrade.crd.yaml b/payload-manifests/crds/0000_80_machine-config_01_containerruntimeconfigs-DevPreviewNoUpgrade.crd.yaml index 8d918545b29..c9fcd29f4de 100644 --- a/payload-manifests/crds/0000_80_machine-config_01_containerruntimeconfigs-DevPreviewNoUpgrade.crd.yaml +++ b/payload-manifests/crds/0000_80_machine-config_01_containerruntimeconfigs-DevPreviewNoUpgrade.crd.yaml @@ -163,15 +163,17 @@ spec: When a container image is requested, layers found at this location will be used instead of retrieving from the registry. The path is required and must be between 1 and 256 characters long, begin with a forward slash, - and only contain the characters a-z, A-Z, 0-9, '/', '.', '_', and '-'. + and only contain the characters a-z, A-Z, 0-9, '/', '.', '_', '-', and may end with the ':ref' suffix + for reference-based layer organization (e.g., /var/lib/stargz-store/store:ref for stargz-store). Consecutive forward slashes are not permitted. maxLength: 256 minLength: 1 type: string x-kubernetes-validations: - message: path must be absolute and contain only alphanumeric - characters, '/', '.', '_', and '-' - rule: self.matches('^/[a-zA-Z0-9/._-]+$') + characters, '/', '.', '_', '-', and optionally end with + ':ref' + rule: self.matches('^/[a-zA-Z0-9/._-]+(:ref)?$') - message: path must not contain consecutive forward slashes rule: '!self.contains(''//'')' required: diff --git a/payload-manifests/crds/0000_80_machine-config_01_containerruntimeconfigs-TechPreviewNoUpgrade.crd.yaml b/payload-manifests/crds/0000_80_machine-config_01_containerruntimeconfigs-TechPreviewNoUpgrade.crd.yaml index 27a0cb3c173..eac8c58b630 100644 --- a/payload-manifests/crds/0000_80_machine-config_01_containerruntimeconfigs-TechPreviewNoUpgrade.crd.yaml +++ b/payload-manifests/crds/0000_80_machine-config_01_containerruntimeconfigs-TechPreviewNoUpgrade.crd.yaml @@ -163,15 +163,17 @@ spec: When a container image is requested, layers found at this location will be used instead of retrieving from the registry. The path is required and must be between 1 and 256 characters long, begin with a forward slash, - and only contain the characters a-z, A-Z, 0-9, '/', '.', '_', and '-'. + and only contain the characters a-z, A-Z, 0-9, '/', '.', '_', '-', and may end with the ':ref' suffix + for reference-based layer organization (e.g., /var/lib/stargz-store/store:ref for stargz-store). Consecutive forward slashes are not permitted. maxLength: 256 minLength: 1 type: string x-kubernetes-validations: - message: path must be absolute and contain only alphanumeric - characters, '/', '.', '_', and '-' - rule: self.matches('^/[a-zA-Z0-9/._-]+$') + characters, '/', '.', '_', '-', and optionally end with + ':ref' + rule: self.matches('^/[a-zA-Z0-9/._-]+(:ref)?$') - message: path must not contain consecutive forward slashes rule: '!self.contains(''//'')' required: