feat: add deployment foundation and cross-device handoff
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
package installplan
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Lock struct {
|
||||
ProtocolVersion int `json:"protocolVersion"`
|
||||
Repository string `json:"repository"`
|
||||
Suite string `json:"suite"`
|
||||
Architecture string `json:"architecture"`
|
||||
ReleaseDigest string `json:"releaseDigest"`
|
||||
Packages []Package `json:"packages"`
|
||||
}
|
||||
type Package struct {
|
||||
Name string `json:"name"`
|
||||
Version string `json:"version"`
|
||||
Filename string `json:"filename"`
|
||||
Digest string `json:"digest"`
|
||||
Size uint64 `json:"size"`
|
||||
}
|
||||
|
||||
var versionPattern = regexp.MustCompile(`^(?:[0-9]+:)?[0-9][0-9A-Za-z.+~-]*$`)
|
||||
var digestPattern = regexp.MustCompile(`^sha256:[0-9a-f]{64}$`)
|
||||
var required = []string{"docker-ce", "docker-ce-cli", "containerd.io", "docker-buildx-plugin", "docker-compose-plugin"}
|
||||
|
||||
// Validate checks a caller-supplied lock against a fixed source policy. This is
|
||||
// NOT repository signature validation or evidence these artifacts exist.
|
||||
func Validate(lock Lock, suite, architecture string) (string, error) {
|
||||
reject := errors.New("invalid Docker package lock")
|
||||
if lock.ProtocolVersion != 1 || lock.Repository != "https://download.docker.com/linux/ubuntu" || lock.Suite != suite || lock.Architecture != architecture {
|
||||
return "", reject
|
||||
}
|
||||
if (suite != "jammy" && suite != "noble" && suite != "resolute") || (architecture != "amd64" && architecture != "arm64") || !digestPattern.MatchString(lock.ReleaseDigest) || len(lock.Packages) != len(required) {
|
||||
return "", reject
|
||||
}
|
||||
versions := map[string]string{}
|
||||
for _, p := range lock.Packages {
|
||||
allowed := false
|
||||
for _, name := range required {
|
||||
if p.Name == name {
|
||||
allowed = true
|
||||
}
|
||||
}
|
||||
if !allowed || versions[p.Name] != "" || len(p.Version) > 128 || !versionPattern.MatchString(p.Version) || !digestPattern.MatchString(p.Digest) || p.Size == 0 || p.Size > 512<<20 {
|
||||
return "", reject
|
||||
}
|
||||
fileVersion := p.Version
|
||||
if _, after, ok := strings.Cut(fileVersion, ":"); ok {
|
||||
fileVersion = after
|
||||
}
|
||||
if p.Filename != "dists/"+suite+"/pool/stable/"+architecture+"/"+p.Name+"_"+fileVersion+"_"+architecture+".deb" {
|
||||
return "", reject
|
||||
}
|
||||
versions[p.Name] = p.Version
|
||||
}
|
||||
if versions["docker-ce"] != versions["docker-ce-cli"] {
|
||||
return "", reject
|
||||
}
|
||||
raw, _ := json.Marshal(lock)
|
||||
sum := sha256.Sum256(raw)
|
||||
return "sha256:" + hex.EncodeToString(sum[:]), nil
|
||||
}
|
||||
Reference in New Issue
Block a user