...

Source file src/edge-infra.dev/pkg/f8n/warehouse/release/environment.go

Documentation: edge-infra.dev/pkg/f8n/warehouse/release

     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  // A release Environment is the structure for turning a list of EdgeReleases into
    16  // a series of explicit pallets, their digests, and associated tags
    17  //
    18  // The CurrentVersion field indicates which version is the most recent and notes
    19  // which version should be tagged with the "latest" tag
    20  // Example (stage1):
    21  //
    22  // source_repository:
    23  //
    24  //	name: "warehouse"
    25  //	location: "us-east1"
    26  //	project: "ret-edge-pltf-infra"
    27  //
    28  // current: "0.20.16"
    29  // additional:
    30  //   - "0.19.11"
    31  //   - "0.18.12"
    32  //
    33  // would create a packagelock.yaml file in the stage1 environment directory
    34  // that contains all of the packages and their sha256 values contained in the
    35  // above releases
    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