Skip to content

Commit d974188

Browse files
authored
Merge pull request #10119 from daehyeok/profile_name
Don't allow profile names that conflict with a multi-node name
2 parents 0509fd8 + a00d632 commit d974188

File tree

5 files changed

+97
-5
lines changed

5 files changed

+97
-5
lines changed

cmd/minikube/cmd/start.go

+21
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,8 @@ func runStart(cmd *cobra.Command, args []string) {
176176

177177
if existing != nil {
178178
upgradeExistingConfig(existing)
179+
} else {
180+
validateProfileName()
179181
}
180182

181183
validateSpecifiedDriver(existing)
@@ -638,6 +640,25 @@ func hostDriver(existing *config.ClusterConfig) string {
638640
return h.Driver.DriverName()
639641
}
640642

643+
// validateProfileName makes sure that new profile name not duplicated with any of machine names in existing multi-node clusters.
644+
func validateProfileName() {
645+
profiles, err := config.ListValidProfiles()
646+
if err != nil {
647+
exit.Message(reason.InternalListConfig, "Unable to list profiles: {{.error}}", out.V{"error": err})
648+
}
649+
for _, p := range profiles {
650+
for _, n := range p.Config.Nodes {
651+
machineName := config.MachineName(*p.Config, n)
652+
if ClusterFlagValue() == machineName {
653+
out.WarningT("Profile name '{{.name}}' is duplicated with machine name '{{.machine}}' in profile '{{.profile}}'", out.V{"name": ClusterFlagValue(),
654+
"machine": machineName,
655+
"profile": p.Name})
656+
exit.Message(reason.Usage, "Profile name should be unique")
657+
}
658+
}
659+
}
660+
}
661+
641662
// validateSpecifiedDriver makes sure that if a user has passed in a driver
642663
// it matches the existing cluster if there is one
643664
func validateSpecifiedDriver(existing *config.ClusterConfig) {

pkg/minikube/config/profile.go

+20-2
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,25 @@ func ListProfiles(miniHome ...string) (validPs []*Profile, inValidPs []*Profile,
223223
return validPs, inValidPs, nil
224224
}
225225

226-
// removeDupes removes duplicates
226+
// ListValidProfiles returns profiles in minikube home dir
227+
// Unlike `ListProfiles` this function doens't try to get profile from container
228+
func ListValidProfiles(miniHome ...string) (ps []*Profile, err error) {
229+
// try to get profiles list based on left over evidences such as directory
230+
pDirs, err := profileDirs(miniHome...)
231+
if err != nil {
232+
return nil, err
233+
}
234+
235+
for _, n := range pDirs {
236+
p, err := LoadProfile(n, miniHome...)
237+
if err == nil && p.IsValid() {
238+
ps = append(ps, p)
239+
}
240+
}
241+
return ps, nil
242+
}
243+
244+
// removeDupes removes duplipcates
227245
func removeDupes(profiles []string) []string {
228246
// Use map to record duplicates as we find them.
229247
seen := map[string]bool{}
@@ -291,7 +309,7 @@ func ProfileFolderPath(profile string, miniHome ...string) string {
291309
// MachineName returns the name of the machine, as seen by the hypervisor given the cluster and node names
292310
func MachineName(cc ClusterConfig, n Node) string {
293311
// For single node cluster, default to back to old naming
294-
if len(cc.Nodes) == 1 || n.ControlPlane {
312+
if (len(cc.Nodes) == 1 && cc.Nodes[0].Name == n.Name) || n.ControlPlane {
295313
return cc.Name
296314
}
297315
return fmt.Sprintf("%s-%s", cc.Name, n.Name)

pkg/minikube/machine/cluster_test.go

+1-3
Original file line numberDiff line numberDiff line change
@@ -146,10 +146,8 @@ func TestStartHostExists(t *testing.T) {
146146
mc := defaultClusterConfig
147147
mc.Name = ih.Name
148148

149-
n := config.Node{Name: ih.Name}
150-
151149
// This should pass without calling Create because the host exists already.
152-
h, _, err := StartHost(api, &mc, &n)
150+
h, _, err := StartHost(api, &mc, &(mc.Nodes[0]))
153151
if err != nil {
154152
t.Fatalf("Error starting host: %v", err)
155153
}

pkg/minikube/node/node.go

+18
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,24 @@ const (
3838

3939
// Add adds a new node config to an existing cluster.
4040
func Add(cc *config.ClusterConfig, n config.Node, delOnFail bool) error {
41+
profiles, err := config.ListValidProfiles()
42+
if err != nil {
43+
return err
44+
}
45+
46+
machineName := config.MachineName(*cc, n)
47+
for _, p := range profiles {
48+
if p.Config.Name == cc.Name {
49+
continue
50+
}
51+
52+
for _, existNode := range p.Config.Nodes {
53+
if machineName == config.MachineName(*p.Config, existNode) {
54+
return errors.Errorf("Node %s already exists in %s profile", machineName, p.Name)
55+
}
56+
}
57+
}
58+
4159
if err := config.SaveNode(cc, &n); err != nil {
4260
return errors.Wrap(err, "save node")
4361
}

test/integration/multinode_test.go

+37
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ func TestMultiNode(t *testing.T) {
4848
{"DeleteNode", validateDeleteNodeFromMultiNode},
4949
{"StopMultiNode", validateStopMultiNodeCluster},
5050
{"RestartMultiNode", validateRestartMultiNodeCluster},
51+
{"ValidateNameConflict", validatNameConflict},
5152
}
5253
for _, tc := range tests {
5354
tc := tc
@@ -308,3 +309,39 @@ func validateDeleteNodeFromMultiNode(ctx context.Context, t *testing.T, profile
308309
t.Errorf("expected 2 nodes Ready status to be True, got %v", rr.Output())
309310
}
310311
}
312+
313+
func validatNameConflict(ctx context.Context, t *testing.T, profile string) {
314+
rr, err := Run(t, exec.CommandContext(ctx, Target(), "node", "list", "-p", profile))
315+
if err != nil {
316+
t.Errorf("failed to run node list. args %q : %v", rr.Command(), err)
317+
}
318+
curNodeNum := strings.Count(rr.Stdout.String(), profile)
319+
320+
// Start new profile. It's expected failture
321+
profileName := fmt.Sprintf("%s-m0%d", profile, curNodeNum)
322+
startArgs := append([]string{"start", "-p", profileName}, StartArgs()...)
323+
rr, err = Run(t, exec.CommandContext(ctx, Target(), startArgs...))
324+
if err == nil {
325+
t.Errorf("expected start profile command to fail. args %q", rr.Command())
326+
}
327+
328+
// Start new profile temporary profile to conflict node name.
329+
profileName = fmt.Sprintf("%s-m0%d", profile, curNodeNum+1)
330+
startArgs = append([]string{"start", "-p", profileName}, StartArgs()...)
331+
rr, err = Run(t, exec.CommandContext(ctx, Target(), startArgs...))
332+
if err != nil {
333+
t.Errorf("failed to start profile. args %q : %v", rr.Command(), err)
334+
}
335+
336+
// Add a node to the current cluster. It's expected failture
337+
addArgs := []string{"node", "add", "-p", profile}
338+
rr, err = Run(t, exec.CommandContext(ctx, Target(), addArgs...))
339+
if err == nil {
340+
t.Errorf("expected add node command to fail. args %q : %v", rr.Command(), err)
341+
}
342+
343+
rr, err = Run(t, exec.CommandContext(ctx, Target(), "delete", "-p", profileName))
344+
if err != nil {
345+
t.Logf("failed to clean temporary profile. args %q : %v", rr.Command(), err)
346+
}
347+
}

0 commit comments

Comments
 (0)