39ef64e128
Hub (v0.16.0):
- store: ArtifactManifest{agent,golden version+sha256} in hub_settings; Get/SetArtifactManifest.
- handler: GET /api/v1/artifacts/{id} (passphrase auth, mirrors config-retrieve). Unset => 200 empty.
- web: operator UI "Day-0 artifacts" card (POST /configs/artifacts), semver + 64-hex validation.
- artifact_test.go: returned-verbatim / unset-empty / 401 / 404 / store round-trip.
host-install (v1.1.0):
- new step 5/8 agent-install: manifest + git token (config-retrieve) -> fetch binary from Gitea ->
verify sha256 vs hub manifest (abort on mismatch) -> install non-root felhom-agent user + binary +
sudoers (visudo -cf) + canonical unit. Idempotent.
- new step 7/8 golden: local fallback else fetch+verify+import from Gitea (--force-gitea-golden).
- agent now runs non-root (privileged.mode sudo), config chowned to the service user.
- README prerequisites trimmed to: install PVE + create customer.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
50 lines
1.5 KiB
Go
50 lines
1.5 KiB
Go
package web
|
|
|
|
import (
|
|
"bytes"
|
|
"io"
|
|
"log"
|
|
"path/filepath"
|
|
"testing"
|
|
"time"
|
|
|
|
"gitea.dooplex.hu/admin/felhom-hub/internal/store"
|
|
)
|
|
|
|
// Catches template SYNTAX errors (template.Must in New panics) and that the floor fields render on the
|
|
// two edited pages. Field-level execution errors surface as a non-nil ExecuteTemplate error.
|
|
func TestTemplates_FloorRender(t *testing.T) {
|
|
st, err := store.New(filepath.Join(t.TempDir(), "t.db"), log.New(io.Discard, "", 0))
|
|
if err != nil {
|
|
t.Fatalf("store.New: %v", err)
|
|
}
|
|
t.Cleanup(func() { st.Close() })
|
|
s := New(st, "", "", "test", time.Hour, log.New(io.Discard, "", 0)) // template.Must runs here
|
|
|
|
// configs.html — the list page data shape used by handleConfigList.
|
|
cfgData := struct {
|
|
Customers []customerListEntry
|
|
GlobalFloor string
|
|
Artifacts store.ArtifactManifest
|
|
ActiveNav string
|
|
Flash string
|
|
CSRFToken string
|
|
CSRFField string
|
|
}{
|
|
Customers: []customerListEntry{{
|
|
CustomerID: "c", EffectiveFloor: "0.87.0", FloorOverride: "0.87.0", BelowFloor: true,
|
|
ControllerVersion: "0.86.0", HasConfig: true,
|
|
}},
|
|
GlobalFloor: "0.86.0",
|
|
Artifacts: store.ArtifactManifest{AgentVersion: "0.43.0", GoldenVersion: "0.85.1"},
|
|
ActiveNav: "configs",
|
|
}
|
|
var buf bytes.Buffer
|
|
if err := s.templates.ExecuteTemplate(&buf, "configs.html", cfgData); err != nil {
|
|
t.Fatalf("render configs.html: %v", err)
|
|
}
|
|
if !bytes.Contains(buf.Bytes(), []byte("0.87.0")) || !bytes.Contains(buf.Bytes(), []byte("global floor")) {
|
|
t.Errorf("configs.html missing floor content")
|
|
}
|
|
}
|