Files
server-deploy/internal/installplan/plan.go
T

43 lines
1.9 KiB
Go

package installplan
import (
"crypto/sha256"
"encoding/hex"
"encoding/json"
"errors"
"server-deploy/internal/preflight"
)
type Draft struct {
Executable bool `json:"executable"`
RepositoryAuthenticated bool `json:"repositoryAuthenticated"`
LockDigest string `json:"lockDigest"`
ObservationDigest string `json:"observationDigest"`
Blockers []string `json:"blockers"`
RequestedPackages []Package `json:"requestedPackages"`
Impacts []string `json:"impacts"`
}
// Build binds requested package pins to a local observation for review only.
// Neither digest is a signature, host identity, freshness token or approval.
func Build(report preflight.Report, lock Lock) (Draft, error) {
digest, err := Validate(lock, lock.Suite, lock.Architecture)
if err != nil {
return Draft{}, err
}
if report.Runtime.OS == "linux" && (report.Runtime.Architecture != lock.Architecture || (report.Distribution.State == "observed" && (report.Distribution.ID != "ubuntu" || report.Distribution.Codename != lock.Suite))) {
return Draft{}, errors.New("lock does not match local platform")
}
proposal := preflight.Plan(report)
blockers := []string{}
for _, b := range proposal.Blockers {
if b != "package_versions_unresolved" {
blockers = append(blockers, b)
}
}
blockers = append(blockers, "dependency_transaction_unresolved", "artifact_bytes_unverified", "repository_metadata_freshness_unverified")
raw, _ := json.Marshal(report)
sum := sha256.Sum256(raw)
return Draft{LockDigest: digest, ObservationDigest: "sha256:" + hex.EncodeToString(sum[:]), Blockers: blockers, RequestedPackages: append([]Package{}, lock.Packages...), Impacts: []string{"package_database_and_repository_changes", "services_may_start_during_package_install", "host_network_rules_may_change", "additional_dependencies_not_yet_resolved"}}, nil
}