From a529418a09bd605ab481c2e0947b47f178387d5c Mon Sep 17 00:00:00 2001 From: caesarsage Date: Thu, 11 Jun 2026 05:07:55 +0100 Subject: [PATCH] fix(start): reconcile instance status against container runtime before trusting it Signed-off-by: caesarsage --- cmd/start.go | 21 ++++++++++++++++++--- pkg/connectors/container_client.go | 16 ++++++++++++++++ 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/cmd/start.go b/cmd/start.go index 828acc1b..b560bc33 100644 --- a/cmd/start.go +++ b/cmd/start.go @@ -47,9 +47,24 @@ 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 + // The recorded status can drift from reality: a system restart, + // autoRemove or a manual `docker rm` removes the container while + // the config still says Running/Exited. Reconcile before trusting it. + if instance.Status != "" && instance.ContainerID != "" { + instanceDriver := instance.Driver + if instanceDriver == "" { + instanceDriver = driver + } + containerClient, err := connectors.NewContainerClient(instanceDriver) + errors.CheckError(err) + exists, err := containerClient.ContainerExists(instance.ContainerID) + containerClient.CloseClient() + errors.CheckError(err) + if !exists { + fmt.Printf("Container for instance %s no longer exists, recreating it\n", name) + instance.Status = "" + instance.ContainerID = "" + } } switch instance.Status { diff --git a/pkg/connectors/container_client.go b/pkg/connectors/container_client.go index 05a08da6..0201c20f 100644 --- a/pkg/connectors/container_client.go +++ b/pkg/connectors/container_client.go @@ -21,6 +21,7 @@ type ContainerClient interface { CreateContainer(opts ContainerOpts) (string, error) StartContainer(containerId string) error StopContainer(continerId string) error + ContainerExists(containerId string) (bool, error) CloseClient() error } @@ -157,6 +158,21 @@ func (cli *containerClient) StopContainer(containerId string) error { return cli.cli.ContainerStop(ctx, containerId, container.StopOptions{Timeout: &noWaitTimeout}) } +// ContainerExists reports whether the container is still known to the +// runtime. "No such container" is a regular outcome here, not an error, +// so callers can reconcile stale config entries. +func (cli *containerClient) ContainerExists(containerId string) (bool, error) { + ctx := context.Background() + _, err := cli.cli.ContainerInspect(ctx, containerId) + if err != nil { + if client.IsErrNotFound(err) { + return false, nil + } + return false, err + } + return true, nil +} + func (cli *containerClient) CloseClient() error { return cli.cli.Close() }