From 0dd274aab4c6a1b000d035fc6318774a920ab134 Mon Sep 17 00:00:00 2001 From: amecea Date: Mon, 10 Dec 2018 17:20:22 +0200 Subject: [PATCH] Add .spec.image on MysqlCluster resource and image map for mysql version --- config/crds/mysql_v1alpha1_mysqlcluster.yaml | 2 ++ pkg/apis/mysql/v1alpha1/mysqlcluster_types.go | 6 ++++ .../internal/syncer/statefullset.go | 2 +- .../mysqlcluster/mysqlcluster_controller.go | 3 ++ pkg/internal/mysqlcluster/defaults.go | 9 +++-- pkg/internal/mysqlcluster/mysqlcluster.go | 17 +++++++++ pkg/internal/mysqlcluster/validation.go | 35 +++++++++++++++++++ pkg/options/options.go | 19 ++-------- pkg/util/constants/constants.go | 9 +++++ 9 files changed, 79 insertions(+), 23 deletions(-) create mode 100644 pkg/internal/mysqlcluster/validation.go diff --git a/config/crds/mysql_v1alpha1_mysqlcluster.yaml b/config/crds/mysql_v1alpha1_mysqlcluster.yaml index a73fae553..84fa42279 100644 --- a/config/crds/mysql_v1alpha1_mysqlcluster.yaml +++ b/config/crds/mysql_v1alpha1_mysqlcluster.yaml @@ -38,6 +38,8 @@ spec: type: string backupUri: type: string + image: + type: string initBucketSecretName: type: string initBucketURI: diff --git a/pkg/apis/mysql/v1alpha1/mysqlcluster_types.go b/pkg/apis/mysql/v1alpha1/mysqlcluster_types.go index a52b68619..db6ae40a8 100644 --- a/pkg/apis/mysql/v1alpha1/mysqlcluster_types.go +++ b/pkg/apis/mysql/v1alpha1/mysqlcluster_types.go @@ -33,6 +33,7 @@ type MysqlClusterSpec struct { // Defaults to 0 // +optional Replicas *int32 `json:"replicas,omitempty"` + // The secret name that contains connection information to initialize database, like // USER, PASSWORD, ROOT_PASSWORD and so on // This secret will be updated with DB_CONNECT_URL and some more configs. @@ -46,6 +47,11 @@ type MysqlClusterSpec struct { // +optional MysqlVersion string `json:"mysqlVersion,omitempty"` + // To specify the image that will be used for mysql server container. + // If this is specified then the mysqlVersion is ignored. + // +optional + Image string `json:"image,omitempty"` + // A bucket URI that contains a xtrabackup to initialize the mysql database. // +optional InitBucketURI string `json:"initBucketURI,omitempty"` diff --git a/pkg/controller/mysqlcluster/internal/syncer/statefullset.go b/pkg/controller/mysqlcluster/internal/syncer/statefullset.go index dcf7ff472..0ef4d151e 100644 --- a/pkg/controller/mysqlcluster/internal/syncer/statefullset.go +++ b/pkg/controller/mysqlcluster/internal/syncer/statefullset.go @@ -326,7 +326,7 @@ func (s *sfsSyncer) ensureInitContainersSpec() []core.Container { func (s *sfsSyncer) ensureContainersSpec() []core.Container { // MYSQL container mysql := s.ensureContainer(containerMysqlName, - s.opt.MysqlImage+":"+s.opt.MysqlImageTag, + s.cluster.GetMysqlImage(), []string{}, ) mysql.Ports = ensurePorts(core.ContainerPort{ diff --git a/pkg/controller/mysqlcluster/mysqlcluster_controller.go b/pkg/controller/mysqlcluster/mysqlcluster_controller.go index ebf29896a..141d52e6d 100644 --- a/pkg/controller/mysqlcluster/mysqlcluster_controller.go +++ b/pkg/controller/mysqlcluster/mysqlcluster_controller.go @@ -151,6 +151,9 @@ func (r *ReconcileMysqlCluster) Reconcile(request reconcile.Request) (reconcile. // Set defaults on cluster r.scheme.Default(cluster.Unwrap()) cluster.SetDefaults(r.opt) + if err = cluster.Validate(); err != nil { + return reconcile.Result{}, err + } status := *cluster.Status.DeepCopy() defer func() { diff --git a/pkg/internal/mysqlcluster/defaults.go b/pkg/internal/mysqlcluster/defaults.go index e4a2e568d..4d01a0d89 100644 --- a/pkg/internal/mysqlcluster/defaults.go +++ b/pkg/internal/mysqlcluster/defaults.go @@ -36,16 +36,15 @@ const ( // SetDefaults set defaults from options // nolint: gocyclo func (cluster *MysqlCluster) SetDefaults(opt *options.Options) { - // set default mysql version - if len(cluster.Spec.MysqlVersion) == 0 { - cluster.Spec.MysqlVersion = opt.MysqlImageTag - } - // set default image pull policy if len(cluster.Spec.PodSpec.ImagePullPolicy) == 0 { cluster.Spec.PodSpec.ImagePullPolicy = opt.ImagePullPolicy } + if len(cluster.Spec.MysqlVersion) == 0 { + cluster.Spec.MysqlVersion = "5.7" + } + // set pod antiaffinity to nodes stay away from other nodes. if cluster.Spec.PodSpec.Affinity.PodAntiAffinity == nil { cluster.Spec.PodSpec.Affinity.PodAntiAffinity = &core.PodAntiAffinity{ diff --git a/pkg/internal/mysqlcluster/mysqlcluster.go b/pkg/internal/mysqlcluster/mysqlcluster.go index 2146e6021..da6435df9 100644 --- a/pkg/internal/mysqlcluster/mysqlcluster.go +++ b/pkg/internal/mysqlcluster/mysqlcluster.go @@ -23,6 +23,7 @@ import ( "k8s.io/apimachinery/pkg/labels" api "github.com/presslabs/mysql-operator/pkg/apis/mysql/v1alpha1" + "github.com/presslabs/mysql-operator/pkg/util/constants" ) // MysqlCluster is the wrapper for api.MysqlCluster type @@ -114,3 +115,19 @@ func (c *MysqlCluster) GetMasterHost() string { return masterHost } + +// GetMysqlImage returns the mysql image for current mysql cluster +func (c *MysqlCluster) GetMysqlImage() string { + if len(c.Spec.Image) != 0 { + return c.Spec.Image + } + + if len(c.Spec.MysqlVersion) != 0 { + if img, ok := constants.MysqlImageVersions[c.Spec.MysqlVersion]; ok { + return img + } + } + + // this means the cluster has a wrong MysqlVersion set + return "" +} diff --git a/pkg/internal/mysqlcluster/validation.go b/pkg/internal/mysqlcluster/validation.go new file mode 100644 index 000000000..c5543baa2 --- /dev/null +++ b/pkg/internal/mysqlcluster/validation.go @@ -0,0 +1,35 @@ +/* +Copyright 2018 Pressinfra SRL + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package mysqlcluster + +import ( + "fmt" +) + +// Validate checks if the cluster spec is validated +func (c *MysqlCluster) Validate() error { + // TODO: this validation should be done in an admission web-hook + if len(c.Spec.SecretName) == 0 { + return fmt.Errorf("spec.secretName is missing") + } + + if len(c.GetMysqlImage()) == 0 { + return fmt.Errorf("%s is not a valid MySQL version", c.Spec.MysqlVersion) + } + + return nil +} diff --git a/pkg/options/options.go b/pkg/options/options.go index 6fd53fb4f..515b0025e 100644 --- a/pkg/options/options.go +++ b/pkg/options/options.go @@ -18,7 +18,6 @@ package options import ( "os" - "strings" "sync" "time" @@ -39,11 +38,6 @@ func getFromEnvOrDefault(key, def string) string { // Options is the data structure that contains information about mysql operator configuration type Options struct { - mysqlImage string - - MysqlImage string - MysqlImageTag string - HelperImage string MetricsExporterImage string @@ -85,10 +79,6 @@ func newPullPolicyValue(defaultValue corev1.PullPolicy, v *corev1.PullPolicy) *p } const ( - // because of moving percona docker images to centos they broke the mysql - // configuration files. - // TODO: fix this issue - defaultMysqlImage = "percona:5.7-stretch" defaultExporterImage = "prom/mysqld-exporter:latest" defaultImagePullPolicy = corev1.PullIfNotPresent @@ -109,10 +99,9 @@ var ( // AddFlags registers all mysql-operator needed flags func (o *Options) AddFlags(fs *pflag.FlagSet) { - fs.StringVar(&o.mysqlImage, "mysql-image", defaultMysqlImage, - "The mysql image.") fs.StringVar(&o.HelperImage, "helper-image", defaultHelperImage, "The image that instrumentate mysql.") + fs.StringVar(&o.MetricsExporterImage, "metrics-exporter-image", defaultExporterImage, "The image for mysql metrics exporter.") fs.StringVar(&o.ImagePullSecretName, "image-pull-secret", "", @@ -146,7 +135,6 @@ var once sync.Once func GetOptions() *Options { once.Do(func() { instance = &Options{ - mysqlImage: defaultMysqlImage, HelperImage: defaultHelperImage, MetricsExporterImage: defaultExporterImage, @@ -165,10 +153,7 @@ func GetOptions() *Options { // Validate validate the command line values func (o *Options) Validate() error { - // Update mysql image and tag. - i := strings.Split(o.mysqlImage, ":") - o.MysqlImage = i[0] - o.MysqlImageTag = i[1] + if len(o.OrchestratorTopologyUser) == 0 { o.OrchestratorTopologyUser = getFromEnvOrDefault("ORC_TOPOLOGY_USER", "") } diff --git a/pkg/util/constants/constants.go b/pkg/util/constants/constants.go index c4258f4ef..e2385efac 100644 --- a/pkg/util/constants/constants.go +++ b/pkg/util/constants/constants.go @@ -56,3 +56,12 @@ const ( // ConfDPath is the path to extra mysql configs dir ConfDPath = "/etc/mysql/conf.d" ) + +var ( + // MysqlImageVersions is a map of supported mysql version and their image + MysqlImageVersions = map[string]string{ + // TODO: modify operator to use percona centos images + // percona:5.7-stretch + "5.7": "percona@sha256:c8b69b3c753cb04f1cbf8a4a1f295f51675761ee6368a47808a5205e2d45cfeb", + } +)