platform/app/webui: ship the power-watch scenario baked into the image
platform.LocalScenariosDir (/usr/share/bee/scenarios, populated from iso/overlay/usr/share/bee/scenarios/ by build.sh's overlay rsync) is now checked before removable media for both `bee run <name>` and the "6. Scenario" page — a scenario shipped with the image works with no USB stick required. ReadScenario/ListAvailableScenarios merge local + USB; the removable-media-only functions from the previous commit are kept as-is (still used directly where that's actually what's wanted) rather than renamed out from under existing callers/tests. iso/overlay/usr/share/bee/scenarios/nvbandwidth-all-gpu-power-watch.json is a copy of scenarios/nvbandwidth-all-gpu-power-watch.json — the two aren't auto-synced (documented in scenarios/README.md), so shipping a scenario baked-in means checking it into both places. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
bcf02e0515
commit
5a780e96b4
@@ -247,3 +247,72 @@ func (s *System) ListScenarioFilesOnRemovableMedia() ([]ScenarioFileOnRemovableM
|
||||
sort.Slice(out, func(i, j int) bool { return out[i].Name < out[j].Name })
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// LocalScenariosDir is where scenario JSON files shipped with the ISO
|
||||
// itself live (rsync'd from this repo's scenarios/ into the overlay at
|
||||
// build time — see iso/builder/build.sh's "preparing staged overlay" step
|
||||
// and iso/overlay/usr/share/bee/scenarios/). Part of the read-only
|
||||
// squashfs, so a scenario here is always available with no USB stick
|
||||
// needed. A package var (not a const) so tests can point it at a temp dir.
|
||||
var LocalScenariosDir = "/usr/share/bee/scenarios"
|
||||
|
||||
// ReadScenarioLocal reads scenarios/<name>.json from LocalScenariosDir.
|
||||
func (s *System) ReadScenarioLocal(name string) ([]byte, error) {
|
||||
name = strings.TrimSpace(name)
|
||||
if name == "" {
|
||||
return nil, fmt.Errorf("scenario name is required")
|
||||
}
|
||||
return os.ReadFile(filepath.Join(LocalScenariosDir, name+".json"))
|
||||
}
|
||||
|
||||
// ListLocalScenarioFiles lists the *.json files under LocalScenariosDir.
|
||||
func (s *System) ListLocalScenarioFiles() ([]ScenarioFileOnRemovableMedia, error) {
|
||||
entries, err := os.ReadDir(LocalScenariosDir)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
var out []ScenarioFileOnRemovableMedia
|
||||
for _, e := range entries {
|
||||
if e.IsDir() || !strings.HasSuffix(e.Name(), ".json") {
|
||||
continue
|
||||
}
|
||||
out = append(out, ScenarioFileOnRemovableMedia{
|
||||
Name: strings.TrimSuffix(e.Name(), ".json"),
|
||||
Device: "local (shipped with image)",
|
||||
})
|
||||
}
|
||||
sort.Slice(out, func(i, j int) bool { return out[i].Name < out[j].Name })
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// ReadScenario resolves scenarios/<name>.json, checking LocalScenariosDir
|
||||
// first (always available, no removable media required) and falling back
|
||||
// to ReadScenarioFromRemovableMedia. Prefer this over calling either one
|
||||
// directly unless you specifically need to restrict the lookup to one
|
||||
// source (as the tests for each do).
|
||||
func (s *System) ReadScenario(name string) ([]byte, error) {
|
||||
if data, err := s.ReadScenarioLocal(name); err == nil {
|
||||
return data, nil
|
||||
}
|
||||
return s.ReadScenarioFromRemovableMedia(name)
|
||||
}
|
||||
|
||||
// ListAvailableScenarios merges ListLocalScenarioFiles (first) with
|
||||
// ListScenarioFilesOnRemovableMedia, for UIs that want to show everything
|
||||
// runnable via ReadScenario in one list.
|
||||
func (s *System) ListAvailableScenarios() ([]ScenarioFileOnRemovableMedia, error) {
|
||||
local, err := s.ListLocalScenarioFiles()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
removable, err := s.ListScenarioFilesOnRemovableMedia()
|
||||
if err != nil {
|
||||
// A removable-media scan failure (e.g. no lsblk) shouldn't hide the
|
||||
// scenarios that are always available regardless of media.
|
||||
return local, nil
|
||||
}
|
||||
return append(local, removable...), nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user