add image-pull-policy flag for karmada init cmd

Signed-off-by: changzhen <changzhen5@huawei.com>
This commit is contained in:
changzhen 2024-04-09 11:34:53 +08:00
parent eadf919b6f
commit 4e8252291f
4 changed files with 43 additions and 12 deletions

View File

@ -21,6 +21,7 @@ import (
"strings" "strings"
"github.com/spf13/cobra" "github.com/spf13/cobra"
corev1 "k8s.io/api/core/v1"
"k8s.io/klog/v2" "k8s.io/klog/v2"
"k8s.io/kubectl/pkg/util/templates" "k8s.io/kubectl/pkg/util/templates"
@ -114,6 +115,7 @@ func NewCmdInit(parentCommand string) *cobra.Command {
} }
flags := cmd.Flags() flags := cmd.Flags()
flags.StringVarP(&opts.ImageRegistry, "private-image-registry", "", "", "Private image registry where pull images from. If set, all required images will be downloaded from it, it would be useful in offline installation scenarios. In addition, you still can use --kube-image-registry to specify the registry for Kubernetes's images.") flags.StringVarP(&opts.ImageRegistry, "private-image-registry", "", "", "Private image registry where pull images from. If set, all required images will be downloaded from it, it would be useful in offline installation scenarios. In addition, you still can use --kube-image-registry to specify the registry for Kubernetes's images.")
flags.StringVarP(&opts.ImagePullPolicy, "image-pull-policy", "", string(corev1.PullIfNotPresent), "The image pull policy for all Karmada components container. One of Always, Never, IfNotPresent. Defaults to IfNotPresent.")
flags.StringSliceVar(&opts.PullSecrets, "image-pull-secrets", nil, "Image pull secrets are used to pull images from the private registry, could be secret list separated by comma (e.g '--image-pull-secrets PullSecret1,PullSecret2', the secrets should be pre-settled in the namespace declared by '--namespace')") flags.StringSliceVar(&opts.PullSecrets, "image-pull-secrets", nil, "Image pull secrets are used to pull images from the private registry, could be secret list separated by comma (e.g '--image-pull-secrets PullSecret1,PullSecret2', the secrets should be pre-settled in the namespace declared by '--namespace')")
// kube image registry // kube image registry
flags.StringVarP(&opts.KubeImageMirrorCountry, "kube-image-mirror-country", "", "", "Country code of the kube image registry to be used. For Chinese mainland users, set it to cn") flags.StringVarP(&opts.KubeImageMirrorCountry, "kube-image-mirror-country", "", "", "Country code of the kube image registry to be used. For Chinese mainland users, set it to cn")

View File

