diff --git a/api/v1alpha1/cluster_types.go b/api/v1alpha1/cluster_types.go index d7749cd4..9f85fac2 100644 --- a/api/v1alpha1/cluster_types.go +++ b/api/v1alpha1/cluster_types.go @@ -60,6 +60,8 @@ type ClusterSpec struct { PVCAutoResizer *PVCAutoResizerSpec `json:"pvcAutoResizer,omitempty"` + LocalDiskActionController *LocalDiskActionControllerSpec `json:"localDiskActionController,omitempty"` + UI *UISpec `json:"ui,omitempty"` DRBD *DRBDSpec `json:"drbd,omitempty"` @@ -170,6 +172,13 @@ type PVCAutoResizerSpec struct { AutoResizer *ContainerCommonSpec `json:"autoresizer,omitempty"` } +type LocalDiskActionControllerSpec struct { + Disable bool `json:"disable,omitempty"` + Replicas int32 `json:"replicas"` + Common *PodCommonSpec `json:"common,omitempty"` + Controller *ContainerCommonSpec `json:"controller,omitempty"` +} + type AdmissionControllerSpec struct { Disable bool `json:"disable,omitempty"` Replicas int32 `json:"replicas,omitempty"` @@ -254,6 +263,7 @@ type ComponentStatus struct { Auditor *AuditorStatus `json:"auditor,omitempty"` FailoverAssistant *FailoverAssistantStatus `json:"failoverAssistant,omitempty"` PVCAutoResizer *PVCAutoResizerStatus `json:"pvcAutoResizer,omitempty"` + LocalDiskActionController *LocalDiskActionControllerStatus `json:"localDiskActionController,omitempty"` Exporter *ExporterStatus `json:"exporter,omitempty"` } @@ -318,6 +328,11 @@ type PVCAutoResizerStatus struct { Health string `json:"health,omitempty"` } +type LocalDiskActionControllerStatus struct { + Instances *DeployStatus `json:"instances,omitempty"` + Health string `json:"health,omitempty"` +} + type ExporterStatus struct { Instances *DeployStatus `json:"instances,omitempty"` Health string `json:"health,omitempty"` diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 67b8cc08..15a8d27e 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -375,6 +375,11 @@ func (in *ClusterSpec) DeepCopyInto(out *ClusterSpec) { *out = new(PVCAutoResizerSpec) (*in).DeepCopyInto(*out) } + if in.LocalDiskActionController != nil { + in, out := &in.LocalDiskActionController, &out.LocalDiskActionController + *out = new(LocalDiskActionControllerSpec) + (*in).DeepCopyInto(*out) + } if in.UI != nil { in, out := &in.UI, &out.UI *out = new(UISpec) @@ -471,6 +476,11 @@ func (in *ComponentStatus) DeepCopyInto(out *ComponentStatus) { *out = new(PVCAutoResizerStatus) (*in).DeepCopyInto(*out) } + if in.LocalDiskActionController != nil { + in, out := &in.LocalDiskActionController, &out.LocalDiskActionController + *out = new(LocalDiskActionControllerStatus) + (*in).DeepCopyInto(*out) + } if in.Exporter != nil { in, out := &in.Exporter, &out.Exporter *out = new(ExporterStatus) @@ -723,6 +733,51 @@ func (in *ImageSpec) DeepCopy() *ImageSpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LocalDiskActionControllerSpec) DeepCopyInto(out *LocalDiskActionControllerSpec) { + *out = *in + if in.Common != nil { + in, out := &in.Common, &out.Common + *out = new(PodCommonSpec) + (*in).DeepCopyInto(*out) + } + if in.Controller != nil { + in, out := &in.Controller, &out.Controller + *out = new(ContainerCommonSpec) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LocalDiskActionControllerSpec. +func (in *LocalDiskActionControllerSpec) DeepCopy() *LocalDiskActionControllerSpec { + if in == nil { + return nil + } + out := new(LocalDiskActionControllerSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LocalDiskActionControllerStatus) DeepCopyInto(out *LocalDiskActionControllerStatus) { + *out = *in + if in.Instances != nil { + in, out := &in.Instances, &out.Instances + *out = new(DeployStatus) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LocalDiskActionControllerStatus. +func (in *LocalDiskActionControllerStatus) DeepCopy() *LocalDiskActionControllerStatus { + if in == nil { + return nil + } + out := new(LocalDiskActionControllerStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *LocalDiskManagerSpec) DeepCopyInto(out *LocalDiskManagerSpec) { *out = *in diff --git a/config/crd/bases/hwameistor.io_clusters.yaml b/config/crd/bases/hwameistor.io_clusters.yaml index bb67b68c..25736428 100644 --- a/config/crd/bases/hwameistor.io_clusters.yaml +++ b/config/crd/bases/hwameistor.io_clusters.yaml @@ -4078,6 +4078,638 @@ spec: required: - replicas type: object + localDiskActionController: + properties: + common: + properties: + nodeAffinity: + description: Node affinity is a group of node affinity scheduling + rules. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods + to nodes that satisfy the affinity expressions specified + by this field, but it may choose a node that violates + one or more of the expressions. The node that is most + preferred is the one with the greatest sum of weights, + i.e. for each node that meets all of the scheduling + requirements (resource request, requiredDuringScheduling + affinity expressions, etc.), compute a sum by iterating + through the elements of this field and adding "weight" + to the sum if the node matches the corresponding matchExpressions; + the node(s) with the highest sum are the most preferred. + items: + description: An empty preferred scheduling term matches + all objects with implicit weight 0 (i.e. it's a no-op). + A null preferred scheduling term matches no objects + (i.e. is also a no-op). + properties: + preference: + description: A node selector term, associated with + the corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement is + a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the + values array must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be empty. If the + operator is Gt or Lt, the values array + must have a single element, which will + be interpreted as an integer. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement is + a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the + values array must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be empty. If the + operator is Gt or Lt, the values array + must have a single element, which will + be interpreted as an integer. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + description: Weight associated with matching the + corresponding nodeSelectorTerm, in the range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by + this field are not met at scheduling time, the pod will + not be scheduled onto the node. If the affinity requirements + specified by this field cease to be met at some point + during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from + its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector terms. + The terms are ORed. + items: + description: A null or empty node selector term + matches no objects. The requirements of them are + ANDed. The TopologySelectorTerm type implements + a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement is + a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the + values array must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be empty. If the + operator is Gt or Lt, the values array + must have a single element, which will + be interpreted as an integer. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement is + a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the + values array must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be empty. If the + operator is Gt or Lt, the values array + must have a single element, which will + be interpreted as an integer. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + description: Pod affinity is a group of inter pod affinity + scheduling rules. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods + to nodes that satisfy the affinity expressions specified + by this field, but it may choose a node that violates + one or more of the expressions. The node that is most + preferred is the one with the greatest sum of weights, + i.e. for each node that meets all of the scheduling + requirements (resource request, requiredDuringScheduling + affinity expressions, etc.), compute a sum by iterating + through the elements of this field and adding "weight" + to the sum if the node has pods which matches the corresponding + podAffinityTerm; the node(s) with the highest sum are + the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied + to the union of the namespaces selected by + this field and the ones listed in the namespaces + field. null selector and null or empty namespaces + list means "this pod's namespace". An empty + selector ({}) matches all namespaces. This + field is alpha-level and is only honored when + PodAffinityNamespaceSelector feature is enabled. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. + The term is applied to the union of the namespaces + listed in this field and the ones selected + by namespaceSelector. null or empty namespaces + list and null namespaceSelector means "this + pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the + pods matching the labelSelector in the specified + namespaces, where co-located is defined as + running on a node whose value of the label + with key topologyKey matches that of any node + on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the + corresponding podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by + this field are not met at scheduling time, the pod will + not be scheduled onto the node. If the affinity requirements + specified by this field cease to be met at some point + during pod execution (e.g. due to a pod label update), + the system may or may not try to eventually evict the + pod from its node. When there are multiple elements, + the lists of nodes corresponding to each podAffinityTerm + are intersected, i.e. all terms must be satisfied. + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or not + co-located (anti-affinity) with, where co-located + is defined as running on a node whose value of the + label with key matches that of any node + on which a pod of the set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied + to the union of the namespaces selected by this + field and the ones listed in the namespaces field. + null selector and null or empty namespaces list + means "this pod's namespace". An empty selector + ({}) matches all namespaces. This field is alpha-level + and is only honored when PodAffinityNamespaceSelector + feature is enabled. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. The + term is applied to the union of the namespaces + listed in this field and the ones selected by + namespaceSelector. null or empty namespaces list + and null namespaceSelector means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified namespaces, + where co-located is defined as running on a node + whose value of the label with key topologyKey + matches that of any node on which any of the selected + pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + priorityClassName: + type: string + tolerations: + items: + description: The pod this Toleration is attached to tolerates + any taint that matches the triple using + the matching operator . + properties: + effect: + description: Effect indicates the taint effect to match. + Empty means match all taint effects. When specified, + allowed values are NoSchedule, PreferNoSchedule and + NoExecute. + type: string + key: + description: Key is the taint key that the toleration + applies to. Empty means match all taint keys. If the + key is empty, operator must be Exists; this combination + means to match all values and all keys. + type: string + operator: + description: Operator represents a key's relationship + to the value. Valid operators are Exists and Equal. + Defaults to Equal. Exists is equivalent to wildcard + for value, so that a pod can tolerate all taints of + a particular category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period + of time the toleration (which must be of effect NoExecute, + otherwise this field is ignored) tolerates the taint. + By default, it is not set, which means tolerate the + taint forever (do not evict). Zero and negative values + will be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration + matches to. If the operator is Exists, the value should + be empty, otherwise just a regular string. + type: string + type: object + type: array + type: object + controller: + properties: + image: + properties: + registry: + type: string + repository: + type: string + tag: + type: string + type: object + resources: + description: ResourceRequirements describes the compute resource + requirements. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of + compute resources required. If Requests is omitted for + a container, it defaults to Limits if that is explicitly + specified, otherwise to an implementation-defined value. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + type: object + disable: + type: boolean + replicas: + format: int32 + type: integer + required: + - replicas + type: object localDiskManager: description: LocalDiskManager represents settings about LocalDiskManager properties: @@ -9390,6 +10022,44 @@ spec: - workloadType type: object type: object + localDiskActionController: + properties: + health: + type: string + instances: + properties: + availablePodCount: + format: int32 + type: integer + desiredPodCount: + format: int32 + type: integer + pods: + items: + properties: + name: + type: string + node: + type: string + status: + type: string + required: + - name + - node + - status + type: object + type: array + workloadName: + type: string + workloadType: + type: string + required: + - availablePodCount + - desiredPodCount + - workloadName + - workloadType + type: object + type: object localDiskManager: properties: csi: diff --git a/controllers/cluster_controller.go b/controllers/cluster_controller.go index f4e5dfb3..d553364d 100644 --- a/controllers/cluster_controller.go +++ b/controllers/cluster_controller.go @@ -43,6 +43,7 @@ import ( "github.com/hwameistor/hwameistor-operator/pkg/install/localstorage" "github.com/hwameistor/hwameistor-operator/pkg/install/lscsicontroller" "github.com/hwameistor/hwameistor-operator/pkg/install/pvcautoresizer" + "github.com/hwameistor/hwameistor-operator/pkg/install/localdiskactioncontroller" "github.com/hwameistor/hwameistor-operator/pkg/install/rbac" "github.com/hwameistor/hwameistor-operator/pkg/install/scheduler" "github.com/hwameistor/hwameistor-operator/pkg/install/storageclass" @@ -318,6 +319,25 @@ func (r *ClusterReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ct } } + if !newInstance.Spec.LocalDiskActionController.Disable { + newInstance, err = localdiskactioncontroller.NewActionControllerMaintainer(r.Client, newInstance).Ensure() + if err != nil { + log.Errorf("ensure localdiskactioncontroller err: %v", err) + return ctrl.Result{}, err + } + + if controller := newInstance.Status.ComponentStatus.LocalDiskActionController; controller != nil { + instances := controller.Instances + if instances != nil { + if instances.AvailablePodCount == instances.DesiredPodCount { + newInstance.Status.ComponentStatus.LocalDiskActionController.Health = "Normal" + } else { + newInstance.Status.ComponentStatus.LocalDiskActionController.Health = "Abnormal" + } + } + } + } + if !newInstance.Spec.ApiServer.Disable { newInstance, err = apiserver.NewApiServerMaintainer(r.Client, newInstance).Ensure() if err != nil { diff --git a/go.mod b/go.mod index 1fbc9880..704743c6 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/onsi/ginkgo v1.16.4 github.com/onsi/ginkgo/v2 v2.1.4 github.com/onsi/gomega v1.19.0 - k8s.io/apimachinery v0.24.2 + k8s.io/apimachinery v0.26.0 k8s.io/client-go v12.0.0+incompatible sigs.k8s.io/controller-runtime v0.9.2 ) @@ -33,16 +33,16 @@ require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/evanphx/json-patch v4.12.0+incompatible // indirect github.com/fsnotify/fsnotify v1.5.1 // indirect - github.com/go-logr/logr v1.2.0 // indirect + github.com/go-logr/logr v1.2.3 // indirect github.com/go-logr/zapr v0.4.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.2 // indirect - github.com/google/go-cmp v0.5.8 // indirect + github.com/google/go-cmp v0.5.9 // indirect github.com/google/gofuzz v1.1.0 // indirect github.com/google/uuid v1.1.2 // indirect github.com/googleapis/gnostic v0.5.5 // indirect - github.com/hwameistor/hwameistor v0.12.2 + github.com/hwameistor/hwameistor v0.12.3 github.com/imdario/mergo v0.3.12 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect @@ -60,11 +60,11 @@ require ( go.uber.org/multierr v1.6.0 // indirect go.uber.org/zap v1.19.1 // indirect golang.org/x/crypto v0.1.0 // indirect - golang.org/x/net v0.2.0 // indirect + golang.org/x/net v0.3.1-0.20221206200815-1e63c2f08a10 // indirect golang.org/x/oauth2 v0.1.0 // indirect - golang.org/x/sys v0.2.0 // indirect - golang.org/x/term v0.2.0 // indirect - golang.org/x/text v0.4.0 // indirect + golang.org/x/sys v0.3.0 // indirect + golang.org/x/term v0.3.0 // indirect + golang.org/x/text v0.5.0 // indirect golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 // indirect gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect google.golang.org/appengine v1.6.7 // indirect @@ -72,13 +72,13 @@ require ( gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect - k8s.io/api v0.24.2 + k8s.io/api v0.26.0 k8s.io/apiextensions-apiserver v0.21.2 k8s.io/component-base v0.21.2 // indirect - k8s.io/klog/v2 v2.60.1 // indirect - k8s.io/kube-openapi v0.0.0-20220328201542-3ee0da9b0b42 // indirect - k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 // indirect - sigs.k8s.io/structured-merge-diff/v4 v4.2.1 // indirect + k8s.io/klog/v2 v2.80.1 // indirect + k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 // indirect + k8s.io/utils v0.0.0-20221107191617-1a15be271d1d // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect sigs.k8s.io/yaml v1.3.0 // indirect ) diff --git a/go.sum b/go.sum index b5653483..7bfe60bb 100644 --- a/go.sum +++ b/go.sum @@ -208,8 +208,8 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= -github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -268,8 +268,8 @@ github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0m github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/hwameistor/hwameistor v0.12.2 h1:zmhkchP30fRBDkaQuG/dQtonJmytKT+VZuw0nE9SBN8= -github.com/hwameistor/hwameistor v0.12.2/go.mod h1:Ht+wwZlbtZilKHabhQWAAxmK8o4SDUgvbULjo+mUbp8= +github.com/hwameistor/hwameistor v0.12.3 h1:QefMAIf0kW/I9yEDsUy1dBWGL684VSAJNHN0PZHOMmk= +github.com/hwameistor/hwameistor v0.12.3/go.mod h1:lhdt7AiKwgOyJfjg0RXC9hAR9V8EULp7tGuAORA6KdU= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= @@ -571,8 +571,8 @@ golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.2.0 h1:sZfSu1wtKLGlWI4ZZayP0ck9Y73K1ynO6gqzTdBVdPU= -golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.3.1-0.20221206200815-1e63c2f08a10 h1:Frnccbp+ok2GkUS2tC84yAq/U9Vg+0sIO7aRL3T4Xnc= +golang.org/x/net v0.3.1-0.20221206200815-1e63c2f08a10/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -662,14 +662,14 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A= -golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ= +golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.2.0 h1:z85xZCsEl7bi/KwbNADeBYoOP0++7W1ipu+aGnpwzRM= -golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= +golang.org/x/term v0.3.0 h1:qoo4akIqOcDME5bhc/NgxUdovd6BSS2uMsVjB56q1xI= +golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -679,8 +679,8 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg= -golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM= +golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -888,8 +888,8 @@ k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7 h1:vEx13qjvaZ4yfObSSXW7Br k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7/go.mod h1:wXW5VT87nVfh/iLV8FpR2uDvrFyomxbtb1KivDbvPTE= k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20210527160623-6fdb442a123b/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 h1:HNSDgDCrr/6Ly3WEGKZftiE7IY19Vz2GdbOCyI4qqhc= -k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +k8s.io/utils v0.0.0-20221107191617-1a15be271d1d h1:0Smp/HP1OH4Rvhe+4B8nWGERtlqAGSftbSbbmm45oFs= +k8s.io/utils v0.0.0-20221107191617-1a15be271d1d/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= @@ -898,8 +898,8 @@ sigs.k8s.io/controller-runtime v0.9.0 h1:ZIZ/dtpboPSbZYY7uUz2OzrkaBTOThx2yekLtpG sigs.k8s.io/controller-runtime v0.9.0/go.mod h1:TgkfvrhhEw3PlI0BRL/5xM+89y3/yc0ZDfdbTl84si8= sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= sigs.k8s.io/structured-merge-diff/v4 v4.1.0/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= -sigs.k8s.io/structured-merge-diff/v4 v4.2.1 h1:bKCqE9GvQ5tiVHn5rfn1r+yao3aLQEaLzkkmAkf+A6Y= -sigs.k8s.io/structured-merge-diff/v4 v4.2.1/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= diff --git a/helm/operator/templates/_helpers.tpl b/helm/operator/templates/_helpers.tpl index d45c4a61..1b06be54 100644 --- a/helm/operator/templates/_helpers.tpl +++ b/helm/operator/templates/_helpers.tpl @@ -116,6 +116,11 @@ Create the name of the service account to use {{- default .Values.global.hwameistorVersion .Values.pvcAutoResizer.tag -}} {{- end -}} +{{/* Allow LocalDiskActionController image tag to be overridden. */}} +{{- define "hwameistor.localDiskActionControllerImageTag" -}} + {{- default .Values.global.hwameistorVersion .Values.localDiskActionController.tag -}} +{{- end -}} + {{/* Allow UI image tag to be overridden. */}} {{- define "hwameistor.uiImageTag" -}} {{- default .Values.global.hwameistorVersion .Values.ui.tag -}} diff --git a/helm/operator/templates/hwameistorcluster.yaml b/helm/operator/templates/hwameistorcluster.yaml index 06342f24..c27c7237 100644 --- a/helm/operator/templates/hwameistorcluster.yaml +++ b/helm/operator/templates/hwameistorcluster.yaml @@ -161,6 +161,14 @@ spec: registry: {{ $.Values.global.hwameistorImageRegistry }} repository: {{ $.Values.pvcAutoResizer.imageRepository }} tag: {{ template "hwameistor.pvcAutoResizerImageTag" . }} + localDiskActionController: + disable: {{ $.Values.localDiskActionController.disable }} + replicas: {{ $.Values.localDiskActionController.replicas }} + controller: + image: + registry: {{ $.Values.global.hwameistorImageRegistry }} + repository: {{ $.Values.localDiskActionController.imageRepository }} + tag: {{ template "hwameistor.localDiskActionControllerImageTag" . }} ui: disable: {{ $.Values.ui.disable }} replicas: {{ $.Values.ui.replicas }} diff --git a/helm/operator/values.yaml b/helm/operator/values.yaml index 02615989..bb2a0f44 100644 --- a/helm/operator/values.yaml +++ b/helm/operator/values.yaml @@ -5,7 +5,7 @@ global: #hwameistorImageRegistry: ghcr.m.daocloud.io k8sImageRegistry: registry.k8s.io # k8sImageRegistry: m.daocloud.io/registry.k8s.io - hwameistorVersion: v0.12.1 + hwameistorVersion: v0.12.3 operator: replicas: 1 @@ -17,7 +17,7 @@ localDiskManager: kubeletRootDir: /var/lib/kubelet manager: imageRepository: hwameistor/local-disk-manager - tag: v0.12.2 + tag: v0.12.3 csi: registrar: imageRepository: sig-storage/csi-node-driver-registrar @@ -37,7 +37,7 @@ localStorage: kubeletRootDir: /var/lib/kubelet member: imageRepository: hwameistor/local-storage - tag: v0.12.2 + tag: v0.12.3 hostPathSSHDir: /root/.ssh hostPathDRBDDir: /etc/drbd.d csi: @@ -73,25 +73,25 @@ scheduler: disable: false replicas: 1 imageRepository: hwameistor/scheduler - tag: v0.12.2 + tag: v0.12.3 admission: disable: false replicas: 1 imageRepository: hwameistor/admission - tag: v0.12.2 + tag: v0.12.3 evictor: disable: false replicas: 1 imageRepository: hwameistor/evictor - tag: v0.12.2 + tag: v0.12.3 apiserver: disable: false replicas: 1 imageRepository: hwameistor/apiserver - tag: v0.12.2 + tag: v0.12.3 authentication: enable: false accessId: admin @@ -101,25 +101,31 @@ exporter: disable: false replicas: 1 imageRepository: hwameistor/exporter - tag: v0.12.2 + tag: v0.12.3 auditor: disable: false replicas: 1 imageRepository: hwameistor/auditor - tag: v0.12.2 + tag: v0.12.3 failoverAssistant: disable: false replicas: 1 imageRepository: hwameistor/failover-assistant - tag: v0.12.2 + tag: v0.12.3 pvcAutoResizer: disable: false replicas: 1 imageRepository: hwameistor/pvc-autoresizer - tag: v0.12.2 + tag: v0.12.3 + +localDiskActionController: + disable: false + replicas: 1 + imageRepository: hwameistor/local-disk-action-controller + tag: v0.12.3 ui: disable: false diff --git a/pkg/install/constants.go b/pkg/install/constants.go index feaf9b29..bb2798b6 100644 --- a/pkg/install/constants.go +++ b/pkg/install/constants.go @@ -1,3 +1,3 @@ package install -const DefaultHwameistorVersion = "v0.12.2" \ No newline at end of file +const DefaultHwameistorVersion = "v0.12.3" \ No newline at end of file diff --git a/pkg/install/localdiskactioncontroller/localdiskactioncontroller.go b/pkg/install/localdiskactioncontroller/localdiskactioncontroller.go new file mode 100644 index 00000000..a4b0ed30 --- /dev/null +++ b/pkg/install/localdiskactioncontroller/localdiskactioncontroller.go @@ -0,0 +1,201 @@ +package localdiskactioncontroller + +import ( + "context" + "errors" + "reflect" + + hwameistoriov1alpha1 "github.com/hwameistor/hwameistor-operator/api/v1alpha1" + log "github.com/sirupsen/logrus" + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +type ActionControllerMaintainer struct { + Client client.Client + ClusterInstance *hwameistoriov1alpha1.Cluster +} + + +var actionControllerLabelSelectorKey = "app" +var actionControllerLabelSelectorValue = "hwameistor-local-disk-action-controller" +var ldaContainerName = "lda-controller" +var replicas = int32(1) + +func NewActionControllerMaintainer(cli client.Client, clusterInstance *hwameistoriov1alpha1.Cluster) *ActionControllerMaintainer { + return &ActionControllerMaintainer{ + Client: cli, + ClusterInstance: clusterInstance, + } +} + +var deployTemplate = appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "hwameistor-local-disk-action-controller", + Labels: map[string]string{ + actionControllerLabelSelectorKey: actionControllerLabelSelectorValue, + }, + }, + Spec: appsv1.DeploymentSpec{ + Replicas: &replicas, + Strategy: appsv1.DeploymentStrategy{ + Type: appsv1.RecreateDeploymentStrategyType, + }, + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + actionControllerLabelSelectorKey: actionControllerLabelSelectorValue, + }, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + actionControllerLabelSelectorKey: actionControllerLabelSelectorValue, + }, + }, + Spec: corev1.PodSpec{ + ServiceAccountName: "hwameistor-admin", + Containers: []corev1.Container{ + { + Name: ldaContainerName, + ImagePullPolicy: corev1.PullIfNotPresent, + }, + }, + }, + }, + }, +} + +func getActionControllerImageStringFromClusterInstance(clusterInstance *hwameistoriov1alpha1.Cluster) string { + imageSpec := clusterInstance.Spec.LocalDiskActionController.Controller.Image + return imageSpec.Registry + "/" + imageSpec.Repository + ":" + imageSpec.Tag +} + +func needOrNotToUpdateActionController (cluster *hwameistoriov1alpha1.Cluster, gotten appsv1.Deployment) (bool, *appsv1.Deployment) { + toUpdate := gotten.DeepCopy() + var needToUpdate bool + + for i, container := range toUpdate.Spec.Template.Spec.Containers { + if container.Name == ldaContainerName { + wantedImage := getActionControllerImageStringFromClusterInstance(cluster) + if container.Image != wantedImage { + container.Image = wantedImage + toUpdate.Spec.Template.Spec.Containers[i] = container + needToUpdate = true + } + } + } + + // wantedReplicas := getActionControllerImageStringFromClusterInstance(cluster) + // if *toUpdate.Spec.Replicas != wantedReplicas { + // toUpdate.Spec.Replicas = &wantedReplicas + // needToUpdate = true + // } + + return needToUpdate, toUpdate +} + +func SetActionController(clusterInstance *hwameistoriov1alpha1.Cluster) *appsv1.Deployment { + deployToCreate := deployTemplate.DeepCopy() + + deployToCreate.Namespace = clusterInstance.Spec.TargetNamespace + deployToCreate.OwnerReferences = append(deployToCreate.OwnerReferences, *metav1.NewControllerRef(clusterInstance, clusterInstance.GroupVersionKind())) + deployToCreate.Spec.Template.Spec.ServiceAccountName = clusterInstance.Spec.RBAC.ServiceAccountName + for i, container := range deployToCreate.Spec.Template.Spec.Containers { + if container.Name == ldaContainerName { + container.Image = getActionControllerImageStringFromClusterInstance(clusterInstance) + } + deployToCreate.Spec.Template.Spec.Containers[i] = container + } + + return deployToCreate +} + +func (m *ActionControllerMaintainer) Ensure() (*hwameistoriov1alpha1.Cluster, error) { + newClusterInstance := m.ClusterInstance.DeepCopy() + deployToCreate := SetActionController(newClusterInstance) + key := types.NamespacedName{ + Namespace: deployToCreate.Namespace, + Name: deployToCreate.Name, + } + var gotten appsv1.Deployment + if err := m.Client.Get(context.TODO(), key, &gotten); err != nil { + if apierrors.IsNotFound(err) { + if errCreate := m.Client.Create(context.TODO(), deployToCreate); errCreate != nil { + log.Errorf("create localdiskactioncontroller err: %v", errCreate) + return newClusterInstance, errCreate + } + return newClusterInstance, nil + } else { + log.Errorf("get localdiskactioncontroller err: %v", err) + return newClusterInstance, err + } + } + + needToUpdate, toUpdate := needOrNotToUpdateActionController(newClusterInstance, gotten) + if needToUpdate { + log.Infof("need to update localdiskactioncontroller") + if err := m.Client.Update(context.TODO(), toUpdate); err != nil { + log.Errorf("update localdiskactioncontroller err: %v", err) + return newClusterInstance, err + } + } + + var podList corev1.PodList + if err := m.Client.List(context.TODO(), &podList, &client.ListOptions{Namespace: deployToCreate.Namespace}); err != nil { + log.Errorf("List pods err: %v", err) + return newClusterInstance, err + } + + var podsManaged []corev1.Pod + for _, pod := range podList.Items { + if pod.Labels[actionControllerLabelSelectorKey] == actionControllerLabelSelectorValue { + podsManaged = append(podsManaged, pod) + } + } + + if len(podsManaged) > int(gotten.Status.Replicas) { + podsManagedErr := errors.New("pods managed more than desired") + log.Errorf("err: %v", podsManagedErr) + return newClusterInstance, podsManagedErr + } + + podsStatus := make([]hwameistoriov1alpha1.PodStatus, 0) + for _, pod := range podsManaged { + podStatus := hwameistoriov1alpha1.PodStatus{ + Name: pod.Name, + Node: pod.Spec.NodeName, + Status: string(pod.Status.Phase), + } + podsStatus = append(podsStatus, podStatus) + } + + instancesStatus := hwameistoriov1alpha1.DeployStatus{ + Pods: podsStatus, + DesiredPodCount: gotten.Status.Replicas, + AvailablePodCount: gotten.Status.AvailableReplicas, + WorkloadType: "Deployment", + WorkloadName: gotten.Name, + } + + if newClusterInstance.Status.ComponentStatus.LocalDiskActionController == nil { + newClusterInstance.Status.ComponentStatus.LocalDiskActionController = &hwameistoriov1alpha1.LocalDiskActionControllerStatus{ + Instances: &instancesStatus, + } + return newClusterInstance, nil + } else { + if newClusterInstance.Status.ComponentStatus.LocalDiskActionController.Instances == nil { + newClusterInstance.Status.ComponentStatus.LocalDiskActionController.Instances = &instancesStatus + return newClusterInstance, nil + } else { + if !reflect.DeepEqual(newClusterInstance.Status.ComponentStatus.LocalDiskActionController.Instances, instancesStatus) { + newClusterInstance.Status.ComponentStatus.LocalDiskActionController.Instances = &instancesStatus + return newClusterInstance, nil + } + } + } + return newClusterInstance, nil +} \ No newline at end of file diff --git a/pkg/install/utils/disk_reserve.go b/pkg/install/utils/disk_reserve.go index ded72372..cb9215ee 100644 --- a/pkg/install/utils/disk_reserve.go +++ b/pkg/install/utils/disk_reserve.go @@ -28,6 +28,11 @@ func CheckComponentsInstalledSuccessfully(cli client.Client, clusterInstance *hw return false } } + if !clusterInstance.Spec.LocalDiskActionController.Disable { + if clusterInstance.Status.ComponentStatus.LocalDiskActionController.Health != "Normal" { + return false + } + } if !clusterInstance.Spec.Scheduler.Disable { if clusterInstance.Status.ComponentStatus.Scheduler.Health != "Normal" { return false diff --git a/vendor/github.com/google/go-cmp/cmp/compare.go b/vendor/github.com/google/go-cmp/cmp/compare.go index fd2b3a42..087320da 100644 --- a/vendor/github.com/google/go-cmp/cmp/compare.go +++ b/vendor/github.com/google/go-cmp/cmp/compare.go @@ -13,21 +13,21 @@ // // The primary features of cmp are: // -// • When the default behavior of equality does not suit the needs of the test, -// custom equality functions can override the equality operation. -// For example, an equality function may report floats as equal so long as they -// are within some tolerance of each other. +// - When the default behavior of equality does not suit the test's needs, +// custom equality functions can override the equality operation. +// For example, an equality function may report floats as equal so long as +// they are within some tolerance of each other. // -// • Types that have an Equal method may use that method to determine equality. -// This allows package authors to determine the equality operation for the types -// that they define. +// - Types with an Equal method may use that method to determine equality. +// This allows package authors to determine the equality operation +// for the types that they define. // -// • If no custom equality functions are used and no Equal method is defined, -// equality is determined by recursively comparing the primitive kinds on both -// values, much like reflect.DeepEqual. Unlike reflect.DeepEqual, unexported -// fields are not compared by default; they result in panics unless suppressed -// by using an Ignore option (see cmpopts.IgnoreUnexported) or explicitly -// compared using the Exporter option. +// - If no custom equality functions are used and no Equal method is defined, +// equality is determined by recursively comparing the primitive kinds on +// both values, much like reflect.DeepEqual. Unlike reflect.DeepEqual, +// unexported fields are not compared by default; they result in panics +// unless suppressed by using an Ignore option (see cmpopts.IgnoreUnexported) +// or explicitly compared using the Exporter option. package cmp import ( @@ -45,25 +45,25 @@ import ( // Equal reports whether x and y are equal by recursively applying the // following rules in the given order to x and y and all of their sub-values: // -// • Let S be the set of all Ignore, Transformer, and Comparer options that -// remain after applying all path filters, value filters, and type filters. -// If at least one Ignore exists in S, then the comparison is ignored. -// If the number of Transformer and Comparer options in S is greater than one, -// then Equal panics because it is ambiguous which option to use. -// If S contains a single Transformer, then use that to transform the current -// values and recursively call Equal on the output values. -// If S contains a single Comparer, then use that to compare the current values. -// Otherwise, evaluation proceeds to the next rule. +// - Let S be the set of all Ignore, Transformer, and Comparer options that +// remain after applying all path filters, value filters, and type filters. +// If at least one Ignore exists in S, then the comparison is ignored. +// If the number of Transformer and Comparer options in S is non-zero, +// then Equal panics because it is ambiguous which option to use. +// If S contains a single Transformer, then use that to transform +// the current values and recursively call Equal on the output values. +// If S contains a single Comparer, then use that to compare the current values. +// Otherwise, evaluation proceeds to the next rule. // -// • If the values have an Equal method of the form "(T) Equal(T) bool" or -// "(T) Equal(I) bool" where T is assignable to I, then use the result of -// x.Equal(y) even if x or y is nil. Otherwise, no such method exists and -// evaluation proceeds to the next rule. +// - If the values have an Equal method of the form "(T) Equal(T) bool" or +// "(T) Equal(I) bool" where T is assignable to I, then use the result of +// x.Equal(y) even if x or y is nil. Otherwise, no such method exists and +// evaluation proceeds to the next rule. // -// • Lastly, try to compare x and y based on their basic kinds. -// Simple kinds like booleans, integers, floats, complex numbers, strings, and -// channels are compared using the equivalent of the == operator in Go. -// Functions are only equal if they are both nil, otherwise they are unequal. +// - Lastly, try to compare x and y based on their basic kinds. +// Simple kinds like booleans, integers, floats, complex numbers, strings, +// and channels are compared using the equivalent of the == operator in Go. +// Functions are only equal if they are both nil, otherwise they are unequal. // // Structs are equal if recursively calling Equal on all fields report equal. // If a struct contains unexported fields, Equal panics unless an Ignore option @@ -144,7 +144,7 @@ func rootStep(x, y interface{}) PathStep { // so that they have the same parent type. var t reflect.Type if !vx.IsValid() || !vy.IsValid() || vx.Type() != vy.Type() { - t = reflect.TypeOf((*interface{})(nil)).Elem() + t = anyType if vx.IsValid() { vvx := reflect.New(t).Elem() vvx.Set(vx) @@ -639,7 +639,9 @@ type dynChecker struct{ curr, next int } // Next increments the state and reports whether a check should be performed. // // Checks occur every Nth function call, where N is a triangular number: +// // 0 1 3 6 10 15 21 28 36 45 55 66 78 91 105 120 136 153 171 190 ... +// // See https://en.wikipedia.org/wiki/Triangular_number // // This sequence ensures that the cost of checks drops significantly as diff --git a/vendor/github.com/google/go-cmp/cmp/internal/diff/diff.go b/vendor/github.com/google/go-cmp/cmp/internal/diff/diff.go index bc196b16..a248e543 100644 --- a/vendor/github.com/google/go-cmp/cmp/internal/diff/diff.go +++ b/vendor/github.com/google/go-cmp/cmp/internal/diff/diff.go @@ -127,9 +127,9 @@ var randBool = rand.New(rand.NewSource(time.Now().Unix())).Intn(2) == 0 // This function returns an edit-script, which is a sequence of operations // needed to convert one list into the other. The following invariants for // the edit-script are maintained: -// • eq == (es.Dist()==0) -// • nx == es.LenX() -// • ny == es.LenY() +// - eq == (es.Dist()==0) +// - nx == es.LenX() +// - ny == es.LenY() // // This algorithm is not guaranteed to be an optimal solution (i.e., one that // produces an edit-script with a minimal Levenshtein distance). This algorithm @@ -169,12 +169,13 @@ func Difference(nx, ny int, f EqualFunc) (es EditScript) { // A diagonal edge is equivalent to a matching symbol between both X and Y. // Invariants: - // • 0 ≤ fwdPath.X ≤ (fwdFrontier.X, revFrontier.X) ≤ revPath.X ≤ nx - // • 0 ≤ fwdPath.Y ≤ (fwdFrontier.Y, revFrontier.Y) ≤ revPath.Y ≤ ny + // - 0 ≤ fwdPath.X ≤ (fwdFrontier.X, revFrontier.X) ≤ revPath.X ≤ nx + // - 0 ≤ fwdPath.Y ≤ (fwdFrontier.Y, revFrontier.Y) ≤ revPath.Y ≤ ny // // In general: - // • fwdFrontier.X < revFrontier.X - // • fwdFrontier.Y < revFrontier.Y + // - fwdFrontier.X < revFrontier.X + // - fwdFrontier.Y < revFrontier.Y + // // Unless, it is time for the algorithm to terminate. fwdPath := path{+1, point{0, 0}, make(EditScript, 0, (nx+ny)/2)} revPath := path{-1, point{nx, ny}, make(EditScript, 0)} @@ -195,19 +196,21 @@ func Difference(nx, ny int, f EqualFunc) (es EditScript) { // computing sub-optimal edit-scripts between two lists. // // The algorithm is approximately as follows: - // • Searching for differences switches back-and-forth between - // a search that starts at the beginning (the top-left corner), and - // a search that starts at the end (the bottom-right corner). The goal of - // the search is connect with the search from the opposite corner. - // • As we search, we build a path in a greedy manner, where the first - // match seen is added to the path (this is sub-optimal, but provides a - // decent result in practice). When matches are found, we try the next pair - // of symbols in the lists and follow all matches as far as possible. - // • When searching for matches, we search along a diagonal going through - // through the "frontier" point. If no matches are found, we advance the - // frontier towards the opposite corner. - // • This algorithm terminates when either the X coordinates or the - // Y coordinates of the forward and reverse frontier points ever intersect. + // - Searching for differences switches back-and-forth between + // a search that starts at the beginning (the top-left corner), and + // a search that starts at the end (the bottom-right corner). + // The goal of the search is connect with the search + // from the opposite corner. + // - As we search, we build a path in a greedy manner, + // where the first match seen is added to the path (this is sub-optimal, + // but provides a decent result in practice). When matches are found, + // we try the next pair of symbols in the lists and follow all matches + // as far as possible. + // - When searching for matches, we search along a diagonal going through + // through the "frontier" point. If no matches are found, + // we advance the frontier towards the opposite corner. + // - This algorithm terminates when either the X coordinates or the + // Y coordinates of the forward and reverse frontier points ever intersect. // This algorithm is correct even if searching only in the forward direction // or in the reverse direction. We do both because it is commonly observed @@ -389,6 +392,7 @@ type point struct{ X, Y int } func (p *point) add(dx, dy int) { p.X += dx; p.Y += dy } // zigzag maps a consecutive sequence of integers to a zig-zag sequence. +// // [0 1 2 3 4 5 ...] => [0 -1 +1 -2 +2 ...] func zigzag(x int) int { if x&1 != 0 { diff --git a/vendor/github.com/google/go-cmp/cmp/internal/value/zero.go b/vendor/github.com/google/go-cmp/cmp/internal/value/zero.go deleted file mode 100644 index 9147a299..00000000 --- a/vendor/github.com/google/go-cmp/cmp/internal/value/zero.go +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2017, The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package value - -import ( - "math" - "reflect" -) - -// IsZero reports whether v is the zero value. -// This does not rely on Interface and so can be used on unexported fields. -func IsZero(v reflect.Value) bool { - switch v.Kind() { - case reflect.Bool: - return v.Bool() == false - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - return v.Int() == 0 - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - return v.Uint() == 0 - case reflect.Float32, reflect.Float64: - return math.Float64bits(v.Float()) == 0 - case reflect.Complex64, reflect.Complex128: - return math.Float64bits(real(v.Complex())) == 0 && math.Float64bits(imag(v.Complex())) == 0 - case reflect.String: - return v.String() == "" - case reflect.UnsafePointer: - return v.Pointer() == 0 - case reflect.Chan, reflect.Func, reflect.Interface, reflect.Ptr, reflect.Map, reflect.Slice: - return v.IsNil() - case reflect.Array: - for i := 0; i < v.Len(); i++ { - if !IsZero(v.Index(i)) { - return false - } - } - return true - case reflect.Struct: - for i := 0; i < v.NumField(); i++ { - if !IsZero(v.Field(i)) { - return false - } - } - return true - } - return false -} diff --git a/vendor/github.com/google/go-cmp/cmp/options.go b/vendor/github.com/google/go-cmp/cmp/options.go index e57b9eb5..1f9ca9c4 100644 --- a/vendor/github.com/google/go-cmp/cmp/options.go +++ b/vendor/github.com/google/go-cmp/cmp/options.go @@ -33,6 +33,7 @@ type Option interface { } // applicableOption represents the following types: +// // Fundamental: ignore | validator | *comparer | *transformer // Grouping: Options type applicableOption interface { @@ -43,6 +44,7 @@ type applicableOption interface { } // coreOption represents the following types: +// // Fundamental: ignore | validator | *comparer | *transformer // Filters: *pathFilter | *valuesFilter type coreOption interface { @@ -336,9 +338,9 @@ func (tr transformer) String() string { // both implement T. // // The equality function must be: -// • Symmetric: equal(x, y) == equal(y, x) -// • Deterministic: equal(x, y) == equal(x, y) -// • Pure: equal(x, y) does not modify x or y +// - Symmetric: equal(x, y) == equal(y, x) +// - Deterministic: equal(x, y) == equal(x, y) +// - Pure: equal(x, y) does not modify x or y func Comparer(f interface{}) Option { v := reflect.ValueOf(f) if !function.IsType(v.Type(), function.Equal) || v.IsNil() { @@ -430,7 +432,7 @@ func AllowUnexported(types ...interface{}) Option { } // Result represents the comparison result for a single node and -// is provided by cmp when calling Result (see Reporter). +// is provided by cmp when calling Report (see Reporter). type Result struct { _ [0]func() // Make Result incomparable flags resultFlags diff --git a/vendor/github.com/google/go-cmp/cmp/path.go b/vendor/github.com/google/go-cmp/cmp/path.go index c7100346..a0a58850 100644 --- a/vendor/github.com/google/go-cmp/cmp/path.go +++ b/vendor/github.com/google/go-cmp/cmp/path.go @@ -41,13 +41,13 @@ type PathStep interface { // The type of each valid value is guaranteed to be identical to Type. // // In some cases, one or both may be invalid or have restrictions: - // • For StructField, both are not interface-able if the current field - // is unexported and the struct type is not explicitly permitted by - // an Exporter to traverse unexported fields. - // • For SliceIndex, one may be invalid if an element is missing from - // either the x or y slice. - // • For MapIndex, one may be invalid if an entry is missing from - // either the x or y map. + // - For StructField, both are not interface-able if the current field + // is unexported and the struct type is not explicitly permitted by + // an Exporter to traverse unexported fields. + // - For SliceIndex, one may be invalid if an element is missing from + // either the x or y slice. + // - For MapIndex, one may be invalid if an entry is missing from + // either the x or y map. // // The provided values must not be mutated. Values() (vx, vy reflect.Value) @@ -94,6 +94,7 @@ func (pa Path) Index(i int) PathStep { // The simplified path only contains struct field accesses. // // For example: +// // MyMap.MySlices.MyField func (pa Path) String() string { var ss []string @@ -108,6 +109,7 @@ func (pa Path) String() string { // GoString returns the path to a specific node using Go syntax. // // For example: +// // (*root.MyMap["key"].(*mypkg.MyStruct).MySlices)[2][3].MyField func (pa Path) GoString() string { var ssPre, ssPost []string @@ -159,7 +161,7 @@ func (ps pathStep) String() string { if ps.typ == nil { return "" } - s := ps.typ.String() + s := value.TypeString(ps.typ, false) if s == "" || strings.ContainsAny(s, "{}\n") { return "root" // Type too simple or complex to print } @@ -282,7 +284,7 @@ type typeAssertion struct { func (ta TypeAssertion) Type() reflect.Type { return ta.typ } func (ta TypeAssertion) Values() (vx, vy reflect.Value) { return ta.vx, ta.vy } -func (ta TypeAssertion) String() string { return fmt.Sprintf(".(%v)", ta.typ) } +func (ta TypeAssertion) String() string { return fmt.Sprintf(".(%v)", value.TypeString(ta.typ, false)) } // Transform is a transformation from the parent type to the current type. type Transform struct{ *transform } diff --git a/vendor/github.com/google/go-cmp/cmp/report_compare.go b/vendor/github.com/google/go-cmp/cmp/report_compare.go index 1ef65ac1..2050bf6b 100644 --- a/vendor/github.com/google/go-cmp/cmp/report_compare.go +++ b/vendor/github.com/google/go-cmp/cmp/report_compare.go @@ -7,8 +7,6 @@ package cmp import ( "fmt" "reflect" - - "github.com/google/go-cmp/cmp/internal/value" ) // numContextRecords is the number of surrounding equal records to print. @@ -117,7 +115,7 @@ func (opts formatOptions) FormatDiff(v *valueNode, ptrs *pointerReferences) (out // For leaf nodes, format the value based on the reflect.Values alone. // As a special case, treat equal []byte as a leaf nodes. - isBytes := v.Type.Kind() == reflect.Slice && v.Type.Elem() == reflect.TypeOf(byte(0)) + isBytes := v.Type.Kind() == reflect.Slice && v.Type.Elem() == byteType isEqualBytes := isBytes && v.NumDiff+v.NumIgnored+v.NumTransformed == 0 if v.MaxDepth == 0 || isEqualBytes { switch opts.DiffMode { @@ -248,11 +246,11 @@ func (opts formatOptions) formatDiffList(recs []reportRecord, k reflect.Kind, pt var isZero bool switch opts.DiffMode { case diffIdentical: - isZero = value.IsZero(r.Value.ValueX) || value.IsZero(r.Value.ValueY) + isZero = r.Value.ValueX.IsZero() || r.Value.ValueY.IsZero() case diffRemoved: - isZero = value.IsZero(r.Value.ValueX) + isZero = r.Value.ValueX.IsZero() case diffInserted: - isZero = value.IsZero(r.Value.ValueY) + isZero = r.Value.ValueY.IsZero() } if isZero { continue diff --git a/vendor/github.com/google/go-cmp/cmp/report_reflect.go b/vendor/github.com/google/go-cmp/cmp/report_reflect.go index 287b8935..2ab41fad 100644 --- a/vendor/github.com/google/go-cmp/cmp/report_reflect.go +++ b/vendor/github.com/google/go-cmp/cmp/report_reflect.go @@ -16,6 +16,13 @@ import ( "github.com/google/go-cmp/cmp/internal/value" ) +var ( + anyType = reflect.TypeOf((*interface{})(nil)).Elem() + stringType = reflect.TypeOf((*string)(nil)).Elem() + bytesType = reflect.TypeOf((*[]byte)(nil)).Elem() + byteType = reflect.TypeOf((*byte)(nil)).Elem() +) + type formatValueOptions struct { // AvoidStringer controls whether to avoid calling custom stringer // methods like error.Error or fmt.Stringer.String. @@ -184,7 +191,7 @@ func (opts formatOptions) FormatValue(v reflect.Value, parentKind reflect.Kind, } for i := 0; i < v.NumField(); i++ { vv := v.Field(i) - if value.IsZero(vv) { + if vv.IsZero() { continue // Elide fields with zero values } if len(list) == maxLen { @@ -205,7 +212,7 @@ func (opts formatOptions) FormatValue(v reflect.Value, parentKind reflect.Kind, } // Check whether this is a []byte of text data. - if t.Elem() == reflect.TypeOf(byte(0)) { + if t.Elem() == byteType { b := v.Bytes() isPrintSpace := func(r rune) bool { return unicode.IsPrint(r) || unicode.IsSpace(r) } if len(b) > 0 && utf8.Valid(b) && len(bytes.TrimFunc(b, isPrintSpace)) == 0 { diff --git a/vendor/github.com/google/go-cmp/cmp/report_slices.go b/vendor/github.com/google/go-cmp/cmp/report_slices.go index 68b5c1ae..23e444f6 100644 --- a/vendor/github.com/google/go-cmp/cmp/report_slices.go +++ b/vendor/github.com/google/go-cmp/cmp/report_slices.go @@ -104,7 +104,7 @@ func (opts formatOptions) FormatDiffSlice(v *valueNode) textNode { case t.Kind() == reflect.String: sx, sy = vx.String(), vy.String() isString = true - case t.Kind() == reflect.Slice && t.Elem() == reflect.TypeOf(byte(0)): + case t.Kind() == reflect.Slice && t.Elem() == byteType: sx, sy = string(vx.Bytes()), string(vy.Bytes()) isString = true case t.Kind() == reflect.Array: @@ -147,7 +147,10 @@ func (opts formatOptions) FormatDiffSlice(v *valueNode) textNode { }) efficiencyLines := float64(esLines.Dist()) / float64(len(esLines)) efficiencyBytes := float64(esBytes.Dist()) / float64(len(esBytes)) - isPureLinedText = efficiencyLines < 4*efficiencyBytes + quotedLength := len(strconv.Quote(sx + sy)) + unquotedLength := len(sx) + len(sy) + escapeExpansionRatio := float64(quotedLength) / float64(unquotedLength) + isPureLinedText = efficiencyLines < 4*efficiencyBytes || escapeExpansionRatio > 1.1 } } @@ -171,12 +174,13 @@ func (opts formatOptions) FormatDiffSlice(v *valueNode) textNode { // differences in a string literal. This format is more readable, // but has edge-cases where differences are visually indistinguishable. // This format is avoided under the following conditions: - // • A line starts with `"""` - // • A line starts with "..." - // • A line contains non-printable characters - // • Adjacent different lines differ only by whitespace + // - A line starts with `"""` + // - A line starts with "..." + // - A line contains non-printable characters + // - Adjacent different lines differ only by whitespace // // For example: + // // """ // ... // 3 identical lines // foo @@ -231,7 +235,7 @@ func (opts formatOptions) FormatDiffSlice(v *valueNode) textNode { var out textNode = &textWrap{Prefix: "(", Value: list2, Suffix: ")"} switch t.Kind() { case reflect.String: - if t != reflect.TypeOf(string("")) { + if t != stringType { out = opts.FormatType(t, out) } case reflect.Slice: @@ -326,12 +330,12 @@ func (opts formatOptions) FormatDiffSlice(v *valueNode) textNode { switch t.Kind() { case reflect.String: out = &textWrap{Prefix: "strings.Join(", Value: out, Suffix: fmt.Sprintf(", %q)", delim)} - if t != reflect.TypeOf(string("")) { + if t != stringType { out = opts.FormatType(t, out) } case reflect.Slice: out = &textWrap{Prefix: "bytes.Join(", Value: out, Suffix: fmt.Sprintf(", %q)", delim)} - if t != reflect.TypeOf([]byte(nil)) { + if t != bytesType { out = opts.FormatType(t, out) } } @@ -446,7 +450,6 @@ func (opts formatOptions) formatDiffSlice( // {NumIdentical: 3}, // {NumInserted: 1}, // ] -// func coalesceAdjacentEdits(name string, es diff.EditScript) (groups []diffStats) { var prevMode byte lastStats := func(mode byte) *diffStats { @@ -503,7 +506,6 @@ func coalesceAdjacentEdits(name string, es diff.EditScript) (groups []diffStats) // {NumIdentical: 8, NumRemoved: 12, NumInserted: 3}, // {NumIdentical: 63}, // ] -// func coalesceInterveningIdentical(groups []diffStats, windowSize int) []diffStats { groups, groupsOrig := groups[:0], groups for i, ds := range groupsOrig { @@ -548,7 +550,6 @@ func coalesceInterveningIdentical(groups []diffStats, windowSize int) []diffStat // {NumRemoved: 9}, // {NumIdentical: 64}, // incremented by 10 // ] -// func cleanupSurroundingIdentical(groups []diffStats, eq func(i, j int) bool) []diffStats { var ix, iy int // indexes into sequence x and y for i, ds := range groups { diff --git a/vendor/github.com/google/go-cmp/cmp/report_text.go b/vendor/github.com/google/go-cmp/cmp/report_text.go index 0fd46d7f..388fcf57 100644 --- a/vendor/github.com/google/go-cmp/cmp/report_text.go +++ b/vendor/github.com/google/go-cmp/cmp/report_text.go @@ -393,6 +393,7 @@ func (s diffStats) Append(ds diffStats) diffStats { // String prints a humanly-readable summary of coalesced records. // // Example: +// // diffStats{Name: "Field", NumIgnored: 5}.String() => "5 ignored fields" func (s diffStats) String() string { var ss []string diff --git a/vendor/github.com/hwameistor/hwameistor/deploy/crds/hwameistor.io_localdiskactions_crd.yaml b/vendor/github.com/hwameistor/hwameistor/deploy/crds/hwameistor.io_localdiskactions_crd.yaml new file mode 100644 index 00000000..fa5a35c7 --- /dev/null +++ b/vendor/github.com/hwameistor/hwameistor/deploy/crds/hwameistor.io_localdiskactions_crd.yaml @@ -0,0 +1,84 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: localdiskactions.hwameistor.io +spec: + group: hwameistor.io + names: + kind: LocalDiskAction + listKind: LocalDiskActionList + plural: localdiskactions + shortNames: + - lda + singular: localdiskaction + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .spec.action + name: Action + type: string + - jsonPath: .spec.rule.maxCapacity + name: MaxCapacity + type: integer + - jsonPath: .spec.rule.minCapacity + name: MinCapacity + type: integer + - jsonPath: .spec.rule.devicePath + name: DevicePath + type: string + name: v1alpha1 + schema: + openAPIV3Schema: + description: LocalDiskAction is the Schema for the localdiskactions API + 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: + type: object + spec: + description: LocalDiskActionSpec defines the desired state of LocalDiskAction + properties: + action: + enum: + - reserve + type: string + rule: + description: LocalDiskActionSpec defines the desired state of LocalDiskAction + properties: + devicePath: + description: Matched by glob, e.g. /dev/rbd* + type: string + maxCapacity: + description: Device capacity should less than this value + format: int64 + type: integer + minCapacity: + description: Device capacity should larger than this value + format: int64 + type: integer + type: object + required: + - action + type: object + status: + description: LocalDiskActionStatus defines the observed state of LocalDiskAction + properties: + latestMatchedLds: + description: latest matched local disks + items: + type: string + type: array + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/vendor/github.com/hwameistor/hwameistor/deploy/crds/hwameistor.io_localdiskclaims_crd.yaml b/vendor/github.com/hwameistor/hwameistor/deploy/crds/hwameistor.io_localdiskclaims_crd.yaml index d9e5f5f7..3e6c7ed9 100644 --- a/vendor/github.com/hwameistor/hwameistor/deploy/crds/hwameistor.io_localdiskclaims_crd.yaml +++ b/vendor/github.com/hwameistor/hwameistor/deploy/crds/hwameistor.io_localdiskclaims_crd.yaml @@ -50,10 +50,22 @@ spec: description: Capacity of the disk in bytes format: int64 type: integer + devicePaths: + description: Match the device path of Localdisk DevicePaths match + all disks if DevicePaths are empty + items: + type: string + type: array diskType: description: DiskType represents the type of drive like SSD, HDD etc., type: string + localDiskNames: + description: Match the name of Localdisk LocalDiskNames match + all disks if LocalDiskNames are empty + items: + type: string + type: array type: object diskRefs: description: DiskRefs represents which disks are assigned to the LocalDiskClaim diff --git a/vendor/github.com/hwameistor/hwameistor/deploy/crds/hwameistor.io_localdisknodes_crd.yaml b/vendor/github.com/hwameistor/hwameistor/deploy/crds/hwameistor.io_localdisknodes_crd.yaml index 0153a540..29bfbabe 100644 --- a/vendor/github.com/hwameistor/hwameistor/deploy/crds/hwameistor.io_localdisknodes_crd.yaml +++ b/vendor/github.com/hwameistor/hwameistor/deploy/crds/hwameistor.io_localdisknodes_crd.yaml @@ -113,10 +113,22 @@ spec: description: Capacity of the disk in bytes format: int64 type: integer + devicePaths: + description: Match the device path of Localdisk DevicePaths + match all disks if DevicePaths are empty + items: + type: string + type: array diskType: description: DiskType represents the type of drive like SSD, HDD etc., type: string + localDiskNames: + description: Match the name of Localdisk LocalDiskNames + match all disks if LocalDiskNames are empty + items: + type: string + type: array type: object diskRefs: description: DiskRefs represents which disks are assigned diff --git a/vendor/github.com/hwameistor/hwameistor/deploy/crds/hwameistor.io_localdisks_crd.yaml b/vendor/github.com/hwameistor/hwameistor/deploy/crds/hwameistor.io_localdisks_crd.yaml index 3e136a26..a137d5a1 100644 --- a/vendor/github.com/hwameistor/hwameistor/deploy/crds/hwameistor.io_localdisks_crd.yaml +++ b/vendor/github.com/hwameistor/hwameistor/deploy/crds/hwameistor.io_localdisks_crd.yaml @@ -34,7 +34,6 @@ spec: type: string - jsonPath: .spec.owner name: Owner - priority: 1 type: string - jsonPath: .status.claimState name: Phase diff --git a/vendor/github.com/hwameistor/hwameistor/deploy/crds/hwameistor.io_localstoragenodes_crd.yaml b/vendor/github.com/hwameistor/hwameistor/deploy/crds/hwameistor.io_localstoragenodes_crd.yaml index 26df3def..117b2afe 100644 --- a/vendor/github.com/hwameistor/hwameistor/deploy/crds/hwameistor.io_localstoragenodes_crd.yaml +++ b/vendor/github.com/hwameistor/hwameistor/deploy/crds/hwameistor.io_localstoragenodes_crd.yaml @@ -112,10 +112,22 @@ spec: description: Capacity of the disk in bytes format: int64 type: integer + devicePaths: + description: Match the device path of Localdisk DevicePaths + match all disks if DevicePaths are empty + items: + type: string + type: array diskType: description: DiskType represents the type of drive like SSD, HDD etc., type: string + localDiskNames: + description: Match the name of Localdisk LocalDiskNames + match all disks if LocalDiskNames are empty + items: + type: string + type: array type: object diskRefs: description: DiskRefs represents which disks are assigned diff --git a/vendor/github.com/hwameistor/hwameistor/deploy/crds/hwameistor.io_localvolumereplicasnapshotrecovers_crd.yaml b/vendor/github.com/hwameistor/hwameistor/deploy/crds/hwameistor.io_localvolumereplicasnapshotrestores_crd.yaml similarity index 67% rename from vendor/github.com/hwameistor/hwameistor/deploy/crds/hwameistor.io_localvolumereplicasnapshotrecovers_crd.yaml rename to vendor/github.com/hwameistor/hwameistor/deploy/crds/hwameistor.io_localvolumereplicasnapshotrestores_crd.yaml index 5cb069fa..ba7b7dbf 100644 --- a/vendor/github.com/hwameistor/hwameistor/deploy/crds/hwameistor.io_localvolumereplicasnapshotrecovers_crd.yaml +++ b/vendor/github.com/hwameistor/hwameistor/deploy/crds/hwameistor.io_localvolumereplicasnapshotrestores_crd.yaml @@ -1,33 +1,33 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: - name: localvolumereplicasnapshotrecovers.hwameistor.io + name: localvolumereplicasnapshotrestores.hwameistor.io spec: group: hwameistor.io names: - kind: LocalVolumeReplicaSnapshotRecover - listKind: LocalVolumeReplicaSnapshotRecoverList - plural: localvolumereplicasnapshotrecovers + kind: LocalVolumeReplicaSnapshotRestore + listKind: LocalVolumeReplicaSnapshotRestoreList + plural: localvolumereplicasnapshotrestores shortNames: - - lvrsrecover - - lvrsnaprecover - singular: localvolumereplicasnapshotrecover + - lvrsrestore + - lvrsnaprestore + singular: localvolumereplicasnapshotrestore scope: Cluster versions: - additionalPrinterColumns: - - description: Node to recover + - description: Node to restore jsonPath: .spec.nodeName name: nodeName type: string - - description: Target for the recover + - description: Target for the restore jsonPath: .spec.targetVolume name: targetvolume type: string - - description: Source snapshot for the recover + - description: Source snapshot for the restore jsonPath: .spec.sourceVolumeSnapshot name: sourcesnapshot type: string - - description: State of the recover + - description: State of the restore jsonPath: .status.state name: state type: string @@ -37,7 +37,7 @@ spec: name: v1alpha1 schema: openAPIV3Schema: - description: LocalVolumeReplicaSnapshotRecover is the Schema for the localvolumereplicasnapshotrecovers + description: LocalVolumeReplicaSnapshotRestore is the Schema for the localvolumereplicasnapshotrestores API properties: apiVersion: @@ -53,61 +53,61 @@ spec: metadata: type: object spec: - description: LocalVolumeReplicaSnapshotRecoverSpec defines the desired - state of LocalVolumeReplicaSnapshotRecover + description: LocalVolumeReplicaSnapshotRestoreSpec defines the desired + state of LocalVolumeReplicaSnapshotRestore properties: abort: default: false - description: Abort can be used to abort the recover operation and - clean up sub resources created by the recover operation automatically + description: Abort can be used to abort the restore operation and + clean up sub resources created by the restore operation automatically type: boolean nodeName: description: NodeName is the name of the node that snapshot will be - recovered at + restored at type: string - recoverType: - default: restore - description: RecoverType is the type about how to recover the volume, - e.g. rollback, restore. By default restore. + restoreType: + default: create + description: RestoreType is the type about how to restore the volume, + e.g. rollback, create. By default create. enum: - rollback - - restore + - create type: string sourceVolumeReplicaSnapshot: description: SourceVolumeReplicaSnapshot represents which replica - snapshot is used for volume to recover from + snapshot is used for volume to restore from type: string sourceVolumeSnapshot: description: SourceVolumeSnapshot represents which snapshot is used - for volume to recover from + for volume to restore from type: string targetPoolName: description: TargetVolume is the name of the target volume will place at type: string targetVolume: - description: TargetVolume is the name of the volume to recover to + description: TargetVolume is the name of the volume to restore to type: string - volumeSnapshotRecover: + volumeSnapshotRestore: type: string required: - nodeName - - recoverType + - restoreType - sourceVolumeReplicaSnapshot - sourceVolumeSnapshot - targetPoolName - targetVolume - - volumeSnapshotRecover + - volumeSnapshotRestore type: object status: - description: LocalVolumeReplicaSnapshotRecoverStatus defines the observed - state of LocalVolumeReplicaSnapshotRecover + description: LocalVolumeReplicaSnapshotRestoreStatus defines the observed + state of LocalVolumeReplicaSnapshotRestore properties: message: description: Message error message to describe some states type: string state: - description: State is the phase of recover volume snapshot, e.g. submitted, + description: State is the phase of restore volume snapshot, e.g. submitted, started, completed, abort, ... type: string type: object diff --git a/vendor/github.com/hwameistor/hwameistor/deploy/crds/hwameistor.io_localvolumesnapshotrecovers_crd.yaml b/vendor/github.com/hwameistor/hwameistor/deploy/crds/hwameistor.io_localvolumesnapshotrestores_crd.yaml similarity index 67% rename from vendor/github.com/hwameistor/hwameistor/deploy/crds/hwameistor.io_localvolumesnapshotrecovers_crd.yaml rename to vendor/github.com/hwameistor/hwameistor/deploy/crds/hwameistor.io_localvolumesnapshotrestores_crd.yaml index 737ac31d..9ca8121b 100644 --- a/vendor/github.com/hwameistor/hwameistor/deploy/crds/hwameistor.io_localvolumesnapshotrecovers_crd.yaml +++ b/vendor/github.com/hwameistor/hwameistor/deploy/crds/hwameistor.io_localvolumesnapshotrestores_crd.yaml @@ -1,29 +1,29 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: - name: localvolumesnapshotrecovers.hwameistor.io + name: localvolumesnapshotrestores.hwameistor.io spec: group: hwameistor.io names: - kind: LocalVolumeSnapshotRecover - listKind: LocalVolumeSnapshotRecoverList - plural: localvolumesnapshotrecovers + kind: LocalVolumeSnapshotRestore + listKind: LocalVolumeSnapshotRestoreList + plural: localvolumesnapshotrestores shortNames: - - lvsrecover - - lvsnaprecover - singular: localvolumesnapshotrecover + - lvsrestore + - lvsnaprestore + singular: localvolumesnapshotrestore scope: Cluster versions: - additionalPrinterColumns: - - description: Target for the recover + - description: Target for the restore jsonPath: .spec.targetVolume name: targetvolume type: string - - description: Source snapshot for the recover + - description: Source snapshot for the restore jsonPath: .spec.sourceVolumeSnapshot name: sourcesnapshot type: string - - description: State of the recover + - description: State of the restore jsonPath: .status.state name: state type: string @@ -33,7 +33,7 @@ spec: name: v1alpha1 schema: openAPIV3Schema: - description: LocalVolumeSnapshotRecover is user's request for either recovering + description: LocalVolumeSnapshotRestore is user's request for either restoring a local volume snapshot to a new volume, or merging into the old volume. properties: apiVersion: @@ -49,51 +49,51 @@ spec: metadata: type: object spec: - description: LocalVolumeSnapshotRecoverSpec defines the desired state - of LocalVolumeSnapshotRecover + description: LocalVolumeSnapshotRestoreSpec defines the desired state + of LocalVolumeSnapshotRestore properties: abort: default: false - description: Abort can be used to abort the recover operation and - clean up sub resources created by the recover operation automatically + description: Abort can be used to abort the restore operation and + clean up sub resources created by the restore operation automatically type: boolean - recoverType: - default: restore - description: RecoverType is the type about how to recover the volume, - e.g. rollback, restore. By default restore. + restoreType: + default: create + description: RestoreType is the type about how to restore the volume, + e.g. rollback, create. By default create. enum: - rollback - - restore + - create type: string sourceVolumeSnapshot: description: SourceVolumeSnapshot represents which snapshot is used - for volume to recover from + for volume to restore from type: string targetPoolName: description: TargetVolume is the name of the target volume will place at type: string targetVolume: - description: TargetVolume is the name of the volume to recover to + description: TargetVolume is the name of the volume to restore to type: string required: - - recoverType + - restoreType - sourceVolumeSnapshot type: object status: - description: LocalVolumeSnapshotRecoverStatus defines the observed state - of LocalVolumeSnapshotRecover + description: LocalVolumeSnapshotRestoreStatus defines the observed state + of LocalVolumeSnapshotRestore properties: message: description: Message error message to describe some states type: string state: - description: State is the phase of recover volume snapshot, e.g. submitted, + description: State is the phase of restore volume snapshot, e.g. submitted, started, completed, abort, ... type: string - volumeReplicaSnapshotRecover: - description: VolumeReplicaSnapshotRecover is the replica snapshot - to be recovered + volumeReplicaSnapshotRestore: + description: VolumeReplicaSnapshotRestore is the replica snapshot + to be restored items: type: string type: array diff --git a/vendor/github.com/hwameistor/hwameistor/pkg/apis/client/clientset/versioned/typed/hwameistor/v1alpha1/generated_expansion.go b/vendor/github.com/hwameistor/hwameistor/pkg/apis/client/clientset/versioned/typed/hwameistor/v1alpha1/generated_expansion.go index 3f1fa6f3..7140fec9 100644 --- a/vendor/github.com/hwameistor/hwameistor/pkg/apis/client/clientset/versioned/typed/hwameistor/v1alpha1/generated_expansion.go +++ b/vendor/github.com/hwameistor/hwameistor/pkg/apis/client/clientset/versioned/typed/hwameistor/v1alpha1/generated_expansion.go @@ -6,6 +6,8 @@ type EventExpansion interface{} type LocalDiskExpansion interface{} +type LocalDiskActionExpansion interface{} + type LocalDiskClaimExpansion interface{} type LocalDiskNodeExpansion interface{} diff --git a/vendor/github.com/hwameistor/hwameistor/pkg/apis/client/clientset/versioned/typed/hwameistor/v1alpha1/hwameistor_client.go b/vendor/github.com/hwameistor/hwameistor/pkg/apis/client/clientset/versioned/typed/hwameistor/v1alpha1/hwameistor_client.go index 4c8aed18..7e361a09 100644 --- a/vendor/github.com/hwameistor/hwameistor/pkg/apis/client/clientset/versioned/typed/hwameistor/v1alpha1/hwameistor_client.go +++ b/vendor/github.com/hwameistor/hwameistor/pkg/apis/client/clientset/versioned/typed/hwameistor/v1alpha1/hwameistor_client.go @@ -12,6 +12,7 @@ type HwameistorV1alpha1Interface interface { RESTClient() rest.Interface EventsGetter LocalDisksGetter + LocalDiskActionsGetter LocalDiskClaimsGetter LocalDiskNodesGetter LocalDiskVolumesGetter @@ -37,6 +38,10 @@ func (c *HwameistorV1alpha1Client) LocalDisks() LocalDiskInterface { return newLocalDisks(c) } +func (c *HwameistorV1alpha1Client) LocalDiskActions() LocalDiskActionInterface { + return newLocalDiskActions(c) +} + func (c *HwameistorV1alpha1Client) LocalDiskClaims() LocalDiskClaimInterface { return newLocalDiskClaims(c) } diff --git a/vendor/github.com/hwameistor/hwameistor/pkg/apis/client/clientset/versioned/typed/hwameistor/v1alpha1/localdiskaction.go b/vendor/github.com/hwameistor/hwameistor/pkg/apis/client/clientset/versioned/typed/hwameistor/v1alpha1/localdiskaction.go new file mode 100644 index 00000000..47cbe497 --- /dev/null +++ b/vendor/github.com/hwameistor/hwameistor/pkg/apis/client/clientset/versioned/typed/hwameistor/v1alpha1/localdiskaction.go @@ -0,0 +1,168 @@ +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "context" + "time" + + scheme "github.com/hwameistor/hwameistor/pkg/apis/client/clientset/versioned/scheme" + v1alpha1 "github.com/hwameistor/hwameistor/pkg/apis/hwameistor/v1alpha1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" +) + +// LocalDiskActionsGetter has a method to return a LocalDiskActionInterface. +// A group's client should implement this interface. +type LocalDiskActionsGetter interface { + LocalDiskActions() LocalDiskActionInterface +} + +// LocalDiskActionInterface has methods to work with LocalDiskAction resources. +type LocalDiskActionInterface interface { + Create(ctx context.Context, localDiskAction *v1alpha1.LocalDiskAction, opts v1.CreateOptions) (*v1alpha1.LocalDiskAction, error) + Update(ctx context.Context, localDiskAction *v1alpha1.LocalDiskAction, opts v1.UpdateOptions) (*v1alpha1.LocalDiskAction, error) + UpdateStatus(ctx context.Context, localDiskAction *v1alpha1.LocalDiskAction, opts v1.UpdateOptions) (*v1alpha1.LocalDiskAction, error) + Delete(ctx context.Context, name string, opts v1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error + Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha1.LocalDiskAction, error) + List(ctx context.Context, opts v1.ListOptions) (*v1alpha1.LocalDiskActionList, error) + Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.LocalDiskAction, err error) + LocalDiskActionExpansion +} + +// localDiskActions implements LocalDiskActionInterface +type localDiskActions struct { + client rest.Interface +} + +// newLocalDiskActions returns a LocalDiskActions +func newLocalDiskActions(c *HwameistorV1alpha1Client) *localDiskActions { + return &localDiskActions{ + client: c.RESTClient(), + } +} + +// Get takes name of the localDiskAction, and returns the corresponding localDiskAction object, and an error if there is any. +func (c *localDiskActions) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.LocalDiskAction, err error) { + result = &v1alpha1.LocalDiskAction{} + err = c.client.Get(). + Resource("localdiskactions"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of LocalDiskActions that match those selectors. +func (c *localDiskActions) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.LocalDiskActionList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1alpha1.LocalDiskActionList{} + err = c.client.Get(). + Resource("localdiskactions"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested localDiskActions. +func (c *localDiskActions) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Resource("localdiskactions"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a localDiskAction and creates it. Returns the server's representation of the localDiskAction, and an error, if there is any. +func (c *localDiskActions) Create(ctx context.Context, localDiskAction *v1alpha1.LocalDiskAction, opts v1.CreateOptions) (result *v1alpha1.LocalDiskAction, err error) { + result = &v1alpha1.LocalDiskAction{} + err = c.client.Post(). + Resource("localdiskactions"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(localDiskAction). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a localDiskAction and updates it. Returns the server's representation of the localDiskAction, and an error, if there is any. +func (c *localDiskActions) Update(ctx context.Context, localDiskAction *v1alpha1.LocalDiskAction, opts v1.UpdateOptions) (result *v1alpha1.LocalDiskAction, err error) { + result = &v1alpha1.LocalDiskAction{} + err = c.client.Put(). + Resource("localdiskactions"). + Name(localDiskAction.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(localDiskAction). + Do(ctx). + Into(result) + return +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *localDiskActions) UpdateStatus(ctx context.Context, localDiskAction *v1alpha1.LocalDiskAction, opts v1.UpdateOptions) (result *v1alpha1.LocalDiskAction, err error) { + result = &v1alpha1.LocalDiskAction{} + err = c.client.Put(). + Resource("localdiskactions"). + Name(localDiskAction.Name). + SubResource("status"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(localDiskAction). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the localDiskAction and deletes it. Returns an error if one occurs. +func (c *localDiskActions) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + return c.client.Delete(). + Resource("localdiskactions"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *localDiskActions) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Resource("localdiskactions"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched localDiskAction. +func (c *localDiskActions) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.LocalDiskAction, err error) { + result = &v1alpha1.LocalDiskAction{} + err = c.client.Patch(pt). + Resource("localdiskactions"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/vendor/github.com/hwameistor/hwameistor/pkg/apis/client/informers/externalversions/hwameistor/v1alpha1/interface.go b/vendor/github.com/hwameistor/hwameistor/pkg/apis/client/informers/externalversions/hwameistor/v1alpha1/interface.go index ccc75e6b..81ec3076 100644 --- a/vendor/github.com/hwameistor/hwameistor/pkg/apis/client/informers/externalversions/hwameistor/v1alpha1/interface.go +++ b/vendor/github.com/hwameistor/hwameistor/pkg/apis/client/informers/externalversions/hwameistor/v1alpha1/interface.go @@ -12,6 +12,8 @@ type Interface interface { Events() EventInformer // LocalDisks returns a LocalDiskInformer. LocalDisks() LocalDiskInformer + // LocalDiskActions returns a LocalDiskActionInformer. + LocalDiskActions() LocalDiskActionInformer // LocalDiskClaims returns a LocalDiskClaimInformer. LocalDiskClaims() LocalDiskClaimInformer // LocalDiskNodes returns a LocalDiskNodeInformer. @@ -55,6 +57,11 @@ func (v *version) LocalDisks() LocalDiskInformer { return &localDiskInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} } +// LocalDiskActions returns a LocalDiskActionInformer. +func (v *version) LocalDiskActions() LocalDiskActionInformer { + return &localDiskActionInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} + // LocalDiskClaims returns a LocalDiskClaimInformer. func (v *version) LocalDiskClaims() LocalDiskClaimInformer { return &localDiskClaimInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} diff --git a/vendor/github.com/hwameistor/hwameistor/pkg/apis/client/informers/externalversions/hwameistor/v1alpha1/localdiskaction.go b/vendor/github.com/hwameistor/hwameistor/pkg/apis/client/informers/externalversions/hwameistor/v1alpha1/localdiskaction.go new file mode 100644 index 00000000..fe825f02 --- /dev/null +++ b/vendor/github.com/hwameistor/hwameistor/pkg/apis/client/informers/externalversions/hwameistor/v1alpha1/localdiskaction.go @@ -0,0 +1,73 @@ +// Code generated by informer-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "context" + time "time" + + versioned "github.com/hwameistor/hwameistor/pkg/apis/client/clientset/versioned" + internalinterfaces "github.com/hwameistor/hwameistor/pkg/apis/client/informers/externalversions/internalinterfaces" + v1alpha1 "github.com/hwameistor/hwameistor/pkg/apis/client/listers/hwameistor/v1alpha1" + hwameistorv1alpha1 "github.com/hwameistor/hwameistor/pkg/apis/hwameistor/v1alpha1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + cache "k8s.io/client-go/tools/cache" +) + +// LocalDiskActionInformer provides access to a shared informer and lister for +// LocalDiskActions. +type LocalDiskActionInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1alpha1.LocalDiskActionLister +} + +type localDiskActionInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// NewLocalDiskActionInformer constructs a new informer for LocalDiskAction type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewLocalDiskActionInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredLocalDiskActionInformer(client, resyncPeriod, indexers, nil) +} + +// NewFilteredLocalDiskActionInformer constructs a new informer for LocalDiskAction type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredLocalDiskActionInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.HwameistorV1alpha1().LocalDiskActions().List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.HwameistorV1alpha1().LocalDiskActions().Watch(context.TODO(), options) + }, + }, + &hwameistorv1alpha1.LocalDiskAction{}, + resyncPeriod, + indexers, + ) +} + +func (f *localDiskActionInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredLocalDiskActionInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *localDiskActionInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&hwameistorv1alpha1.LocalDiskAction{}, f.defaultInformer) +} + +func (f *localDiskActionInformer) Lister() v1alpha1.LocalDiskActionLister { + return v1alpha1.NewLocalDiskActionLister(f.Informer().GetIndexer()) +} diff --git a/vendor/github.com/hwameistor/hwameistor/pkg/apis/client/listers/hwameistor/v1alpha1/expansion_generated.go b/vendor/github.com/hwameistor/hwameistor/pkg/apis/client/listers/hwameistor/v1alpha1/expansion_generated.go index dc4f72e5..4f8728d5 100644 --- a/vendor/github.com/hwameistor/hwameistor/pkg/apis/client/listers/hwameistor/v1alpha1/expansion_generated.go +++ b/vendor/github.com/hwameistor/hwameistor/pkg/apis/client/listers/hwameistor/v1alpha1/expansion_generated.go @@ -10,6 +10,10 @@ type EventListerExpansion interface{} // LocalDiskLister. type LocalDiskListerExpansion interface{} +// LocalDiskActionListerExpansion allows custom methods to be added to +// LocalDiskActionLister. +type LocalDiskActionListerExpansion interface{} + // LocalDiskClaimListerExpansion allows custom methods to be added to // LocalDiskClaimLister. type LocalDiskClaimListerExpansion interface{} diff --git a/vendor/github.com/hwameistor/hwameistor/pkg/apis/client/listers/hwameistor/v1alpha1/localdiskaction.go b/vendor/github.com/hwameistor/hwameistor/pkg/apis/client/listers/hwameistor/v1alpha1/localdiskaction.go new file mode 100644 index 00000000..5d6b87ee --- /dev/null +++ b/vendor/github.com/hwameistor/hwameistor/pkg/apis/client/listers/hwameistor/v1alpha1/localdiskaction.go @@ -0,0 +1,49 @@ +// Code generated by lister-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + v1alpha1 "github.com/hwameistor/hwameistor/pkg/apis/hwameistor/v1alpha1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// LocalDiskActionLister helps list LocalDiskActions. +type LocalDiskActionLister interface { + // List lists all LocalDiskActions in the indexer. + List(selector labels.Selector) (ret []*v1alpha1.LocalDiskAction, err error) + // Get retrieves the LocalDiskAction from the index for a given name. + Get(name string) (*v1alpha1.LocalDiskAction, error) + LocalDiskActionListerExpansion +} + +// localDiskActionLister implements the LocalDiskActionLister interface. +type localDiskActionLister struct { + indexer cache.Indexer +} + +// NewLocalDiskActionLister returns a new LocalDiskActionLister. +func NewLocalDiskActionLister(indexer cache.Indexer) LocalDiskActionLister { + return &localDiskActionLister{indexer: indexer} +} + +// List lists all LocalDiskActions in the indexer. +func (s *localDiskActionLister) List(selector labels.Selector) (ret []*v1alpha1.LocalDiskAction, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1alpha1.LocalDiskAction)) + }) + return ret, err +} + +// Get retrieves the LocalDiskAction from the index for a given name. +func (s *localDiskActionLister) Get(name string) (*v1alpha1.LocalDiskAction, error) { + obj, exists, err := s.indexer.GetByKey(name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1alpha1.Resource("localdiskaction"), name) + } + return obj.(*v1alpha1.LocalDiskAction), nil +} diff --git a/vendor/github.com/hwameistor/hwameistor/pkg/apis/hwameistor/v1alpha1/localdisk_types.go b/vendor/github.com/hwameistor/hwameistor/pkg/apis/hwameistor/v1alpha1/localdisk_types.go index 1af4d97b..a1c5e246 100644 --- a/vendor/github.com/hwameistor/hwameistor/pkg/apis/hwameistor/v1alpha1/localdisk_types.go +++ b/vendor/github.com/hwameistor/hwameistor/pkg/apis/hwameistor/v1alpha1/localdisk_types.go @@ -259,7 +259,7 @@ type LocalDiskStatus struct { // +kubebuilder:printcolumn:JSONPath=".spec.preNodeName",name=PreNodeMatch,type=string,priority=1 // +kubebuilder:printcolumn:JSONPath=".spec.devicePath",name=DevicePath,type=string // +kubebuilder:printcolumn:JSONPath=".spec.preDevicePath",name=PreDevicePath,type=string,priority=1 -// +kubebuilder:printcolumn:JSONPath=".spec.owner",name=Owner,type=string,priority=1 +// +kubebuilder:printcolumn:JSONPath=".spec.owner",name=Owner,type=string // +kubebuilder:printcolumn:JSONPath=".status.claimState",name=Phase,type=string // +kubebuilder:printcolumn:JSONPath=".spec.smartInfo.overallHealth",name=Health,type=string,priority=1 // +kubebuilder:printcolumn:JSONPath=".spec.reserved",name=Reserved,type=boolean,priority=1 diff --git a/vendor/github.com/hwameistor/hwameistor/pkg/apis/hwameistor/v1alpha1/localdiskaction_types.go b/vendor/github.com/hwameistor/hwameistor/pkg/apis/hwameistor/v1alpha1/localdiskaction_types.go new file mode 100644 index 00000000..0cbf1ace --- /dev/null +++ b/vendor/github.com/hwameistor/hwameistor/pkg/apis/hwameistor/v1alpha1/localdiskaction_types.go @@ -0,0 +1,77 @@ +package v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! +// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. + +// +kubebuilder:validation:Enum=reserve +type Action string + +const LocalDiskActionReserve Action = "reserve" + +// LocalDiskActionSpec defines the desired state of LocalDiskAction +type LocalDiskActionRule struct { + // Device capacity should less than this value + // +optional + MaxCapacity int64 `json:"maxCapacity,omitempty"` + // Device capacity should larger than this value + // +optional + MinCapacity int64 `json:"minCapacity,omitempty"` + // Matched by glob, e.g. /dev/rbd* + // +optional + DevicePath string `json:"devicePath,omitempty"` +} + +// LocalDiskActionSpec defines the desired state of LocalDiskAction +type LocalDiskActionSpec struct { + // +optional + Rule LocalDiskActionRule `json:"rule,omitempty"` + + // +kubebuilder:validation:Required + Action Action `json:"action"` +} + +// LocalDiskActionStatus defines the observed state of LocalDiskAction +type LocalDiskActionStatus struct { + // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster + // Important: Run "operator-sdk generate k8s" to regenerate code after modifying this file + // Add custom validation using kubebuilder tags: https://book-v1.book.kubebuilder.io/beyond_basics/generating_crd.html + + // latest matched local disks + LatestMatchedLds []string `json:"latestMatchedLds,omitempty"` +} + +// +genclient +// +genclient:nonNamespaced +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// LocalDiskAction is the Schema for the localdiskactions API +// +kubebuilder:subresource:status +// +kubebuilder:resource:scope=Cluster,shortName=lda +// +kubebuilder:printcolumn:JSONPath=".spec.action",name=Action,type=string +// +kubebuilder:printcolumn:JSONPath=".spec.rule.maxCapacity",name=MaxCapacity,type=integer +// +kubebuilder:printcolumn:JSONPath=".spec.rule.minCapacity",name=MinCapacity,type=integer +// +kubebuilder:printcolumn:JSONPath=".spec.rule.devicePath",name=DevicePath,type=string +type LocalDiskAction struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec LocalDiskActionSpec `json:"spec,omitempty"` + Status LocalDiskActionStatus `json:"status,omitempty"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// LocalDiskActionList contains a list of LocalDiskAction +type LocalDiskActionList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []LocalDiskAction `json:"items"` +} + +func init() { + SchemeBuilder.Register(&LocalDiskAction{}, &LocalDiskActionList{}) +} diff --git a/vendor/github.com/hwameistor/hwameistor/pkg/apis/hwameistor/v1alpha1/localdiskclaim_types.go b/vendor/github.com/hwameistor/hwameistor/pkg/apis/hwameistor/v1alpha1/localdiskclaim_types.go index 132866a2..b9f11eec 100644 --- a/vendor/github.com/hwameistor/hwameistor/pkg/apis/hwameistor/v1alpha1/localdiskclaim_types.go +++ b/vendor/github.com/hwameistor/hwameistor/pkg/apis/hwameistor/v1alpha1/localdiskclaim_types.go @@ -41,12 +41,12 @@ type LocalDiskClaimStatus struct { // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // LocalDiskClaim is the Schema for the localdiskclaims API -//+kubebuilder:validation:Required -//+kubebuilder:subresource:status -//+kubebuilder:printcolumn:JSONPath=".spec.nodeName",name=NodeMatch,type=string -//+kubebuilder:printcolumn:JSONPath=".status.status",name=Phase,type=string -//+kubebuilder:printcolumn:JSONPath=".spec.owner",name=Owner,type=string -//+kubebuilder:resource:scope=Cluster,shortName=ldc +// +kubebuilder:validation:Required +// +kubebuilder:subresource:status +// +kubebuilder:printcolumn:JSONPath=".spec.nodeName",name=NodeMatch,type=string +// +kubebuilder:printcolumn:JSONPath=".status.status",name=Phase,type=string +// +kubebuilder:printcolumn:JSONPath=".spec.owner",name=Owner,type=string +// +kubebuilder:resource:scope=Cluster,shortName=ldc type LocalDiskClaim struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` @@ -72,6 +72,14 @@ type DiskClaimDescription struct { // Capacity of the disk in bytes Capacity int64 `json:"capacity,omitempty"` + + // Match the name of Localdisk + // LocalDiskNames match all disks if LocalDiskNames are empty + LocalDiskNames []string `json:"localDiskNames,omitempty"` + + // Match the device path of Localdisk + // DevicePaths match all disks if DevicePaths are empty + DevicePaths []string `json:"devicePaths,omitempty"` } // DiskClaimStatus is a typed string for phase field of BlockDeviceClaim. diff --git a/vendor/github.com/hwameistor/hwameistor/pkg/apis/hwameistor/v1alpha1/localvolumereplicasnapshotrecover_types.go b/vendor/github.com/hwameistor/hwameistor/pkg/apis/hwameistor/v1alpha1/localvolumereplicasnapshotrestore_types.go similarity index 51% rename from vendor/github.com/hwameistor/hwameistor/pkg/apis/hwameistor/v1alpha1/localvolumereplicasnapshotrecover_types.go rename to vendor/github.com/hwameistor/hwameistor/pkg/apis/hwameistor/v1alpha1/localvolumereplicasnapshotrestore_types.go index 15ff1951..14b37e5f 100644 --- a/vendor/github.com/hwameistor/hwameistor/pkg/apis/hwameistor/v1alpha1/localvolumereplicasnapshotrecover_types.go +++ b/vendor/github.com/hwameistor/hwameistor/pkg/apis/hwameistor/v1alpha1/localvolumereplicasnapshotrestore_types.go @@ -7,13 +7,13 @@ import ( // EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! // NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. -// LocalVolumeReplicaSnapshotRecoverSpec defines the desired state of LocalVolumeReplicaSnapshotRecover -type LocalVolumeReplicaSnapshotRecoverSpec struct { - // NodeName is the name of the node that snapshot will be recovered at +// LocalVolumeReplicaSnapshotRestoreSpec defines the desired state of LocalVolumeReplicaSnapshotRestore +type LocalVolumeReplicaSnapshotRestoreSpec struct { + // NodeName is the name of the node that snapshot will be restored at // +kubebuilder:validation:Required NodeName string `json:"nodeName"` - // TargetVolume is the name of the volume to recover to + // TargetVolume is the name of the volume to restore to // +kubebuilder:validation:Required TargetVolume string `json:"targetVolume"` @@ -21,31 +21,31 @@ type LocalVolumeReplicaSnapshotRecoverSpec struct { // +kubebuilder:validation:Required TargetPoolName string `json:"targetPoolName"` - // SourceVolumeSnapshot represents which snapshot is used for volume to recover from + // SourceVolumeSnapshot represents which snapshot is used for volume to restore from // +kubebuilder:validation:Required SourceVolumeSnapshot string `json:"sourceVolumeSnapshot"` - // SourceVolumeReplicaSnapshot represents which replica snapshot is used for volume to recover from + // SourceVolumeReplicaSnapshot represents which replica snapshot is used for volume to restore from // +kubebuilder:validation:Required SourceVolumeReplicaSnapshot string `json:"sourceVolumeReplicaSnapshot"` - // RecoverType is the type about how to recover the volume, e.g. rollback, restore. By default restore. - // +kubebuilder:default:=restore + // RestoreType is the type about how to restore the volume, e.g. rollback, create. By default create. + // +kubebuilder:default:=create // +kubebuilder:validation:Required - // +kubebuilder:validation:Enum:=rollback;restore - RecoverType RecoverType `json:"recoverType"` + // +kubebuilder:validation:Enum:=rollback;create + RestoreType RestoreType `json:"restoreType"` // +kubebuilder:validation:Required - VolumeSnapshotRecover string `json:"volumeSnapshotRecover"` + VolumeSnapshotRestore string `json:"volumeSnapshotRestore"` - // Abort can be used to abort the recover operation and clean up sub resources created by the recover operation automatically + // Abort can be used to abort the restore operation and clean up sub resources created by the restore operation automatically // +kubebuilder:default:=false Abort bool `json:"abort,omitempty"` } -// LocalVolumeReplicaSnapshotRecoverStatus defines the observed state of LocalVolumeReplicaSnapshotRecover -type LocalVolumeReplicaSnapshotRecoverStatus struct { - // State is the phase of recover volume snapshot, e.g. submitted, started, completed, abort, ... +// LocalVolumeReplicaSnapshotRestoreStatus defines the observed state of LocalVolumeReplicaSnapshotRestore +type LocalVolumeReplicaSnapshotRestoreStatus struct { + // State is the phase of restore volume snapshot, e.g. submitted, started, completed, abort, ... State State `json:"state,omitempty"` // Message error message to describe some states @@ -54,31 +54,31 @@ type LocalVolumeReplicaSnapshotRecoverStatus struct { // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object -// LocalVolumeReplicaSnapshotRecover is the Schema for the localvolumereplicasnapshotrecovers API +// LocalVolumeReplicaSnapshotRestore is the Schema for the localvolumereplicasnapshotrestores API // +kubebuilder:subresource:status -// +kubebuilder:resource:path=localvolumereplicasnapshotrecovers,scope=Cluster,shortName=lvrsrecover;lvrsnaprecover -// +kubebuilder:printcolumn:name="nodeName",type=string,JSONPath=`.spec.nodeName`,description="Node to recover" -// +kubebuilder:printcolumn:name="targetvolume",type=string,JSONPath=`.spec.targetVolume`,description="Target for the recover" -// +kubebuilder:printcolumn:name="sourcesnapshot",type=string,JSONPath=`.spec.sourceVolumeSnapshot`,description="Source snapshot for the recover" -// +kubebuilder:printcolumn:name="state",type=string,JSONPath=`.status.state`,description="State of the recover" +// +kubebuilder:resource:path=localvolumereplicasnapshotrestores,scope=Cluster,shortName=lvrsrestore;lvrsnaprestore +// +kubebuilder:printcolumn:name="nodeName",type=string,JSONPath=`.spec.nodeName`,description="Node to restore" +// +kubebuilder:printcolumn:name="targetvolume",type=string,JSONPath=`.spec.targetVolume`,description="Target for the restore" +// +kubebuilder:printcolumn:name="sourcesnapshot",type=string,JSONPath=`.spec.sourceVolumeSnapshot`,description="Source snapshot for the restore" +// +kubebuilder:printcolumn:name="state",type=string,JSONPath=`.status.state`,description="State of the restore" // +kubebuilder:printcolumn:name="age",type=date,JSONPath=`.metadata.creationTimestamp` -type LocalVolumeReplicaSnapshotRecover struct { +type LocalVolumeReplicaSnapshotRestore struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` - Spec LocalVolumeReplicaSnapshotRecoverSpec `json:"spec,omitempty"` - Status LocalVolumeReplicaSnapshotRecoverStatus `json:"status,omitempty"` + Spec LocalVolumeReplicaSnapshotRestoreSpec `json:"spec,omitempty"` + Status LocalVolumeReplicaSnapshotRestoreStatus `json:"status,omitempty"` } // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object -// LocalVolumeReplicaSnapshotRecoverList contains a list of LocalVolumeReplicaSnapshotRecover -type LocalVolumeReplicaSnapshotRecoverList struct { +// LocalVolumeReplicaSnapshotRestoreList contains a list of LocalVolumeReplicaSnapshotRestore +type LocalVolumeReplicaSnapshotRestoreList struct { metav1.TypeMeta `json:",inline"` metav1.ListMeta `json:"metadata,omitempty"` - Items []LocalVolumeReplicaSnapshotRecover `json:"items"` + Items []LocalVolumeReplicaSnapshotRestore `json:"items"` } func init() { - SchemeBuilder.Register(&LocalVolumeReplicaSnapshotRecover{}, &LocalVolumeReplicaSnapshotRecoverList{}) + SchemeBuilder.Register(&LocalVolumeReplicaSnapshotRestore{}, &LocalVolumeReplicaSnapshotRestoreList{}) } diff --git a/vendor/github.com/hwameistor/hwameistor/pkg/apis/hwameistor/v1alpha1/localvolumesnapshot_types.go b/vendor/github.com/hwameistor/hwameistor/pkg/apis/hwameistor/v1alpha1/localvolumesnapshot_types.go index dd0a7a32..12153ad4 100644 --- a/vendor/github.com/hwameistor/hwameistor/pkg/apis/hwameistor/v1alpha1/localvolumesnapshot_types.go +++ b/vendor/github.com/hwameistor/hwameistor/pkg/apis/hwameistor/v1alpha1/localvolumesnapshot_types.go @@ -5,7 +5,7 @@ import ( ) const ( - SnapshotRecoveringFinalizer = "provisioner.hwameistor.io/recovering-protection" + SnapshotRestoringFinalizer = "provisioner.hwameistor.io/restoring-protection" ) // VolumeSnapshotSpec describes the common attributes of a volume snapshot. diff --git a/vendor/github.com/hwameistor/hwameistor/pkg/apis/hwameistor/v1alpha1/localvolumesnapshotrecover_types.go b/vendor/github.com/hwameistor/hwameistor/pkg/apis/hwameistor/v1alpha1/localvolumesnapshotrecover_types.go deleted file mode 100644 index 43102913..00000000 --- a/vendor/github.com/hwameistor/hwameistor/pkg/apis/hwameistor/v1alpha1/localvolumesnapshotrecover_types.go +++ /dev/null @@ -1,78 +0,0 @@ -package v1alpha1 - -import ( - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! -// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. - -const ( - SourceVolumeSnapshotAnnoKey = "hwameistor.io/source-snapshot" - VolumeSnapshotRecoverCompletedAnnoKey = "hwameistor.io/snapshot-recover-completed" -) - -// LocalVolumeSnapshotRecoverSpec defines the desired state of LocalVolumeSnapshotRecover -type LocalVolumeSnapshotRecoverSpec struct { - // TargetVolume is the name of the volume to recover to - TargetVolume string `json:"targetVolume,omitempty"` - - // TargetVolume is the name of the target volume will place at - TargetPoolName string `json:"targetPoolName,omitempty"` - - // SourceVolumeSnapshot represents which snapshot is used for volume to recover from - // +kubebuilder:validation:Required - SourceVolumeSnapshot string `json:"sourceVolumeSnapshot"` - - // RecoverType is the type about how to recover the volume, e.g. rollback, restore. By default restore. - // +kubebuilder:default:=restore - // +kubebuilder:validation:Required - // +kubebuilder:validation:Enum:=rollback;restore - RecoverType RecoverType `json:"recoverType"` - - // Abort can be used to abort the recover operation and clean up sub resources created by the recover operation automatically - // +kubebuilder:default:=false - Abort bool `json:"abort,omitempty"` -} - -// LocalVolumeSnapshotRecoverStatus defines the observed state of LocalVolumeSnapshotRecover -type LocalVolumeSnapshotRecoverStatus struct { - // VolumeReplicaSnapshotRecover is the replica snapshot to be recovered - VolumeReplicaSnapshotRecover []string `json:"volumeReplicaSnapshotRecover,omitempty"` - - // State is the phase of recover volume snapshot, e.g. submitted, started, completed, abort, ... - State State `json:"state,omitempty"` - - // Message error message to describe some states - Message string `json:"message,omitempty"` -} - -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - -// LocalVolumeSnapshotRecover is user's request for either recovering a local volume snapshot to a new volume, or merging into the old volume. -// +kubebuilder:subresource:status -// +kubebuilder:resource:path=localvolumesnapshotrecovers,scope=Cluster,shortName=lvsrecover;lvsnaprecover -// +kubebuilder:printcolumn:name="targetvolume",type=string,JSONPath=`.spec.targetVolume`,description="Target for the recover" -// +kubebuilder:printcolumn:name="sourcesnapshot",type=string,JSONPath=`.spec.sourceVolumeSnapshot`,description="Source snapshot for the recover" -// +kubebuilder:printcolumn:name="state",type=string,JSONPath=`.status.state`,description="State of the recover" -// +kubebuilder:printcolumn:name="age",type=date,JSONPath=`.metadata.creationTimestamp` -type LocalVolumeSnapshotRecover struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - Spec LocalVolumeSnapshotRecoverSpec `json:"spec,omitempty"` - Status LocalVolumeSnapshotRecoverStatus `json:"status,omitempty"` -} - -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - -// LocalVolumeSnapshotRecoverList contains a list of LocalVolumeSnapshotRecover -type LocalVolumeSnapshotRecoverList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []LocalVolumeSnapshotRecover `json:"items"` -} - -func init() { - SchemeBuilder.Register(&LocalVolumeSnapshotRecover{}, &LocalVolumeSnapshotRecoverList{}) -} diff --git a/vendor/github.com/hwameistor/hwameistor/pkg/apis/hwameistor/v1alpha1/localvolumesnapshotrestore_types.go b/vendor/github.com/hwameistor/hwameistor/pkg/apis/hwameistor/v1alpha1/localvolumesnapshotrestore_types.go new file mode 100644 index 00000000..0cf3bd3e --- /dev/null +++ b/vendor/github.com/hwameistor/hwameistor/pkg/apis/hwameistor/v1alpha1/localvolumesnapshotrestore_types.go @@ -0,0 +1,78 @@ +package v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! +// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. + +const ( + SourceVolumeSnapshotAnnoKey = "hwameistor.io/source-snapshot" + VolumeSnapshotRestoreCompletedAnnoKey = "hwameistor.io/snapshot-restore-completed" +) + +// LocalVolumeSnapshotRestoreSpec defines the desired state of LocalVolumeSnapshotRestore +type LocalVolumeSnapshotRestoreSpec struct { + // TargetVolume is the name of the volume to restore to + TargetVolume string `json:"targetVolume,omitempty"` + + // TargetVolume is the name of the target volume will place at + TargetPoolName string `json:"targetPoolName,omitempty"` + + // SourceVolumeSnapshot represents which snapshot is used for volume to restore from + // +kubebuilder:validation:Required + SourceVolumeSnapshot string `json:"sourceVolumeSnapshot"` + + // RestoreType is the type about how to restore the volume, e.g. rollback, create. By default create. + // +kubebuilder:default:=create + // +kubebuilder:validation:Required + // +kubebuilder:validation:Enum:=rollback;create + RestoreType RestoreType `json:"restoreType"` + + // Abort can be used to abort the restore operation and clean up sub resources created by the restore operation automatically + // +kubebuilder:default:=false + Abort bool `json:"abort,omitempty"` +} + +// LocalVolumeSnapshotRestoreStatus defines the observed state of LocalVolumeSnapshotRestore +type LocalVolumeSnapshotRestoreStatus struct { + // VolumeReplicaSnapshotRestore is the replica snapshot to be restored + VolumeReplicaSnapshotRestore []string `json:"volumeReplicaSnapshotRestore,omitempty"` + + // State is the phase of restore volume snapshot, e.g. submitted, started, completed, abort, ... + State State `json:"state,omitempty"` + + // Message error message to describe some states + Message string `json:"message,omitempty"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// LocalVolumeSnapshotRestore is user's request for either restoring a local volume snapshot to a new volume, or merging into the old volume. +// +kubebuilder:subresource:status +// +kubebuilder:resource:path=localvolumesnapshotrestores,scope=Cluster,shortName=lvsrestore;lvsnaprestore +// +kubebuilder:printcolumn:name="targetvolume",type=string,JSONPath=`.spec.targetVolume`,description="Target for the restore" +// +kubebuilder:printcolumn:name="sourcesnapshot",type=string,JSONPath=`.spec.sourceVolumeSnapshot`,description="Source snapshot for the restore" +// +kubebuilder:printcolumn:name="state",type=string,JSONPath=`.status.state`,description="State of the restore" +// +kubebuilder:printcolumn:name="age",type=date,JSONPath=`.metadata.creationTimestamp` +type LocalVolumeSnapshotRestore struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec LocalVolumeSnapshotRestoreSpec `json:"spec,omitempty"` + Status LocalVolumeSnapshotRestoreStatus `json:"status,omitempty"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// LocalVolumeSnapshotRestoreList contains a list of LocalVolumeSnapshotRestore +type LocalVolumeSnapshotRestoreList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []LocalVolumeSnapshotRestore `json:"items"` +} + +func init() { + SchemeBuilder.Register(&LocalVolumeSnapshotRestore{}, &LocalVolumeSnapshotRestoreList{}) +} diff --git a/vendor/github.com/hwameistor/hwameistor/pkg/apis/hwameistor/v1alpha1/types.go b/vendor/github.com/hwameistor/hwameistor/pkg/apis/hwameistor/v1alpha1/types.go index 68ff169a..d2afa16a 100644 --- a/vendor/github.com/hwameistor/hwameistor/pkg/apis/hwameistor/v1alpha1/types.go +++ b/vendor/github.com/hwameistor/hwameistor/pkg/apis/hwameistor/v1alpha1/types.go @@ -122,15 +122,15 @@ const ( SnapshotParameterSizeKey = "snapsize" ) -type RecoverType string +type RestoreType string // consts for snapshot restore const ( - // RecoverTypeRollback is used to merge snapshot to existing volume - RecoverTypeRollback RecoverType = "rollback" - // RecoverTypeRestore is used to create a new volume from existing snapshot - RecoverTypeRestore RecoverType = "restore" + // RestoreTypeRollback is used to merge snapshot to existing volume + RestoreTypeRollback RestoreType = "rollback" + // RestoreTypeCreate is used to create a new volume from existing snapshot + RestoreTypeCreate RestoreType = "create" ) // misc diff --git a/vendor/github.com/hwameistor/hwameistor/pkg/apis/hwameistor/v1alpha1/zz_generated.deepcopy.go b/vendor/github.com/hwameistor/hwameistor/pkg/apis/hwameistor/v1alpha1/zz_generated.deepcopy.go index 97cb4997..91eba860 100644 --- a/vendor/github.com/hwameistor/hwameistor/pkg/apis/hwameistor/v1alpha1/zz_generated.deepcopy.go +++ b/vendor/github.com/hwameistor/hwameistor/pkg/apis/hwameistor/v1alpha1/zz_generated.deepcopy.go @@ -93,6 +93,16 @@ func (in *DiskAttributes) DeepCopy() *DiskAttributes { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *DiskClaimDescription) DeepCopyInto(out *DiskClaimDescription) { *out = *in + if in.LocalDiskNames != nil { + in, out := &in.LocalDiskNames, &out.LocalDiskNames + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.DevicePaths != nil { + in, out := &in.DevicePaths, &out.DevicePaths + *out = make([]string, len(*in)) + copy(*out, *in) + } return } @@ -299,6 +309,121 @@ func (in *LocalDisk) DeepCopyObject() runtime.Object { return nil } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LocalDiskAction) DeepCopyInto(out *LocalDiskAction) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + out.Spec = in.Spec + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LocalDiskAction. +func (in *LocalDiskAction) DeepCopy() *LocalDiskAction { + if in == nil { + return nil + } + out := new(LocalDiskAction) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *LocalDiskAction) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LocalDiskActionList) DeepCopyInto(out *LocalDiskActionList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]LocalDiskAction, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LocalDiskActionList. +func (in *LocalDiskActionList) DeepCopy() *LocalDiskActionList { + if in == nil { + return nil + } + out := new(LocalDiskActionList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *LocalDiskActionList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LocalDiskActionRule) DeepCopyInto(out *LocalDiskActionRule) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LocalDiskActionRule. +func (in *LocalDiskActionRule) DeepCopy() *LocalDiskActionRule { + if in == nil { + return nil + } + out := new(LocalDiskActionRule) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LocalDiskActionSpec) DeepCopyInto(out *LocalDiskActionSpec) { + *out = *in + out.Rule = in.Rule + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LocalDiskActionSpec. +func (in *LocalDiskActionSpec) DeepCopy() *LocalDiskActionSpec { + if in == nil { + return nil + } + out := new(LocalDiskActionSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LocalDiskActionStatus) DeepCopyInto(out *LocalDiskActionStatus) { + *out = *in + if in.LatestMatchedLds != nil { + in, out := &in.LatestMatchedLds, &out.LatestMatchedLds + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LocalDiskActionStatus. +func (in *LocalDiskActionStatus) DeepCopy() *LocalDiskActionStatus { + if in == nil { + return nil + } + out := new(LocalDiskActionStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *LocalDiskClaim) DeepCopyInto(out *LocalDiskClaim) { *out = *in @@ -363,7 +488,7 @@ func (in *LocalDiskClaimList) DeepCopyObject() runtime.Object { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *LocalDiskClaimSpec) DeepCopyInto(out *LocalDiskClaimSpec) { *out = *in - out.Description = in.Description + in.Description.DeepCopyInto(&out.Description) if in.DiskRefs != nil { in, out := &in.DiskRefs, &out.DiskRefs *out = make([]*v1.ObjectReference, len(*in)) @@ -1477,7 +1602,7 @@ func (in *LocalVolumeReplicaSnapshotList) DeepCopyObject() runtime.Object { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *LocalVolumeReplicaSnapshotRecover) DeepCopyInto(out *LocalVolumeReplicaSnapshotRecover) { +func (in *LocalVolumeReplicaSnapshotRestore) DeepCopyInto(out *LocalVolumeReplicaSnapshotRestore) { *out = *in out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) @@ -1486,18 +1611,18 @@ func (in *LocalVolumeReplicaSnapshotRecover) DeepCopyInto(out *LocalVolumeReplic return } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LocalVolumeReplicaSnapshotRecover. -func (in *LocalVolumeReplicaSnapshotRecover) DeepCopy() *LocalVolumeReplicaSnapshotRecover { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LocalVolumeReplicaSnapshotRestore. +func (in *LocalVolumeReplicaSnapshotRestore) DeepCopy() *LocalVolumeReplicaSnapshotRestore { if in == nil { return nil } - out := new(LocalVolumeReplicaSnapshotRecover) + out := new(LocalVolumeReplicaSnapshotRestore) in.DeepCopyInto(out) return out } // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *LocalVolumeReplicaSnapshotRecover) DeepCopyObject() runtime.Object { +func (in *LocalVolumeReplicaSnapshotRestore) DeepCopyObject() runtime.Object { if c := in.DeepCopy(); c != nil { return c } @@ -1505,13 +1630,13 @@ func (in *LocalVolumeReplicaSnapshotRecover) DeepCopyObject() runtime.Object { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *LocalVolumeReplicaSnapshotRecoverList) DeepCopyInto(out *LocalVolumeReplicaSnapshotRecoverList) { +func (in *LocalVolumeReplicaSnapshotRestoreList) DeepCopyInto(out *LocalVolumeReplicaSnapshotRestoreList) { *out = *in out.TypeMeta = in.TypeMeta in.ListMeta.DeepCopyInto(&out.ListMeta) if in.Items != nil { in, out := &in.Items, &out.Items - *out = make([]LocalVolumeReplicaSnapshotRecover, len(*in)) + *out = make([]LocalVolumeReplicaSnapshotRestore, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } @@ -1519,18 +1644,18 @@ func (in *LocalVolumeReplicaSnapshotRecoverList) DeepCopyInto(out *LocalVolumeRe return } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LocalVolumeReplicaSnapshotRecoverList. -func (in *LocalVolumeReplicaSnapshotRecoverList) DeepCopy() *LocalVolumeReplicaSnapshotRecoverList { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LocalVolumeReplicaSnapshotRestoreList. +func (in *LocalVolumeReplicaSnapshotRestoreList) DeepCopy() *LocalVolumeReplicaSnapshotRestoreList { if in == nil { return nil } - out := new(LocalVolumeReplicaSnapshotRecoverList) + out := new(LocalVolumeReplicaSnapshotRestoreList) in.DeepCopyInto(out) return out } // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *LocalVolumeReplicaSnapshotRecoverList) DeepCopyObject() runtime.Object { +func (in *LocalVolumeReplicaSnapshotRestoreList) DeepCopyObject() runtime.Object { if c := in.DeepCopy(); c != nil { return c } @@ -1538,33 +1663,33 @@ func (in *LocalVolumeReplicaSnapshotRecoverList) DeepCopyObject() runtime.Object } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *LocalVolumeReplicaSnapshotRecoverSpec) DeepCopyInto(out *LocalVolumeReplicaSnapshotRecoverSpec) { +func (in *LocalVolumeReplicaSnapshotRestoreSpec) DeepCopyInto(out *LocalVolumeReplicaSnapshotRestoreSpec) { *out = *in return } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LocalVolumeReplicaSnapshotRecoverSpec. -func (in *LocalVolumeReplicaSnapshotRecoverSpec) DeepCopy() *LocalVolumeReplicaSnapshotRecoverSpec { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LocalVolumeReplicaSnapshotRestoreSpec. +func (in *LocalVolumeReplicaSnapshotRestoreSpec) DeepCopy() *LocalVolumeReplicaSnapshotRestoreSpec { if in == nil { return nil } - out := new(LocalVolumeReplicaSnapshotRecoverSpec) + out := new(LocalVolumeReplicaSnapshotRestoreSpec) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *LocalVolumeReplicaSnapshotRecoverStatus) DeepCopyInto(out *LocalVolumeReplicaSnapshotRecoverStatus) { +func (in *LocalVolumeReplicaSnapshotRestoreStatus) DeepCopyInto(out *LocalVolumeReplicaSnapshotRestoreStatus) { *out = *in return } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LocalVolumeReplicaSnapshotRecoverStatus. -func (in *LocalVolumeReplicaSnapshotRecoverStatus) DeepCopy() *LocalVolumeReplicaSnapshotRecoverStatus { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LocalVolumeReplicaSnapshotRestoreStatus. +func (in *LocalVolumeReplicaSnapshotRestoreStatus) DeepCopy() *LocalVolumeReplicaSnapshotRestoreStatus { if in == nil { return nil } - out := new(LocalVolumeReplicaSnapshotRecoverStatus) + out := new(LocalVolumeReplicaSnapshotRestoreStatus) in.DeepCopyInto(out) return out } @@ -1711,7 +1836,7 @@ func (in *LocalVolumeSnapshotList) DeepCopyObject() runtime.Object { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *LocalVolumeSnapshotRecover) DeepCopyInto(out *LocalVolumeSnapshotRecover) { +func (in *LocalVolumeSnapshotRestore) DeepCopyInto(out *LocalVolumeSnapshotRestore) { *out = *in out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) @@ -1720,18 +1845,18 @@ func (in *LocalVolumeSnapshotRecover) DeepCopyInto(out *LocalVolumeSnapshotRecov return } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LocalVolumeSnapshotRecover. -func (in *LocalVolumeSnapshotRecover) DeepCopy() *LocalVolumeSnapshotRecover { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LocalVolumeSnapshotRestore. +func (in *LocalVolumeSnapshotRestore) DeepCopy() *LocalVolumeSnapshotRestore { if in == nil { return nil } - out := new(LocalVolumeSnapshotRecover) + out := new(LocalVolumeSnapshotRestore) in.DeepCopyInto(out) return out } // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *LocalVolumeSnapshotRecover) DeepCopyObject() runtime.Object { +func (in *LocalVolumeSnapshotRestore) DeepCopyObject() runtime.Object { if c := in.DeepCopy(); c != nil { return c } @@ -1739,13 +1864,13 @@ func (in *LocalVolumeSnapshotRecover) DeepCopyObject() runtime.Object { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *LocalVolumeSnapshotRecoverList) DeepCopyInto(out *LocalVolumeSnapshotRecoverList) { +func (in *LocalVolumeSnapshotRestoreList) DeepCopyInto(out *LocalVolumeSnapshotRestoreList) { *out = *in out.TypeMeta = in.TypeMeta in.ListMeta.DeepCopyInto(&out.ListMeta) if in.Items != nil { in, out := &in.Items, &out.Items - *out = make([]LocalVolumeSnapshotRecover, len(*in)) + *out = make([]LocalVolumeSnapshotRestore, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } @@ -1753,18 +1878,18 @@ func (in *LocalVolumeSnapshotRecoverList) DeepCopyInto(out *LocalVolumeSnapshotR return } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LocalVolumeSnapshotRecoverList. -func (in *LocalVolumeSnapshotRecoverList) DeepCopy() *LocalVolumeSnapshotRecoverList { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LocalVolumeSnapshotRestoreList. +func (in *LocalVolumeSnapshotRestoreList) DeepCopy() *LocalVolumeSnapshotRestoreList { if in == nil { return nil } - out := new(LocalVolumeSnapshotRecoverList) + out := new(LocalVolumeSnapshotRestoreList) in.DeepCopyInto(out) return out } // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *LocalVolumeSnapshotRecoverList) DeepCopyObject() runtime.Object { +func (in *LocalVolumeSnapshotRestoreList) DeepCopyObject() runtime.Object { if c := in.DeepCopy(); c != nil { return c } @@ -1772,38 +1897,38 @@ func (in *LocalVolumeSnapshotRecoverList) DeepCopyObject() runtime.Object { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *LocalVolumeSnapshotRecoverSpec) DeepCopyInto(out *LocalVolumeSnapshotRecoverSpec) { +func (in *LocalVolumeSnapshotRestoreSpec) DeepCopyInto(out *LocalVolumeSnapshotRestoreSpec) { *out = *in return } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LocalVolumeSnapshotRecoverSpec. -func (in *LocalVolumeSnapshotRecoverSpec) DeepCopy() *LocalVolumeSnapshotRecoverSpec { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LocalVolumeSnapshotRestoreSpec. +func (in *LocalVolumeSnapshotRestoreSpec) DeepCopy() *LocalVolumeSnapshotRestoreSpec { if in == nil { return nil } - out := new(LocalVolumeSnapshotRecoverSpec) + out := new(LocalVolumeSnapshotRestoreSpec) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *LocalVolumeSnapshotRecoverStatus) DeepCopyInto(out *LocalVolumeSnapshotRecoverStatus) { +func (in *LocalVolumeSnapshotRestoreStatus) DeepCopyInto(out *LocalVolumeSnapshotRestoreStatus) { *out = *in - if in.VolumeReplicaSnapshotRecover != nil { - in, out := &in.VolumeReplicaSnapshotRecover, &out.VolumeReplicaSnapshotRecover + if in.VolumeReplicaSnapshotRestore != nil { + in, out := &in.VolumeReplicaSnapshotRestore, &out.VolumeReplicaSnapshotRestore *out = make([]string, len(*in)) copy(*out, *in) } return } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LocalVolumeSnapshotRecoverStatus. -func (in *LocalVolumeSnapshotRecoverStatus) DeepCopy() *LocalVolumeSnapshotRecoverStatus { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LocalVolumeSnapshotRestoreStatus. +func (in *LocalVolumeSnapshotRestoreStatus) DeepCopy() *LocalVolumeSnapshotRestoreStatus { if in == nil { return nil } - out := new(LocalVolumeSnapshotRecoverStatus) + out := new(LocalVolumeSnapshotRestoreStatus) in.DeepCopyInto(out) return out } diff --git a/vendor/golang.org/x/net/http2/hpack/encode.go b/vendor/golang.org/x/net/http2/hpack/encode.go index 6886dc16..46219da2 100644 --- a/vendor/golang.org/x/net/http2/hpack/encode.go +++ b/vendor/golang.org/x/net/http2/hpack/encode.go @@ -116,6 +116,11 @@ func (e *Encoder) SetMaxDynamicTableSize(v uint32) { e.dynTab.setMaxSize(v) } +// MaxDynamicTableSize returns the current dynamic header table size. +func (e *Encoder) MaxDynamicTableSize() (v uint32) { + return e.dynTab.maxSize +} + // SetMaxDynamicTableSizeLimit changes the maximum value that can be // specified in SetMaxDynamicTableSize to v. By default, it is set to // 4096, which is the same size of the default dynamic header table diff --git a/vendor/golang.org/x/net/http2/server.go b/vendor/golang.org/x/net/http2/server.go index d8a17aa9..4eb7617f 100644 --- a/vendor/golang.org/x/net/http2/server.go +++ b/vendor/golang.org/x/net/http2/server.go @@ -98,6 +98,19 @@ type Server struct { // the HTTP/2 spec's recommendations. MaxConcurrentStreams uint32 + // MaxDecoderHeaderTableSize optionally specifies the http2 + // SETTINGS_HEADER_TABLE_SIZE to send in the initial settings frame. It + // informs the remote endpoint of the maximum size of the header compression + // table used to decode header blocks, in octets. If zero, the default value + // of 4096 is used. + MaxDecoderHeaderTableSize uint32 + + // MaxEncoderHeaderTableSize optionally specifies an upper limit for the + // header compression table used for encoding request headers. Received + // SETTINGS_HEADER_TABLE_SIZE settings are capped at this limit. If zero, + // the default value of 4096 is used. + MaxEncoderHeaderTableSize uint32 + // MaxReadFrameSize optionally specifies the largest frame // this server is willing to read. A valid value is between // 16k and 16M, inclusive. If zero or otherwise invalid, a @@ -170,6 +183,20 @@ func (s *Server) maxConcurrentStreams() uint32 { return defaultMaxStreams } +func (s *Server) maxDecoderHeaderTableSize() uint32 { + if v := s.MaxDecoderHeaderTableSize; v > 0 { + return v + } + return initialHeaderTableSize +} + +func (s *Server) maxEncoderHeaderTableSize() uint32 { + if v := s.MaxEncoderHeaderTableSize; v > 0 { + return v + } + return initialHeaderTableSize +} + // maxQueuedControlFrames is the maximum number of control frames like // SETTINGS, PING and RST_STREAM that will be queued for writing before // the connection is closed to prevent memory exhaustion attacks. @@ -394,7 +421,6 @@ func (s *Server) ServeConn(c net.Conn, opts *ServeConnOpts) { advMaxStreams: s.maxConcurrentStreams(), initialStreamSendWindowSize: initialWindowSize, maxFrameSize: initialMaxFrameSize, - headerTableSize: initialHeaderTableSize, serveG: newGoroutineLock(), pushEnabled: true, sawClientPreface: opts.SawClientPreface, @@ -424,12 +450,13 @@ func (s *Server) ServeConn(c net.Conn, opts *ServeConnOpts) { sc.flow.add(initialWindowSize) sc.inflow.add(initialWindowSize) sc.hpackEncoder = hpack.NewEncoder(&sc.headerWriteBuf) + sc.hpackEncoder.SetMaxDynamicTableSizeLimit(s.maxEncoderHeaderTableSize()) fr := NewFramer(sc.bw, c) if s.CountError != nil { fr.countError = s.CountError } - fr.ReadMetaHeaders = hpack.NewDecoder(initialHeaderTableSize, nil) + fr.ReadMetaHeaders = hpack.NewDecoder(s.maxDecoderHeaderTableSize(), nil) fr.MaxHeaderListSize = sc.maxHeaderListSize() fr.SetMaxReadFrameSize(s.maxReadFrameSize()) sc.framer = fr @@ -559,9 +586,9 @@ type serverConn struct { streams map[uint32]*stream initialStreamSendWindowSize int32 maxFrameSize int32 - headerTableSize uint32 peerMaxHeaderListSize uint32 // zero means unknown (default) canonHeader map[string]string // http2-lower-case -> Go-Canonical-Case + canonHeaderKeysSize int // canonHeader keys size in bytes writingFrame bool // started writing a frame (on serve goroutine or separate) writingFrameAsync bool // started a frame on its own goroutine but haven't heard back on wroteFrameCh needsFrameFlush bool // last frame write wasn't a flush @@ -740,6 +767,13 @@ func (sc *serverConn) condlogf(err error, format string, args ...interface{}) { } } +// maxCachedCanonicalHeadersKeysSize is an arbitrarily-chosen limit on the size +// of the entries in the canonHeader cache. +// This should be larger than the size of unique, uncommon header keys likely to +// be sent by the peer, while not so high as to permit unreasonable memory usage +// if the peer sends an unbounded number of unique header keys. +const maxCachedCanonicalHeadersKeysSize = 2048 + func (sc *serverConn) canonicalHeader(v string) string { sc.serveG.check() buildCommonHeaderMapsOnce() @@ -755,14 +789,10 @@ func (sc *serverConn) canonicalHeader(v string) string { sc.canonHeader = make(map[string]string) } cv = http.CanonicalHeaderKey(v) - // maxCachedCanonicalHeaders is an arbitrarily-chosen limit on the number of - // entries in the canonHeader cache. This should be larger than the number - // of unique, uncommon header keys likely to be sent by the peer, while not - // so high as to permit unreasonable memory usage if the peer sends an unbounded - // number of unique header keys. - const maxCachedCanonicalHeaders = 32 - if len(sc.canonHeader) < maxCachedCanonicalHeaders { + size := 100 + len(v)*2 // 100 bytes of map overhead + key + value + if sc.canonHeaderKeysSize+size <= maxCachedCanonicalHeadersKeysSize { sc.canonHeader[v] = cv + sc.canonHeaderKeysSize += size } return cv } @@ -864,6 +894,7 @@ func (sc *serverConn) serve() { {SettingMaxFrameSize, sc.srv.maxReadFrameSize()}, {SettingMaxConcurrentStreams, sc.advMaxStreams}, {SettingMaxHeaderListSize, sc.maxHeaderListSize()}, + {SettingHeaderTableSize, sc.srv.maxDecoderHeaderTableSize()}, {SettingInitialWindowSize, uint32(sc.srv.initialStreamRecvWindowSize())}, }, }) @@ -1661,7 +1692,6 @@ func (sc *serverConn) processSetting(s Setting) error { } switch s.ID { case SettingHeaderTableSize: - sc.headerTableSize = s.Val sc.hpackEncoder.SetMaxDynamicTableSize(s.Val) case SettingEnablePush: sc.pushEnabled = s.Val != 0 diff --git a/vendor/golang.org/x/net/http2/transport.go b/vendor/golang.org/x/net/http2/transport.go index 46dda4dc..30f706e6 100644 --- a/vendor/golang.org/x/net/http2/transport.go +++ b/vendor/golang.org/x/net/http2/transport.go @@ -118,6 +118,28 @@ type Transport struct { // to mean no limit. MaxHeaderListSize uint32 + // MaxReadFrameSize is the http2 SETTINGS_MAX_FRAME_SIZE to send in the + // initial settings frame. It is the size in bytes of the largest frame + // payload that the sender is willing to receive. If 0, no setting is + // sent, and the value is provided by the peer, which should be 16384 + // according to the spec: + // https://datatracker.ietf.org/doc/html/rfc7540#section-6.5.2. + // Values are bounded in the range 16k to 16M. + MaxReadFrameSize uint32 + + // MaxDecoderHeaderTableSize optionally specifies the http2 + // SETTINGS_HEADER_TABLE_SIZE to send in the initial settings frame. It + // informs the remote endpoint of the maximum size of the header compression + // table used to decode header blocks, in octets. If zero, the default value + // of 4096 is used. + MaxDecoderHeaderTableSize uint32 + + // MaxEncoderHeaderTableSize optionally specifies an upper limit for the + // header compression table used for encoding request headers. Received + // SETTINGS_HEADER_TABLE_SIZE settings are capped at this limit. If zero, + // the default value of 4096 is used. + MaxEncoderHeaderTableSize uint32 + // StrictMaxConcurrentStreams controls whether the server's // SETTINGS_MAX_CONCURRENT_STREAMS should be respected // globally. If false, new TCP connections are created to the @@ -171,6 +193,19 @@ func (t *Transport) maxHeaderListSize() uint32 { return t.MaxHeaderListSize } +func (t *Transport) maxFrameReadSize() uint32 { + if t.MaxReadFrameSize == 0 { + return 0 // use the default provided by the peer + } + if t.MaxReadFrameSize < minMaxFrameSize { + return minMaxFrameSize + } + if t.MaxReadFrameSize > maxFrameSize { + return maxFrameSize + } + return t.MaxReadFrameSize +} + func (t *Transport) disableCompression() bool { return t.DisableCompression || (t.t1 != nil && t.t1.DisableCompression) } @@ -293,10 +328,11 @@ type ClientConn struct { lastActive time.Time lastIdle time.Time // time last idle // Settings from peer: (also guarded by wmu) - maxFrameSize uint32 - maxConcurrentStreams uint32 - peerMaxHeaderListSize uint64 - initialWindowSize uint32 + maxFrameSize uint32 + maxConcurrentStreams uint32 + peerMaxHeaderListSize uint64 + peerMaxHeaderTableSize uint32 + initialWindowSize uint32 // reqHeaderMu is a 1-element semaphore channel controlling access to sending new requests. // Write to reqHeaderMu to lock it, read from it to unlock. @@ -681,6 +717,20 @@ func (t *Transport) expectContinueTimeout() time.Duration { return t.t1.ExpectContinueTimeout } +func (t *Transport) maxDecoderHeaderTableSize() uint32 { + if v := t.MaxDecoderHeaderTableSize; v > 0 { + return v + } + return initialHeaderTableSize +} + +func (t *Transport) maxEncoderHeaderTableSize() uint32 { + if v := t.MaxEncoderHeaderTableSize; v > 0 { + return v + } + return initialHeaderTableSize +} + func (t *Transport) NewClientConn(c net.Conn) (*ClientConn, error) { return t.newClientConn(c, t.disableKeepAlives()) } @@ -721,15 +771,19 @@ func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, erro }) cc.br = bufio.NewReader(c) cc.fr = NewFramer(cc.bw, cc.br) + if t.maxFrameReadSize() != 0 { + cc.fr.SetMaxReadFrameSize(t.maxFrameReadSize()) + } if t.CountError != nil { cc.fr.countError = t.CountError } - cc.fr.ReadMetaHeaders = hpack.NewDecoder(initialHeaderTableSize, nil) + maxHeaderTableSize := t.maxDecoderHeaderTableSize() + cc.fr.ReadMetaHeaders = hpack.NewDecoder(maxHeaderTableSize, nil) cc.fr.MaxHeaderListSize = t.maxHeaderListSize() - // TODO: SetMaxDynamicTableSize, SetMaxDynamicTableSizeLimit on - // henc in response to SETTINGS frames? cc.henc = hpack.NewEncoder(&cc.hbuf) + cc.henc.SetMaxDynamicTableSizeLimit(t.maxEncoderHeaderTableSize()) + cc.peerMaxHeaderTableSize = initialHeaderTableSize if t.AllowHTTP { cc.nextStreamID = 3 @@ -744,9 +798,15 @@ func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, erro {ID: SettingEnablePush, Val: 0}, {ID: SettingInitialWindowSize, Val: transportDefaultStreamFlow}, } + if max := t.maxFrameReadSize(); max != 0 { + initialSettings = append(initialSettings, Setting{ID: SettingMaxFrameSize, Val: max}) + } if max := t.maxHeaderListSize(); max != 0 { initialSettings = append(initialSettings, Setting{ID: SettingMaxHeaderListSize, Val: max}) } + if maxHeaderTableSize != initialHeaderTableSize { + initialSettings = append(initialSettings, Setting{ID: SettingHeaderTableSize, Val: maxHeaderTableSize}) + } cc.bw.Write(clientPreface) cc.fr.WriteSettings(initialSettings...) @@ -2773,8 +2833,10 @@ func (rl *clientConnReadLoop) processSettingsNoWrite(f *SettingsFrame) error { cc.cond.Broadcast() cc.initialWindowSize = s.Val + case SettingHeaderTableSize: + cc.henc.SetMaxDynamicTableSize(s.Val) + cc.peerMaxHeaderTableSize = s.Val default: - // TODO(bradfitz): handle more settings? SETTINGS_HEADER_TABLE_SIZE probably. cc.vlogf("Unhandled Setting: %v", s) } return nil diff --git a/vendor/golang.org/x/sys/windows/syscall_windows.go b/vendor/golang.org/x/sys/windows/syscall_windows.go index 7a6ba43a..a49853e9 100644 --- a/vendor/golang.org/x/sys/windows/syscall_windows.go +++ b/vendor/golang.org/x/sys/windows/syscall_windows.go @@ -367,6 +367,7 @@ func NewCallbackCDecl(fn interface{}) uintptr { //sys IsWindowUnicode(hwnd HWND) (isUnicode bool) = user32.IsWindowUnicode //sys IsWindowVisible(hwnd HWND) (isVisible bool) = user32.IsWindowVisible //sys GetGUIThreadInfo(thread uint32, info *GUIThreadInfo) (err error) = user32.GetGUIThreadInfo +//sys GetLargePageMinimum() (size uintptr) // Volume Management Functions //sys DefineDosDevice(flags uint32, deviceName *uint16, targetPath *uint16) (err error) = DefineDosDeviceW diff --git a/vendor/golang.org/x/sys/windows/zsyscall_windows.go b/vendor/golang.org/x/sys/windows/zsyscall_windows.go index 96ba8559..ac60052e 100644 --- a/vendor/golang.org/x/sys/windows/zsyscall_windows.go +++ b/vendor/golang.org/x/sys/windows/zsyscall_windows.go @@ -252,6 +252,7 @@ var ( procGetFileType = modkernel32.NewProc("GetFileType") procGetFinalPathNameByHandleW = modkernel32.NewProc("GetFinalPathNameByHandleW") procGetFullPathNameW = modkernel32.NewProc("GetFullPathNameW") + procGetLargePageMinimum = modkernel32.NewProc("GetLargePageMinimum") procGetLastError = modkernel32.NewProc("GetLastError") procGetLogicalDriveStringsW = modkernel32.NewProc("GetLogicalDriveStringsW") procGetLogicalDrives = modkernel32.NewProc("GetLogicalDrives") @@ -2180,6 +2181,12 @@ func GetFullPathName(path *uint16, buflen uint32, buf *uint16, fname **uint16) ( return } +func GetLargePageMinimum() (size uintptr) { + r0, _, _ := syscall.Syscall(procGetLargePageMinimum.Addr(), 0, 0, 0, 0) + size = uintptr(r0) + return +} + func GetLastError() (lasterr error) { r0, _, _ := syscall.Syscall(procGetLastError.Addr(), 0, 0, 0, 0) if r0 != 0 { diff --git a/vendor/golang.org/x/text/unicode/bidi/trieval.go b/vendor/golang.org/x/text/unicode/bidi/trieval.go index 4c459c4b..6a796e22 100644 --- a/vendor/golang.org/x/text/unicode/bidi/trieval.go +++ b/vendor/golang.org/x/text/unicode/bidi/trieval.go @@ -37,18 +37,6 @@ const ( unknownClass = ^Class(0) ) -var controlToClass = map[rune]Class{ - 0x202D: LRO, // LeftToRightOverride, - 0x202E: RLO, // RightToLeftOverride, - 0x202A: LRE, // LeftToRightEmbedding, - 0x202B: RLE, // RightToLeftEmbedding, - 0x202C: PDF, // PopDirectionalFormat, - 0x2066: LRI, // LeftToRightIsolate, - 0x2067: RLI, // RightToLeftIsolate, - 0x2068: FSI, // FirstStrongIsolate, - 0x2069: PDI, // PopDirectionalIsolate, -} - // A trie entry has the following bits: // 7..5 XOR mask for brackets // 4 1: Bracket open, 0: Bracket close diff --git a/vendor/k8s.io/utils/pointer/pointer.go b/vendor/k8s.io/utils/pointer/pointer.go index f5802d2e..b8103223 100644 --- a/vendor/k8s.io/utils/pointer/pointer.go +++ b/vendor/k8s.io/utils/pointer/pointer.go @@ -52,6 +52,9 @@ func Int(i int) *int { return &i } +// IntPtr is a function variable referring to Int. +// +// Deprecated: Use Int instead. var IntPtr = Int // for back-compat // IntDeref dereferences the int ptr and returns it if not nil, or else @@ -63,6 +66,9 @@ func IntDeref(ptr *int, def int) int { return def } +// IntPtrDerefOr is a function variable referring to IntDeref. +// +// Deprecated: Use IntDeref instead. var IntPtrDerefOr = IntDeref // for back-compat // Int32 returns a pointer to an int32. @@ -70,6 +76,9 @@ func Int32(i int32) *int32 { return &i } +// Int32Ptr is a function variable referring to Int32. +// +// Deprecated: Use Int32 instead. var Int32Ptr = Int32 // for back-compat // Int32Deref dereferences the int32 ptr and returns it if not nil, or else @@ -81,6 +90,9 @@ func Int32Deref(ptr *int32, def int32) int32 { return def } +// Int32PtrDerefOr is a function variable referring to Int32Deref. +// +// Deprecated: Use Int32Deref instead. var Int32PtrDerefOr = Int32Deref // for back-compat // Int32Equal returns true if both arguments are nil or both arguments @@ -95,11 +107,74 @@ func Int32Equal(a, b *int32) bool { return *a == *b } +// Uint returns a pointer to an uint +func Uint(i uint) *uint { + return &i +} + +// UintPtr is a function variable referring to Uint. +// +// Deprecated: Use Uint instead. +var UintPtr = Uint // for back-compat + +// UintDeref dereferences the uint ptr and returns it if not nil, or else +// returns def. +func UintDeref(ptr *uint, def uint) uint { + if ptr != nil { + return *ptr + } + return def +} + +// UintPtrDerefOr is a function variable referring to UintDeref. +// +// Deprecated: Use UintDeref instead. +var UintPtrDerefOr = UintDeref // for back-compat + +// Uint32 returns a pointer to an uint32. +func Uint32(i uint32) *uint32 { + return &i +} + +// Uint32Ptr is a function variable referring to Uint32. +// +// Deprecated: Use Uint32 instead. +var Uint32Ptr = Uint32 // for back-compat + +// Uint32Deref dereferences the uint32 ptr and returns it if not nil, or else +// returns def. +func Uint32Deref(ptr *uint32, def uint32) uint32 { + if ptr != nil { + return *ptr + } + return def +} + +// Uint32PtrDerefOr is a function variable referring to Uint32Deref. +// +// Deprecated: Use Uint32Deref instead. +var Uint32PtrDerefOr = Uint32Deref // for back-compat + +// Uint32Equal returns true if both arguments are nil or both arguments +// dereference to the same value. +func Uint32Equal(a, b *uint32) bool { + if (a == nil) != (b == nil) { + return false + } + if a == nil { + return true + } + return *a == *b +} + // Int64 returns a pointer to an int64. func Int64(i int64) *int64 { return &i } +// Int64Ptr is a function variable referring to Int64. +// +// Deprecated: Use Int64 instead. var Int64Ptr = Int64 // for back-compat // Int64Deref dereferences the int64 ptr and returns it if not nil, or else @@ -111,6 +186,9 @@ func Int64Deref(ptr *int64, def int64) int64 { return def } +// Int64PtrDerefOr is a function variable referring to Int64Deref. +// +// Deprecated: Use Int64Deref instead. var Int64PtrDerefOr = Int64Deref // for back-compat // Int64Equal returns true if both arguments are nil or both arguments @@ -125,11 +203,50 @@ func Int64Equal(a, b *int64) bool { return *a == *b } +// Uint64 returns a pointer to an uint64. +func Uint64(i uint64) *uint64 { + return &i +} + +// Uint64Ptr is a function variable referring to Uint64. +// +// Deprecated: Use Uint64 instead. +var Uint64Ptr = Uint64 // for back-compat + +// Uint64Deref dereferences the uint64 ptr and returns it if not nil, or else +// returns def. +func Uint64Deref(ptr *uint64, def uint64) uint64 { + if ptr != nil { + return *ptr + } + return def +} + +// Uint64PtrDerefOr is a function variable referring to Uint64Deref. +// +// Deprecated: Use Uint64Deref instead. +var Uint64PtrDerefOr = Uint64Deref // for back-compat + +// Uint64Equal returns true if both arguments are nil or both arguments +// dereference to the same value. +func Uint64Equal(a, b *uint64) bool { + if (a == nil) != (b == nil) { + return false + } + if a == nil { + return true + } + return *a == *b +} + // Bool returns a pointer to a bool. func Bool(b bool) *bool { return &b } +// BoolPtr is a function variable referring to Bool. +// +// Deprecated: Use Bool instead. var BoolPtr = Bool // for back-compat // BoolDeref dereferences the bool ptr and returns it if not nil, or else @@ -141,6 +258,9 @@ func BoolDeref(ptr *bool, def bool) bool { return def } +// BoolPtrDerefOr is a function variable referring to BoolDeref. +// +// Deprecated: Use BoolDeref instead. var BoolPtrDerefOr = BoolDeref // for back-compat // BoolEqual returns true if both arguments are nil or both arguments @@ -160,6 +280,9 @@ func String(s string) *string { return &s } +// StringPtr is a function variable referring to String. +// +// Deprecated: Use String instead. var StringPtr = String // for back-compat // StringDeref dereferences the string ptr and returns it if not nil, or else @@ -171,6 +294,9 @@ func StringDeref(ptr *string, def string) string { return def } +// StringPtrDerefOr is a function variable referring to StringDeref. +// +// Deprecated: Use StringDeref instead. var StringPtrDerefOr = StringDeref // for back-compat // StringEqual returns true if both arguments are nil or both arguments @@ -190,6 +316,9 @@ func Float32(i float32) *float32 { return &i } +// Float32Ptr is a function variable referring to Float32. +// +// Deprecated: Use Float32 instead. var Float32Ptr = Float32 // Float32Deref dereferences the float32 ptr and returns it if not nil, or else @@ -201,6 +330,9 @@ func Float32Deref(ptr *float32, def float32) float32 { return def } +// Float32PtrDerefOr is a function variable referring to Float32Deref. +// +// Deprecated: Use Float32Deref instead. var Float32PtrDerefOr = Float32Deref // for back-compat // Float32Equal returns true if both arguments are nil or both arguments @@ -220,6 +352,9 @@ func Float64(i float64) *float64 { return &i } +// Float64Ptr is a function variable referring to Float64. +// +// Deprecated: Use Float64 instead. var Float64Ptr = Float64 // Float64Deref dereferences the float64 ptr and returns it if not nil, or else @@ -231,6 +366,9 @@ func Float64Deref(ptr *float64, def float64) float64 { return def } +// Float64PtrDerefOr is a function variable referring to Float64Deref. +// +// Deprecated: Use Float64Deref instead. var Float64PtrDerefOr = Float64Deref // for back-compat // Float64Equal returns true if both arguments are nil or both arguments diff --git a/vendor/k8s.io/utils/trace/trace.go b/vendor/k8s.io/utils/trace/trace.go index 3023d106..a0b07a6d 100644 --- a/vendor/k8s.io/utils/trace/trace.go +++ b/vendor/k8s.io/utils/trace/trace.go @@ -21,6 +21,7 @@ import ( "context" "fmt" "math/rand" + "sync" "time" "k8s.io/klog/v2" @@ -93,13 +94,16 @@ func (s traceStep) writeItem(b *bytes.Buffer, formatter string, startTime time.T // Trace keeps track of a set of "steps" and allows us to log a specific // step if it took longer than its share of the total allowed time type Trace struct { + // constant fields name string fields []Field - threshold *time.Duration startTime time.Time - endTime *time.Time - traceItems []traceItem parentTrace *Trace + // fields guarded by a lock + lock sync.RWMutex + threshold *time.Duration + endTime *time.Time + traceItems []traceItem } func (t *Trace) time() time.Time { @@ -138,6 +142,8 @@ func New(name string, fields ...Field) *Trace { // how long it took. The Fields add key value pairs to provide additional details about the trace // step. func (t *Trace) Step(msg string, fields ...Field) { + t.lock.Lock() + defer t.lock.Unlock() if t.traceItems == nil { // traces almost always have less than 6 steps, do this to avoid more than a single allocation t.traceItems = make([]traceItem, 0, 6) @@ -153,7 +159,9 @@ func (t *Trace) Nest(msg string, fields ...Field) *Trace { newTrace := New(msg, fields...) if t != nil { newTrace.parentTrace = t + t.lock.Lock() t.traceItems = append(t.traceItems, newTrace) + t.lock.Unlock() } return newTrace } @@ -163,7 +171,9 @@ func (t *Trace) Nest(msg string, fields ...Field) *Trace { // is logged. func (t *Trace) Log() { endTime := time.Now() + t.lock.Lock() t.endTime = &endTime + t.lock.Unlock() // an explicit logging request should dump all the steps out at the higher level if t.parentTrace == nil { // We don't start logging until Log or LogIfLong is called on the root trace t.logTrace() @@ -178,13 +188,17 @@ func (t *Trace) Log() { // If the Trace is nested it is not immediately logged. Instead, it is logged when the trace it // is nested within is logged. func (t *Trace) LogIfLong(threshold time.Duration) { + t.lock.Lock() t.threshold = &threshold + t.lock.Unlock() t.Log() } // logTopLevelTraces finds all traces in a hierarchy of nested traces that should be logged but do not have any // parents that will be logged, due to threshold limits, and logs them as top level traces. func (t *Trace) logTrace() { + t.lock.RLock() + defer t.lock.RUnlock() if t.durationIsWithinThreshold() { var buffer bytes.Buffer traceNum := rand.Int31() @@ -244,9 +258,13 @@ func (t *Trace) calculateStepThreshold() *time.Duration { traceThreshold := *t.threshold for _, s := range t.traceItems { nestedTrace, ok := s.(*Trace) - if ok && nestedTrace.threshold != nil { - traceThreshold = traceThreshold - *nestedTrace.threshold - lenTrace-- + if ok { + nestedTrace.lock.RLock() + if nestedTrace.threshold != nil { + traceThreshold = traceThreshold - *nestedTrace.threshold + lenTrace-- + } + nestedTrace.lock.RUnlock() } } diff --git a/vendor/modules.txt b/vendor/modules.txt index 8c9da79a..79d36cb2 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -38,7 +38,7 @@ github.com/evanphx/json-patch # github.com/fsnotify/fsnotify v1.5.1 ## explicit; go 1.13 github.com/fsnotify/fsnotify -# github.com/go-logr/logr v1.2.0 => github.com/go-logr/logr v0.4.0 +# github.com/go-logr/logr v1.2.3 => github.com/go-logr/logr v0.4.0 ## explicit; go 1.14 github.com/go-logr/logr # github.com/go-logr/zapr v0.4.0 @@ -63,7 +63,7 @@ github.com/golang/protobuf/ptypes/any github.com/golang/protobuf/ptypes/duration github.com/golang/protobuf/ptypes/timestamp github.com/golang/protobuf/ptypes/wrappers -# github.com/google/go-cmp v0.5.8 +# github.com/google/go-cmp v0.5.9 ## explicit; go 1.13 github.com/google/go-cmp/cmp github.com/google/go-cmp/cmp/internal/diff @@ -85,7 +85,7 @@ github.com/googleapis/gnostic/openapiv2 ## explicit; go 1.12 github.com/hashicorp/golang-lru github.com/hashicorp/golang-lru/simplelru -# github.com/hwameistor/hwameistor v0.12.2 +# github.com/hwameistor/hwameistor v0.12.3 ## explicit; go 1.18 github.com/hwameistor/hwameistor/deploy/crds github.com/hwameistor/hwameistor/pkg/apis/client/clientset/versioned @@ -212,7 +212,7 @@ go.uber.org/zap/zapcore ## explicit; go 1.17 golang.org/x/crypto/pkcs12 golang.org/x/crypto/pkcs12/internal/rc2 -# golang.org/x/net v0.2.0 +# golang.org/x/net v0.3.1-0.20221206200815-1e63c2f08a10 ## explicit; go 1.17 golang.org/x/net/context golang.org/x/net/context/ctxhttp @@ -234,16 +234,16 @@ golang.org/x/oauth2/google/internal/externalaccount golang.org/x/oauth2/internal golang.org/x/oauth2/jws golang.org/x/oauth2/jwt -# golang.org/x/sys v0.2.0 +# golang.org/x/sys v0.3.0 ## explicit; go 1.17 golang.org/x/sys/internal/unsafeheader golang.org/x/sys/plan9 golang.org/x/sys/unix golang.org/x/sys/windows -# golang.org/x/term v0.2.0 +# golang.org/x/term v0.3.0 ## explicit; go 1.17 golang.org/x/term -# golang.org/x/text v0.4.0 +# golang.org/x/text v0.5.0 ## explicit; go 1.17 golang.org/x/text/encoding golang.org/x/text/encoding/charmap @@ -366,7 +366,7 @@ gopkg.in/tomb.v1 # gopkg.in/yaml.v2 v2.4.0 => gopkg.in/yaml.v2 v2.4.0 ## explicit; go 1.15 gopkg.in/yaml.v2 -# k8s.io/api v0.24.2 => k8s.io/api v0.21.0 +# k8s.io/api v0.26.0 => k8s.io/api v0.21.0 ## explicit; go 1.16 k8s.io/api/admission/v1 k8s.io/api/admission/v1beta1 @@ -422,7 +422,7 @@ k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/scheme k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1 k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1beta1 -# k8s.io/apimachinery v0.24.2 => k8s.io/apimachinery v0.21.1-rc.0 +# k8s.io/apimachinery v0.26.0 => k8s.io/apimachinery v0.21.1-rc.0 ## explicit; go 1.16 k8s.io/apimachinery/pkg/api/equality k8s.io/apimachinery/pkg/api/errors @@ -609,14 +609,14 @@ k8s.io/client-go/util/workqueue ## explicit; go 1.16 k8s.io/component-base/config k8s.io/component-base/config/v1alpha1 -# k8s.io/klog/v2 v2.60.1 => k8s.io/klog/v2 v2.8.0 +# k8s.io/klog/v2 v2.80.1 => k8s.io/klog/v2 v2.8.0 ## explicit; go 1.13 k8s.io/klog/v2 -# k8s.io/kube-openapi v0.0.0-20220328201542-3ee0da9b0b42 => k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7 +# k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 => k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7 ## explicit; go 1.12 k8s.io/kube-openapi/pkg/util/proto -# k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 -## explicit; go 1.12 +# k8s.io/utils v0.0.0-20221107191617-1a15be271d1d +## explicit; go 1.18 k8s.io/utils/buffer k8s.io/utils/integer k8s.io/utils/pointer @@ -669,7 +669,7 @@ sigs.k8s.io/controller-runtime/pkg/webhook sigs.k8s.io/controller-runtime/pkg/webhook/admission sigs.k8s.io/controller-runtime/pkg/webhook/conversion sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics -# sigs.k8s.io/structured-merge-diff/v4 v4.2.1 +# sigs.k8s.io/structured-merge-diff/v4 v4.2.3 ## explicit; go 1.13 sigs.k8s.io/structured-merge-diff/v4/fieldpath sigs.k8s.io/structured-merge-diff/v4/schema diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/schema/elements.go b/vendor/sigs.k8s.io/structured-merge-diff/v4/schema/elements.go index 01103b38..7e5dc758 100644 --- a/vendor/sigs.k8s.io/structured-merge-diff/v4/schema/elements.go +++ b/vendor/sigs.k8s.io/structured-merge-diff/v4/schema/elements.go @@ -16,7 +16,9 @@ limitations under the License. package schema -import "sync" +import ( + "sync" +) // Schema is a list of named types. // @@ -27,6 +29,11 @@ type Schema struct { once sync.Once m map[string]TypeDef + + lock sync.Mutex + // Cached results of resolving type references to atoms. Only stores + // type references which require fields of Atom to be overriden. + resolvedTypes map[TypeRef]Atom } // A TypeSpecifier references a particular type in a schema. @@ -48,6 +55,12 @@ type TypeRef struct { // Either the name or one member of Atom should be set. NamedType *string `yaml:"namedType,omitempty"` Inlined Atom `yaml:",inline,omitempty"` + + // If this reference refers to a map-type or list-type, this field overrides + // the `ElementRelationship` of the referred type when resolved. + // If this field is nil, then it has no effect. + // See `Map` and `List` for more information about `ElementRelationship` + ElementRelationship *ElementRelationship `yaml:"elementRelationship,omitempty"` } // Atom represents the smallest possible pieces of the type system. @@ -88,11 +101,11 @@ const ( // Map is a key-value pair. Its default semantics are the same as an // associative list, but: -// * It is serialized differently: +// - It is serialized differently: // map: {"k": {"value": "v"}} // list: [{"key": "k", "value": "v"}] -// * Keys must be string typed. -// * Keys can't have multiple components. +// - Keys must be string typed. +// - Keys can't have multiple components. // // Optionally, maps may be atomic (for example, imagine representing an RGB // color value--it doesn't make sense to have different actors own the R and G @@ -146,6 +159,31 @@ func (m *Map) FindField(name string) (StructField, bool) { return sf, ok } +// CopyInto this instance of Map into the other +// If other is nil this method does nothing. +// If other is already initialized, overwrites it with this instance +// Warning: Not thread safe +func (m *Map) CopyInto(dst *Map) { + if dst == nil { + return + } + + // Map type is considered immutable so sharing references + dst.Fields = m.Fields + dst.ElementType = m.ElementType + dst.Unions = m.Unions + dst.ElementRelationship = m.ElementRelationship + + if m.m != nil { + // If cache is non-nil then the once token had been consumed. + // Must reset token and use it again to ensure same semantics. + dst.once = sync.Once{} + dst.once.Do(func() { + dst.m = m.m + }) + } +} + // UnionFields are mapping between the fields that are part of the union and // their discriminated value. The discriminated value has to be set, and // should not conflict with other discriminated value in the list. @@ -244,18 +282,93 @@ func (s *Schema) FindNamedType(name string) (TypeDef, bool) { return t, ok } +func (s *Schema) resolveNoOverrides(tr TypeRef) (Atom, bool) { + result := Atom{} + + if tr.NamedType != nil { + t, ok := s.FindNamedType(*tr.NamedType) + if !ok { + return Atom{}, false + } + + result = t.Atom + } else { + result = tr.Inlined + } + + return result, true +} + // Resolve is a convenience function which returns the atom referenced, whether // it is inline or named. Returns (Atom{}, false) if the type can't be resolved. // // This allows callers to not care about the difference between a (possibly // inlined) reference and a definition. func (s *Schema) Resolve(tr TypeRef) (Atom, bool) { - if tr.NamedType != nil { - t, ok := s.FindNamedType(*tr.NamedType) - if !ok { + // If this is a plain reference with no overrides, just return the type + if tr.ElementRelationship == nil { + return s.resolveNoOverrides(tr) + } + + s.lock.Lock() + defer s.lock.Unlock() + + if s.resolvedTypes == nil { + s.resolvedTypes = make(map[TypeRef]Atom) + } + + var result Atom + var exists bool + + // Return cached result if available + // If not, calculate result and cache it + if result, exists = s.resolvedTypes[tr]; !exists { + if result, exists = s.resolveNoOverrides(tr); exists { + // Allow field-level electives to override the referred type's modifiers + switch { + case result.Map != nil: + mapCopy := Map{} + result.Map.CopyInto(&mapCopy) + mapCopy.ElementRelationship = *tr.ElementRelationship + result.Map = &mapCopy + case result.List != nil: + listCopy := *result.List + listCopy.ElementRelationship = *tr.ElementRelationship + result.List = &listCopy + case result.Scalar != nil: + return Atom{}, false + default: + return Atom{}, false + } + } else { return Atom{}, false } - return t.Atom, true + + // Save result. If it is nil, that is also recorded as not existing. + s.resolvedTypes[tr] = result + } + + return result, true +} + +// Clones this instance of Schema into the other +// If other is nil this method does nothing. +// If other is already initialized, overwrites it with this instance +// Warning: Not thread safe +func (s *Schema) CopyInto(dst *Schema) { + if dst == nil { + return + } + + // Schema type is considered immutable so sharing references + dst.Types = s.Types + + if s.m != nil { + // If cache is non-nil then the once token had been consumed. + // Must reset token and use it again to ensure same semantics. + dst.once = sync.Once{} + dst.once.Do(func() { + dst.m = s.m + }) } - return tr.Inlined, true } diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/schema/equals.go b/vendor/sigs.k8s.io/structured-merge-diff/v4/schema/equals.go index 4c303eec..b668eff8 100644 --- a/vendor/sigs.k8s.io/structured-merge-diff/v4/schema/equals.go +++ b/vendor/sigs.k8s.io/structured-merge-diff/v4/schema/equals.go @@ -52,6 +52,9 @@ func (a *TypeRef) Equals(b *TypeRef) bool { } //return true } + if a.ElementRelationship != b.ElementRelationship { + return false + } return a.Inlined.Equals(&b.Inlined) } diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/schema/schemaschema.go b/vendor/sigs.k8s.io/structured-merge-diff/v4/schema/schemaschema.go index bb60e2a5..7d64d130 100644 --- a/vendor/sigs.k8s.io/structured-merge-diff/v4/schema/schemaschema.go +++ b/vendor/sigs.k8s.io/structured-merge-diff/v4/schema/schemaschema.go @@ -66,6 +66,9 @@ var SchemaSchemaYAML = `types: - name: untyped type: namedType: untyped + - name: elementRelationship + type: + scalar: string - name: scalar scalar: string - name: map diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/typed/helpers.go b/vendor/sigs.k8s.io/structured-merge-diff/v4/typed/helpers.go index 6b2b2cb4..19c77334 100644 --- a/vendor/sigs.k8s.io/structured-merge-diff/v4/typed/helpers.go +++ b/vendor/sigs.k8s.io/structured-merge-diff/v4/typed/helpers.go @@ -105,7 +105,11 @@ type atomHandler interface { func resolveSchema(s *schema.Schema, tr schema.TypeRef, v value.Value, ah atomHandler) ValidationErrors { a, ok := s.Resolve(tr) if !ok { - return errorf("schema error: no type found matching: %v", *tr.NamedType) + typeName := "inlined type" + if tr.NamedType != nil { + typeName = *tr.NamedType + } + return errorf("schema error: no type found matching: %v", typeName) } a = deduceAtom(a, v) diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/typed/merge.go b/vendor/sigs.k8s.io/structured-merge-diff/v4/typed/merge.go index 75244ef6..91364408 100644 --- a/vendor/sigs.k8s.io/structured-merge-diff/v4/typed/merge.go +++ b/vendor/sigs.k8s.io/structured-merge-diff/v4/typed/merge.go @@ -80,7 +80,12 @@ func (w *mergingWalker) merge(prefixFn func() string) (errs ValidationErrors) { alhs := deduceAtom(a, w.lhs) arhs := deduceAtom(a, w.rhs) - if alhs.Equals(&arhs) { + + // deduceAtom does not fix the type for nil values + // nil is a wildcard and will accept whatever form the other operand takes + if w.rhs == nil { + errs = append(errs, handleAtom(alhs, w.typeRef, w)...) + } else if w.lhs == nil || alhs.Equals(&arhs) { errs = append(errs, handleAtom(arhs, w.typeRef, w)...) } else { w2 := *w diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/typed/reconcile_schema.go b/vendor/sigs.k8s.io/structured-merge-diff/v4/typed/reconcile_schema.go index 2b98b729..6a7697e3 100644 --- a/vendor/sigs.k8s.io/structured-merge-diff/v4/typed/reconcile_schema.go +++ b/vendor/sigs.k8s.io/structured-merge-diff/v4/typed/reconcile_schema.go @@ -110,7 +110,7 @@ func (v *reconcileWithSchemaWalker) finishDescent(v2 *reconcileWithSchemaWalker) } // ReconcileFieldSetWithSchema reconciles the a field set with any changes to the -//// object's schema since the field set was written. Returns the reconciled field set, or nil of +// object's schema since the field set was written. Returns the reconciled field set, or nil of // no changes were made to the field set. // // Supports: diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/typed/typed.go b/vendor/sigs.k8s.io/structured-merge-diff/v4/typed/typed.go index e9e6be8b..d63a97fe 100644 --- a/vendor/sigs.k8s.io/structured-merge-diff/v4/typed/typed.go +++ b/vendor/sigs.k8s.io/structured-merge-diff/v4/typed/typed.go @@ -99,12 +99,13 @@ func (tv TypedValue) ToFieldSet() (*fieldpath.Set, error) { // Merge returns the result of merging tv and pso ("partially specified // object") together. Of note: -// * No fields can be removed by this operation. -// * If both tv and pso specify a given leaf field, the result will keep pso's -// value. -// * Container typed elements will have their items ordered: -// * like tv, if pso doesn't change anything in the container -// * like pso, if pso does change something in the container. +// - No fields can be removed by this operation. +// - If both tv and pso specify a given leaf field, the result will keep pso's +// value. +// - Container typed elements will have their items ordered: +// 1. like tv, if pso doesn't change anything in the container +// 2. like pso, if pso does change something in the container. +// // tv and pso must both be of the same type (their Schema and TypeRef must // match), or an error will be returned. Validation errors will be returned if // the objects don't conform to the schema.