This commit is contained in:
2026-04-22 16:12:50 +02:00
parent 26a098baec
commit 0ee35713a4
11 changed files with 853 additions and 0 deletions
+121
View File
@@ -0,0 +1,121 @@
package main
import (
"os/exec"
"strings"
tea "charm.land/bubbletea/v2"
)
type Service struct {
Name string
Desc string
Active string
}
type ServicesLoadedMsg struct {
services []Service
err error
}
func LoadServices() tea.Msg {
cmd := exec.Command("systemctl", "list-units", "--type=service", "--all", "--no-pager", "--plain")
out, err := cmd.Output()
if err != nil {
return ServicesLoadedMsg{err: err}
}
services := parseServices(out)
return ServicesLoadedMsg{services: services}
}
func parseServices(out []byte) []Service {
lines := strings.Split(string(out), "\n")
var services []Service
for i, line := range lines {
if i == 0 {
continue
}
line = strings.TrimSpace(line)
if line == "" {
continue
}
if strings.HasPrefix(line, "Legend:") {
return services
}
fields := strings.Fields(line)
if len(fields) < 5 {
continue
}
services = append(services, Service{
Name: fields[0],
Active: fields[2],
Desc: strings.Join(fields[4:], " "),
})
}
return services
}
func (m *model) filterServices() {
q := strings.ToLower(strings.TrimSpace(m.query.Value()))
if q == "" {
m.filtered = slicesClone(m.services)
} else {
var filtered []Service
for _, s := range m.services {
if matchesService(s, q) {
filtered = append(filtered, s)
}
}
m.filtered = filtered
}
if len(m.filtered) == 0 {
m.cursor = 0
m.offset = 0
return
}
if m.cursor >= len(m.filtered) {
m.cursor = len(m.filtered) - 1
m.offset = max(0, m.cursor-m.amount)
}
}
func matchesService(s Service, q string) bool {
return strings.Contains(strings.ToLower(s.Name), q) ||
strings.Contains(strings.ToLower(s.Active), q) ||
strings.Contains(strings.ToLower(s.Desc), q)
}
func slicesClone(in []Service) []Service {
out := make([]Service, len(in))
copy(out, in)
return out
}
func (m *model) StopService() {
s := m.filtered[m.cursor]
if s.Active != "active" {
return
}
cmd := exec.Command("systemctl", "stop", s.Name)
cmd.Run()
}
func (m *model) StartService() {
s := m.filtered[m.cursor]
if s.Active != "active" {
cmd := exec.Command("systemctl", "start", s.Name)
cmd.Run()
}
}