github.com/turbot/steampipe@v1.7.0-rc.0.0.20240517123944-7cef272d4458/pkg/dashboard/dashboardexecute/container_run.go (about) 1 package dashboardexecute 2 3 import ( 4 "context" 5 "fmt" 6 "log" 7 8 "github.com/turbot/steampipe/pkg/dashboard/dashboardtypes" 9 "github.com/turbot/steampipe/pkg/steampipeconfig/modconfig" 10 ) 11 12 // DashboardContainerRun is a struct representing a container run 13 type DashboardContainerRun struct { 14 DashboardParentImpl 15 16 dashboardNode *modconfig.DashboardContainer 17 } 18 19 func (r *DashboardContainerRun) AsTreeNode() *dashboardtypes.SnapshotTreeNode { 20 res := &dashboardtypes.SnapshotTreeNode{ 21 Name: r.Name, 22 NodeType: r.NodeType, 23 Children: make([]*dashboardtypes.SnapshotTreeNode, len(r.children)), 24 } 25 for i, c := range r.children { 26 res.Children[i] = c.AsTreeNode() 27 } 28 return res 29 } 30 31 func NewDashboardContainerRun(container *modconfig.DashboardContainer, parent dashboardtypes.DashboardParent, executionTree *DashboardExecutionTree) (*DashboardContainerRun, error) { 32 children := container.GetChildren() 33 34 r := &DashboardContainerRun{dashboardNode: container} 35 // create NewDashboardTreeRunImpl 36 // (we must create after creating the run as it requires a ref to the run) 37 r.DashboardParentImpl = newDashboardParentImpl(container, parent, r, executionTree) 38 39 if container.Title != nil { 40 r.Title = *container.Title 41 } 42 43 if container.Width != nil { 44 r.Width = *container.Width 45 } 46 r.childCompleteChan = make(chan dashboardtypes.DashboardTreeRun, len(children)) 47 for _, child := range children { 48 var childRun dashboardtypes.DashboardTreeRun 49 //nolint:golint // using a global var here to maintain parity with definition of childRun 50 var err error 51 switch i := child.(type) { 52 case *modconfig.DashboardContainer: 53 childRun, err = NewDashboardContainerRun(i, r, executionTree) 54 if err != nil { 55 return nil, err 56 } 57 case *modconfig.Dashboard: 58 childRun, err = NewDashboardRun(i, r, executionTree) 59 if err != nil { 60 return nil, err 61 } 62 case *modconfig.Benchmark, *modconfig.Control: 63 childRun, err = NewCheckRun(i.(modconfig.DashboardLeafNode), r, executionTree) 64 if err != nil { 65 return nil, err 66 } 67 68 default: 69 // ensure this item is a DashboardLeafNode 70 leafNode, ok := i.(modconfig.DashboardLeafNode) 71 if !ok { 72 return nil, fmt.Errorf("child %s does not implement DashboardLeafNode", i.Name()) 73 } 74 75 childRun, err = NewLeafRun(leafNode, r, executionTree) 76 if err != nil { 77 return nil, err 78 } 79 } 80 81 // should never happen - container children must be either container or counter 82 if childRun == nil { 83 continue 84 } 85 86 // if our child has not completed, we have not completed 87 if childRun.GetRunStatus() == dashboardtypes.RunInitialized { 88 r.Status = dashboardtypes.RunInitialized 89 } 90 r.children = append(r.children, childRun) 91 } 92 // add r into execution tree 93 executionTree.runs[r.Name] = r 94 return r, nil 95 } 96 97 // Initialise implements DashboardTreeRun 98 func (r *DashboardContainerRun) Initialise(ctx context.Context) { 99 // initialise our children 100 if err := r.initialiseChildren(ctx); err != nil { 101 r.SetError(ctx, err) 102 } 103 } 104 105 // Execute implements DashboardTreeRun 106 // execute all children and wait for them to complete 107 func (r *DashboardContainerRun) Execute(ctx context.Context) { 108 // execute all children asynchronously 109 r.executeChildrenAsync(ctx) 110 111 // try to set status as running (will be set to blocked if any children are blocked) 112 r.setRunning(ctx) 113 114 // wait for children to complete 115 err := <-r.waitForChildrenAsync(ctx) 116 if err == nil { 117 log.Printf("[TRACE] %s Execute waitForChildrenAsync returned success", r.Name) 118 // set complete status on dashboard 119 r.SetComplete(ctx) 120 } else { 121 log.Printf("[TRACE] %s Execute waitForChildrenAsync returned err %s", r.Name, err.Error()) 122 r.SetError(ctx, err) 123 } 124 } 125 126 // IsSnapshotPanel implements SnapshotPanel 127 func (*DashboardContainerRun) IsSnapshotPanel() {}