diff --git a/cmd/start.go b/cmd/start.go index 8044603..ba5831c 100644 --- a/cmd/start.go +++ b/cmd/start.go @@ -47,30 +47,34 @@ microcks start --name [name of you container/instance]`, instance = &config.Instance{} } - if instance.Status == "Running" { - fmt.Printf("Microcks instance with name %s is already running", name) - return - } + containerClient, err := connectors.NewContainerClient(driver) + errors.CheckError(err) + defer containerClient.CloseClient() - switch instance.Status { - case "Running": - fmt.Printf("Microcks instance with name %s is already running", name) - return - case "Exited": - containerClient, err := connectors.NewContainerClient(instance.Driver) - errors.CheckError(err) - defer containerClient.CloseClient() + daemonID, daemonStatus, err := containerClient.GetContainer(name) + if err != nil { + log.Fatalf("failed to inspect container: %v", err) + } - if err := containerClient.StartContainer(instance.ContainerID); err != nil { - log.Fatalf("failed to start container: %v", err) + if daemonID != "" { + if daemonStatus == "running" { + fmt.Printf("Microcks instance with name %s is already running\n", name) return } + if err := containerClient.StartContainer(daemonID); err != nil { + log.Fatalf("failed to start container: %v", err) + } + instance.ContainerID = daemonID + instance.Name = name + if instance.Port == "" { + instance.Port = hostPort + } + if instance.Image == "" { + instance.Image = imageName + } + instance.Driver = driver instance.Status = "Running" - default: - containerClient, err := connectors.NewContainerClient(driver) - errors.CheckError(err) - defer containerClient.CloseClient() - + } else { containerId, err := containerClient.CreateContainer(connectors.ContainerOpts{ Image: imageName, Port: hostPort, @@ -79,12 +83,10 @@ microcks start --name [name of you container/instance]`, }) if err != nil { log.Fatalf("Failed to create a container: %v", err) - return } if err := containerClient.StartContainer(containerId); err != nil { log.Fatalf("failed to start container: %v", err) - return } instance.ContainerID = containerId diff --git a/cmd/stop.go b/cmd/stop.go index eaba91f..296974c 100644 --- a/cmd/stop.go +++ b/cmd/stop.go @@ -40,13 +40,24 @@ func NewStopCommand(globalClientOpts *connectors.ClientOptions) *cobra.Command { errors.CheckError(err) defer containerClient.CloseClient() - err = containerClient.StopContainer(instance.ContainerID) + daemonID, daemonStatus, err := containerClient.GetContainer(instance.Name) if err != nil { - log.Fatalf("Failed to stop a container: %v", err) - return + log.Fatalf("failed to inspect container: %v", err) + } + + if daemonID == "" { + fmt.Printf("Container %s not found in daemon; cleaning up config.\n", instance.Name) + } else if daemonStatus != "running" && daemonStatus != "restarting" && daemonStatus != "paused" { + fmt.Printf("Microcks instance %s is already stopped (status: %s)\n", instance.Name, daemonStatus) + } else { + err = containerClient.StopContainer(daemonID) + if err != nil { + log.Fatalf("Failed to stop a container: %v", err) + return + } + fmt.Println("") + log.Printf("Instance %s stopped successfully", instance.Name) } - fmt.Println("") - log.Printf("Instance %s stopped successfully", instance.Name) // update configs @@ -64,9 +75,11 @@ func NewStopCommand(globalClientOpts *connectors.ClientOptions) *cobra.Command { localConfig.CurrentContext = "" log.Printf("Instance %s removed successfully", instance.Name) } else { - instance.Status = "Exited" - localConfig.UpsertInstance(instance) - log.Printf("Instance %s status updated to Exited", instance.Name) + if instance.Status != "Exited" { + instance.Status = "Exited" + localConfig.UpsertInstance(instance) + log.Printf("Instance %s status updated to Exited", instance.Name) + } } err = config.WriteLocalConfig(*localConfig, configFile) errors.CheckError(err) diff --git a/go.mod b/go.mod index ffb58d3..06f0b3b 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module github.com/microcks/microcks-cli go 1.25.0 require ( + github.com/containerd/errdefs v1.0.0 github.com/coreos/go-oidc/v3 v3.15.0 github.com/docker/docker v28.5.1+incompatible github.com/docker/go-connections v0.6.0 @@ -18,7 +19,6 @@ require ( require ( github.com/Microsoft/go-winio v0.4.21 // indirect - github.com/containerd/errdefs v1.0.0 // indirect github.com/containerd/errdefs/pkg v0.3.0 // indirect github.com/containerd/log v0.1.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect diff --git a/microcks b/microcks new file mode 100755 index 0000000..deb52e9 Binary files /dev/null and b/microcks differ diff --git a/pkg/config/localconfig.go b/pkg/config/localconfig.go index 1e5eeda..2b85ddc 100644 --- a/pkg/config/localconfig.go +++ b/pkg/config/localconfig.go @@ -312,7 +312,7 @@ func (l *LocalConfig) GetInstance(name string) (*Instance, error) { func (l *LocalConfig) UpsertInstance(instance Instance) { for a, i := range l.Instances { - if i.ContainerID == instance.ContainerID { + if i.Name == instance.Name { l.Instances[a] = instance return } diff --git a/pkg/connectors/container_client.go b/pkg/connectors/container_client.go index 84f5472..a74c7de 100644 --- a/pkg/connectors/container_client.go +++ b/pkg/connectors/container_client.go @@ -9,6 +9,7 @@ import ( "runtime" "strings" + "github.com/containerd/errdefs" "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/image" "github.com/docker/docker/client" @@ -20,6 +21,7 @@ type ContainerClient interface { CreateContainer(opts ContainerOpts) (string, error) StartContainer(containerId string) error StopContainer(continerId string) error + GetContainer(name string) (string, string, error) CloseClient() error } @@ -145,6 +147,18 @@ func (cli *containerClient) StopContainer(containerId string) error { return cli.cli.ContainerStop(ctx, containerId, container.StopOptions{Timeout: &noWaitTimeout}) } +func (cli *containerClient) GetContainer(name string) (string, string, error) { + ctx := context.Background() + c, err := cli.cli.ContainerInspect(ctx, name) + if err != nil { + if errdefs.IsNotFound(err) { + return "", "", nil + } + return "", "", err + } + return c.ID, c.State.Status, nil +} + func (cli *containerClient) CloseClient() error { return cli.cli.Close() }