feat: reveal saved server deployment inputs
This commit is contained in:
@@ -86,6 +86,7 @@ type Core interface {
|
||||
CreateServerInstanceWorkflow(domain.ServerLifecycleCreate) (domain.ServerLifecycleResult, error)
|
||||
CreateServerInstanceWorkflowForSession(string, domain.ServerLifecycleCreate) (domain.ServerLifecycleResult, error)
|
||||
GetServerDeploymentForSession(string, string) (domain.ServerDeploymentView, error)
|
||||
RevealServerDeploymentForSession(string, string) (domain.ServerDeploymentReveal, error)
|
||||
UpdateServerDeploymentForSession(string, string, domain.ServerDeploymentUpdate) (domain.ServerDeploymentView, error)
|
||||
DeployServerInstanceForSession(string, domain.ServerLifecycleCommand) (domain.ServerLifecycleResult, error)
|
||||
StartServerInstance(domain.ServerLifecycleCommand) (domain.ServerLifecycleResult, error)
|
||||
|
||||
@@ -3,6 +3,7 @@ package service
|
||||
import (
|
||||
"errors"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"browser.local/platform/domain"
|
||||
"browser.local/platform/repo"
|
||||
@@ -17,7 +18,16 @@ func (svc *CoreService) GetServerDeploymentForSession(sessionID, serverInstanceI
|
||||
if err != nil {
|
||||
return domain.ServerDeploymentView{}, err
|
||||
}
|
||||
return deploymentView(instance), nil
|
||||
return svc.deploymentView(instance)
|
||||
}
|
||||
|
||||
func (svc *CoreService) RevealServerDeploymentForSession(sessionID, serverInstanceID string) (domain.ServerDeploymentReveal, error) {
|
||||
_, instance, err := svc.requireServerOwner(sessionID, serverInstanceID)
|
||||
if err != nil {
|
||||
return domain.ServerDeploymentReveal{}, err
|
||||
}
|
||||
definition := instance.Deployment
|
||||
return domain.ServerDeploymentReveal{ServerInstanceID: instance.ID, ServerRoot: definition.ServerRoot, WorkingDirectory: definition.WorkingDirectory, InstallCommand: definition.InstallCommand, StartCommand: definition.StartCommand, StopCommand: definition.StopCommand, StatusCommand: definition.StatusCommand}, nil
|
||||
}
|
||||
|
||||
func (svc *CoreService) UpdateServerDeploymentForSession(sessionID, serverInstanceID string, update domain.ServerDeploymentUpdate) (domain.ServerDeploymentView, error) {
|
||||
@@ -70,7 +80,7 @@ func (svc *CoreService) UpdateServerDeploymentForSession(sessionID, serverInstan
|
||||
if err := svc.store.ServerInstances().Update(instance); err != nil {
|
||||
return domain.ServerDeploymentView{}, err
|
||||
}
|
||||
return deploymentView(instance), nil
|
||||
return svc.deploymentView(instance)
|
||||
}
|
||||
|
||||
func (svc *CoreService) DeployServerInstanceForSession(sessionID string, command domain.ServerLifecycleCommand) (domain.ServerLifecycleResult, error) {
|
||||
@@ -216,11 +226,24 @@ func mergeDeploymentDefinition(current domain.ServerDeploymentDefinition, update
|
||||
return definition
|
||||
}
|
||||
|
||||
func deploymentView(instance domain.ServerInstance) domain.ServerDeploymentView {
|
||||
func (svc *CoreService) deploymentView(instance domain.ServerInstance) (domain.ServerDeploymentView, error) {
|
||||
definition := instance.Deployment
|
||||
return domain.CopyServerDeploymentView(domain.ServerDeploymentView{
|
||||
view := domain.ServerDeploymentView{
|
||||
ServerInstanceID: instance.ID, Mode: definition.Mode, ProfileKey: definition.ProfileKey, CreateInputs: domain.CopyStringMap(definition.CreateInputs),
|
||||
ServerRootConfigured: definition.ServerRoot != "", WorkingDirectoryConfigured: definition.WorkingDirectory != "", InstallCommandConfigured: definition.InstallCommand != "", StartCommandConfigured: definition.StartCommand != "", StopCommandConfigured: definition.StopCommand != "", StatusCommandConfigured: definition.StatusCommand != "", Shell: definition.Shell, Revision: definition.Revision, UpdatedAt: definition.UpdatedAt,
|
||||
Projection: instance.DeploymentProjection,
|
||||
})
|
||||
}
|
||||
jobs, err := svc.store.Jobs().List(domain.JobFilter{ServerInstanceID: instance.ID})
|
||||
if err != nil {
|
||||
return domain.ServerDeploymentView{}, err
|
||||
}
|
||||
var latestDispatchAt time.Time
|
||||
for _, job := range jobs {
|
||||
if job.ExecutionInput.Deployment == nil || (view.LatestDispatch != nil && !job.CreatedAt.After(latestDispatchAt)) {
|
||||
continue
|
||||
}
|
||||
view.LatestDispatch = &domain.ServerDeploymentDispatchEvidence{JobID: job.ID, JobState: job.State, DeploymentRevision: job.ExecutionInput.Deployment.Revision, DeploymentDefinitionIncluded: true}
|
||||
latestDispatchAt = job.CreatedAt
|
||||
}
|
||||
return domain.CopyServerDeploymentView(view), nil
|
||||
}
|
||||
|
||||
@@ -32,6 +32,10 @@ func TestCoreServiceSavesDraftDeploymentRedactsReadsAndDispatchesOnlyToCompatibl
|
||||
if strings.Contains(strings.Join([]string{view.ServerInstanceID, string(view.Mode), view.ProfileKey}, " "), "/srv/") {
|
||||
t.Fatalf("redacted deployment view leaked host path: %+v", view)
|
||||
}
|
||||
revealed, err := svc.RevealServerDeploymentForSession(ownerSession, draft.Instance.ID)
|
||||
if err != nil || revealed.ServerRoot != "/srv/venv-server" || revealed.WorkingDirectory != "/srv/venv-server" || revealed.StartCommand != "/srv/venv-server/.venv/bin/python server.py" {
|
||||
t.Fatalf("expected explicit deployment reveal, reveal=%+v err=%v", revealed, err)
|
||||
}
|
||||
|
||||
if _, err := svc.UpdateServerDeploymentForSession(ownerSession, draft.Instance.ID, domain.ServerDeploymentUpdate{RunEndpointID: "run-local", Mode: domain.ServerDeploymentModeCustom}); err != nil {
|
||||
t.Fatalf("bind draft to run: %v", err)
|
||||
@@ -55,4 +59,8 @@ func TestCoreServiceSavesDraftDeploymentRedactsReadsAndDispatchesOnlyToCompatibl
|
||||
if deployed.Job.ExecutionInput.Deployment == nil || deployed.Job.ExecutionInput.Deployment.StartCommand != "/srv/venv-server/.venv/bin/python server.py" || deployed.Job.Progress.Phase != "queued" {
|
||||
t.Fatalf("Run job must carry protected plan and queued phase: %+v", deployed.Job)
|
||||
}
|
||||
view, err = svc.GetServerDeploymentForSession(ownerSession, draft.Instance.ID)
|
||||
if err != nil || view.LatestDispatch == nil || view.LatestDispatch.JobID != deployed.Job.ID || view.LatestDispatch.DeploymentRevision != deployed.Job.ExecutionInput.Deployment.Revision || !view.LatestDispatch.DeploymentDefinitionIncluded {
|
||||
t.Fatalf("expected safe dispatch evidence, view=%+v err=%v", view, err)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user