Skip to content

Subscription affinity api #353

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ require (
github.com/mikefarah/yq/v3 v3.0.0-20201202084205-8846255d1c37
github.com/onsi/ginkgo/v2 v2.1.3
github.com/openshift/api v0.0.0-20200331152225-585af27e34fd
github.com/operator-framework/api v0.15.0
github.com/operator-framework/api v0.16.0
github.com/operator-framework/operator-lifecycle-manager v0.0.0-00010101000000-000000000000
github.com/operator-framework/operator-registry v1.17.5
github.com/sirupsen/logrus v1.8.1
Expand Down
461 changes: 461 additions & 0 deletions manifests/0000_50_olm_00-subscriptions.crd.yaml

Large diffs are not rendered by default.

461 changes: 461 additions & 0 deletions staging/api/crds/operators.coreos.com_subscriptions.yaml

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion staging/api/crds/zz_defs.go

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions staging/api/pkg/operators/v1alpha1/subscription_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,12 @@ type SubscriptionConfig struct {
// List of VolumeMounts to set in the container.
// +optional
VolumeMounts []corev1.VolumeMount `json:"volumeMounts,omitempty"`

// If specified, overrides the pod's scheduling constraints.
// nil sub-attributes will *not* override the original values in the pod.spec for those sub-attributes.
// Use empty object ({}) to erase original sub-attribute values.
// +optional
Affinity *corev1.Affinity `json:"affinity,omitempty" protobuf:"bytes,18,opt,name=affinity"`
}

// SubscriptionConditionType indicates an explicit state condition about a Subscription in "abnormal-true"
Expand Down
5 changes: 5 additions & 0 deletions staging/api/pkg/operators/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion staging/operator-lifecycle-manager/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ require (
github.com/onsi/gomega v1.18.1
github.com/openshift/api v0.0.0-20200331152225-585af27e34fd
github.com/openshift/client-go v0.0.0-20200326155132-2a6cd50aedd0
github.com/operator-framework/api v0.15.0
github.com/operator-framework/api v0.16.0
github.com/operator-framework/operator-registry v1.17.5
github.com/otiai10/copy v1.2.0
github.com/pkg/errors v0.9.1
Expand Down
4 changes: 2 additions & 2 deletions staging/operator-lifecycle-manager/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1078,8 +1078,8 @@ github.com/openshift/client-go v0.0.0-20200326155132-2a6cd50aedd0/go.mod h1:uUQ4
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
github.com/operator-framework/api v0.7.1/go.mod h1:L7IvLd/ckxJEJg/t4oTTlnHKAJIP/p51AvEslW3wYdY=
github.com/operator-framework/api v0.15.0 h1:4f9i0drtqHj7ykLoHxv92GR43S7MmQHhmFQkfm5YaGI=
github.com/operator-framework/api v0.15.0/go.mod h1:scnY9xqSeCsOdtJtNoHIXd7OtHZ14gj1hkDA4+DlgLY=
github.com/operator-framework/api v0.16.0 h1:swUOhVv7QDszxBTwYM8QAtyeqI4EQHNVAiKMS+xjakY=
github.com/operator-framework/api v0.16.0/go.mod h1:kk8xJahHJR3bKqrA+A+1VIrhOTmyV76k+ARv+iV+u1Q=
github.com/operator-framework/operator-registry v1.17.5 h1:LR8m1rFz5Gcyje8WK6iYt+gIhtzqo52zMRALdmTYHT0=
github.com/operator-framework/operator-registry v1.17.5/go.mod h1:sRQIgDMZZdUcmHltzyCnM6RUoDF+WS8Arj1BQIARDS8=
github.com/otiai10/copy v1.2.0 h1:HvG945u96iNadPoG2/Ja2+AUJeW5YuFQMixq9yirC+k=
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ type operatorConfig struct {
logger *logrus.Logger
}

func (o *operatorConfig) GetConfigOverrides(ownerCSV ownerutil.Owner) (envVarOverrides []corev1.EnvVar, volumeOverrides []corev1.Volume, volumeMountOverrides []corev1.VolumeMount, tolerationOverrides []corev1.Toleration, resourcesOverride *corev1.ResourceRequirements, nodeSelectorOverride map[string]string, err error) {
func (o *operatorConfig) GetConfigOverrides(ownerCSV ownerutil.Owner) (envVarOverrides []corev1.EnvVar, volumeOverrides []corev1.Volume, volumeMountOverrides []corev1.VolumeMount, tolerationOverrides []corev1.Toleration, resourcesOverride *corev1.ResourceRequirements, nodeSelectorOverride map[string]string, affinity *corev1.Affinity, err error) {
list, listErr := o.lister.OperatorsV1alpha1().SubscriptionLister().Subscriptions(ownerCSV.GetNamespace()).List(labels.Everything())
if listErr != nil {
err = fmt.Errorf("failed to list subscription namespace=%s - %v", ownerCSV.GetNamespace(), listErr)
Expand All @@ -40,6 +40,7 @@ func (o *operatorConfig) GetConfigOverrides(ownerCSV ownerutil.Owner) (envVarOve
tolerationOverrides = owner.Spec.Config.Tolerations
resourcesOverride = owner.Spec.Config.Resources
nodeSelectorOverride = owner.Spec.Config.NodeSelector
affinity = owner.Spec.Config.Affinity

return
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ func (d *DeploymentInitializer) initialize(ownerCSV ownerutil.Owner, deployment
var envVarOverrides, proxyEnvVar, merged []corev1.EnvVar
var err error

envVarOverrides, volumeOverrides, volumeMountOverrides, tolerationOverrides, resourcesOverride, nodeSelectorOverride, err := d.config.GetConfigOverrides(ownerCSV)
envVarOverrides, volumeOverrides, volumeMountOverrides, tolerationOverrides, resourcesOverride, nodeSelectorOverride, affinity, err := d.config.GetConfigOverrides(ownerCSV)
if err != nil {
err = fmt.Errorf("failed to get subscription pod configuration - %v", err)
return err
Expand Down Expand Up @@ -92,6 +92,10 @@ func (d *DeploymentInitializer) initialize(ownerCSV ownerutil.Owner, deployment
return fmt.Errorf("failed to inject nodeSelector into deployment spec name=%s - %v", deployment.Name, err)
}

if err = inject.OverrideDeploymentAffinity(podSpec, affinity); err != nil {
return fmt.Errorf("failed to inject affinity into deployment spec name=%s - %s", deployment.Name, err)
}

return nil
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -230,3 +230,71 @@ func InjectNodeSelectorIntoDeployment(podSpec *corev1.PodSpec, nodeSelector map[

return nil
}

// OverrideDeploymentAffinity will override the corev1.Affinity defined in the Deployment
// with the given corev1.Affinity. Any nil top-level sub-attributes (e.g. NodeAffinity, PodAffinity, and PodAntiAffinity)
// will be ignored. Hint: to overwrite those top-level attributes, empty them out. I.e. use the empty/default object ({})
// e.g. NodeAffinity{}. In yaml:
// affinity:
// nodeAffinity: {}
// podAffinity: {}
// podAntiAffinity: {}
// will completely remove the deployment podSpec.affinity and is equivalent to
// affinity: {}
func OverrideDeploymentAffinity(podSpec *corev1.PodSpec, affinity *corev1.Affinity) error {
if podSpec == nil {
return errors.New("no pod spec provided")
}

if affinity == nil {
return nil
}

// if podSpec.Affinity is nil or empty/default then completely override podSpec.Affinity with overrides
if podSpec.Affinity == nil || reflect.DeepEqual(podSpec.Affinity, &corev1.Affinity{}) {
if reflect.DeepEqual(affinity, &corev1.Affinity{}) {
podSpec.Affinity = nil
} else {
podSpec.Affinity = affinity
}
return nil
}

// if overriding affinity is empty/default then nil out podSpec.Affinity
if reflect.DeepEqual(affinity, &corev1.Affinity{}) {
podSpec.Affinity = nil
return nil
}

// override podSpec.Affinity each attribute as necessary nilling out any default/empty overrides on the podSpec
if affinity.NodeAffinity != nil {
if reflect.DeepEqual(affinity.NodeAffinity, &corev1.NodeAffinity{}) {
podSpec.Affinity.NodeAffinity = nil
} else {
podSpec.Affinity.NodeAffinity = affinity.NodeAffinity
}
}

if affinity.PodAffinity != nil {
if reflect.DeepEqual(affinity.PodAffinity, &corev1.PodAffinity{}) {
podSpec.Affinity.PodAffinity = nil
} else {
podSpec.Affinity.PodAffinity = affinity.PodAffinity
}
}

if affinity.PodAntiAffinity != nil {
if reflect.DeepEqual(affinity.PodAntiAffinity, &corev1.PodAntiAffinity{}) {
podSpec.Affinity = nil
} else {
podSpec.Affinity.PodAntiAffinity = affinity.PodAntiAffinity
}
}

// special case: if after being overridden, podSpec is the same as default/empty then nil it out
if reflect.DeepEqual(&corev1.Affinity{}, podSpec.Affinity) {
podSpec.Affinity = nil
}

return nil
}
Loading