@ -124,6 +124,7 @@ func init() {
// CommandInitOption holds all flags options for init. // CommandInitOption holds all flags options for init.
type CommandInitOption struct { type CommandInitOption struct {
ImageRegistry string ImageRegistry string
ImagePullPolicy string
KubeImageRegistry string KubeImageRegistry string
KubeImageMirrorCountry string KubeImageMirrorCountry string
KubeImageTag string KubeImageTag string
@ -218,8 +219,6 @@ func (i *CommandInitOption) isExternalEtcdProvided() bool {
} }
// Validate Check that there are enough flags to run the command. // Validate Check that there are enough flags to run the command.
//
//nolint:gocyclo
func (i *CommandInitOption) Validate(parentCommand string) error { func (i *CommandInitOption) Validate(parentCommand string) error {
if i.KarmadaAPIServerAdvertiseAddress != "" { if i.KarmadaAPIServerAdvertiseAddress != "" {
if netutils.ParseIPSloppy(i.KarmadaAPIServerAdvertiseAddress) == nil { if netutils.ParseIPSloppy(i.KarmadaAPIServerAdvertiseAddress) == nil {
@ -227,6 +226,13 @@ func (i *CommandInitOption) Validate(parentCommand string) error {
} }
} }
switch i.ImagePullPolicy {
case string(corev1.PullAlways), string(corev1.PullIfNotPresent), string(corev1.PullNever):
// continue
default:
return fmt.Errorf("invalid image pull policy: %s", i.ImagePullPolicy)
}
if i.isExternalEtcdProvided() { if i.isExternalEtcdProvided() {
return i.validateExternalEtcd(parentCommand) return i.validateExternalEtcd(parentCommand)
} }

View File

@ -23,6 +23,7 @@ import (
"testing" "testing"
"time" "time"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes/fake" "k8s.io/client-go/kubernetes/fake"
@ -75,6 +76,7 @@ func TestCommandInitOption_Validate(t *testing.T) {
name: "Invalid KarmadaAPIServerAdvertiseAddress", name: "Invalid KarmadaAPIServerAdvertiseAddress",
opt: CommandInitOption{ opt: CommandInitOption{
KarmadaAPIServerAdvertiseAddress: "111", KarmadaAPIServerAdvertiseAddress: "111",
ImagePullPolicy: string(corev1.PullIfNotPresent),
}, },
wantErr: true, wantErr: true,
errorMsg: "CommandInitOption.Validate() does not return err when KarmadaAPIServerAdvertiseAddress is wrong", errorMsg: "CommandInitOption.Validate() does not return err when KarmadaAPIServerAdvertiseAddress is wrong",
@ -85,6 +87,7 @@ func TestCommandInitOption_Validate(t *testing.T) {
KarmadaAPIServerAdvertiseAddress: "192.0.2.1", KarmadaAPIServerAdvertiseAddress: "192.0.2.1",
EtcdStorageMode: etcdStorageModeHostPath, EtcdStorageMode: etcdStorageModeHostPath,
EtcdHostDataPath: "", EtcdHostDataPath: "",
ImagePullPolicy: string(corev1.PullIfNotPresent),
}, },
wantErr: true, wantErr: true,
errorMsg: "CommandInitOption.Validate() does not return err when EtcdHostDataPath is empty", errorMsg: "CommandInitOption.Validate() does not return err when EtcdHostDataPath is empty",
@ -96,6 +99,7 @@ func TestCommandInitOption_Validate(t *testing.T) {
EtcdStorageMode: etcdStorageModeHostPath, EtcdStorageMode: etcdStorageModeHostPath,
EtcdHostDataPath: "/data", EtcdHostDataPath: "/data",
EtcdNodeSelectorLabels: "key", EtcdNodeSelectorLabels: "key",
ImagePullPolicy: string(corev1.PullIfNotPresent),
}, },
wantErr: true, wantErr: true,
errorMsg: "CommandInitOption.Validate() does not return err when EtcdNodeSelectorLabels is %v", errorMsg: "CommandInitOption.Validate() does not return err when EtcdNodeSelectorLabels is %v",
@ -108,6 +112,7 @@ func TestCommandInitOption_Validate(t *testing.T) {
EtcdHostDataPath: "/data", EtcdHostDataPath: "/data",
EtcdNodeSelectorLabels: "key=value", EtcdNodeSelectorLabels: "key=value",
EtcdReplicas: 2, EtcdReplicas: 2,
ImagePullPolicy: string(corev1.PullIfNotPresent),
}, },
wantErr: true, wantErr: true,
errorMsg: "CommandInitOption.Validate() does not return err when EtcdReplicas is %v", errorMsg: "CommandInitOption.Validate() does not return err when EtcdReplicas is %v",
@ -121,6 +126,7 @@ func TestCommandInitOption_Validate(t *testing.T) {
EtcdNodeSelectorLabels: "key=value", EtcdNodeSelectorLabels: "key=value",
EtcdReplicas: 1, EtcdReplicas: 1,
StorageClassesName: "", StorageClassesName: "",
ImagePullPolicy: string(corev1.PullIfNotPresent),
}, },
wantErr: true, wantErr: true,
errorMsg: "CommandInitOption.Validate() does not return err when StorageClassesName is empty", errorMsg: "CommandInitOption.Validate() does not return err when StorageClassesName is empty",
@ -130,6 +136,7 @@ func TestCommandInitOption_Validate(t *testing.T) {
opt: CommandInitOption{ opt: CommandInitOption{
KarmadaAPIServerAdvertiseAddress: "192.0.2.1", KarmadaAPIServerAdvertiseAddress: "192.0.2.1",
EtcdStorageMode: "unknown", EtcdStorageMode: "unknown",
ImagePullPolicy: string(corev1.PullIfNotPresent),
}, },
wantErr: true, wantErr: true,
errorMsg: "CommandInitOption.Validate() does not return err when EtcdStorageMode is unknown", errorMsg: "CommandInitOption.Validate() does not return err when EtcdStorageMode is unknown",
@ -139,6 +146,7 @@ func TestCommandInitOption_Validate(t *testing.T) {
opt: CommandInitOption{ opt: CommandInitOption{
KarmadaAPIServerAdvertiseAddress: "192.0.2.1", KarmadaAPIServerAdvertiseAddress: "192.0.2.1",
EtcdStorageMode: etcdStorageModeEmptyDir, EtcdStorageMode: etcdStorageModeEmptyDir,
ImagePullPolicy: string(corev1.PullIfNotPresent),
}, },
wantErr: false, wantErr: false,
errorMsg: "CommandInitOption.Validate() returns err when EtcdStorageMode is emptyDir", errorMsg: "CommandInitOption.Validate() returns err when EtcdStorageMode is emptyDir",
@ -148,16 +156,27 @@ func TestCommandInitOption_Validate(t *testing.T) {
opt: CommandInitOption{ opt: CommandInitOption{
KarmadaAPIServerAdvertiseAddress: "192.0.2.1", KarmadaAPIServerAdvertiseAddress: "192.0.2.1",
EtcdStorageMode: "", EtcdStorageMode: "",
ImagePullPolicy: string(corev1.PullIfNotPresent),
}, },
wantErr: false, wantErr: false,
errorMsg: "CommandInitOption.Validate() returns err when EtcdStorageMode is empty", errorMsg: "CommandInitOption.Validate() returns err when EtcdStorageMode is empty",
}, },
{
name: "Invalid ImagePullPolicy",
opt: CommandInitOption{
KarmadaAPIServerAdvertiseAddress: "192.0.2.1",
EtcdStorageMode: "",
ImagePullPolicy: "NotExistImagePullPolicy",
},
wantErr: true,
errorMsg: "CommandInitOption.Validate() returns err when invalid ImagePullPolicy",
},
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
if err := tt.opt.Validate("parentCommand"); (err != nil) != tt.wantErr { if err := tt.opt.Validate("parentCommand"); (err != nil) != tt.wantErr {
t.Errorf(tt.errorMsg) t.Errorf("%s err = %v, want %v", tt.name, err.Error(), tt.errorMsg)
} }
}) })
} }

