feat(auth): integrate authentication with installation lifecycle
This commit is contained in:
@@ -39,13 +39,6 @@ type settingsFileSnapshot struct {
|
||||
RawBase64 string `json:"rawBase64"`
|
||||
}
|
||||
|
||||
var internalIdentityHeaders = []string{
|
||||
"-H", "x-thoth-principal-issuer: tht",
|
||||
"-H", "x-thoth-principal-subject: tht-maintenance",
|
||||
"-H", "x-thoth-principal-display-name: Tht maintenance",
|
||||
"-H", "x-thoth-is-admin: 1",
|
||||
}
|
||||
|
||||
// Configure changes the backend's real installation settings through a core-side helper. It
|
||||
// deliberately has no secret or endpoint input: external endpoints remain Compose-owned.
|
||||
func Configure(ctx context.Context, runner Runner, value Defaults) error {
|
||||
@@ -127,9 +120,7 @@ func ConfigurationOptions(ctx context.Context, runner Runner) ([]ModelOption, er
|
||||
}
|
||||
|
||||
func configurationOptions(ctx context.Context, runner Runner) (piOptions, error) {
|
||||
args := append([]string{"exec", "-T", "core", "curl", "-fsS"}, internalIdentityHeaders...)
|
||||
args = append(args, "http://127.0.0.1:8787/pi-management/options")
|
||||
result, err := runCompose(ctx, runner, args...)
|
||||
result, err := runCompose(ctx, runner, "exec", "-T", "core", "node", "/app/backend/dist/operator-command.js", "pi-options")
|
||||
if err != nil {
|
||||
return piOptions{}, commandError("Pi options check", result, err)
|
||||
}
|
||||
@@ -204,9 +195,7 @@ func restoreSettingsFile(ctx context.Context, runner Runner, snapshot settingsFi
|
||||
}
|
||||
|
||||
func readEffectiveSettings(ctx context.Context, runner Runner) ([]byte, error) {
|
||||
args := append([]string{"exec", "-T", "core", "curl", "-fsS"}, internalIdentityHeaders...)
|
||||
args = append(args, "http://127.0.0.1:8787/settings")
|
||||
result, err := runCompose(ctx, runner, args...)
|
||||
result, err := runCompose(ctx, runner, "exec", "-T", "core", "node", "/app/backend/dist/operator-command.js", "effective-settings")
|
||||
if err != nil {
|
||||
return nil, commandError("Pi installation settings read-back", result, err)
|
||||
}
|
||||
@@ -288,15 +277,13 @@ func expectedVersions(ctx context.Context, runner Runner) (string, string, error
|
||||
return expectedValue, labelValue, nil
|
||||
}
|
||||
|
||||
// Test retains the direct image-version signal, then delegates all Pi configuration/provider smoke
|
||||
// validation to core's dedicated, admin-only Pi Management endpoint.
|
||||
// Test retains the direct image-version signal, then invokes the same Pi management service via a
|
||||
// scoped core-side command. No HTTP principal or privileged header exists on this path.
|
||||
func Test(ctx context.Context, runner Runner) error {
|
||||
if _, err := Status(ctx, runner); err != nil {
|
||||
return err
|
||||
}
|
||||
args := append([]string{"exec", "-T", "core", "curl", "-fsS", "-X", "POST"}, internalIdentityHeaders...)
|
||||
args = append(args, "http://127.0.0.1:8787/pi-management/test")
|
||||
smoke, err := runCompose(ctx, runner, args...)
|
||||
smoke, err := runCompose(ctx, runner, "exec", "-T", "core", "node", "/app/backend/dist/operator-command.js", "pi-test")
|
||||
if err != nil {
|
||||
return commandError("Pi smoke check", smoke, err)
|
||||
}
|
||||
|
||||
@@ -103,6 +103,7 @@ func TestConfigurePreservesTypedRecoveryRequiredErrorFromSettingsRestore(t *test
|
||||
}
|
||||
|
||||
type configureRunner struct {
|
||||
calls []string
|
||||
failure string
|
||||
restoreDurabilityFailure bool
|
||||
settings Defaults
|
||||
@@ -115,6 +116,7 @@ type configureRunner struct {
|
||||
|
||||
func (f *configureRunner) Run(_ context.Context, args []string, stdin io.Reader) (compose.Result, error) {
|
||||
call := strings.Join(args, " ")
|
||||
f.calls = append(f.calls, call)
|
||||
switch {
|
||||
case strings.Contains(call, "config --format json"):
|
||||
f.configReads++
|
||||
@@ -123,7 +125,7 @@ func (f *configureRunner) Run(_ context.Context, args []string, stdin io.Reader)
|
||||
endpoint = "https://drift.example.invalid"
|
||||
}
|
||||
return compose.Result{Stdout: `{"services":{"core":{"image":"thothii-core:local","environment":{"THT_LLM_URL":"` + endpoint + `"}}}}`}, nil
|
||||
case strings.Contains(call, "/pi-management/options"):
|
||||
case strings.Contains(call, "operator-command.js pi-options"):
|
||||
return compose.Result{Stdout: `{"providers":["old","new"],"models":[{"provider":"old","id":"old-model"},{"provider":"new","id":"new-model"}],"reasoning":["low","medium","high"]}`}, nil
|
||||
case strings.Contains(call, "settings-cli.js --snapshot"):
|
||||
raw := f.settingsRaw
|
||||
@@ -164,7 +166,7 @@ func (f *configureRunner) Run(_ context.Context, args []string, stdin io.Reader)
|
||||
f.settingsRaw, _ = json.Marshal(f.settings)
|
||||
}
|
||||
return compose.Result{}, nil
|
||||
case strings.Contains(call, "/settings"):
|
||||
case strings.Contains(call, "operator-command.js effective-settings"):
|
||||
f.settingsReads++
|
||||
if f.failure == "readback" && f.settings.Provider == "new" {
|
||||
return compose.Result{Stdout: `{}`}, nil
|
||||
@@ -220,18 +222,21 @@ func TestConfigureCompensationRestoresAbsentAndExactEmptyPriorFiles(t *testing.T
|
||||
|
||||
// Catches tht reading the legacy public model route instead of the admin-only closed Pi
|
||||
// Management choices before it writes shared installation defaults.
|
||||
func TestConfigureLoadsDedicatedClosedOptionsWritesRealCoreSettingsAndUsesUpstreamIdentity(t *testing.T) {
|
||||
fake := newFakeRunner()
|
||||
if err := Configure(context.Background(), fake, Defaults{Provider: "provider", Model: "model", Thinking: "medium"}); err != nil {
|
||||
func TestConfigureUsesScopedCoreCommandWithoutMintingAnHTTPIdentity(t *testing.T) {
|
||||
fake := &configureRunner{
|
||||
settings: Defaults{Provider: "old", Model: "old-model", Thinking: "low"},
|
||||
settingsExist: true,
|
||||
settingsRaw: []byte(`{"provider":"old","model":"old-model","thinking":"low"}`),
|
||||
}
|
||||
if err := Configure(context.Background(), fake, Defaults{Provider: "new", Model: "new-model", Thinking: "high"}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
assertCalled(t, fake.calls, "/pi-management/options")
|
||||
assertCalled(t, fake.calls, "node /app/backend/dist/settings/settings-cli.js --provider provider --model model --thinking medium")
|
||||
assertCalled(t, fake.calls, "x-thoth-principal-subject: tht-maintenance")
|
||||
if got := strings.Join(fake.calls, "\n"); strings.Contains(got, "pi-defaults.json") || strings.Contains(got, "secret") {
|
||||
assertCalled(t, fake.calls, "operator-command.js pi-options")
|
||||
assertCalled(t, fake.calls, "node /app/backend/dist/settings/settings-cli.js --provider new --model new-model --thinking high")
|
||||
if got := strings.Join(fake.calls, "\n"); strings.Contains(got, "x-thoth-principal") || strings.Contains(got, "x-thoth-is-admin") || strings.Contains(got, "pi-defaults.json") || strings.Contains(got, "secret") {
|
||||
t.Fatalf("commands=%q", got)
|
||||
}
|
||||
if err := Configure(context.Background(), fake, Defaults{Provider: "provider", Model: "unknown", Thinking: "medium"}); err == nil {
|
||||
if err := Configure(context.Background(), fake, Defaults{Provider: "new", Model: "unknown", Thinking: "medium"}); err == nil {
|
||||
t.Fatal("expected unknown model rejection")
|
||||
}
|
||||
}
|
||||
@@ -243,10 +248,10 @@ func TestTestUsesDedicatedSmokeEndpointAndIndependentImageVersionProbe(t *testin
|
||||
if err := Test(context.Background(), fake); err != nil {
|
||||
t.Fatalf("Test() error = %v", err)
|
||||
}
|
||||
for _, command := range []string{"pi --version", "/pi-management/test", "x-thoth-principal-subject: tht-maintenance"} {
|
||||
for _, command := range []string{"pi --version", "operator-command.js pi-test"} {
|
||||
assertCalled(t, fake.calls, command)
|
||||
}
|
||||
for _, legacy := range []string{"/health", "/models", "/settings"} {
|
||||
for _, legacy := range []string{"/pi-management/test", "x-thoth-principal", "x-thoth-is-admin"} {
|
||||
if strings.Contains(strings.Join(fake.calls, "\n"), legacy) {
|
||||
t.Fatalf("Pi smoke invoked legacy endpoint %q: %s", legacy, strings.Join(fake.calls, "\n"))
|
||||
}
|
||||
|
||||
@@ -149,8 +149,8 @@ func TestRestartActivationFailureClearsPreMutationMaintenance(t *testing.T) {
|
||||
if fake.recreated {
|
||||
t.Fatal("pre-mutation activation failure recreated core")
|
||||
}
|
||||
assertCalled(t, fake.calls, "/internal/maintenance/activate")
|
||||
assertCalled(t, fake.calls, "/internal/maintenance/deactivate")
|
||||
assertCalled(t, fake.calls, "operator-command.js maintenance-activate")
|
||||
assertCalled(t, fake.calls, "operator-command.js maintenance-deactivate")
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -319,17 +319,17 @@ func TestRecoverLifecycleMaintenanceVerifiesAndClearsRestartState(t *testing.T)
|
||||
if err != nil || updateState.Phase != PhaseVerified {
|
||||
t.Fatalf("update recovery state = %+v, %v; want verified image rollback metadata", updateState, err)
|
||||
}
|
||||
deactivate := callIndex(fake.calls, "/internal/maintenance/deactivate")
|
||||
lastVerification := lastCallIndexBefore(fake.calls, "/pi-management/test", deactivate)
|
||||
deactivate := callIndex(fake.calls, "operator-command.js maintenance-deactivate")
|
||||
lastVerification := lastCallIndexBefore(fake.calls, "operator-command.js pi-test", deactivate)
|
||||
if deactivate < 0 || lastVerification < 0 {
|
||||
t.Fatalf("calls = %v; want verification before maintenance deactivation", fake.calls)
|
||||
}
|
||||
verificationCount := 0
|
||||
for index := 0; index < deactivate; index++ {
|
||||
if strings.Contains(fake.calls[index], "/internal/maintenance/deactivate") {
|
||||
if strings.Contains(fake.calls[index], "operator-command.js maintenance-deactivate") {
|
||||
t.Fatalf("maintenance reopened before combined verification: %v", fake.calls)
|
||||
}
|
||||
if strings.Contains(fake.calls[index], "/pi-management/test") {
|
||||
if strings.Contains(fake.calls[index], "operator-command.js pi-test") {
|
||||
verificationCount++
|
||||
}
|
||||
}
|
||||
@@ -373,7 +373,7 @@ func TestRecoverLifecycleMaintenanceRejectsMalformedRestartState(t *testing.T) {
|
||||
if _, stateErr := os.Stat(restartStatePath); stateErr != nil {
|
||||
t.Fatalf("malformed restart state was removed: %v", stateErr)
|
||||
}
|
||||
assertNotCalled(t, fake.calls, "/internal/maintenance/deactivate")
|
||||
assertNotCalled(t, fake.calls, "operator-command.js maintenance-deactivate")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -473,13 +473,11 @@ func canonicalDigestReference(value string) (string, error) {
|
||||
}
|
||||
|
||||
func setMaintenance(ctx context.Context, runner Runner, enabled bool) error {
|
||||
path := "deactivate"
|
||||
action := "maintenance-deactivate"
|
||||
if enabled {
|
||||
path = "activate"
|
||||
action = "maintenance-activate"
|
||||
}
|
||||
args := append([]string{"exec", "-T", "core", "curl", "-fsS"}, internalIdentityHeaders...)
|
||||
args = append(args, "-X", "POST", "http://127.0.0.1:8787/internal/maintenance/"+path)
|
||||
result, err := runCompose(ctx, runner, args...)
|
||||
result, err := runCompose(ctx, runner, "exec", "-T", "core", "node", "/app/backend/dist/operator-command.js", action)
|
||||
status, valid := parseMaintenanceStatus(result.Stdout)
|
||||
if err == nil && valid && status.Active == enabled && status.Admissions == 0 && !status.RecoveryRequired {
|
||||
return nil
|
||||
@@ -518,9 +516,7 @@ func parseMaintenanceStatus(value string) (MaintenanceState, bool) {
|
||||
}
|
||||
|
||||
func MaintenanceStatus(ctx context.Context, runner Runner) (MaintenanceState, error) {
|
||||
args := append([]string{"exec", "-T", "core", "curl", "-fsS"}, internalIdentityHeaders...)
|
||||
args = append(args, "http://127.0.0.1:8787/internal/maintenance/status")
|
||||
result, err := runCompose(ctx, runner, args...)
|
||||
result, err := runCompose(ctx, runner, "exec", "-T", "core", "node", "/app/backend/dist/operator-command.js", "maintenance-status")
|
||||
if err != nil {
|
||||
return MaintenanceState{}, commandError("maintenance status check", result, err)
|
||||
}
|
||||
@@ -549,9 +545,7 @@ func activeSessions(ctx context.Context, runner Runner) (bool, error) {
|
||||
scope = requested
|
||||
}
|
||||
}
|
||||
args := append([]string{"exec", "-T", "core", "curl", "-fsS"}, internalIdentityHeaders...)
|
||||
args = append(args, "http://127.0.0.1:8787/sessions?scope="+scope)
|
||||
result, err := runCompose(ctx, runner, args...)
|
||||
result, err := runCompose(ctx, runner, "exec", "-T", "core", "node", "/app/backend/dist/operator-command.js", "session-inventory", scope)
|
||||
if err != nil {
|
||||
return false, commandError("active-session check", result, err)
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ func TestActiveSessionsUsesInstallationScopedInventory(t *testing.T) {
|
||||
if active, err := activeSessions(context.Background(), runner); err != nil || active {
|
||||
t.Fatalf("activeSessions(%s) = %t, %v; want false, nil", scope, active, err)
|
||||
}
|
||||
if len(runner.calls) != 1 || !strings.Contains(runner.calls[0], "/sessions?scope="+scope) {
|
||||
if len(runner.calls) != 1 || !strings.Contains(runner.calls[0], "operator-command.js session-inventory "+scope) {
|
||||
t.Fatalf("activeSessions(%s) call = %v; want installation-scoped inventory", scope, runner.calls)
|
||||
}
|
||||
}
|
||||
@@ -250,7 +250,7 @@ func TestMaintenanceTransportLossAfterBackendRestartRequiresRecovery(t *testing.
|
||||
if fake.backendRestarts != 1 {
|
||||
t.Fatalf("backend restarts = %d, want 1", fake.backendRestarts)
|
||||
}
|
||||
assertCalled(t, fake.calls, "/internal/maintenance/status")
|
||||
assertCalled(t, fake.calls, "operator-command.js maintenance-status")
|
||||
for index, active := range fake.maintenanceAtRecreate {
|
||||
if !active {
|
||||
t.Fatalf("recreate %d started without durable maintenance", index+1)
|
||||
@@ -344,8 +344,8 @@ func TestCompensationReactivatesMaintenanceAndRescansBeforeRollback(t *testing.T
|
||||
t.Fatalf("calls %v contain no rollback", fake.calls)
|
||||
}
|
||||
recreate := callIndex(fake.calls, "force-recreate core")
|
||||
activate := lastCallIndexBefore(fake.calls, "/internal/maintenance/activate", rollback)
|
||||
scan := lastCallIndexBefore(fake.calls, "/sessions?scope=all", rollback)
|
||||
activate := lastCallIndexBefore(fake.calls, "operator-command.js maintenance-activate", rollback)
|
||||
scan := lastCallIndexBefore(fake.calls, "operator-command.js session-inventory all", rollback)
|
||||
if activate <= recreate || scan <= recreate {
|
||||
t.Fatalf("calls %v do not reactivate/confirm and rescan after candidate recreate before rollback", fake.calls)
|
||||
}
|
||||
@@ -599,7 +599,7 @@ func TestRecoverMaintenanceClearsOnlyAfterTerminalStateAndVerifiedSmoke(t *testi
|
||||
if selected := readSelectorReference(t, currentImageOverridePath(statePath)); selected != previous.Reference {
|
||||
t.Fatalf("maintenance cleanup changed durable selector to %q", selected)
|
||||
}
|
||||
assertCalled(t, fake.calls, "/pi-management/test")
|
||||
assertCalled(t, fake.calls, "operator-command.js pi-test")
|
||||
}
|
||||
|
||||
func TestRecoverMaintenanceRefusesPendingTransaction(t *testing.T) {
|
||||
@@ -774,12 +774,12 @@ func TestUpdateRequiresConfirmationAndDrainsActiveSessions(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("Update() with drain error = %v", err)
|
||||
}
|
||||
assertCalled(t, fake.calls, "http://127.0.0.1:8787/sessions?scope=all")
|
||||
assertCalled(t, fake.calls, "/internal/maintenance/activate")
|
||||
assertCalled(t, fake.calls, "/internal/maintenance/deactivate")
|
||||
assertCalled(t, fake.calls, "operator-command.js session-inventory all")
|
||||
assertCalled(t, fake.calls, "operator-command.js maintenance-activate")
|
||||
assertCalled(t, fake.calls, "operator-command.js maintenance-deactivate")
|
||||
}
|
||||
|
||||
func TestMaintenanceControlUsesExactLoopbackOperatorIdentity(t *testing.T) {
|
||||
func TestMaintenanceControlUsesOnlyTheScopedNonNetworkCommand(t *testing.T) {
|
||||
fake := newFakeRunner()
|
||||
if err := setMaintenance(context.Background(), fake, true); err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -788,26 +788,15 @@ func TestMaintenanceControlUsesExactLoopbackOperatorIdentity(t *testing.T) {
|
||||
if _, err := MaintenanceStatus(context.Background(), fake); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for _, path := range []string{"/internal/maintenance/activate", "/internal/maintenance/status"} {
|
||||
found := false
|
||||
for _, call := range fake.calls {
|
||||
if !strings.Contains(call, path) {
|
||||
continue
|
||||
}
|
||||
found = true
|
||||
for _, header := range []string{
|
||||
"x-thoth-principal-issuer: tht",
|
||||
"x-thoth-principal-subject: tht-maintenance",
|
||||
"x-thoth-principal-display-name: Tht maintenance",
|
||||
"x-thoth-is-admin: 1",
|
||||
} {
|
||||
if !strings.Contains(call, header) {
|
||||
t.Fatalf("maintenance call %q lacks %q", call, header)
|
||||
}
|
||||
}
|
||||
joined := strings.Join(fake.calls, "\n")
|
||||
for _, action := range []string{"operator-command.js maintenance-activate", "operator-command.js maintenance-status"} {
|
||||
if !strings.Contains(joined, action) {
|
||||
t.Fatalf("maintenance action %q was not made: %s", action, joined)
|
||||
}
|
||||
if !found {
|
||||
t.Fatalf("maintenance call %q was not made", path)
|
||||
}
|
||||
for _, forbidden := range []string{"curl", "x-thoth-principal", "x-thoth-is-admin"} {
|
||||
if strings.Contains(joined, forbidden) {
|
||||
t.Fatalf("maintenance commands retained HTTP identity material %q: %s", forbidden, joined)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1074,7 +1063,7 @@ func (f *fakeRunner) Run(_ context.Context, args []string, _ io.Reader) (compose
|
||||
if f.fail == "version" && (f.built || f.recreated) && strings.Contains(call, "pi --version") && strings.Contains(call, "exec") {
|
||||
return compose.Result{ExitCode: 1}, errors.New("version token=secret")
|
||||
}
|
||||
if f.fail == "smoke" && (f.built || f.recreated) && strings.Contains(call, "127.0.0.1:8787/pi-management/test") {
|
||||
if f.fail == "smoke" && (f.built || f.recreated) && strings.Contains(call, "operator-command.js pi-test") {
|
||||
return compose.Result{ExitCode: 1}, errors.New("smoke token=secret")
|
||||
}
|
||||
switch {
|
||||
@@ -1106,7 +1095,7 @@ func (f *fakeRunner) Run(_ context.Context, args []string, _ io.Reader) (compose
|
||||
return compose.Result{Stdout: f.mountsJSON}, nil
|
||||
}
|
||||
return compose.Result{Stdout: `[{"Type":"volume","Name":"settings","Source":"settings","Destination":"/data/settings","RW":true},{"Type":"volume","Name":"pi-state","Source":"pi-state","Destination":"/home/thoth/.pi","RW":true},{"Type":"volume","Name":"sessions","Source":"sessions","Destination":"/data/sessions","RW":true},{"Type":"volume","Name":"workspace-registry","Source":"workspace-registry","Destination":"/data/workspace-registry","RW":true}]`}, nil
|
||||
case strings.Contains(call, "/internal/maintenance/activate"):
|
||||
case strings.Contains(call, "operator-command.js maintenance-activate"):
|
||||
f.maintenance = true
|
||||
if f.fail == "maintenance-activate-durability" || f.fail == "maintenance-activate-durability-without-status-flag" {
|
||||
return compose.Result{ExitCode: 22}, errors.New("maintenance activation durability was not acknowledged")
|
||||
@@ -1119,7 +1108,7 @@ func (f *fakeRunner) Run(_ context.Context, args []string, _ io.Reader) (compose
|
||||
return compose.Result{ExitCode: 52}, errors.New("lost activation response")
|
||||
}
|
||||
return compose.Result{Stdout: `{"active":true,"admissions":0}`}, nil
|
||||
case strings.Contains(call, "/internal/maintenance/deactivate"):
|
||||
case strings.Contains(call, "operator-command.js maintenance-deactivate"):
|
||||
if f.fail == "maintenance-clear" {
|
||||
return compose.Result{ExitCode: 53}, errors.New("maintenance clear failure")
|
||||
}
|
||||
@@ -1138,7 +1127,7 @@ func (f *fakeRunner) Run(_ context.Context, args []string, _ io.Reader) (compose
|
||||
return compose.Result{ExitCode: 52}, errors.New("lost deactivation response")
|
||||
}
|
||||
return compose.Result{Stdout: `{"active":false,"admissions":0}`}, nil
|
||||
case strings.Contains(call, "/internal/maintenance/status"):
|
||||
case strings.Contains(call, "operator-command.js maintenance-status"):
|
||||
if f.fail == "maintenance-proof" && f.recreated {
|
||||
return compose.Result{Stdout: fmt.Sprintf(`{"active":%t,"admissions":0,"recoveryRequired":true}`, f.maintenance)}, nil
|
||||
}
|
||||
@@ -1149,7 +1138,7 @@ func (f *fakeRunner) Run(_ context.Context, args []string, _ io.Reader) (compose
|
||||
return compose.Result{Stdout: fmt.Sprintf(`{"active":%t,"admissions":0,"recoveryRequired":true}`, f.maintenance)}, nil
|
||||
}
|
||||
return compose.Result{Stdout: fmt.Sprintf(`{"active":%t,"admissions":0}`, f.maintenance)}, nil
|
||||
case strings.Contains(call, "/sessions?scope=all"):
|
||||
case strings.Contains(call, "operator-command.js session-inventory all"):
|
||||
if f.sessionsWire != "" {
|
||||
return compose.Result{Stdout: f.sessionsWire}, nil
|
||||
}
|
||||
@@ -1230,12 +1219,12 @@ func (f *fakeRunner) Run(_ context.Context, args []string, _ io.Reader) (compose
|
||||
return compose.Result{Stdout: f.version + "\n"}, nil
|
||||
case strings.Contains(call, "PI_VERSION"):
|
||||
return compose.Result{Stdout: f.expectedVersion + "\n"}, nil
|
||||
case strings.Contains(call, "/pi-management/options"):
|
||||
case strings.Contains(call, "operator-command.js pi-options"):
|
||||
if f.piManagementOptionsWire != "" {
|
||||
return compose.Result{Stdout: f.piManagementOptionsWire}, nil
|
||||
}
|
||||
return compose.Result{Stdout: `{"providers":["provider"],"models":[{"id":"model","provider":"provider"}],"reasoning":["low","medium","high"]}`}, nil
|
||||
case strings.Contains(call, "/pi-management/test"):
|
||||
case strings.Contains(call, "operator-command.js pi-test"):
|
||||
if f.currentImage == "sha256:old" {
|
||||
f.restoredProofComplete = true
|
||||
}
|
||||
@@ -1248,7 +1237,7 @@ func (f *fakeRunner) Run(_ context.Context, args []string, _ io.Reader) (compose
|
||||
return compose.Result{Stdout: f.modelsWire}, nil
|
||||
}
|
||||
return compose.Result{Stdout: `{"models":[{"id":"model","provider":"provider"}]}`}, nil
|
||||
case strings.Contains(call, "/settings"):
|
||||
case strings.Contains(call, "operator-command.js effective-settings"):
|
||||
if f.currentImage == "sha256:old" {
|
||||
f.restoredProofComplete = true
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user