From ed83288b73ea508a1363703452cbc53535691fee Mon Sep 17 00:00:00 2001 From: Jarred Wilson Date: Thu, 14 Nov 2024 00:46:54 +0000 Subject: [PATCH] fix:[#427] refuse to remove stack if in use - add check for stack in use before removing subsystem - add error message for in use stack in locales --- cmd/stacks.go | 17 +++++++++++++++++ core/subSystem.go | 41 +++++++++++++++++++++++++++++++++++++++++ locales/en.yml | 1 + 3 files changed, 59 insertions(+) diff --git a/cmd/stacks.go b/cmd/stacks.go index 313f991a..04412aca 100644 --- a/cmd/stacks.go +++ b/cmd/stacks.go @@ -488,6 +488,23 @@ func removeStack(cmd *cobra.Command, args []string) error { return nil } + subSystems, _ := core.ListSubsystemForStack(stackName) + if len(subSystems) > 0 { + cmdr.Error.Printfln(apx.Trans("stacks.rm.error.inUse"), len(subSystems)) + table := core.CreateApxTable(os.Stdout) + table.SetHeader([]string{apx.Trans("subsystems.labels.name"), "Stack", apx.Trans("subsystems.labels.status"), "Pkgs"}) + for _, subSystem := range subSystems { + table.Append([]string{ + subSystem.Name, + subSystem.Stack.Name, + subSystem.Status, + fmt.Sprintf("%d", len(subSystem.Stack.Packages)), + }) + } + table.Render() + return nil + } + force, _ := cmd.Flags().GetBool("force") if !force { diff --git a/core/subSystem.go b/core/subSystem.go index c07329db..1d7ffbc4 100644 --- a/core/subSystem.go +++ b/core/subSystem.go @@ -308,6 +308,47 @@ func ListSubSystems(includeManaged bool, includeRootFull bool) ([]*SubSystem, er return subsystems, nil } +// ListSubsystemForStack returns a list of subsystems for the specified stack. +func ListSubsystemForStack(stackName string) ([]*SubSystem, error) { + dbox, err := NewDbox() + if err != nil { + return nil, err + } + + containers, err := dbox.ListContainers(true) + if err != nil { + return nil, err + } + + subsystems := []*SubSystem{} + for _, container := range containers { + if _, ok := container.Labels["name"]; !ok { + continue + } + + stack, err := LoadStack(stackName) + if err != nil { + log.Printf("Error loading stack %s: %s", stackName, err) + continue + } + + internalName := genInternalName(container.Labels["name"]) + subsystem := &SubSystem{ + InternalName: internalName, + Name: container.Labels["name"], + Stack: stack, + Status: container.Status, + ExportedPrograms: findExported(internalName, container.Labels["name"]), + } + + if subsystem.Stack.Name == stack.Name { + subsystems = append(subsystems, subsystem) + } + } + + return subsystems, nil +} + func (s *SubSystem) Exec(captureOutput, detachedMode bool, args ...string) (string, error) { dbox, err := NewDbox() if err != nil { diff --git a/locales/en.yml b/locales/en.yml index a0e9a0e0..0f2aa5a3 100644 --- a/locales/en.yml +++ b/locales/en.yml @@ -295,6 +295,7 @@ stacks: description: "Remove the specified stack." error: noName: "No name specified." + inUse: "The stack is used in %d subsystems:" info: askConfirmation: "Are you sure you want to remove '%s'?" success: "Removed stack '%s'."