feat: move distribution builds to platform Docker builder
This commit is contained in:
@@ -291,7 +291,9 @@ func TestConfigWriteAndFileDispatchAPIAreScopedAndSafe(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestCoreAPIServerRuntimeDistributionAndJobWorkflows(t *testing.T) {
|
||||
router := newTestRouter()
|
||||
releaseBuilds := make(chan struct{})
|
||||
t.Cleanup(func() { close(releaseBuilds) })
|
||||
router := newTestRouterWithDistributionBuilder(apiTestDistributionBuilder{release: releaseBuilds})
|
||||
adminSession := createAdminSession(t, router)
|
||||
serverID := createRuntimeAPIFixtures(t, router, adminSession)
|
||||
|
||||
@@ -1604,14 +1606,34 @@ func TestProductionOperationsGovernanceRoutesAreDurableAndRedacted(t *testing.T)
|
||||
}
|
||||
}
|
||||
|
||||
func newTestRouter() http.Handler {
|
||||
type apiTestDistributionBuilder struct {
|
||||
release <-chan struct{}
|
||||
}
|
||||
|
||||
func (builder apiTestDistributionBuilder) Readiness() (bool, string) {
|
||||
return true, ""
|
||||
}
|
||||
|
||||
func (builder apiTestDistributionBuilder) Build(input domain.DistributionBuildInput) ([]byte, error) {
|
||||
if builder.release != nil {
|
||||
<-builder.release
|
||||
}
|
||||
return []byte("api-platform-built-distribution:" + input.JobID), nil
|
||||
}
|
||||
|
||||
func newTestRouterWithDistributionBuilder(builder service.DistributionBuilder) http.Handler {
|
||||
core := service.NewCoreService(repo.NewMemoryStore())
|
||||
core.ConfigureDistributionBuilder(builder)
|
||||
if err := core.SeedLocalPlatformAdmin(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return NewTestRouterWithCore(core)
|
||||
}
|
||||
|
||||
func newTestRouter() http.Handler {
|
||||
return newTestRouterWithDistributionBuilder(nil)
|
||||
}
|
||||
|
||||
func apiRouterWithoutSeededAdmin() http.Handler {
|
||||
return NewTestRouterWithCore(service.NewCoreService(repo.NewMemoryStore()))
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"browser.local/platform/config"
|
||||
"browser.local/platform/repo"
|
||||
@@ -47,6 +48,13 @@ func NewRouterFromConfig(cfg config.Config) (http.Handler, error) {
|
||||
if err := core.ConfigureSecretEnvelopeKey(cfg.SecretEnvelopeKey); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
core.ConfigureDistributionBuilder(service.NewDockerDistributionBuilder(service.DockerDistributionBuilderConfig{
|
||||
DockerBinary: cfg.BuilderDockerBinary,
|
||||
Image: cfg.BuilderImage,
|
||||
SourceDir: cfg.BuilderSourceDir,
|
||||
WorkspaceDir: cfg.BuilderWorkspaceDir,
|
||||
Timeout: time.Duration(cfg.BuilderTimeoutSeconds) * time.Second,
|
||||
}))
|
||||
if err := core.ConfigureAIProviderMode(cfg.AIProviderMode); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -137,7 +137,7 @@ Artifact bridge execution returns safe metadata and platform content routes only
|
||||
|
||||
## Implemented Server Lifecycle Actions
|
||||
|
||||
- `POST /api/v1/server-instances/workflows/create`: accepts `ServerLifecycleCreateRequest`. A legacy `runEndpointId` creates and dispatches through the existing endpoint. A `deploymentTargetId` creates a target-bound draft with a reserved dedicated Run identity; no install job is dispatched until that Run registers and `deploy` is requested.
|
||||
- `POST /api/v1/server-instances/workflows/create`: accepts `ServerLifecycleCreateRequest`. Creation requires only `pluginId` and `name`; it creates an unbound instance without dispatching an install job. Runtime binding and optional deployment settings are configured after creation. Legacy `runEndpointId` and `deploymentTargetId` inputs remain accepted for compatible programmatic flows, but are never prerequisites for creation and do not select a distribution builder.
|
||||
- `POST /api/v1/server-instances/{id}/start`: accept `ServerLifecycleCommandRequest`, validate state/config version/run capability, and queue a `process.start` job using `ServerLifecycleResponse`.
|
||||
- `POST /api/v1/server-instances/{id}/stop`: accept `ServerLifecycleCommandRequest`, validate state/config version/run capability, and queue a `process.stop` job using `ServerLifecycleResponse`.
|
||||
|
||||
@@ -148,7 +148,7 @@ Lifecycle workflow responses include accepted status, action, bounded server ins
|
||||
- `GET /api/v1/server-instances/{id}/runtime-binding`: returns the visible server's selected profile and redacted logical binding readiness. Values are represented only by configured/secret-backed flags.
|
||||
- `PUT /api/v1/server-instances/{id}/runtime-binding`: lets the server owner or a platform administrator select a declared profile and patch safe logical refs. Undeclared keys, unsafe paths/sockets/credentials, and changes to an existing active binding are rejected.
|
||||
- `GET /api/v1/server-instances/{id}/runtime/actions`: returns the current user-visible runtime action matrix for the server, including run endpoint status, action availability, and safe unavailable reasons.
|
||||
- `POST /api/v1/server-instances/{id}/run/generate`: accepts `RunDistributionGenerateRequest`, creates or reuses the server's current encrypted run key, writes that key into the secret-bearing generated package config, publishes an artifact, and returns `RunDistributionResponse` with checksum, key generation, artifact ID, and redacted secret ref only.
|
||||
- `POST /api/v1/server-instances/{id}/run/generate`: accepts `RunDistributionGenerateRequest`, queues a platform-owned Docker build, creates or reuses the server's current encrypted run key, writes that key into the secret-bearing generated package config, publishes an artifact, and returns `RunDistributionResponse` with checksum, key generation, artifact ID, build job ID, and redacted secret ref only.
|
||||
- `POST /api/v1/server-instances/{id}/run/download`: opens the latest available run package through `ArtifactDownloadReferenceResponse` after server-scoped authorization.
|
||||
- `POST /api/v1/server-instances/{id}/run/key/reset`: resets the server's single active run key, increments generation, revokes previous run packages, and returns `ComponentKeyResponse`.
|
||||
- `POST /api/v1/server-instances/{id}/run/update`: accepts `RunUpdateRequest` with an approved artifact ID/checksum and queues a bounded `run.self-update` job through `RunUpdateJobResponse`.
|
||||
@@ -162,9 +162,9 @@ Lifecycle workflow responses include accepted status, action, bounded server ins
|
||||
- `GET /api/v1/server-instances/{id}/logs/live`: returns safe live log stream metadata for the selected server using `LogStreamListResponse`.
|
||||
- `POST /api/v1/server-instances/{id}/logs/backfill`: accepts `LogBackfillRequest`, queues a `logs.backfill` job with source key, checkpoint ref, limit, and idempotency metadata, and keeps log bodies out of job results.
|
||||
|
||||
Runtime distribution and client-manager APIs require the current bearer session, server visibility, plugin-declared permissions, complete runtime bindings where required, and run endpoint capability support for run-side jobs. Responses and audit summaries expose artifact IDs, job IDs, checksums, key generations, fingerprints, status, and redacted `secret://runtime-keys/.../current` refs only. They do not expose raw run keys, client-manager keys, FTP passwords, database DSNs, RCON passwords, host paths, direct sockets, run endpoint private addresses, build workspace paths, or large inline logs.
|
||||
Runtime distribution and client-manager APIs require the current bearer session, server visibility, plugin-declared permissions, complete runtime bindings where required, and platform-builder readiness. Run-side lifecycle commands separately require run endpoint capability support. Responses and audit summaries expose artifact IDs, job IDs, checksums, key generations, fingerprints, status, and redacted `secret://runtime-keys/.../current` refs only. They do not expose raw run keys, client-manager keys, FTP passwords, database DSNs, RCON passwords, host paths, direct sockets, run endpoint private addresses, build workspace paths, or large inline logs.
|
||||
|
||||
`POST /api/v1/server-instances/workflows/create` requires `profileKey` and initial `bindings`. Platform validates completeness and persists the binding before dispatching the install job; the job `targetKey` identifies the selected declared profile. Existing servers without a binding remain readable, but lifecycle and runtime-dependent actions return a safe configuration-required reason.
|
||||
`POST /api/v1/server-instances/workflows/create` requires only the plugin type and server name. A runtime binding is set later through `PUT /api/v1/server-instances/{id}/runtime-binding`; until then, lifecycle and runtime-dependent actions return a safe configuration-required reason. Platform builds distributions itself and never needs a registered Run endpoint with `distribution.build` to do so.
|
||||
|
||||
## Private Run Dependency And Update Routes
|
||||
|
||||
|
||||
Reference in New Issue
Block a user