1 package release
2
3 import (
4 "fmt"
5 "strings"
6
7 "github.com/go-logr/logr"
8 ociname "github.com/google/go-containerregistry/pkg/name"
9
10 edgename "edge-infra.dev/pkg/f8n/warehouse/oci/name"
11 "edge-infra.dev/pkg/f8n/warehouse/oci/remote"
12 "edge-infra.dev/pkg/f8n/warehouse/packagelock"
13 )
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36 type Environment struct {
37 SourceRepository Repository `yaml:"source_repository"`
38 CurrentVersion string `yaml:"current"`
39 AdditionalVersions []string `yaml:"additional,omitempty"`
40 Log logr.Logger
41 }
42
43 func (e *Environment) PullReleases() ([]EdgeRelease, error) {
44 versions := []string{e.CurrentVersion}
45 versions = append(versions, e.AdditionalVersions...)
46 releases := []EdgeRelease{}
47
48 for _, version := range versions {
49 pkgPath := fmt.Sprintf("%s/%s:%s", e.SourceRepository, ReleaseImageName, version)
50 t, err := edgename.Tag(
51 pkgPath,
52 []ociname.Option{
53 ociname.WithDefaultRegistry(e.SourceRepository.Registry()),
54 }...,
55 )
56 if err != nil {
57 return nil, err
58 }
59
60 e.Log.Info(fmt.Sprintf("pulling %s", pkgPath))
61 relDescr, err := remote.Get(t)
62 if err != nil {
63 return nil, err
64 }
65
66 release, err := ImageIndex(relDescr)
67 if err != nil {
68 return nil, err
69 }
70 releases = append(releases, release)
71 }
72
73 return releases, nil
74 }
75
76 func (e *Environment) LockReleases(releases []EdgeRelease) (packagelock.PackageLock, error) {
77 palletVersionMap := map[string][]packagelock.Version{}
78 for _, r := range releases {
79 isLatest := false
80 if r.Metadata.Version == e.CurrentVersion {
81 isLatest = true
82 }
83
84 releaseLocks, err := lockRelease(r, isLatest)
85 if err != nil {
86 return packagelock.PackageLock{}, err
87 }
88
89 for _, rl := range releaseLocks {
90 _, found := palletVersionMap[rl.Name]
91 if !found {
92 palletVersionMap[rl.Name] = rl.Versions
93 } else {
94 palletVersionMap[rl.Name] = append(palletVersionMap[rl.Name], rl.Versions...)
95 }
96 }
97 }
98 packages := packagelock.Packages{}
99 for pName, versions := range palletVersionMap {
100 packages = append(packages, packagelock.LockPackage{Name: pName, Versions: versions})
101 }
102
103 return packagelock.PackageLock{Packages: packages}, nil
104 }
105
106 func lockRelease(r EdgeRelease, isLatest bool) ([]packagelock.LockPackage, error) {
107 lockPackages := []packagelock.LockPackage{}
108 for _, p := range r.Pallets {
109 pHash, err := p.Digest()
110 if err != nil {
111 return nil, err
112 }
113
114 minor, err := semverPatchToMinor(r.Metadata.Version)
115 if err != nil {
116 return nil, err
117 }
118
119 tags := []string{r.Metadata.Version, minor}
120
121 if isLatest {
122 tags = append(tags, "latest")
123 }
124
125 lp := packagelock.LockPackage{
126 Name: p.Name(),
127 Versions: []packagelock.Version{
128 {
129 Digest: fmt.Sprintf("sha256:%s", pHash.Hex),
130 Tags: tags,
131 },
132 },
133 }
134 lockPackages = append(lockPackages, lp)
135 }
136
137 return lockPackages, nil
138 }
139
140 func semverPatchToMinor(v string) (string, error) {
141 elems := strings.Split(v, ".")
142 if len(elems) != 3 {
143 return "", fmt.Errorf("could not create minor version out of semver %s", v)
144 }
145
146 return fmt.Sprintf("%s.%s", elems[0], elems[1]), nil
147 }
148
View as plain text