View File

@ -446,6 +446,7 @@ func (i *CommandInitOption) makeKarmadaSchedulerDeployment() *appsv1.Deployment
{ {
Name: schedulerDeploymentNameAndServiceAccountName, Name: schedulerDeploymentNameAndServiceAccountName,
Image: i.karmadaSchedulerImage(), Image: i.karmadaSchedulerImage(),
ImagePullPolicy: corev1.PullPolicy(i.ImagePullPolicy),
Command: []string{ Command: []string{
"/bin/karmada-scheduler", "/bin/karmada-scheduler",
"--kubeconfig=/etc/kubeconfig", "--kubeconfig=/etc/kubeconfig",
@ -561,6 +562,7 @@ func (i *CommandInitOption) makeKarmadaControllerManagerDeployment() *appsv1.Dep
{ {
Name: controllerManagerDeploymentAndServiceName, Name: controllerManagerDeploymentAndServiceName,
Image: i.karmadaControllerManagerImage(), Image: i.karmadaControllerManagerImage(),
ImagePullPolicy: corev1.PullPolicy(i.ImagePullPolicy),
Command: []string{ Command: []string{
"/bin/karmada-controller-manager", "/bin/karmada-controller-manager",
"--kubeconfig=/etc/kubeconfig", "--kubeconfig=/etc/kubeconfig",
@ -679,6 +681,7 @@ func (i *CommandInitOption) makeKarmadaWebhookDeployment() *appsv1.Deployment {
{ {
Name: webhookDeploymentAndServiceAccountAndServiceName, Name: webhookDeploymentAndServiceAccountAndServiceName,
Image: i.karmadaWebhookImage(), Image: i.karmadaWebhookImage(),
ImagePullPolicy: corev1.PullPolicy(i.ImagePullPolicy),
Command: []string{ Command: []string{
"/bin/karmada-webhook", "/bin/karmada-webhook",
"--kubeconfig=/etc/kubeconfig", "--kubeconfig=/etc/kubeconfig",
@ -849,6 +852,7 @@ func (i *CommandInitOption) makeKarmadaAggregatedAPIServerDeployment() *appsv1.D
{ {
Name: karmadaAggregatedAPIServerDeploymentAndServiceName, Name: karmadaAggregatedAPIServerDeploymentAndServiceName,
Image: i.karmadaAggregatedAPIServerImage(), Image: i.karmadaAggregatedAPIServerImage(),
ImagePullPolicy: corev1.PullPolicy(i.ImagePullPolicy),
Command: command, Command: command,
VolumeMounts: []corev1.VolumeMount{ VolumeMounts: []corev1.VolumeMount{
{ {