Skip to content

Commit

Permalink
Add support reload pipeline dashboard data automatically (#222)
Browse files Browse the repository at this point in the history
* Add support reload pipeline dashboard data automatically

* Fix the glint issues
  • Loading branch information
LinuxSuRen committed Oct 14, 2021
1 parent cc9090c commit 1767f34
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 28 deletions.
34 changes: 6 additions & 28 deletions kubectl-plugin/pipeline/dashboard.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import (
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/watch"
Expand All @@ -41,7 +40,7 @@ type dashboardOption struct {
header *ui.Header
footer *tview.Table
app *tview.Application
pipelineListView *tview.Table
pipelineListView *ui.ResourceTable
}

func newDashboardCmd() (cmd *cobra.Command) {
Expand Down Expand Up @@ -82,7 +81,6 @@ func (o *dashboardOption) runE(cmd *cobra.Command, args []string) (err error) {
}()
o.stack.Push(grid)
if err = o.app.
//SetRoot(grid, true).
Run(); err != nil {
panic(err)
}
Expand Down Expand Up @@ -125,10 +123,7 @@ func updateTable(table *tview.Table, name string, values ...string) {
}

func (o *dashboardOption) createPipelineList() (listView tview.Primitive) {
table := tview.NewTable()
table.SetBorder(true).SetTitle("pipelines")
table.SetSelectable(true, false).Select(1, 0).SetFixed(1, 0)
table.SetBorderPadding(0, 0, 1, 1)
table := ui.NewResourceTable(o.restClient, o.app)
o.pipelineListView = table
listView = table
table.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey {
Expand Down Expand Up @@ -178,29 +173,12 @@ func (o *dashboardOption) listPipelineRuns(index int, mainText string, secondary
_ = o.getTable(mainText, "pipelineruns", o.pipelineListView)
}

func (o *dashboardOption) getTable(ns, kind string, table *tview.Table) (err error) {
tableData := &metav1beta1.Table{}
table.Clear()
table.SetTitle(fmt.Sprintf("%s(%s)[%d]", kind, ns, 0))
listOpt := &metav1.ListOptions{}
func (o *dashboardOption) getTable(ns, kind string, table *ui.ResourceTable) (err error) {
var labelSelector string
if kind == "pipelineruns" {
listOpt.LabelSelector = fmt.Sprintf("devops.kubesphere.io/pipeline=%s", o.pipeline)
}

if err = o.restClient.Get().Namespace(ns).Resource(kind).
VersionedParams(listOpt, metav1.ParameterCodec).
SetHeader("Accept", "application/json;as=Table;v=v1beta1;g=meta.k8s.io").
Do(context.TODO()).Into(tableData); err == nil {
for i, col := range tableData.ColumnDefinitions {
table.SetCellSimple(0, i, col.Name)
}
for i, row := range tableData.Rows {
for j, cell := range row.Cells {
table.SetCellSimple(i+1, j, fmt.Sprintf("%v", cell))
}
}
table.SetTitle(fmt.Sprintf("%s(%s)[%d]", kind, ns, len(tableData.Rows)))
labelSelector = fmt.Sprintf("devops.kubesphere.io/pipeline=%s", o.pipeline)
}
table.Load(ns, kind, labelSelector)
return
}

Expand Down
93 changes: 93 additions & 0 deletions kubectl-plugin/pipeline/ui/resource_table.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package ui

import (
"context"
"fmt"
"github.com/rivo/tview"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1"
"k8s.io/client-go/rest"
"time"
)

// ResourceTable represents a table of a Kubernetes resource
type ResourceTable struct {
*tview.Table

//client dynamic.Interface
client *rest.RESTClient
app *tview.Application

// inner fields
ticker *time.Ticker
}

// NewResourceTable creates a table for Kubernetes resource
func NewResourceTable(client *rest.RESTClient, app *tview.Application) *ResourceTable {
table := tview.NewTable()
table.SetBorder(true)
table.SetSelectable(true, false).Select(1, 0).SetFixed(1, 0)
table.SetBorderPadding(0, 0, 1, 1)

return &ResourceTable{
client: client,
app: app,
Table: table,
}
}

const gvFmt = "application/json;as=Table;v=%s;g=%s, application/json"

// Load loads the data of a Kubernetes resource
func (t *ResourceTable) Load(ns, kind, labelSelector string) {
t.Stop().Clear()
t.SetTitle("loading")
// TODO provide a way to let users set it
t.ticker = time.NewTicker(time.Second * 2)

go func() {
ctx := context.TODO()
// give it an initial data setting
t.reload(ctx, ns, kind, labelSelector)

for range t.ticker.C {
t.reload(ctx, ns, kind, labelSelector)
}
}()
}

func (t *ResourceTable) reload(ctx context.Context, ns, kind, labelSelector string) {
listOpt := metav1.ListOptions{
LabelSelector: labelSelector,
}
t.SetTitle(fmt.Sprintf("%s(%s)[%d]", kind, ns, 0))
tableData := &metav1beta1.Table{}
if err := t.client.Get().Namespace(ns).Resource(kind).
VersionedParams(&listOpt, metav1.ParameterCodec).
SetHeader("Accept", fmt.Sprintf(gvFmt, metav1beta1.SchemeGroupVersion.Version, metav1beta1.GroupName)).
Do(ctx).Into(tableData); err != nil {
// TODO provide a better way to handle this error
panic(err)
return
}

for i, col := range tableData.ColumnDefinitions {
t.SetCellSimple(0, i, col.Name)
}
for i, row := range tableData.Rows {
for j, cell := range row.Cells {
t.SetCellSimple(i+1, j, fmt.Sprintf("%v", cell))
}
}
t.SetTitle(fmt.Sprintf("%s(%s)[%d]", kind, ns, len(tableData.Rows)))
t.app.Draw()
}

// Stop stops the refresh data action
func (t *ResourceTable) Stop() *ResourceTable {
if t.ticker != nil {
t.ticker.Stop()
t.ticker = nil
}
return t
}

0 comments on commit 1767f34

Please sign in to comment.