diff --git a/api/.gitkeep b/api/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/api/v1alpha1/etcdcluster_types.go b/api/v1alpha1/etcdcluster_types.go index 23ea2cdc..5e168e13 100644 --- a/api/v1alpha1/etcdcluster_types.go +++ b/api/v1alpha1/etcdcluster_types.go @@ -21,6 +21,8 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) +const defaultEtcdImage = "quay.io/coreos/etcd:v3.5.12" + // EtcdClusterSpec defines the desired state of EtcdCluster type EtcdClusterSpec struct { // Replicas is the count of etcd instances in cluster. @@ -103,6 +105,9 @@ type EmbeddedObjectMetadata struct { // PodSpec defines the desired state of PodSpec for etcd members. // +k8s:openapi-gen=true type PodSpec struct { + // Image is the etcd container image name + // +optional + Image string `json:"image,omitempty"` // ImagePullPolicy describes a policy for if/when to pull a container image // +kubebuilder:default:=IfNotPresent // +optional diff --git a/api/v1alpha1/etcdcluster_webhook.go b/api/v1alpha1/etcdcluster_webhook.go index 14e0bdbb..1c6fc800 100644 --- a/api/v1alpha1/etcdcluster_webhook.go +++ b/api/v1alpha1/etcdcluster_webhook.go @@ -46,6 +46,9 @@ var _ webhook.Defaulter = &EtcdCluster{} // Default implements webhook.Defaulter so a webhook will be registered for the type func (r *EtcdCluster) Default() { etcdclusterlog.Info("default", "name", r.Name) + if len(r.Spec.PodSpec.Image) == 0 { + r.Spec.PodSpec.Image = defaultEtcdImage + } if r.Spec.Storage.EmptyDir == nil { if len(r.Spec.Storage.VolumeClaimTemplate.Spec.AccessModes) == 0 { r.Spec.Storage.VolumeClaimTemplate.Spec.AccessModes = []corev1.PersistentVolumeAccessMode{corev1.ReadWriteOnce} diff --git a/api/v1alpha1/etcdcluster_webhook_test.go b/api/v1alpha1/etcdcluster_webhook_test.go index 1932a580..93357211 100644 --- a/api/v1alpha1/etcdcluster_webhook_test.go +++ b/api/v1alpha1/etcdcluster_webhook_test.go @@ -31,6 +31,7 @@ var _ = Describe("EtcdCluster Webhook", func() { It("Should fill in the default value if a required field is empty", func() { etcdCluster := &EtcdCluster{} etcdCluster.Default() + gomega.Expect(etcdCluster.Spec.PodSpec.Image).To(gomega.Equal(defaultEtcdImage)) gomega.Expect(etcdCluster.Spec.Replicas).To(gomega.BeNil(), "User should have an opportunity to create cluster with 0 replicas") gomega.Expect(etcdCluster.Spec.Storage.EmptyDir).To(gomega.BeNil()) storage := etcdCluster.Spec.Storage.VolumeClaimTemplate.Spec.Resources.Requests.Storage() @@ -43,6 +44,9 @@ var _ = Describe("EtcdCluster Webhook", func() { etcdCluster := &EtcdCluster{ Spec: EtcdClusterSpec{ Replicas: ptr.To(int32(5)), + PodSpec: PodSpec{ + Image: "myregistry.local/etcd:v1.1.1", + }, Storage: StorageSpec{ VolumeClaimTemplate: EmbeddedPersistentVolumeClaim{ Spec: corev1.PersistentVolumeClaimSpec{ @@ -60,6 +64,7 @@ var _ = Describe("EtcdCluster Webhook", func() { } etcdCluster.Default() gomega.Expect(*etcdCluster.Spec.Replicas).To(gomega.Equal(int32(5))) + gomega.Expect(etcdCluster.Spec.PodSpec.Image).To(gomega.Equal("myregistry.local/etcd:v1.1.1")) gomega.Expect(etcdCluster.Spec.Storage.EmptyDir).To(gomega.BeNil()) storage := etcdCluster.Spec.Storage.VolumeClaimTemplate.Spec.Resources.Requests.Storage() if gomega.Expect(storage).NotTo(gomega.BeNil()) { diff --git a/config/crd/bases/etcd.aenix.io_etcdclusters.yaml b/config/crd/bases/etcd.aenix.io_etcdclusters.yaml index c71f699e..990a49e3 100644 --- a/config/crd/bases/etcd.aenix.io_etcdclusters.yaml +++ b/config/crd/bases/etcd.aenix.io_etcdclusters.yaml @@ -1058,6 +1058,9 @@ spec: - name type: object type: array + image: + description: Image is the etcd container image name + type: string imagePullPolicy: default: IfNotPresent description: ImagePullPolicy describes a policy for if/when to diff --git a/internal/controller/factory/statefulset.go b/internal/controller/factory/statefulset.go index 6ee0c179..77198df8 100644 --- a/internal/controller/factory/statefulset.go +++ b/internal/controller/factory/statefulset.go @@ -100,7 +100,7 @@ func CreateOrUpdateStatefulSet( Containers: []corev1.Container{ { Name: "etcd", - Image: "quay.io/coreos/etcd:v3.5.12", + Image: cluster.Spec.PodSpec.Image, ImagePullPolicy: cluster.Spec.PodSpec.ImagePullPolicy, Command: generateEtcdCommand(cluster), Ports: []corev1.ContainerPort{