mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-10-15 00:22:28 +00:00
33d318a29e
The only production consumer of the UpdaterRegistry is the plan endpoint (GET /api/updates/plan); every real apply runs through the in-Go pipeline in manager.go ApplyUpdate, with concurrency held by updateMu/updateInFlight. The InstallShAdapter Execute/Rollback path (install.sh piping, rollback binary download, health wait) and the UpdateQueue were never called outside tests, so fixes made there silently did nothing. Adapters are now plan providers only: the Updater interface keeps SupportsApply, PrepareUpdate, and GetDeploymentType, pinned by the new registry proof in internal/api/updates_test.go. The orphaned fetchAndVerifyReleaseSignature helper goes with it; its fail-closed sidecar tests now exercise the manager's downloadAndVerifyReleaseSignature directly. The deployment-installability sshsig invariant now names the manager pipeline as the only surface that fetches release artifacts, and api-contracts, storage-recovery, and agent-lifecycle pin the same plan-provider-only shape at their update transport boundaries. Stale adapter references in build-release.sh, validate-release.sh, and the installtests comments are updated to match.
102 lines
3.1 KiB
Go
102 lines
3.1 KiB
Go
package updates
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
)
|
|
|
|
// UpdateRequest represents a request to update
|
|
type UpdateRequest struct {
|
|
Version string
|
|
Channel string
|
|
Force bool
|
|
DryRun bool
|
|
}
|
|
|
|
// UpdatePlan contains information about how an update will be performed
|
|
type UpdatePlan struct {
|
|
CanAutoUpdate bool `json:"canAutoUpdate"`
|
|
Instructions []string `json:"instructions"`
|
|
Prerequisites []string `json:"prerequisites"`
|
|
EstimatedTime string `json:"estimatedTime,omitempty"`
|
|
RequiresRoot bool `json:"requiresRoot"`
|
|
RollbackSupport bool `json:"rollbackSupport"`
|
|
DownloadURL string `json:"downloadUrl,omitempty"`
|
|
Readiness *UpdateReadiness `json:"readiness,omitempty"`
|
|
}
|
|
|
|
// UpdateReadiness is the operator-facing preflight summary attached to an
|
|
// update plan. It is advisory unless a check is explicitly "blocked".
|
|
type UpdateReadiness struct {
|
|
Status string `json:"status"`
|
|
Summary string `json:"summary"`
|
|
Checks []UpdateReadinessCheck `json:"checks"`
|
|
}
|
|
|
|
// UpdateReadinessCheck is one concrete compatibility or continuity check for
|
|
// the requested server update.
|
|
type UpdateReadinessCheck struct {
|
|
ID string `json:"id"`
|
|
Status string `json:"status"`
|
|
Title string `json:"title"`
|
|
Summary string `json:"summary"`
|
|
Details []string `json:"details,omitempty"`
|
|
}
|
|
|
|
func EmptyUpdatePlan() UpdatePlan {
|
|
return UpdatePlan{}.NormalizeCollections()
|
|
}
|
|
|
|
func (p UpdatePlan) NormalizeCollections() UpdatePlan {
|
|
if p.Instructions == nil {
|
|
p.Instructions = []string{}
|
|
}
|
|
if p.Prerequisites == nil {
|
|
p.Prerequisites = []string{}
|
|
}
|
|
if p.Readiness != nil && p.Readiness.Checks == nil {
|
|
p.Readiness.Checks = []UpdateReadinessCheck{}
|
|
}
|
|
return p
|
|
}
|
|
|
|
// Updater describes how an update would be performed for a deployment type.
|
|
// Implementations are plan providers only; the actual apply runs through the
|
|
// in-Go pipeline in manager.go ApplyUpdate.
|
|
type Updater interface {
|
|
// SupportsApply returns true if this deployment type supports automated updates
|
|
SupportsApply() bool
|
|
|
|
// PrepareUpdate returns a plan describing how the update will be performed
|
|
PrepareUpdate(ctx context.Context, request UpdateRequest) (*UpdatePlan, error)
|
|
|
|
// GetDeploymentType returns the deployment type this updater handles
|
|
GetDeploymentType() string
|
|
}
|
|
|
|
// UpdaterRegistry manages updaters for different deployment types
|
|
type UpdaterRegistry struct {
|
|
updaters map[string]Updater
|
|
}
|
|
|
|
// NewUpdaterRegistry creates a new updater registry
|
|
func NewUpdaterRegistry() *UpdaterRegistry {
|
|
return &UpdaterRegistry{
|
|
updaters: make(map[string]Updater),
|
|
}
|
|
}
|
|
|
|
// Register registers an updater for a deployment type
|
|
func (r *UpdaterRegistry) Register(deploymentType string, updater Updater) {
|
|
r.updaters[deploymentType] = updater
|
|
}
|
|
|
|
// Get returns the updater for a deployment type
|
|
func (r *UpdaterRegistry) Get(deploymentType string) (Updater, error) {
|
|
updater, ok := r.updaters[deploymentType]
|
|
if !ok {
|
|
return nil, fmt.Errorf("no updater registered for deployment type: %s", deploymentType)
|
|
}
|
|
return updater, nil
|
|
}
|