75 lines
2.6 KiB
Go
75 lines
2.6 KiB
Go
// Package facts собирает минимальный набор фактов о хосте — ровно
|
||
// столько, сколько нужно, чтобы плейбук мог сам выбрать нужную ветку
|
||
// для разных дистрибутивов (apt vs rpm_package), без ручного указания
|
||
// ОС в инвентаре. Это не полноценный gather_facts — осознанно маленький
|
||
// набор, расширяемый по мере реальной необходимости.
|
||
package facts
|
||
|
||
import (
|
||
"strings"
|
||
|
||
"github.com/vladimir/goherence/internal/ssh"
|
||
)
|
||
|
||
// Gather подключается к уже открытой SSH-сессии и вычисляет:
|
||
// - os_family: "Debian" | "RedHat" | "Unknown"
|
||
// - distribution: значение ID= из /etc/os-release (ubuntu, debian, rhel, almalinux...)
|
||
// - system: вывод `uname -s` (обычно "Linux")
|
||
func Gather(conn *ssh.Conn) (map[string]interface{}, error) {
|
||
res, err := conn.Run("cat /etc/os-release 2>/dev/null; echo '---'; uname -s")
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
parts := strings.SplitN(res.Stdout, "---", 2)
|
||
osRelease := parts[0]
|
||
system := "Unknown"
|
||
if len(parts) > 1 {
|
||
system = strings.TrimSpace(parts[1])
|
||
}
|
||
|
||
distro := parseOSReleaseID(osRelease)
|
||
|
||
return map[string]interface{}{
|
||
"os_family": familyFor(distro),
|
||
"distribution": distro,
|
||
"system": system,
|
||
}, nil
|
||
}
|
||
|
||
// parseOSReleaseID вытаскивает значение ID= из /etc/os-release
|
||
// (например ID=ubuntu, ID="almalinux", ID=rhel).
|
||
func parseOSReleaseID(osRelease string) string {
|
||
for _, line := range strings.Split(osRelease, "\n") {
|
||
line = strings.TrimSpace(line)
|
||
if strings.HasPrefix(line, "ID=") {
|
||
v := strings.TrimPrefix(line, "ID=")
|
||
return strings.Trim(v, `"'`)
|
||
}
|
||
}
|
||
return "unknown"
|
||
}
|
||
|
||
// debianFamily / redHatFamily — известные ID из /etc/os-release,
|
||
// относящиеся к каждому семейству. Список расширяется по мере
|
||
// встречи новых дистрибутивов, а не пытается быть исчерпывающим сразу.
|
||
var (
|
||
debianFamily = map[string]bool{
|
||
"debian": true, "ubuntu": true, "raspbian": true, "linuxmint": true,
|
||
}
|
||
redHatFamily = map[string]bool{
|
||
"rhel": true, "centos": true, "fedora": true, "almalinux": true,
|
||
"rocky": true, "amzn": true,
|
||
}
|
||
)
|
||
|
||
func familyFor(distro string) string {
|
||
switch {
|
||
case debianFamily[distro]:
|
||
return "Debian"
|
||
case redHatFamily[distro]:
|
||
return "RedHat"
|
||
default:
|
||
return "Unknown"
|
||
}
|
||
}
|