Reputation: 1569
I'm building a terminal user interface (TUI) application in Go using the tview library, and I'm encountering an issue with duplicate mainSection and footer entries being displayed in my grid layout.
func kubernetesLanding(app *tview.Application, clientset *kubernetes.Clientset) {
newPrimitive := func(text string) tview.Primitive {
return tview.NewTextView().
SetTextAlign(tview.AlignCenter).
SetText(text)
}
mainSection := tview.NewTextView().
SetTextAlign(tview.AlignCenter).
SetText("Main content")
footer := newPrimitive("Footer")
clusterInfo := ClusterInfo{
Context: "dev-context",
Cluster: "my-cluster",
Memory: "16Gi",
CPU: "4 cores",
NumberOfNodes: 3,
}
commands := []Command{
{"a", "Attach"},
{"d", "Delete"},
}
header := renderHeader(clusterInfo, commands)
grid := tview.NewGrid().
SetRows(6, 0, 3).
SetBorders(true)
grid.AddItem(header, 0, 0, 1, 3, 0, 0, false).
AddItem(mainSection, 1, 0, 1, 3, 0, 0, false).
AddItem(footer, 2, 0, 1, 3, 0, 0, false)
// Initialize watch for pods
watchPods(clientset, "default", grid, app)
if err := app.SetRoot(grid, true).EnableMouse(true).Run(); err != nil {
logMessage("Error: " + err.Error())
panic(err)
}
}
and this is the watchPods function:
func watchPods(clientset *kubernetes.Clientset, namespace string, grid *tview.Grid, app *tview.Application) {
// Create a list/watch pod request
watchInterface, err := clientset.CoreV1().Pods(namespace).Watch(context.TODO(), metav1.ListOptions{})
if err != nil {
log.Fatalf("Error setting up watch: %v", err)
}
table := tview.NewTable().SetBorders(false).SetSelectable(true, false)
grid.AddItem(table, 1, 0, 1, 3, 0, 0, true)
// Watch for events in a goroutine
go func() {
for event := range watchInterface.ResultChan() {
pod, ok := event.Object.(*v1.Pod)
if !ok {
logMessage("Error converting event object to Pod")
continue
}
switch event.Type {
case watch.Added:
logMessage(fmt.Sprintf("Pod added: %s", pod.Name))
// Update the pod list (You may want to maintain an array of Pods to keep track)
displayPodsInTable(table, []Pod{convertToPod(pod)})
case watch.Modified:
logMessage(fmt.Sprintf("Pod modified: %s", pod.Name))
// Update the pod list
displayPodsInTable(table, []Pod{convertToPod(pod)})
case watch.Deleted:
logMessage(fmt.Sprintf("Pod deleted: %s", pod.Name))
// Refresh the table (You may want to keep track of the pods for better handling)
// You can clear and reload all pods
refreshPods(clientset, namespace, table)
}
}
}()
// Initial load of pods
refreshPods(clientset, namespace, table)
}
And here is the main function:
func main() {
app := tview.NewApplication()
clientset, err := GetClient()
if err != nil {
log.Fatalf("Failed to get Kubernetes client: %v", err)
}
list := tview.NewList().
AddItem("Kubernetes", "Some explanatory text", 'a', func() {
kubernetesLanding(app, clientset)
}).
AddItem("Quit", "Press to exit", 'q', func() {
app.Stop()
})
// Set a uniform background color for the list
list.SetBackgroundColor(tcell.ColorBlack) // Use your preferred color here
if err := app.SetRoot(list, true).EnableMouse(true).Run(); err != nil {
panic(err)
}
}
To clarify better the issue. when i go to the kubernetes section: i should see the grid in this following format:
initially, before integrating any kubernetes code, this was working as expected, so i introduced the watchpod function to replicate the command kubectl get pods
and start having some experience with those libraries. and this is where the weird behaviour start happening. At every events, instead of just updating the mainSection, it creates a new mainsection and footer. So lets assume i have 3 events firing, what i see in the terminal is:
i tried to remove the Items from the function so have always a new one added, but this seems not to work and the same outcome is happening.
I hope somebody can help me out with this and undertand what i am doing wrong here because i am quiet confused. And please if youhave any further question, just let me know.
thank you so much in advance
Upvotes: 1
Views: 29