From 1fcfbe33b265bb5a2a2b48971d268a09d4de752b Mon Sep 17 00:00:00 2001 From: syedowais312 Date: Thu, 10 Sep 2026 17:31:30 +0530 Subject: [PATCH] fix: remove stale instance entry on recreate Signed-off-by: syedowais312 --- cmd/start.go | 3 +- cmd/stop.go | 12 +++++- pkg/config/config_test.go | 2 +- pkg/config/localconfig.go | 6 +-- pkg/config/localconfig_test.go | 71 ++++++++++++++++++++++++++++++++++ 5 files changed, 88 insertions(+), 6 deletions(-) create mode 100644 pkg/config/localconfig_test.go diff --git a/cmd/start.go b/cmd/start.go index ee5bf71..ad5250b 100644 --- a/cmd/start.go +++ b/cmd/start.go @@ -99,8 +99,9 @@ microcks start --name [name of you container/instance]`, if _, err := fmt.Fprintf(progress, "Container for instance %s no longer exists, recreating it\n", name); err != nil { return errors.Wrap(errors.KindEnvironment, err) } + + localConfig.RemoveInstance(instance.ContainerID) instance.Status = "" - instance.ContainerID = "" } } diff --git a/cmd/stop.go b/cmd/stop.go index 1a01325..279a109 100644 --- a/cmd/stop.go +++ b/cmd/stop.go @@ -62,6 +62,16 @@ func NewStopCommand(globalClientOpts *connectors.ClientOptions) *cobra.Command { } defer containerClient.CloseClient() + exists, err := containerClient.ContainerExists(instance.ContainerID) + if err != nil { + return errors.Wrap(errors.KindEnvironment, err) + } + if !exists { + fmt.Printf("Container for instance %s no longer exists\n", instance.Name) + fmt.Printf("Run 'microcks start --name %s' to bring the container back\n", instance.Name) + return nil + } + if err := containerClient.StopContainer(instance.ContainerID); err != nil { return errors.Wrap(errors.KindEnvironment, fmt.Errorf("failed to stop container: %w", err)) } @@ -78,7 +88,7 @@ func NewStopCommand(globalClientOpts *connectors.ClientOptions) *cobra.Command { localConfig.RemoveServer(ctx.Server.Server) localConfig.RemoveUser(ctx.User.Name) localConfig.RemoveAuth(ctx.Server.Server) - localConfig.RemoveInstance(instance.Name) + localConfig.RemoveInstance(instance.ContainerID) localConfig.CurrentContext = "" log.Printf("Instance %s removed successfully", instance.Name) diff --git a/pkg/config/config_test.go b/pkg/config/config_test.go index d15a272..bc61cfb 100644 --- a/pkg/config/config_test.go +++ b/pkg/config/config_test.go @@ -369,7 +369,7 @@ func TestLocalConfigCRUDAndValidation(t *testing.T) { assert.NoError(t, err) assert.Equal(t, "cont456", inst2Updated.ContainerID) - ok = loadedCfg.RemoveInstance("inst2-updated") + ok = loadedCfg.RemoveInstance("cont456") assert.True(t, ok) ok = loadedCfg.RemoveInstance("") diff --git a/pkg/config/localconfig.go b/pkg/config/localconfig.go index b930704..b0e7fe9 100644 --- a/pkg/config/localconfig.go +++ b/pkg/config/localconfig.go @@ -337,12 +337,12 @@ func (l *LocalConfig) UpsertInstance(instance Instance) { } // Returns true if server was removed successfully -func (l *LocalConfig) RemoveInstance(instanceName string) bool { - if instanceName == "" { +func (l *LocalConfig) RemoveInstance(instanceID string) bool { + if instanceID == "" { return true } for a, i := range l.Instances { - if i.Name == instanceName { + if i.ContainerID == instanceID { l.Instances = append(l.Instances[:a], l.Instances[a+1:]...) return true } diff --git a/pkg/config/localconfig_test.go b/pkg/config/localconfig_test.go new file mode 100644 index 0000000..420432b --- /dev/null +++ b/pkg/config/localconfig_test.go @@ -0,0 +1,71 @@ +/* + * Copyright The Microcks Authors. + * + * 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 config + +import ( + "testing" +) + +func TestRemoveInstance_ByContainerID(t *testing.T) { + localConfig := &LocalConfig{ + Instances: []Instance{ + {Name: "microcks", ContainerID: "old-id-123", Status: "Running", Port: "8585"}, + {Name: "staging", ContainerID: "staging-id-456", Status: "Running", Port: "8586"}, + }, + } + + removed := localConfig.RemoveInstance("old-id-123") + + if !removed { + t.Error("expected RemoveInstance to return true") + } + // staging should still be there + if len(localConfig.Instances) != 1 { + t.Errorf("expected 1 instance remaining, got %d", len(localConfig.Instances)) + } + if localConfig.Instances[0].ContainerID != "staging-id-456" { + t.Errorf("expected staging instance to remain, got %s", localConfig.Instances[0].ContainerID) + } +} + +func TestRemoveInstance_NoDuplicatesAfterRecreate(t *testing.T) { + localConfig := &LocalConfig{ + Instances: []Instance{ + {Name: "microcks", ContainerID: "old-id-123", Status: "Running", Port: "8585"}, + {Name: "staging", ContainerID: "staging-id-456", Status: "Running", Port: "8586"}, + }, + } + + localConfig.RemoveInstance("old-id-123") + + localConfig.UpsertInstance(Instance{ + Name: "microcks", + ContainerID: "new-id-789", + Status: "Running", + Port: "8585", + }) + + // staging + recreated microcks = 2, no duplicates + if len(localConfig.Instances) != 2 { + t.Errorf("expected 2 instances, got %d — duplicate entries present", len(localConfig.Instances)) + } + // verify microcks has new ID + for _, i := range localConfig.Instances { + if i.Name == "microcks" && i.ContainerID != "new-id-789" { + t.Errorf("expected new-id-789, got %s", i.ContainerID) + } + } +}