...

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

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

     1  package promote
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"flag"
     7  	"fmt"
     8  
     9  	"github.com/go-logr/logr"
    10  
    11  	"edge-infra.dev/pkg/edge/api/types"
    12  	"edge-infra.dev/pkg/f8n/warehouse/packagelock"
    13  	"edge-infra.dev/pkg/lib/gcp/pubsub"
    14  )
    15  
    16  const (
    17  	PromoteTag = "promote"
    18  	Latest     = "latest"
    19  )
    20  
    21  func Run(ctx context.Context, log logr.Logger) error {
    22  	cfg, err := newConfig()
    23  	if err != nil {
    24  		if errors.Is(err, flag.ErrHelp) {
    25  			return nil
    26  		}
    27  		log.Error(err, "failed to load config")
    28  		return err
    29  	}
    30  
    31  	log.Info("loaded config", "config", cfg)
    32  	log.Info("promotion started", "description", cfg.Description())
    33  
    34  	ps, err := pubsub.New(ctx, cfg.ForwarderProjectID)
    35  	if err != nil {
    36  		log.Error(err, "failed to create Pub/Sub connection to project", "project-id", cfg.ForwarderProjectID)
    37  		return err
    38  	}
    39  
    40  	plr, err := packagelock.NewRules()
    41  	if err != nil {
    42  		log.Error(err, "failed to create package lock rules")
    43  		return err
    44  	}
    45  
    46  	pl, err := plr.ParsePackageLock(cfg.LockFile)
    47  	if err != nil {
    48  		log.Error(err, "failed to parse package lock")
    49  		return err
    50  	}
    51  
    52  	digests, err := Promote(ctx, cfg, pl, ps)
    53  	if err != nil {
    54  		log.Error(err, "promotion failed")
    55  		return err
    56  	}
    57  
    58  	// TODO(aj185259): This is printing "digests" as eg "us-east1-docker.pkg.dev/ret-edge-stage1-foreman/warehouse-dk185217/banner-infra-cluster:latest"
    59  	// based on old packages.lock format. Update to more accurate message eventually
    60  	log.Info("promotion complete", "digests", digests)
    61  	return nil
    62  }
    63  
    64  func Promote(ctx context.Context, cfg *Config, pl packagelock.PackageLock, ps types.PubSubService) ([]string, error) {
    65  	sourceRepo := cfg.SourceRepo
    66  	destinationRepo := cfg.DestinationRepo
    67  	digests := []string{}
    68  
    69  	for _, lockPkg := range pl.Packages {
    70  		for _, version := range lockPkg.Versions {
    71  			if err := sourceRepo.EnsurePackageDigestExists(lockPkg.Name, version.Digest); err != nil {
    72  				return nil, fmt.Errorf("failed to get hash for package: %s, reason: %v", lockPkg.Name, err)
    73  			}
    74  		}
    75  	}
    76  
    77  	for _, lockPkg := range pl.Packages {
    78  		pkgDigests, err := promotePackage(ctx, lockPkg, sourceRepo, destinationRepo, ps)
    79  		if err != nil {
    80  			return nil, err
    81  		}
    82  		digests = append(digests, pkgDigests...)
    83  	}
    84  
    85  	return digests, nil
    86  }
    87  
    88  func promotePackage(ctx context.Context, lockPkg packagelock.LockPackage, sourceRepo, destinationRepo Repository, ps types.PubSubService) ([]string, error) {
    89  	tagsSent := []string{}
    90  	for _, version := range lockPkg.Versions {
    91  		// send all tags
    92  		for _, tag := range version.Tags {
    93  			// message format requires source repo to build digest
    94  			sourceDigest, err := sourceRepo.NewPackageDigest(lockPkg.Name, version.Digest)
    95  			if err != nil {
    96  				return nil, err
    97  			}
    98  
    99  			// message format requires destination repo to build tag
   100  			destinationTag, err := destinationRepo.NewPackageTag(lockPkg.Name, tag)
   101  			if err != nil {
   102  				return nil, err
   103  			}
   104  			msg := newPromotionMessage(sourceDigest, destinationTag, destinationRepo)
   105  			if err := msg.Send(ctx, ps); err != nil {
   106  				return nil, fmt.Errorf("failed to publish promotion message to topic: %s, reason: %v", PromotionsTopic, err)
   107  			}
   108  			tagsSent = append(tagsSent, tag)
   109  		}
   110  	}
   111  	return destinationRepo.PackageTagRefs(lockPkg.Name, tagsSent), nil
   112  }
   113  

View as plain text