feat: move distribution builds to platform Docker builder

This commit is contained in:
npc0-hue
2026-07-30 19:25:50 +08:00
parent 1e004dc9ec
commit e614a17fe3
45 changed files with 4492 additions and 294 deletions
+41 -8
View File
@@ -249,6 +249,9 @@ type CoreService struct {
aiProviderClient AIProviderClient
secretEnvelope SecretEnvelope
networkFingerprintKey []byte
distributionBuilder DistributionBuilder
distributionBuildMu sync.Mutex
distributionBuilds map[string]struct{}
}
var _ Core = (*CoreService)(nil)
@@ -284,10 +287,34 @@ func newCoreServiceWithLogStore(store repo.Store, logStore LogBodyStore, now fun
aiProviderClient: MockAIProviderClient{},
secretEnvelope: newSecretEnvelope(developmentSecretEnvelopeKey),
networkFingerprintKey: []byte(developmentSecretEnvelopeKey),
distributionBuilder: unconfiguredDistributionBuilder{},
distributionBuilds: map[string]struct{}{},
}
return service
}
// ConfigureDistributionBuilder installs the platform-owned builder that
// executes distribution builds. Build execution is a platform responsibility,
// so a nil builder leaves the platform reporting an unconfigured builder rather
// than falling back to a machine-side run endpoint.
func (svc *CoreService) ConfigureDistributionBuilder(builder DistributionBuilder) {
if builder == nil {
builder = unconfiguredDistributionBuilder{}
}
svc.distributionBuildMu.Lock()
svc.distributionBuilder = builder
svc.distributionBuildMu.Unlock()
jobs, err := svc.store.Jobs().List(domain.JobFilter{RunEndpointID: platformDistributionBuilderEndpointID})
if err != nil {
return
}
for _, job := range jobs {
if job.Capability == domain.JobCapabilityDistributionBuild && !isTerminalJobState(job.State) {
svc.enqueueDistributionBuild(job)
}
}
}
func NewCoreServiceWithDurableStores(store repo.Store, logStore LogBodyStore, artifactStore ArtifactBodyStore) (*CoreService, error) {
if artifactStore == nil {
artifactStore = NewMemoryArtifactBodyStore()
@@ -2195,12 +2222,18 @@ func (svc *CoreService) CreateJob(job domain.Job) (domain.Job, error) {
return domain.Job{}, err
}
endpoint, err := svc.store.RunEndpoints().Get(job.RunEndpointID)
if err != nil {
return domain.Job{}, fmt.Errorf("get run endpoint dependency: %w", err)
}
if err := svc.validateRunnableEndpoint(endpoint, job.Capability); err != nil {
return domain.Job{}, err
if job.Capability == domain.JobCapabilityDistributionBuild {
if job.RunEndpointID != platformDistributionBuilderEndpointID {
return domain.Job{}, validationError("distribution build job must target the platform builder")
}
} else {
endpoint, err := svc.store.RunEndpoints().Get(job.RunEndpointID)
if err != nil {
return domain.Job{}, fmt.Errorf("get run endpoint dependency: %w", err)
}
if err := svc.validateRunnableEndpoint(endpoint, job.Capability); err != nil {
return domain.Job{}, err
}
}
if job.ServerInstanceID != "" {
instance, err := svc.store.ServerInstances().Get(job.ServerInstanceID)
@@ -2346,8 +2379,8 @@ func validateJobServerTarget(job domain.Job, instance domain.ServerInstance, plu
if instance.State == domain.ServerInstanceStateDeleted {
return validationError("server instance must not be deleted")
}
usesDeploymentTarget := job.Capability == domain.JobCapabilityDistributionBuild && instance.DeploymentTargetID != "" && instance.DeploymentTargetID == job.RunEndpointID
if instance.RunEndpointID != job.RunEndpointID && !usesDeploymentTarget {
usesPlatformBuilder := job.Capability == domain.JobCapabilityDistributionBuild && job.RunEndpointID == platformDistributionBuilderEndpointID
if instance.RunEndpointID != job.RunEndpointID && !usesPlatformBuilder {
return validationError("job runEndpointId must match server instance")
}
if plugin.ID != instance.PluginID {