Step 28: Machine identity and targeting core.

Entry gains Only/Never fields for per-machine targeting. Machine
identity = short hostname + os:<GOOS> + arch:<GOARCH> + tag:<name>.
Tags stored in local <repo>/tags file (added to .gitignore by init).
EntryApplies() matching: only=any-match, never=no-match, both=error.
13 tests covering matching, identity, tags CRUD, gitignore.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-24 22:47:02 -07:00
parent 7797de7d48
commit 589f76c10e
7 changed files with 393 additions and 3 deletions

37
garden/identity.go Normal file
View File

@@ -0,0 +1,37 @@
package garden
import (
"os"
"runtime"
"strings"
)
// Identity returns the machine's label set: short hostname, os:<GOOS>,
// arch:<GOARCH>, and tag:<name> for each tag in <repo>/tags.
func (g *Garden) Identity() []string {
labels := []string{
shortHostname(),
"os:" + runtime.GOOS,
"arch:" + runtime.GOARCH,
}
tags := g.LoadTags()
for _, tag := range tags {
labels = append(labels, "tag:"+tag)
}
return labels
}
// shortHostname returns the hostname before the first dot, lowercased.
func shortHostname() string {
host, err := os.Hostname()
if err != nil {
return "unknown"
}
host = strings.ToLower(host)
if idx := strings.IndexByte(host, '.'); idx >= 0 {
host = host[:idx]
}
return host
}