Skip to content

Commit 2f632bb

Browse files
authored
fix(BRE2-877): fix ls --all (#340)
1 parent ec04f83 commit 2f632bb

2 files changed

Lines changed: 226 additions & 84 deletions

File tree

pkg/cmd/ls/ls.go

Lines changed: 69 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ with other commands like stop, start, or delete.`,
137137
fmt.Print(breverrors.WrapAndTrace(err))
138138
}
139139

140-
cmd.Flags().BoolVar(&showAll, "all", false, "show all workspaces in org")
140+
cmd.Flags().BoolVar(&showAll, "all", false, "show all instances and external nodes in org")
141141
cmd.Flags().BoolVar(&jsonOutput, "json", false, "output as JSON")
142142

143143
return cmd
@@ -452,9 +452,13 @@ func (ls Ls) RunWorkspaces(org *entity.Organization, user *entity.User, showAll
452452
var allWorkspaces []entity.Workspace
453453
var wsErr error
454454
var gpuLookup map[string]string
455+
var nodes []*nodev1.ExternalNode
455456

456457
var wg sync.WaitGroup
457458
wg.Add(2)
459+
if showAll {
460+
wg.Add(1)
461+
}
458462
go func() {
459463
defer wg.Done()
460464
allWorkspaces, wsErr = ls.lsStore.GetWorkspaces(org.ID, nil)
@@ -463,6 +467,18 @@ func (ls Ls) RunWorkspaces(org *entity.Organization, user *entity.User, showAll
463467
defer wg.Done()
464468
gpuLookup = buildGPULookup(ls.lsStore)
465469
}()
470+
if showAll {
471+
go func() {
472+
defer wg.Done()
473+
var err error
474+
nodes, err = ls.listNodes(org)
475+
if err != nil {
476+
if featureflag.Debug() {
477+
_, _ = fmt.Fprintf(os.Stderr, "debug: failed to list external nodes: %v\n", err)
478+
}
479+
}
480+
}()
481+
}
466482
wg.Wait()
467483

468484
if wsErr != nil {
@@ -479,7 +495,7 @@ func (ls Ls) RunWorkspaces(org *entity.Organization, user *entity.User, showAll
479495

480496
// Handle JSON output
481497
if ls.jsonOutput {
482-
return ls.outputWorkspacesJSON(workspacesToShow, gpuLookup)
498+
return ls.outputWorkspacesJSON(workspacesToShow, gpuLookup, nodes)
483499
}
484500

485501
// Table output with colors and help text
@@ -489,6 +505,10 @@ func (ls Ls) RunWorkspaces(org *entity.Organization, user *entity.User, showAll
489505
}
490506
if showAll {
491507
ls.ShowAllWorkspaces(org, orgs, user, allWorkspaces, gpuLookup)
508+
if len(nodes) > 0 {
509+
ls.terminal.Vprintf("\nYou have %d external node(s) in Org %s\n", len(nodes), ls.terminal.Yellow(org.Name))
510+
displayNodesTable(ls.terminal, nodes, ls.piped)
511+
}
492512
} else {
493513
ls.ShowUserWorkspaces(org, orgs, user, allWorkspaces, gpuLookup)
494514
}
@@ -545,11 +565,23 @@ func getInstanceTypeAndKind(w entity.Workspace, gpuLookup map[string]string) (st
545565
return "", ""
546566
}
547567

548-
func (ls Ls) outputWorkspacesJSON(workspaces []entity.Workspace, gpuLookup map[string]string) error {
549-
var infos []WorkspaceInfo
568+
func toNodeInfos(nodes []*nodev1.ExternalNode) []NodeInfo {
569+
var infos []NodeInfo
570+
for _, n := range nodes {
571+
infos = append(infos, NodeInfo{
572+
Name: n.GetName(),
573+
OrgID: n.GetOrganizationId(),
574+
Status: nodeConnectionStatus(n),
575+
})
576+
}
577+
return infos
578+
}
579+
580+
func (ls Ls) outputWorkspacesJSON(workspaces []entity.Workspace, gpuLookup map[string]string, nodes []*nodev1.ExternalNode) error {
581+
var wsInfos []WorkspaceInfo
550582
for _, w := range workspaces {
551583
instanceType, instanceKind := getInstanceTypeAndKind(w, gpuLookup)
552-
infos = append(infos, WorkspaceInfo{
584+
wsInfos = append(wsInfos, WorkspaceInfo{
553585
Name: w.Name,
554586
ID: w.ID,
555587
Status: getWorkspaceDisplayStatus(w),
@@ -561,7 +593,25 @@ func (ls Ls) outputWorkspacesJSON(workspaces []entity.Workspace, gpuLookup map[s
561593
GPU: getGPUForInstance(w, gpuLookup),
562594
})
563595
}
564-
output, err := json.MarshalIndent(infos, "", " ")
596+
597+
var result any
598+
if nodes != nil {
599+
result = struct {
600+
Workspaces []WorkspaceInfo `json:"workspaces"`
601+
Nodes []NodeInfo `json:"nodes"`
602+
}{
603+
Workspaces: wsInfos,
604+
Nodes: toNodeInfos(nodes),
605+
}
606+
} else {
607+
result = struct {
608+
Workspaces []WorkspaceInfo `json:"workspaces"`
609+
}{
610+
Workspaces: wsInfos,
611+
}
612+
}
613+
614+
output, err := json.MarshalIndent(result, "", " ")
565615
if err != nil {
566616
return breverrors.WrapAndTrace(err)
567617
}
@@ -727,10 +777,9 @@ func getStatusColoredText(t *terminal.Terminal, status string) string {
727777

728778
// NodeInfo represents external node data for JSON output.
729779
type NodeInfo struct {
730-
Name string `json:"name"`
731-
ExternalNodeID string `json:"external_node_id"`
732-
OrgID string `json:"org_id"`
733-
Status string `json:"status"`
780+
Name string `json:"name"`
781+
OrgID string `json:"org_id"`
782+
Status string `json:"status"`
734783
}
735784

736785
func (ls Ls) listNodes(org *entity.Organization) ([]*nodev1.ExternalNode, error) {
@@ -766,53 +815,33 @@ func (ls Ls) RunNodes(org *entity.Organization) error {
766815
if ls.jsonOutput {
767816
return ls.outputNodesJSON(nodes)
768817
}
769-
if ls.piped {
770-
displayNodesTablePlain(nodes)
771-
return nil
818+
if !ls.piped {
819+
ls.terminal.Vprintf("\nYou have %d external node(s) in Org %s\n", len(nodes), ls.terminal.Yellow(org.Name))
772820
}
773-
774-
ls.terminal.Vprintf("\nYou have %d external node(s) in Org %s\n", len(nodes), ls.terminal.Yellow(org.Name))
775-
displayNodesTable(ls.terminal, nodes)
821+
displayNodesTable(ls.terminal, nodes, ls.piped)
776822
return nil
777823
}
778824

779825
func (ls Ls) outputNodesJSON(nodes []*nodev1.ExternalNode) error {
780-
var infos []NodeInfo
781-
for _, n := range nodes {
782-
infos = append(infos, NodeInfo{
783-
Name: n.GetName(),
784-
ExternalNodeID: n.GetExternalNodeId(),
785-
OrgID: n.GetOrganizationId(),
786-
Status: nodeConnectionStatus(n),
787-
})
788-
}
789-
output, err := json.MarshalIndent(infos, "", " ")
826+
output, err := json.MarshalIndent(toNodeInfos(nodes), "", " ")
790827
if err != nil {
791828
return breverrors.WrapAndTrace(err)
792829
}
793830
fmt.Println(string(output))
794831
return nil
795832
}
796833

797-
func displayNodesTable(t *terminal.Terminal, nodes []*nodev1.ExternalNode) {
834+
func displayNodesTable(t *terminal.Terminal, nodes []*nodev1.ExternalNode, isPiped bool) {
798835
ta := table.NewWriter()
799836
ta.SetOutputMirror(os.Stdout)
800837
ta.Style().Options = getBrevTableOptions()
801-
ta.AppendHeader(table.Row{"NAME", "NODE ID", "DEVICE ID", "STATUS"})
838+
ta.AppendHeader(table.Row{"NAME", "STATUS"})
802839
for _, n := range nodes {
803840
status := nodeConnectionStatus(n)
804-
ta.AppendRows([]table.Row{{n.GetName(), n.GetExternalNodeId(), n.GetDeviceId(), getStatusColoredText(t, status)}})
805-
}
806-
ta.Render()
807-
}
808-
809-
func displayNodesTablePlain(nodes []*nodev1.ExternalNode) {
810-
ta := table.NewWriter()
811-
ta.SetOutputMirror(os.Stdout)
812-
ta.Style().Options = getBrevTableOptions()
813-
ta.AppendHeader(table.Row{"NAME", "NODE ID", "DEVICE ID", "STATUS"})
814-
for _, n := range nodes {
815-
ta.AppendRows([]table.Row{{n.GetName(), n.GetExternalNodeId(), n.GetDeviceId(), nodeConnectionStatus(n)}})
841+
if !isPiped {
842+
status = getStatusColoredText(t, status)
843+
}
844+
ta.AppendRows([]table.Row{{n.GetName(), status}})
816845
}
817846
ta.Render()
818847
}

0 commit comments

Comments
 (0)