Files
techsuppgetinfo/DCIManager6/dci6-support-reader/server_docker_tab.go
2026-04-04 00:09:02 +08:00

249 lines
6.5 KiB
Go

package main
import (
"fmt"
"strconv"
"strings"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/widget"
)
func createDockerTab(server outputStruct) *container.AppTabs {
dockerTabs := container.NewAppTabs()
dockerTabs.Append(container.NewTabItem("docker ps", createDockerPsTab(server)))
dockerTabs.Append(container.NewTabItem("docker stats", createDockerStats(server)))
dockerTabs.Append(container.NewTabItem("supervisor status", createDockerSupervisorTab(server)))
return dockerTabs
}
// type dockerStats struct {
// BlockIO string `json:"BlockIO"`
// CPUPerc string `json:"CPUPerc"`
// Container string `json:"Container"`
// ID string `json:"ID"`
// MemPerc string `json:"MemPerc"`
// MemUsage string `json:"MemUsage"`
// Name string `json:"Name"`
// NetIO string `json:"NetIO"`
// PIDs string `json:"PIDs"`
// }
func shortId(id string) string {
if len(id) > 12 {
return id[:12]
}
return id
}
func parsePercent(percent string) float64 {
var val float64
fmt.Sscanf(percent, "%f%%", &val)
return val
}
func createDockerStats(server outputStruct) *fyne.Container {
// Заголовки таблицы
headers := []string{"CONTAINER", "NAME", "CPU %", "MEM %", "MEM USAGE", "NET I/O", "BLOCK I/O", "PIDs"}
// Данные
stats := server.DockerStats
// Создаю таблицу
table := widget.NewTable(
func() (rows int, cols int) {
return len(stats) + 1, len(headers)
},
func() fyne.CanvasObject {
label := widget.NewLabel("Template")
label.Selectable = true
label.Alignment = fyne.TextAlignCenter
return label
},
func(id widget.TableCellID, obj fyne.CanvasObject) {
label := obj.(*widget.Label)
// Заголовки
if id.Row == 0 {
label.SetText(headers[id.Col])
label.TextStyle.Bold = true
label.Alignment = fyne.TextAlignCenter
}
// Данные
row := id.Row - 1
// if row < len(stats) {
if len(stats) > 0 && row >= 0 && row < len(stats) {
switch id.Col {
case 0:
// label.SetText(shortId(stats[row].Container))
label.SetText(stats[row].Container)
case 1:
label.SetText(stats[row].Name)
case 2:
label.SetText(stats[row].CPUPerc)
case 3:
label.SetText(stats[row].MemPerc)
if memPercent := parsePercent(stats[row].MemPerc); memPercent > 50 {
label.Importance = widget.HighImportance
}
case 4:
label.SetText(stats[row].MemUsage)
case 5:
label.SetText(stats[row].NetIO)
case 6:
label.SetText(stats[row].BlockIO)
case 7:
label.SetText(stats[row].PIDs)
}
}
},
)
//Размер колонок
table.SetColumnWidth(0, 100)
table.SetColumnWidth(1, 150)
table.SetColumnWidth(2, 70)
table.SetColumnWidth(3, 70)
table.SetColumnWidth(4, 140)
table.SetColumnWidth(5, 140)
table.SetColumnWidth(6, 140)
table.SetColumnWidth(7, 50)
table.Refresh()
tab := container.NewBorder(
widget.NewSeparator(),
nil, nil, nil,
container.NewScroll(table),
)
return tab
}
func createDockerPsTab(server outputStruct) *fyne.Container {
searchDockerEntry := widget.NewEntry()
searchDockerEntry.SetPlaceHolder("Поиск контейнеров ...")
filteredDockers := server.DockerPsA
// type dockerPs struct {
// Id string `json:"id"`
// Image string `json:"image"`
// Names []string `json:"names"`
// Created int64 `json:"running_for"`
// State string `json:"state"`
// Status string `json:"status"`
// }
dockerList := widget.NewList(
func() int {
return len(filteredDockers)
},
func() fyne.CanvasObject {
return container.NewHBox(
widget.NewLabel("id"),
widget.NewLabel("image"),
widget.NewLabel("names"),
widget.NewLabel("created"),
widget.NewLabel("state"),
widget.NewLabel("status"),
)
},
func(id widget.ListItemID, obj fyne.CanvasObject) {
hbox := obj.(*fyne.Container)
dock := filteredDockers[id]
idLabel := hbox.Objects[0].(*widget.Label)
imageLabel := hbox.Objects[1].(*widget.Label)
namesLabel := hbox.Objects[2].(*widget.Label)
createdLabel := hbox.Objects[3].(*widget.Label)
stateLabel := hbox.Objects[4].(*widget.Label)
statusLabel := hbox.Objects[5].(*widget.Label)
idLabel.SetText(dock.Id)
imageLabel.SetText(dock.Image)
namesLabel.SetText(fmt.Sprintf("%s", dock.Names))
createdLabel.SetText(strconv.Itoa(int(dock.Created)))
stateLabel.SetText(dock.State)
statusLabel.SetText(dock.Status)
},
)
searchDockerEntry.OnChanged = func(text string) {
if text == "" {
filteredDockers = server.DockerPsA
} else {
filtered := []dockerPs{}
lowerText := strings.ToLower(text)
for _, d := range server.DockerPsA {
if strings.Contains(strings.ToLower(d.Image), lowerText) || strings.Contains(strings.ToLower(d.State), lowerText) || strings.Contains(strings.ToLower(fmt.Sprintf("%s", d.Names)), lowerText) || strings.Contains(strings.ToLower(d.Status), lowerText) {
filtered = append(filtered, d)
}
}
filteredDockers = filtered
}
dockerList.Refresh()
}
dockerTab := container.NewBorder(
container.NewVBox(
searchDockerEntry,
widget.NewSeparator(),
), nil, nil, nil,
container.NewScroll(dockerList),
)
return dockerTab
}
func createDockerSupervisorTab(server outputStruct) *fyne.Container {
searchEntry := widget.NewEntry()
searchEntry.SetPlaceHolder("Поиск ...")
filtered := server.DockerSupervisor
list := widget.NewList(
func() int {
return len(filtered)
},
func() fyne.CanvasObject {
entry := widget.NewMultiLineEntry()
entry.SetMinRowsVisible(10)
entry.Wrapping = fyne.TextWrapWord
return container.NewVBox(
widget.NewLabel("container_name"),
entry,
)
},
func(id widget.ListItemID, obj fyne.CanvasObject) {
box := obj.(*fyne.Container)
e := filtered[id]
containerName := box.Objects[0].(*widget.Label)
containerName.SetText(e.Name)
containerName.TextStyle.Bold = true
containerName.Selectable = true
supervisorStatus := box.Objects[1].(*widget.Entry)
supervisorStatus.SetText(e.SupStatus)
},
)
searchEntry.OnChanged = func(text string) {
if text == "" {
filtered = server.DockerSupervisor
} else {
var f []dockerSupervisor
lText := strings.ToLower(text)
for _, elem := range server.DockerSupervisor {
if strings.Contains(strings.ToLower(elem.Name), lText) {
f = append(f, elem)
}
}
filtered = f
}
list.Refresh()
}
tab := container.NewBorder(
container.NewVBox(
searchEntry,
widget.NewSeparator(),
), nil, nil, nil,
container.NewScroll(list),
)
return tab
}