...

Source file src/edge-infra.dev/pkg/edge/edgeadmin/commands/cfg/updatemanifests/update_manifests.go

Documentation: edge-infra.dev/pkg/edge/edgeadmin/commands/cfg/updatemanifests

     1  // // Package updatemanifests contains the `cfg update-manifests` CLI command, which
     2  // // can be used in CI pipelines to update the container images a set of existing
     3  // // manifests reference and apply build metadata labels, e.g., commit, version,
     4  // // etc.
     5  // //
     6  // // The goal of this command is to allow easy integration between an existing
     7  // // CI pipeline and the Edge platform CI pipeline.
     8  // package updatemanifests
     9  
    10  // Package updatemanifests contains the `cfg update-manifests` CLI command, which
    11  // can be used in CI pipelines to update the container images a set of existing
    12  // manifests reference and apply build metadata labels, e.g., commit, version,
    13  // etc.
    14  //
    15  // The goal of this command is to allow easy integration between an existing
    16  // CI pipeline and the Edge platform CI pipeline.
    17  package updatemanifests
    18  
    19  import (
    20  	"context"
    21  	"fmt"
    22  	"path/filepath"
    23  	"strings"
    24  
    25  	goerrors "errors"
    26  
    27  	"github.com/google/go-containerregistry/pkg/crane"
    28  	"github.com/google/go-containerregistry/pkg/name"
    29  
    30  	"edge-infra.dev/pkg/edge/component/build/image"
    31  	"edge-infra.dev/pkg/edge/component/build/updatemanifests"
    32  	"edge-infra.dev/pkg/edge/constants"
    33  	"edge-infra.dev/pkg/edge/edgecli"
    34  	"edge-infra.dev/pkg/edge/edgecli/flagutil"
    35  	"edge-infra.dev/pkg/edge/gitops/fns/edgerelease"
    36  	"edge-infra.dev/pkg/lib/build/bazel"
    37  	"edge-infra.dev/pkg/lib/cli/command"
    38  	"edge-infra.dev/pkg/lib/cli/rags"
    39  	"edge-infra.dev/pkg/lib/errors"
    40  )
    41  
    42  // NewCmd creates a new cli.Command and returns it.
    43  func NewCmd(_ *edgecli.Config) *command.Command {
    44  	var flagsets []*rags.Rag
    45  	var imgFlag, manifestFlag, componentFlag string
    46  	var cmd *command.Command
    47  	cmd = &command.Command{
    48  		ShortUsage: "edgeadmin cfg update-manifests",
    49  		ShortHelp:  "updates manifests with provided image digests",
    50  		LongHelp:   fmt.Sprintf("update manifests for a K8s component, based on the Edge platform labels (%s)", constants.PlatformComponent),
    51  		Flags: append(flagsets,
    52  			&rags.Rag{
    53  				Name:     flagutil.Manifest,
    54  				Short:    "m",
    55  				Usage:    "path to directory containing K8s manifests to update, relative to working directory",
    56  				Required: true,
    57  				Value:    &rags.String{Var: &manifestFlag},
    58  			},
    59  			&rags.Rag{
    60  				Name: flagutil.Image,
    61  				Usage: `the image ref and container name for the component that the 
    62  	manifests should be updated to reference in the format name=ref. e.g.:
    63  	--image bff=us-east1-docker.pkg.dev/ret-edge-pltf-infra/workloads/bff:dev
    64  	--image controller=us-east1-docker.pkg.dev/ret-edge-pltf-infra/workloads/talaria:dev`,
    65  				Required: true,
    66  				Value:    &rags.String{Var: &imgFlag},
    67  			},
    68  			&rags.Rag{
    69  				Name:     flagutil.Components,
    70  				Short:    "c",
    71  				Usage:    fmt.Sprintf("the component that will have its manifests updated.  only manifests where the label %s matches this value will be updated", constants.PlatformComponent),
    72  				Required: true,
    73  				Value:    &rags.String{Var: &componentFlag},
    74  			},
    75  		),
    76  
    77  		Exec: func(_ context.Context, _ []string) error {
    78  			if err := flagutil.ValidateRequiredFlags(cmd.Rags); err != nil {
    79  				return err
    80  			}
    81  
    82  			refs := map[string]name.Reference{}
    83  			img := flagutil.GetStringFlag(cmd.Rags, flagutil.Image)
    84  			tokens := strings.Split(img, "=")
    85  			if len(tokens) != 2 {
    86  				return goerrors.New("--image value is invalid, should be container=ref." +
    87  					"see `edgeadmin cfg update-manifests --help`")
    88  			}
    89  			fmt.Println("parsing image reference...", img)
    90  
    91  			ref, err := name.ParseReference(tokens[1], name.StrictValidation)
    92  			if err != nil {
    93  				return errors.New(fmt.Sprintf("%s is not a valid image ref", img), err)
    94  			}
    95  			refs[tokens[0]] = ref
    96  
    97  			// bazel.ResolveWd simply resolves the wd whether or not we are
    98  			// running via Bazel run or not
    99  			wd, err := bazel.ResolveWd()
   100  			if err != nil {
   101  				return errors.New("failed to determine current working directory", err)
   102  			}
   103  
   104  			// build full path to our manifests directory
   105  			manifests := filepath.Join(wd, flagutil.GetStringFlag(cmd.Rags, flagutil.Manifest))
   106  
   107  			component := edgerelease.Component{Name: flagutil.GetStringFlag(cmd.Rags, flagutil.Components)}
   108  			for name, ref := range refs {
   109  				fmt.Printf("resolving digest for %s...\n", ref)
   110  
   111  				digest, err := crane.Digest(ref.String())
   112  				if err != nil {
   113  					return errors.New(
   114  						fmt.Sprintf("failed to resolve digest for %s", ref.String()), err,
   115  					)
   116  				}
   117  				fmt.Println("resolved digest:", digest)
   118  				component.Images = append(component.Images, edgerelease.PodImage{
   119  					Name: name,
   120  					Image: image.Image{
   121  						Registry:   ref.Context().RegistryStr(),
   122  						Repository: ref.Context().RepositoryStr(),
   123  						Digest:     digest,
   124  					},
   125  				})
   126  			}
   127  			edgeRelease := edgerelease.New(edgerelease.Spec{
   128  				AddBuildLabels: false,
   129  				Components:     []edgerelease.Component{component},
   130  			})
   131  
   132  			if err := updatemanifests.Update(edgeRelease, manifests); err != nil {
   133  				return errors.New("failed to update manifests", err)
   134  			}
   135  			fmt.Println("successfully updated manifests for component:", flagutil.GetStringFlag(cmd.Rags, flagutil.Components))
   136  
   137  			return nil
   138  		},
   139  	}
   140  	return cmd
   141  }
   142  

View as plain text