1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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
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
98
99 wd, err := bazel.ResolveWd()
100 if err != nil {
101 return errors.New("failed to determine current working directory", err)
102 }
103
104
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