diff --git a/api/v1alpha1/perconaservermysql_types.go b/api/v1alpha1/perconaservermysql_types.go index f2067eaec..8aa3fa770 100644 --- a/api/v1alpha1/perconaservermysql_types.go +++ b/api/v1alpha1/perconaservermysql_types.go @@ -63,7 +63,7 @@ type PerconaServerMySQLSpec struct { SecretsName string `json:"secretsName,omitempty"` SSLSecretName string `json:"sslSecretName,omitempty"` Unsafe UnsafeFlags `json:"unsafeFlags,omitempty"` - InitImage string `json:"initImage,omitempty"` + InitContainer InitContainerSpec `json:"initContainer,omitempty"` IgnoreAnnotations []string `json:"ignoreAnnotations,omitempty"` IgnoreLabels []string `json:"ignoreLabels,omitempty"` MySQL MySQLSpec `json:"mysql,omitempty"` @@ -77,6 +77,12 @@ type PerconaServerMySQLSpec struct { UpdateStrategy appsv1.StatefulSetUpdateStrategyType `json:"updateStrategy,omitempty"` } +type InitContainerSpec struct { + Image string `json:"image,omitempty"` + Resources *corev1.ResourceRequirements `json:"resources,omitempty"` + ContainerSecurityContext *corev1.SecurityContext `json:"containerSecurityContext,omitempty"` +} + type UnsafeFlags struct { // MySQLSize allows to set MySQL size to a value less than the minimum safe size or higher than the maximum safe size. MySQLSize bool `json:"mysqlSize,omitempty"` diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 06c7984bd..1bc4a9595 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -21,9 +21,9 @@ limitations under the License. package v1alpha1 import ( - "github.com/cert-manager/cert-manager/pkg/apis/meta/v1" - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + metav1 "github.com/cert-manager/cert-manager/pkg/apis/meta/v1" + "k8s.io/api/core/v1" + apismetav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/intstr" ) @@ -48,12 +48,12 @@ func (in *BackupSpec) DeepCopyInto(out *BackupSpec) { *out = *in if in.ImagePullSecrets != nil { in, out := &in.ImagePullSecrets, &out.ImagePullSecrets - *out = make([]corev1.LocalObjectReference, len(*in)) + *out = make([]v1.LocalObjectReference, len(*in)) copy(*out, *in) } if in.ContainerSecurityContext != nil { in, out := &in.ContainerSecurityContext, &out.ContainerSecurityContext - *out = new(corev1.SecurityContext) + *out = new(v1.SecurityContext) (*in).DeepCopyInto(*out) } in.Resources.DeepCopyInto(&out.Resources) @@ -174,19 +174,19 @@ func (in *BackupStorageSpec) DeepCopyInto(out *BackupStorageSpec) { in.Resources.DeepCopyInto(&out.Resources) if in.Affinity != nil { in, out := &in.Affinity, &out.Affinity - *out = new(corev1.Affinity) + *out = new(v1.Affinity) (*in).DeepCopyInto(*out) } if in.TopologySpreadConstraints != nil { in, out := &in.TopologySpreadConstraints, &out.TopologySpreadConstraints - *out = make([]corev1.TopologySpreadConstraint, len(*in)) + *out = make([]v1.TopologySpreadConstraint, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } } if in.Tolerations != nil { in, out := &in.Tolerations, &out.Tolerations - *out = make([]corev1.Toleration, len(*in)) + *out = make([]v1.Toleration, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } @@ -207,12 +207,12 @@ func (in *BackupStorageSpec) DeepCopyInto(out *BackupStorageSpec) { } if in.PodSecurityContext != nil { in, out := &in.PodSecurityContext, &out.PodSecurityContext - *out = new(corev1.PodSecurityContext) + *out = new(v1.PodSecurityContext) (*in).DeepCopyInto(*out) } if in.ContainerSecurityContext != nil { in, out := &in.ContainerSecurityContext, &out.ContainerSecurityContext - *out = new(corev1.SecurityContext) + *out = new(v1.SecurityContext) (*in).DeepCopyInto(*out) } if in.RuntimeClassName != nil { @@ -279,7 +279,7 @@ func (in *ContainerSpec) DeepCopyInto(out *ContainerSpec) { *out = *in if in.ImagePullSecrets != nil { in, out := &in.ImagePullSecrets, &out.ImagePullSecrets - *out = make([]corev1.LocalObjectReference, len(*in)) + *out = make([]v1.LocalObjectReference, len(*in)) copy(*out, *in) } in.Resources.DeepCopyInto(&out.Resources) @@ -288,19 +288,19 @@ func (in *ContainerSpec) DeepCopyInto(out *ContainerSpec) { in.LivenessProbe.DeepCopyInto(&out.LivenessProbe) if in.ContainerSecurityContext != nil { in, out := &in.ContainerSecurityContext, &out.ContainerSecurityContext - *out = new(corev1.SecurityContext) + *out = new(v1.SecurityContext) (*in).DeepCopyInto(*out) } if in.Env != nil { in, out := &in.Env, &out.Env - *out = make([]corev1.EnvVar, len(*in)) + *out = make([]v1.EnvVar, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } } if in.EnvFrom != nil { in, out := &in.EnvFrom, &out.EnvFrom - *out = make([]corev1.EnvFromSource, len(*in)) + *out = make([]v1.EnvFromSource, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } @@ -334,13 +334,38 @@ func (in *HAProxySpec) DeepCopy() *HAProxySpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *InitContainerSpec) DeepCopyInto(out *InitContainerSpec) { + *out = *in + if in.Resources != nil { + in, out := &in.Resources, &out.Resources + *out = new(v1.ResourceRequirements) + (*in).DeepCopyInto(*out) + } + if in.ContainerSecurityContext != nil { + in, out := &in.ContainerSecurityContext, &out.ContainerSecurityContext + *out = new(v1.SecurityContext) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InitContainerSpec. +func (in *InitContainerSpec) DeepCopy() *InitContainerSpec { + if in == nil { + return nil + } + out := new(InitContainerSpec) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *MySQLRouterSpec) DeepCopyInto(out *MySQLRouterSpec) { *out = *in in.Expose.DeepCopyInto(&out.Expose) if in.Ports != nil { in, out := &in.Ports, &out.Ports - *out = make([]corev1.ServicePort, len(*in)) + *out = make([]v1.ServicePort, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } @@ -365,14 +390,14 @@ func (in *MySQLSpec) DeepCopyInto(out *MySQLSpec) { in.Expose.DeepCopyInto(&out.Expose) if in.Sidecars != nil { in, out := &in.Sidecars, &out.Sidecars - *out = make([]corev1.Container, len(*in)) + *out = make([]v1.Container, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } } if in.SidecarVolumes != nil { in, out := &in.SidecarVolumes, &out.SidecarVolumes - *out = make([]corev1.Volume, len(*in)) + *out = make([]v1.Volume, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } @@ -420,7 +445,7 @@ func (in *PMMSpec) DeepCopyInto(out *PMMSpec) { in.Resources.DeepCopyInto(&out.Resources) if in.ContainerSecurityContext != nil { in, out := &in.ContainerSecurityContext, &out.ContainerSecurityContext - *out = new(corev1.SecurityContext) + *out = new(v1.SecurityContext) (*in).DeepCopyInto(*out) } } @@ -694,6 +719,7 @@ func (in *PerconaServerMySQLRestoreStatus) DeepCopy() *PerconaServerMySQLRestore func (in *PerconaServerMySQLSpec) DeepCopyInto(out *PerconaServerMySQLSpec) { *out = *in out.Unsafe = in.Unsafe + in.InitContainer.DeepCopyInto(&out.InitContainer) if in.IgnoreAnnotations != nil { in, out := &in.IgnoreAnnotations, &out.IgnoreAnnotations *out = make([]string, len(*in)) @@ -749,7 +775,7 @@ func (in *PerconaServerMySQLStatus) DeepCopyInto(out *PerconaServerMySQLStatus) out.Router = in.Router if in.Conditions != nil { in, out := &in.Conditions, &out.Conditions - *out = make([]metav1.Condition, len(*in)) + *out = make([]apismetav1.Condition, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } @@ -796,7 +822,7 @@ func (in *PodAffinity) DeepCopyInto(out *PodAffinity) { } if in.Advanced != nil { in, out := &in.Advanced, &out.Advanced - *out = new(corev1.Affinity) + *out = new(v1.Affinity) (*in).DeepCopyInto(*out) } } @@ -865,7 +891,7 @@ func (in *PodSpec) DeepCopyInto(out *PodSpec) { } if in.TopologySpreadConstraints != nil { in, out := &in.TopologySpreadConstraints, &out.TopologySpreadConstraints - *out = make([]corev1.TopologySpreadConstraint, len(*in)) + *out = make([]v1.TopologySpreadConstraint, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } @@ -879,7 +905,7 @@ func (in *PodSpec) DeepCopyInto(out *PodSpec) { } if in.Tolerations != nil { in, out := &in.Tolerations, &out.Tolerations - *out = make([]corev1.Toleration, len(*in)) + *out = make([]v1.Toleration, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } @@ -896,7 +922,7 @@ func (in *PodSpec) DeepCopyInto(out *PodSpec) { } if in.PodSecurityContext != nil { in, out := &in.PodSecurityContext, &out.PodSecurityContext - *out = new(corev1.PodSecurityContext) + *out = new(v1.PodSecurityContext) (*in).DeepCopyInto(*out) } in.ContainerSpec.DeepCopyInto(&out.ContainerSpec) @@ -961,7 +987,7 @@ func (in *ServiceExpose) DeepCopyInto(out *ServiceExpose) { } if in.InternalTrafficPolicy != nil { in, out := &in.InternalTrafficPolicy, &out.InternalTrafficPolicy - *out = new(corev1.ServiceInternalTrafficPolicy) + *out = new(v1.ServiceInternalTrafficPolicy) **out = **in } } @@ -1033,7 +1059,7 @@ func (in *TLSSpec) DeepCopyInto(out *TLSSpec) { } if in.IssuerConf != nil { in, out := &in.IssuerConf, &out.IssuerConf - *out = new(v1.ObjectReference) + *out = new(metav1.ObjectReference) **out = **in } } @@ -1099,17 +1125,17 @@ func (in *VolumeSpec) DeepCopyInto(out *VolumeSpec) { *out = *in if in.EmptyDir != nil { in, out := &in.EmptyDir, &out.EmptyDir - *out = new(corev1.EmptyDirVolumeSource) + *out = new(v1.EmptyDirVolumeSource) (*in).DeepCopyInto(*out) } if in.HostPath != nil { in, out := &in.HostPath, &out.HostPath - *out = new(corev1.HostPathVolumeSource) + *out = new(v1.HostPathVolumeSource) (*in).DeepCopyInto(*out) } if in.PersistentVolumeClaim != nil { in, out := &in.PersistentVolumeClaim, &out.PersistentVolumeClaim - *out = new(corev1.PersistentVolumeClaimSpec) + *out = new(v1.PersistentVolumeClaimSpec) (*in).DeepCopyInto(*out) } } diff --git a/config/crd/bases/ps.percona.com_perconaservermysqls.yaml b/config/crd/bases/ps.percona.com_perconaservermysqls.yaml index 38a71a851..1363b6102 100644 --- a/config/crd/bases/ps.percona.com_perconaservermysqls.yaml +++ b/config/crd/bases/ps.percona.com_perconaservermysqls.yaml @@ -2336,8 +2336,116 @@ spec: items: type: string type: array - initImage: - type: string + initContainer: + properties: + containerSecurityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + image: + type: string + resources: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + 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 + 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 + type: object + type: object + type: object mysql: properties: affinity: diff --git a/deploy/bundle.yaml b/deploy/bundle.yaml index 817a5cd65..97945b4ec 100644 --- a/deploy/bundle.yaml +++ b/deploy/bundle.yaml @@ -4259,8 +4259,116 @@ spec: items: type: string type: array - initImage: - type: string + initContainer: + properties: + containerSecurityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + image: + type: string + resources: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + 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 + 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 + type: object + type: object + type: object mysql: properties: affinity: diff --git a/deploy/cr.yaml b/deploy/cr.yaml index 78af79a94..d978c7cb7 100644 --- a/deploy/cr.yaml +++ b/deploy/cr.yaml @@ -22,7 +22,19 @@ spec: upgradeOptions: versionServiceEndpoint: https://check.percona.com apply: disabled -# initImage: perconalab/percona-server-mysql-operator:main +# initContainer: +# image: perconalab/percona-server-mysql-operator:main +# containerSecurityContext: +# privileged: false +# runAsUser: 1001 +# runAsGroup: 1001 +# resources: +# requests: +# memory: 100M +# cpu: 100m +# limits: +# memory: 200M +# cpu: 200m # ignoreAnnotations: # - service.beta.kubernetes.io/aws-load-balancer-backend-protocol # ignoreLabels: diff --git a/deploy/crd.yaml b/deploy/crd.yaml index 11599fa9c..c8e70102a 100644 --- a/deploy/crd.yaml +++ b/deploy/crd.yaml @@ -4259,8 +4259,116 @@ spec: items: type: string type: array - initImage: - type: string + initContainer: + properties: + containerSecurityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + image: + type: string + resources: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + 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 + 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 + type: object + type: object + type: object mysql: properties: affinity: diff --git a/deploy/cw-bundle.yaml b/deploy/cw-bundle.yaml index e8659ef47..a963421c4 100644 --- a/deploy/cw-bundle.yaml +++ b/deploy/cw-bundle.yaml @@ -4259,8 +4259,116 @@ spec: items: type: string type: array - initImage: - type: string + initContainer: + properties: + containerSecurityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + image: + type: string + resources: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + 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 + 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 + type: object + type: object + type: object mysql: properties: affinity: diff --git a/e2e-tests/functions b/e2e-tests/functions index e48cb6d3a..7a71ac697 100755 --- a/e2e-tests/functions +++ b/e2e-tests/functions @@ -551,12 +551,12 @@ get_cr() { local name_suffix=$1 yq eval "$(printf '.metadata.name="%s"' "${test_name}${name_suffix:+-$name_suffix}")" "${DEPLOY_DIR}/cr.yaml" \ - | yq eval "$(printf '.spec.initImage="%s"' "${IMAGE}")" - \ + | yq eval "$(printf '.spec.initContainer.image="%s"' "${IMAGE}")" - \ | yq eval '.spec.secretsName="test-secrets"' - \ | yq eval '.spec.sslSecretName="test-ssl"' - \ | yq eval '.spec.upgradeOptions.apply="disabled"' - \ | yq eval '.spec.mysql.clusterType="async"' - \ - | yq eval '.spec.mysql.gracePeriod=30' - \ + | yq eval '.spec.mysql.gracePeriod=30' - \ | yq eval '.spec.orchestrator.enabled=true' - \ | yq eval "$(printf '.spec.mysql.image="%s"' "${IMAGE_MYSQL}")" - \ | yq eval "$(printf '.spec.backup.image="%s"' "${IMAGE_BACKUP}")" - \ @@ -1260,8 +1260,8 @@ deploy_cmctl() { } get_user_pass() { - local user="${1:-root}" - kubectl -n "${NAMESPACE}" get secret test-secrets -o jsonpath="{.data.${user}}" | base64 --decode + local user="${1:-root}" + kubectl -n "${NAMESPACE}" get secret test-secrets -o jsonpath="{.data.${user}}" | base64 --decode } get_operator_version() { diff --git a/pkg/binlogserver/binlog_server.go b/pkg/binlogserver/binlog_server.go index 1207a2496..4214409aa 100644 --- a/pkg/binlogserver/binlog_server.go +++ b/pkg/binlogserver/binlog_server.go @@ -78,6 +78,7 @@ func StatefulSet(cr *apiv1alpha1.PerconaServerMySQL, initImage, configHash strin Spec: corev1.PodSpec{ InitContainers: []corev1.Container{ k8s.InitContainer( + cr, AppName, initImage, spec.ImagePullPolicy, diff --git a/pkg/controller/ps/suite_test.go b/pkg/controller/ps/suite_test.go index f5747ba0c..fbdc9e1a4 100644 --- a/pkg/controller/ps/suite_test.go +++ b/pkg/controller/ps/suite_test.go @@ -123,6 +123,6 @@ func readDefaultCR(name, namespace string) (*psv1alpha1.PerconaServerMySQL, erro cr.Name = name cr.Namespace = namespace - cr.Spec.InitImage = "perconalab/percona-server-mysql-operator:main" + cr.Spec.InitContainer.Image = "perconalab/percona-server-mysql-operator:main" return cr, nil } diff --git a/pkg/controller/psrestore/helpers_test.go b/pkg/controller/psrestore/helpers_test.go index 706299acc..195753de8 100644 --- a/pkg/controller/psrestore/helpers_test.go +++ b/pkg/controller/psrestore/helpers_test.go @@ -25,7 +25,7 @@ func readDefaultCluster(t *testing.T, name, namespace string) *apiv1alpha1.Perco cr.Name = name cr.Namespace = namespace - cr.Spec.InitImage = "init-image" + cr.Spec.InitContainer.Image = "init-image" return cr } diff --git a/pkg/haproxy/haproxy.go b/pkg/haproxy/haproxy.go index 052e522e2..7d1d402b7 100644 --- a/pkg/haproxy/haproxy.go +++ b/pkg/haproxy/haproxy.go @@ -164,6 +164,7 @@ func StatefulSet(cr *apiv1alpha1.PerconaServerMySQL, initImage, configHash, tlsH RuntimeClassName: cr.Spec.Proxy.HAProxy.RuntimeClassName, InitContainers: []corev1.Container{ k8s.InitContainer( + cr, AppName, initImage, cr.Spec.Proxy.HAProxy.ImagePullPolicy, diff --git a/pkg/haproxy/helpers_test.go b/pkg/haproxy/helpers_test.go index bd081de3d..a0850c7fb 100644 --- a/pkg/haproxy/helpers_test.go +++ b/pkg/haproxy/helpers_test.go @@ -18,7 +18,7 @@ func readDefaultCluster(t *testing.T, name, namespace string) *apiv1alpha1.Perco cr.Name = name cr.Namespace = namespace - cr.Spec.InitImage = "init-image" + cr.Spec.InitContainer.Image = "init-image" return cr } diff --git a/pkg/k8s/init_image.go b/pkg/k8s/init_image.go index 84f70c90b..f53e27133 100644 --- a/pkg/k8s/init_image.go +++ b/pkg/k8s/init_image.go @@ -16,13 +16,12 @@ type ComponentWithInit interface { GetInitImage() string } -func InitContainer(component, image string, +func InitContainer(cr *apiv1alpha1.PerconaServerMySQL, component, image string, pullPolicy corev1.PullPolicy, secCtx *corev1.SecurityContext, resources corev1.ResourceRequirements, extraVolumeMounts []corev1.VolumeMount, ) corev1.Container { - volumeMounts := []corev1.VolumeMount{ { Name: apiv1alpha1.BinVolumeName, @@ -34,6 +33,14 @@ func InitContainer(component, image string, volumeMounts = append(volumeMounts, extraVolumeMounts...) } + if cr.Spec.InitContainer.Resources != nil { + resources = *cr.Spec.InitContainer.Resources + } + + if cr.Spec.InitContainer.ContainerSecurityContext != nil { + secCtx = cr.Spec.InitContainer.ContainerSecurityContext + } + return corev1.Container{ Name: component + "-init", Image: image, @@ -54,7 +61,7 @@ func InitImage(ctx context.Context, cl client.Reader, cr *apiv1alpha1.PerconaSer if image := comp.GetInitImage(); len(image) > 0 { return image, nil } - if image := cr.Spec.InitImage; len(image) > 0 { + if image := cr.Spec.InitContainer.Image; len(image) > 0 { return image, nil } return OperatorImage(ctx, cl) diff --git a/pkg/k8s/init_image_test.go b/pkg/k8s/init_image_test.go index a785c0ed1..cf3f1d20e 100644 --- a/pkg/k8s/init_image_test.go +++ b/pkg/k8s/init_image_test.go @@ -1,10 +1,14 @@ package k8s import ( + "testing" + "github.com/stretchr/testify/assert" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" - "testing" + "k8s.io/utils/ptr" + + apiv1alpha1 "github.com/percona/percona-server-mysql-operator/api/v1alpha1" ) func TestInitContainer(t *testing.T) { @@ -35,11 +39,16 @@ func TestInitContainer(t *testing.T) { } tests := map[string]struct { - inputVolumes []corev1.VolumeMount - expectedVolumes []corev1.VolumeMount + cr *apiv1alpha1.PerconaServerMySQL + inputVolumes []corev1.VolumeMount + expectedVolumes []corev1.VolumeMount + expectedResources corev1.ResourceRequirements + expectedSecurityContext corev1.SecurityContext }{ "default volumes": { - expectedVolumes: expectedVolumeMounts, + expectedVolumes: expectedVolumeMounts, + expectedResources: expectedResources, + expectedSecurityContext: *secCtx, }, "additional volumes": { inputVolumes: []corev1.VolumeMount{ @@ -51,12 +60,56 @@ func TestInitContainer(t *testing.T) { expectedVolumes: append(expectedVolumeMounts, corev1.VolumeMount{ Name: "dataVolumeName", - MountPath: "dataMountPath"}), + MountPath: "dataMountPath", + }), + expectedResources: expectedResources, + }, + "initContainer.resources": { + cr: &apiv1alpha1.PerconaServerMySQL{ + Spec: apiv1alpha1.PerconaServerMySQLSpec{ + InitContainer: apiv1alpha1.InitContainerSpec{ + Image: "initcontainer-image", + Resources: &corev1.ResourceRequirements{ + Limits: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("500m"), + corev1.ResourceMemory: resource.MustParse("256Mi"), + }, + }, + }, + }, + }, + expectedResources: corev1.ResourceRequirements{ + Limits: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("500m"), + corev1.ResourceMemory: resource.MustParse("256Mi"), + }, + }, + expectedVolumes: expectedVolumeMounts, + }, + "initContainer.containerSecurityContext": { + expectedVolumes: expectedVolumeMounts, + cr: &apiv1alpha1.PerconaServerMySQL{ + Spec: apiv1alpha1.PerconaServerMySQLSpec{ + InitContainer: apiv1alpha1.InitContainerSpec{ + ContainerSecurityContext: &corev1.SecurityContext{ + Privileged: ptr.To(true), + }, + }, + }, + }, + expectedSecurityContext: corev1.SecurityContext{ + Privileged: ptr.To(true), + }, + expectedResources: expectedResources, }, } for name, tt := range tests { t.Run(name, func(t *testing.T) { - container := InitContainer(componentName, image, pullPolicy, secCtx, expectedResources, tt.inputVolumes) + cr := new(apiv1alpha1.PerconaServerMySQL) + if tt.cr != nil { + cr = tt.cr + } + container := InitContainer(cr, componentName, image, pullPolicy, secCtx, expectedResources, tt.inputVolumes) assert.Equal(t, componentName+"-init", container.Name) assert.Equal(t, image, container.Image) @@ -65,8 +118,8 @@ func TestInitContainer(t *testing.T) { assert.Equal(t, expectedCommand, container.Command) assert.Equal(t, expectedTerminationMessagePath, container.TerminationMessagePath) assert.Equal(t, expectedTerminationMessagePolicy, container.TerminationMessagePolicy) - assert.Equal(t, secCtx, container.SecurityContext) - assert.Equal(t, expectedResources, container.Resources) + assert.Equal(t, tt.expectedSecurityContext, *container.SecurityContext) + assert.Equal(t, tt.expectedResources, container.Resources) }) } } diff --git a/pkg/mysql/helpers_test.go b/pkg/mysql/helpers_test.go index 8df2f242b..44f4b93ac 100644 --- a/pkg/mysql/helpers_test.go +++ b/pkg/mysql/helpers_test.go @@ -18,7 +18,7 @@ func readDefaultCluster(t *testing.T, name, namespace string) *apiv1alpha1.Perco cr.Name = name cr.Namespace = namespace - cr.Spec.InitImage = "init-image" + cr.Spec.InitContainer.Image = "init-image" return cr } diff --git a/pkg/mysql/mysql.go b/pkg/mysql/mysql.go index 51a5412f7..2cda39327 100644 --- a/pkg/mysql/mysql.go +++ b/pkg/mysql/mysql.go @@ -166,6 +166,7 @@ func StatefulSet(cr *apiv1alpha1.PerconaServerMySQL, initImage, configHash, tlsH Spec: corev1.PodSpec{ InitContainers: []corev1.Container{ k8s.InitContainer( + cr, AppName, initImage, spec.ImagePullPolicy, diff --git a/pkg/orchestrator/helpers_test.go b/pkg/orchestrator/helpers_test.go index 9e6ead15e..b0e07c6d1 100644 --- a/pkg/orchestrator/helpers_test.go +++ b/pkg/orchestrator/helpers_test.go @@ -18,7 +18,7 @@ func readDefaultCluster(t *testing.T, name, namespace string) *apiv1alpha1.Perco cr.Name = name cr.Namespace = namespace - cr.Spec.InitImage = "init-image" + cr.Spec.InitContainer.Image = "init-image" return cr } diff --git a/pkg/orchestrator/orchestrator.go b/pkg/orchestrator/orchestrator.go index 9b0f81ef3..af3a55c41 100644 --- a/pkg/orchestrator/orchestrator.go +++ b/pkg/orchestrator/orchestrator.go @@ -142,6 +142,7 @@ func StatefulSet(cr *apiv1alpha1.PerconaServerMySQL, initImage, tlsHash string) Spec: corev1.PodSpec{ InitContainers: []corev1.Container{ k8s.InitContainer( + cr, AppName, initImage, spec.ImagePullPolicy, diff --git a/pkg/router/helpers_test.go b/pkg/router/helpers_test.go index 6b5f87784..0694c564f 100644 --- a/pkg/router/helpers_test.go +++ b/pkg/router/helpers_test.go @@ -18,7 +18,7 @@ func readDefaultCluster(t *testing.T, name, namespace string) *apiv1alpha1.Perco cr.Name = name cr.Namespace = namespace - cr.Spec.InitImage = "init-image" + cr.Spec.InitContainer.Image = "init-image" return cr } diff --git a/pkg/router/router.go b/pkg/router/router.go index 46c038872..c9d328f88 100644 --- a/pkg/router/router.go +++ b/pkg/router/router.go @@ -137,6 +137,7 @@ func Deployment(cr *apiv1alpha1.PerconaServerMySQL, initImage, configHash, tlsHa Spec: corev1.PodSpec{ InitContainers: []corev1.Container{ k8s.InitContainer( + cr, AppName, initImage, spec.ImagePullPolicy, diff --git a/pkg/xtrabackup/helpers_test.go b/pkg/xtrabackup/helpers_test.go index dfd2b6708..2e519fe49 100644 --- a/pkg/xtrabackup/helpers_test.go +++ b/pkg/xtrabackup/helpers_test.go @@ -18,7 +18,7 @@ func readDefaultCluster(t *testing.T, name, namespace string) *apiv1alpha1.Perco cr.Name = name cr.Namespace = namespace - cr.Spec.InitImage = "init-image" + cr.Spec.InitContainer.Image = "init-image" return cr } diff --git a/pkg/xtrabackup/xtrabackup.go b/pkg/xtrabackup/xtrabackup.go index e56137ec2..09fbfa713 100644 --- a/pkg/xtrabackup/xtrabackup.go +++ b/pkg/xtrabackup/xtrabackup.go @@ -136,6 +136,7 @@ func Job( SetHostnameAsFQDN: &t, InitContainers: []corev1.Container{ k8s.InitContainer( + cluster, appName, initImage, cluster.Spec.Backup.ImagePullPolicy, @@ -356,7 +357,7 @@ func RestoreJob( RestartPolicy: corev1.RestartPolicyNever, ImagePullSecrets: cluster.Spec.Backup.ImagePullSecrets, InitContainers: []corev1.Container{ - k8s.InitContainer(appName, initImage, + k8s.InitContainer(cluster, appName, initImage, cluster.Spec.Backup.ImagePullPolicy, storage.ContainerSecurityContext, cluster.Spec.Backup.Resources,