package kubernetes import ( "fmt" "strings" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "github.com/karmada-io/karmada/pkg/karmadactl/cmdinit/options" "github.com/karmada-io/karmada/pkg/karmadactl/cmdinit/utils" ) const ( etcdStatefulSetAndServiceName = "etcd" etcdStatefulSetAPIVersion = "apps/v1" etcdStatefulSetKind = "StatefulSet" etcdContainerClientPortName = "client" etcdContainerClientPort = 2379 etcdContainerServerPortName = "server" etcdContainerServerPort = 2380 etcdContainerDataVolumeMountName = "etcd-data" etcdContainerDataVolumeMountPath = "/var/lib/etcd" etcdContainerConfigVolumeMountName = "etcd-config" etcdContainerConfigDataMountPath = "/etc/etcd" etcdConfigName = "etcd.conf" etcdEnvPodName = "POD_NAME" etcdEnvPodIP = "POD_IP" //secrets name etcdCertName = "etcd-cert" ) var ( // appLabels remove via Labels karmada StatefulSet Deployment appLabels = map[string]string{"karmada.io/bootstrapping": "app-defaults"} etcdLabels = map[string]string{"app": etcdStatefulSetAndServiceName} ) func (i CommandInitOption) etcdVolume() (*[]corev1.Volume, *corev1.PersistentVolumeClaim) { var Volumes []corev1.Volume secretVolume := corev1.Volume{ Name: etcdCertName, VolumeSource: corev1.VolumeSource{ Secret: &corev1.SecretVolumeSource{ SecretName: etcdCertName, }, }, } configVolume := corev1.Volume{ Name: etcdContainerConfigVolumeMountName, VolumeSource: corev1.VolumeSource{ EmptyDir: &corev1.EmptyDirVolumeSource{}, }, } Volumes = append(Volumes, secretVolume, configVolume) switch i.EtcdStorageMode { case "PVC": mode := corev1.PersistentVolumeFilesystem persistentVolumeClaim := corev1.PersistentVolumeClaim{ TypeMeta: metav1.TypeMeta{ APIVersion: "v1", Kind: "PersistentVolumeClaim", }, ObjectMeta: metav1.ObjectMeta{ Namespace: i.Namespace, Name: etcdContainerDataVolumeMountName, Labels: map[string]string{"karmada.io/bootstrapping": "pvc-defaults"}, }, Spec: corev1.PersistentVolumeClaimSpec{ AccessModes: []corev1.PersistentVolumeAccessMode{corev1.ReadWriteOnce}, StorageClassName: &i.StorageClassesName, VolumeMode: &mode, Resources: corev1.ResourceRequirements{ Requests: corev1.ResourceList{ corev1.ResourceStorage: resource.MustParse(i.EtcdPersistentVolumeSize), }, }, }, } return &Volumes, &persistentVolumeClaim case "hostPath": t := corev1.HostPathDirectoryOrCreate hostPath := corev1.Volume{ Name: etcdContainerDataVolumeMountName, VolumeSource: corev1.VolumeSource{ HostPath: &corev1.HostPathVolumeSource{ Path: i.EtcdHostDataPath, Type: &t, }, }, } Volumes = append(Volumes, hostPath) return &Volumes, nil default: emptyDir := corev1.Volume{ Name: etcdContainerDataVolumeMountName, VolumeSource: corev1.VolumeSource{ EmptyDir: &corev1.EmptyDirVolumeSource{}, }, } Volumes = append(Volumes, emptyDir) return &Volumes, nil } } func (i *CommandInitOption) etcdInitContainerCommand() []string { etcdClusterConfig := "" for v := int32(0); v < i.EtcdReplicas; v++ { etcdClusterConfig += fmt.Sprintf("%s-%v=http://%s-%v.%s.%s.svc.cluster.local:%v", etcdStatefulSetAndServiceName, v, etcdStatefulSetAndServiceName, v, etcdStatefulSetAndServiceName, i.Namespace, etcdContainerServerPort) + "," } command := []string{ "sh", "-c", fmt.Sprintf( `set -ex cat <