mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-07-09 16:00:59 +00:00
Make discovery a fast surface scan, not a deep scan
Discovery is the index, not the encyclopedia: it needs to quickly answer 'what is this and how do I reach it', then the Assistant supplies standard-service knowledge and runs commands on demand for specifics. Trim the guest command sets to surface identity signals only (OS, hostname, running services, listening ports, top processes for LXC/VM; OS, processes, ports, env for Docker). Drop the deep enumeration — installed_packages, config_files, docker_mounts, hardware/GPU, disk, cron, nested docker_check — which bloated the evidence payload (and the AI analysis) for no benefit the Assistant can't get live. Remove the now-unused dockerMountsCommand const and retire its test; add TestGuestCommandSetsAreSurfaceOnly to pin the surface intent (verified live: HA LXC went from 13 commands to 5). Note: full speed also needs a fast identification path (the configured reasoning model still exceeds the 45s analysis timeout on its own) — that's the follow-up.
This commit is contained in:
parent
33701fe274
commit
f18fb88cdc
2 changed files with 35 additions and 127 deletions
|
|
@ -43,10 +43,6 @@ type DiscoveryCommand struct {
|
|||
Optional bool `json:"optional"` // If true, don't fail if command fails
|
||||
}
|
||||
|
||||
// dockerMountsCommand collects Docker mount metadata without relying on extra
|
||||
// text utilities (sed/grep), which may be missing in minimal guest images.
|
||||
const dockerMountsCommand = `sh -c 'docker ps -q 2>/dev/null | head -15 | while read -r id; do name=$(docker inspect --format "{{.Name}}" "$id" 2>/dev/null); name=${name#/}; [ -n "$name" ] || name="$id"; echo "CONTAINER:$name"; docker inspect --format "{{range .Mounts}}{{.Source}}|{{.Destination}}|{{.Type}}{{println}}{{end}}" "$id" 2>/dev/null || true; done; echo docker_mounts_done'`
|
||||
|
||||
// GetCommandsForResource returns the commands to run for a given resource type.
|
||||
func GetCommandsForResource(resourceType ResourceType) []DiscoveryCommand {
|
||||
switch resourceType {
|
||||
|
|
@ -105,62 +101,12 @@ func getSystemContainerCommands() []DiscoveryCommand {
|
|||
Categories: []string{"service"},
|
||||
Optional: true,
|
||||
},
|
||||
{
|
||||
Name: "disk_usage",
|
||||
Command: "df -h 2>/dev/null | head -15",
|
||||
Description: "Disk usage and mount points",
|
||||
Categories: []string{"storage"},
|
||||
Optional: true,
|
||||
},
|
||||
{
|
||||
Name: "docker_check",
|
||||
Command: "docker ps --format '{{.Names}}: {{.Image}} ({{.Status}})' 2>/dev/null | head -20 || echo 'no_docker'",
|
||||
Description: "Docker containers if running",
|
||||
Categories: []string{"service", "container"},
|
||||
Optional: true,
|
||||
},
|
||||
{
|
||||
Name: "docker_mounts",
|
||||
Command: dockerMountsCommand,
|
||||
Description: "Docker container bind mounts (source -> destination)",
|
||||
Categories: []string{"config", "storage"},
|
||||
Optional: true,
|
||||
},
|
||||
{
|
||||
Name: "installed_packages",
|
||||
Command: "dpkg -l 2>/dev/null | grep -E '^ii' | awk '{print $2}' | head -50 || rpm -qa 2>/dev/null | head -50 || apk list --installed 2>/dev/null | head -50",
|
||||
Description: "Installed packages",
|
||||
Categories: []string{"version", "service"},
|
||||
Optional: true,
|
||||
},
|
||||
{
|
||||
Name: "config_files",
|
||||
Command: "find /etc -name '*.conf' -o -name '*.yml' -o -name '*.yaml' -o -name '*.json' 2>/dev/null | head -30",
|
||||
Description: "Configuration files",
|
||||
Categories: []string{"config"},
|
||||
Optional: true,
|
||||
},
|
||||
{
|
||||
Name: "cron_jobs",
|
||||
Command: "crontab -l 2>/dev/null | grep -v '^#' | head -10 || ls -la /etc/cron.d/ 2>/dev/null | head -10",
|
||||
Description: "Scheduled jobs",
|
||||
Categories: []string{"service"},
|
||||
Optional: true,
|
||||
},
|
||||
{
|
||||
Name: "hardware_info",
|
||||
Command: "lspci 2>/dev/null | head -20 || echo 'no_lspci'",
|
||||
Description: "Hardware devices (e.g., Coral TPU)",
|
||||
Categories: []string{"hardware"},
|
||||
Optional: true,
|
||||
},
|
||||
{
|
||||
Name: "gpu_devices",
|
||||
Command: "ls -la /dev/dri/ 2>/dev/null; ls -la /dev/apex* 2>/dev/null; nvidia-smi -L 2>/dev/null || echo 'no_gpu'",
|
||||
Description: "GPU and TPU devices",
|
||||
Categories: []string{"hardware"},
|
||||
Optional: true,
|
||||
},
|
||||
// Surface discovery only: identity + how-to-reach. Deep enumeration
|
||||
// (installed packages, config-file trees, hardware/GPU, bind mounts,
|
||||
// disk, cron) is intentionally omitted — it bloats the evidence payload
|
||||
// and slows AI analysis, and it re-derives what the Assistant already
|
||||
// knows about standard services. Specifics are fetched on demand via
|
||||
// agent commands when actually needed. See discovery-assistant-goal.
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -202,41 +148,10 @@ func getVMCommands() []DiscoveryCommand {
|
|||
Categories: []string{"service"},
|
||||
Optional: true,
|
||||
},
|
||||
{
|
||||
Name: "disk_usage",
|
||||
Command: "df -h 2>/dev/null | head -15",
|
||||
Description: "Disk usage and mount points",
|
||||
Categories: []string{"storage"},
|
||||
Optional: true,
|
||||
},
|
||||
{
|
||||
Name: "docker_check",
|
||||
Command: "docker ps --format '{{.Names}}: {{.Image}} ({{.Status}})' 2>/dev/null | head -20 || echo 'no_docker'",
|
||||
Description: "Docker containers if running",
|
||||
Categories: []string{"service", "container"},
|
||||
Optional: true,
|
||||
},
|
||||
{
|
||||
Name: "docker_mounts",
|
||||
Command: dockerMountsCommand,
|
||||
Description: "Docker container bind mounts (source -> destination)",
|
||||
Categories: []string{"config", "storage"},
|
||||
Optional: true,
|
||||
},
|
||||
{
|
||||
Name: "hardware_info",
|
||||
Command: "lspci 2>/dev/null | head -20",
|
||||
Description: "PCI hardware devices",
|
||||
Categories: []string{"hardware"},
|
||||
Optional: true,
|
||||
},
|
||||
{
|
||||
Name: "gpu_devices",
|
||||
Command: "ls -la /dev/dri/ 2>/dev/null; nvidia-smi -L 2>/dev/null || echo 'no_gpu'",
|
||||
Description: "GPU devices",
|
||||
Categories: []string{"hardware"},
|
||||
Optional: true,
|
||||
},
|
||||
// Surface discovery only — identity + how-to-reach. Deep enumeration
|
||||
// (disk, nested docker + bind mounts, hardware/GPU) is omitted and
|
||||
// fetched on demand via agent commands when needed. See
|
||||
// getSystemContainerCommands / discovery-assistant-goal.
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -272,13 +187,8 @@ func getDockerCommands() []DiscoveryCommand {
|
|||
Categories: []string{"config"},
|
||||
Optional: true,
|
||||
},
|
||||
{
|
||||
Name: "config_files",
|
||||
Command: "find /config /data /app /etc -maxdepth 2 -name '*.conf' -o -name '*.yml' -o -name '*.yaml' -o -name '*.json' 2>/dev/null | head -20",
|
||||
Description: "Configuration files",
|
||||
Categories: []string{"config"},
|
||||
Optional: true,
|
||||
},
|
||||
// Surface discovery only — config-file enumeration omitted; the
|
||||
// Assistant fetches specifics on demand. See discovery-assistant-goal.
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -80,33 +80,31 @@ func TestCommandsAndTemplates(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestDockerMountsCommandAvoidsExtraTextUtilities(t *testing.T) {
|
||||
lxcCmds := GetCommandsForResource(ResourceTypeSystemContainer)
|
||||
vmCmds := GetCommandsForResource(ResourceTypeVM)
|
||||
|
||||
findByName := func(cmds []DiscoveryCommand, name string) string {
|
||||
for _, cmd := range cmds {
|
||||
if cmd.Name == name {
|
||||
return cmd.Command
|
||||
func TestGuestCommandSetsAreSurfaceOnly(t *testing.T) {
|
||||
// Discovery is a fast surface index (identity + how-to-reach), not a deep
|
||||
// scan. Guest command sets must stay light and must NOT include the deep
|
||||
// enumeration commands — the Assistant knows standard service layouts and
|
||||
// fetches specifics on demand. See discovery-assistant-goal.
|
||||
deep := map[string]bool{
|
||||
"installed_packages": true,
|
||||
"config_files": true,
|
||||
"docker_mounts": true,
|
||||
"hardware_info": true,
|
||||
"gpu_devices": true,
|
||||
"disk_usage": true,
|
||||
"cron_jobs": true,
|
||||
"docker_check": true,
|
||||
}
|
||||
for _, rt := range []ResourceType{ResourceTypeSystemContainer, ResourceTypeVM, ResourceTypeDocker} {
|
||||
cmds := GetCommandsForResource(rt)
|
||||
if len(cmds) == 0 || len(cmds) > 6 {
|
||||
t.Errorf("%s surface command set should be small (1-6 commands), got %d", rt, len(cmds))
|
||||
}
|
||||
for _, c := range cmds {
|
||||
if deep[c.Name] {
|
||||
t.Errorf("%s should not run deep command %q in a surface scan", rt, c.Name)
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
lxcMounts := findByName(lxcCmds, "docker_mounts")
|
||||
vmMounts := findByName(vmCmds, "docker_mounts")
|
||||
|
||||
if lxcMounts == "" || vmMounts == "" {
|
||||
t.Fatalf("expected docker_mounts command for both LXC and VM")
|
||||
}
|
||||
if lxcMounts != vmMounts {
|
||||
t.Fatalf("expected shared docker_mounts command, got lxc=%q vm=%q", lxcMounts, vmMounts)
|
||||
}
|
||||
if strings.Contains(lxcMounts, "sed ") || strings.Contains(lxcMounts, "grep ") {
|
||||
t.Fatalf("docker_mounts should not depend on sed/grep: %s", lxcMounts)
|
||||
}
|
||||
if !strings.Contains(lxcMounts, "name=${name#/}") {
|
||||
t.Fatalf("expected shell-native container name trimming, got: %s", lxcMounts)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue