feat: add motd-assist TUI for managing dynamic MOTDs
Initial Go project built with Bubble Tea and Lip Gloss: - Live preview and management of /etc/update-motd.d scripts - Embedded presets (ubuntu-default, minimal, server-dashboard) - Bundled POSIX sh style scripts (brand header, sysinfo panel, footer) - Snapshot/restore safety around applying changes - CLI subcommands preview, apply, restore, list-presets - Unit tests for detect, sanitize, and apply logic
This commit is contained in:
commit
d56659e21a
34 changed files with 3260 additions and 0 deletions
72
internal/assets/assets.go
Normal file
72
internal/assets/assets.go
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
// Package assets hält die eingebetteten Presets und Custom-Scripte.
|
||||
package assets
|
||||
|
||||
import (
|
||||
"embed"
|
||||
"strings"
|
||||
)
|
||||
|
||||
//go:embed presets scripts
|
||||
var embedded embed.FS
|
||||
|
||||
// ScriptContent liefert den Inhalt einer gebündelten Script-Vorlage.
|
||||
func ScriptContent(name string) (string, bool) {
|
||||
b, err := embedded.ReadFile("scripts/" + name)
|
||||
if err != nil {
|
||||
return "", false
|
||||
}
|
||||
return string(b), true
|
||||
}
|
||||
|
||||
// ScriptNames listet alle gebündelten Script-Vorlagen.
|
||||
func ScriptNames() []string {
|
||||
entries, err := embedded.ReadDir("scripts")
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
names := make([]string, 0, len(entries))
|
||||
for _, e := range entries {
|
||||
if !e.IsDir() {
|
||||
names = append(names, e.Name())
|
||||
}
|
||||
}
|
||||
return names
|
||||
}
|
||||
|
||||
// PresetFiles liefert Dateiname → Inhalt aller eingebetteten Presets.
|
||||
func PresetFiles() map[string]string {
|
||||
entries, err := embedded.ReadDir("presets")
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
files := make(map[string]string, len(entries))
|
||||
for _, e := range entries {
|
||||
if e.IsDir() {
|
||||
continue
|
||||
}
|
||||
if b, err := embedded.ReadFile("presets/" + e.Name()); err == nil {
|
||||
files[e.Name()] = string(b)
|
||||
}
|
||||
}
|
||||
return files
|
||||
}
|
||||
|
||||
// MatchScript findet die Vorlage, deren Inhalt zu content passt, und
|
||||
// erkennt damit bereits installierte motd-assist-Scripte.
|
||||
func MatchScript(content string) (string, bool) {
|
||||
return MatchScriptBytes([]byte(content))
|
||||
}
|
||||
|
||||
// MatchScriptBytes ist die Byte-Variante von MatchScript.
|
||||
func MatchScriptBytes(b []byte) (string, bool) {
|
||||
content := strings.TrimSpace(string(b))
|
||||
if content == "" {
|
||||
return "", false
|
||||
}
|
||||
for _, name := range ScriptNames() {
|
||||
if c, ok := ScriptContent(name); ok && strings.TrimSpace(c) == content {
|
||||
return name, true
|
||||
}
|
||||
}
|
||||
return "", false
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue