Skip to content

Commit 6138177

Browse files
authored
refactor(helm): Replace VFS with embed for Helm chart rendering (#14272)
Replace the static FS generated by the vfs package with the go embed directive. These are the same in concept, except that the go embed directive is performed automatically by the go build system at build time instead of requiring a separate `go generate` step. Therefore this allows us to remove our use of `go generate` and avoids needing to manage generated sources. Signed-off-by: Alex Leong <[email protected]>
1 parent 4e30191 commit 6138177

38 files changed

+244
-402
lines changed

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ web/app/js/locales/_build
1212
web/app/js/locales/**/*.js
1313
web/app/yarn-error.log
1414
vendor
15-
**/*.gogen*
1615
**/*.swp
1716
**/charts/**/charts
1817
package-lock.json

bin/build-cli-bin

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,7 @@ rootdir=$( cd "$bindir"/.. && pwd )
1717
cd "$rootdir"
1818
cd "$(pwd -P)"
1919
target=target/cli/$(os)/linkerd
20-
# TODO: `go generate` does not honor -mod=readonly
21-
GO111MODULE=on go generate -mod=readonly ./pkg/charts/static
22-
GO111MODULE=on go generate -mod=readonly ./jaeger/static
23-
GO111MODULE=on go generate -mod=readonly ./multicluster/static
24-
GO111MODULE=on go generate -mod=readonly ./viz/static
25-
20+
2621
root_tag=$("$bindir"/root-tag)
2722
GO111MODULE=on CGO_ENABLED=0 go build -o "$target" -tags prod -mod=readonly -ldflags "-s -w -X github.com/linkerd/linkerd2/pkg/version.Version=$root_tag" ./cli
2823
echo "$target"

charts/templates.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package charts
2+
3+
import (
4+
"embed"
5+
)
6+
7+
//go:embed linkerd-control-plane linkerd-crds linkerd2-cni all:partials patch
8+
var Templates embed.FS

cli/Dockerfile

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,6 @@ COPY controller/api controller/api
2222
COPY controller/gen controller/gen
2323
COPY pkg pkg
2424

25-
# Generate static templates
26-
# TODO: `go generate` does not honor -mod=readonly
27-
RUN go generate -mod=readonly ./pkg/charts/static
28-
RUN go generate -mod=readonly ./jaeger/static
29-
RUN go generate -mod=readonly ./multicluster/static
30-
RUN go generate -mod=readonly ./viz/static
31-
3225
RUN mkdir -p /out
3326

3427
FROM go-gen AS linux-amd64-full

cli/cmd/completion_test.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,22 @@ import (
55
)
66

77
func TestCompletion(t *testing.T) {
8+
rootCmd := NewRootCmd()
89
t.Run("Returns completion code", func(t *testing.T) {
910

10-
_, err := getCompletion("bash", RootCmd)
11+
_, err := getCompletion("bash", rootCmd)
1112
if err != nil {
1213
t.Fatalf("Unexpected error: %+v", err)
1314
}
1415

15-
_, err = getCompletion("zsh", RootCmd)
16+
_, err = getCompletion("zsh", rootCmd)
1617
if err != nil {
1718
t.Fatalf("Unexpected error: %+v", err)
1819
}
1920
})
2021

2122
t.Run("Fails with invalid shell type", func(t *testing.T) {
22-
out, err := getCompletion("foo", RootCmd)
23+
out, err := getCompletion("foo", rootCmd)
2324
if err == nil {
2425
t.Fatalf("Unexpected success for invalid shell type: %+v", out)
2526
}

cli/cmd/doc.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,14 @@ type annotationDoc struct {
4040
Description string
4141
}
4242

43-
func newCmdDoc() *cobra.Command {
43+
func newCmdDoc(rootCmd *cobra.Command) *cobra.Command {
4444
cmd := &cobra.Command{
4545
Use: "doc",
4646
Hidden: true,
4747
Short: "Generate YAML documentation for the Linkerd CLI & Proxy annotations",
4848
Args: cobra.NoArgs,
4949
RunE: func(cmd *cobra.Command, args []string) error {
50-
cmdList, err := generateCLIDocs(RootCmd)
50+
cmdList, err := generateCLIDocs(rootCmd)
5151
if err != nil {
5252
return err
5353
}

cli/cmd/install-cni-plugin.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ import (
66
"os"
77
"strings"
88

9-
"github.com/linkerd/linkerd2/pkg/charts"
9+
"github.com/linkerd/linkerd2/charts"
10+
chartspkg "github.com/linkerd/linkerd2/pkg/charts"
1011
cnicharts "github.com/linkerd/linkerd2/pkg/charts/cni"
11-
"github.com/linkerd/linkerd2/pkg/charts/static"
1212
"github.com/linkerd/linkerd2/pkg/cmd"
1313
"github.com/linkerd/linkerd2/pkg/flags"
1414
"github.com/linkerd/linkerd2/pkg/version"
@@ -249,13 +249,13 @@ func renderCNIPlugin(w io.Writer, valOpts values.Options, config *cniPluginOptio
249249
{Name: "templates/cni-plugin.yaml"},
250250
}
251251

252-
ch := &charts.Chart{
252+
ch := &chartspkg.Chart{
253253
Name: helmCNIDefaultChartName,
254254
Dir: helmCNIDefaultChartDir,
255255
Namespace: defaultCNINamespace,
256256
Values: mergedValues,
257257
Files: files,
258-
Fs: static.Templates,
258+
Fs: charts.Templates,
259259
}
260260

261261
buf, err := ch.RenderCNI()

cli/cmd/install.go

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@ import (
1313
"text/template"
1414
"time"
1515

16+
"github.com/linkerd/linkerd2/charts"
1617
"github.com/linkerd/linkerd2/cli/flag"
17-
"github.com/linkerd/linkerd2/pkg/charts"
18+
chartspkg "github.com/linkerd/linkerd2/pkg/charts"
1819
l5dcharts "github.com/linkerd/linkerd2/pkg/charts/linkerd2"
19-
"github.com/linkerd/linkerd2/pkg/charts/static"
2020
pkgcmd "github.com/linkerd/linkerd2/pkg/cmd"
2121
flagspkg "github.com/linkerd/linkerd2/pkg/flags"
2222
"github.com/linkerd/linkerd2/pkg/healthcheck"
@@ -331,14 +331,11 @@ func isRunAsRoot(values map[string]interface{}) bool {
331331
// them into a buffer. The coalesced values are also returned so that they may be rendered via
332332
// `renderOverrides` if appropriate.
333333
func renderChartToBuffer(files []*loader.BufferedFile, values map[string]interface{}, valuesOverrides map[string]interface{}) (*bytes.Buffer, chartutil.Values, error) {
334-
// Load the partials in addition to the main chart.
335-
var partials []*loader.BufferedFile
336-
for _, template := range charts.L5dPartials {
337-
partials = append(partials, &loader.BufferedFile{Name: template})
338-
}
339-
if err := charts.FilesReader(static.Templates, "", partials); err != nil {
334+
partials, err := chartspkg.LoadPartials()
335+
if err != nil {
340336
return nil, nil, err
341337
}
338+
342339
chart, err := loader.LoadFiles(append(files, partials...))
343340
if err != nil {
344341
return nil, nil, err
@@ -435,13 +432,13 @@ func renderCRDs(ctx context.Context, k *k8s.KubernetesAPI, w io.Writer, options
435432
for _, template := range TemplatesCrdFiles {
436433
files = append(files, &loader.BufferedFile{Name: template})
437434
}
438-
if err := charts.FilesReader(static.Templates, l5dcharts.HelmChartDirCrds+"/", files); err != nil {
435+
if err := chartspkg.FilesReader(charts.Templates, l5dcharts.HelmChartDirCrds+"/", files); err != nil {
439436
return err
440437
}
441438

442439
// Load defaults from values.yaml
443440
valuesFile := &loader.BufferedFile{Name: l5dcharts.HelmChartDirCrds + "/values.yaml"}
444-
if err := charts.ReadFile(static.Templates, "/", valuesFile); err != nil {
441+
if err := chartspkg.ReadFile(charts.Templates, "", valuesFile); err != nil {
445442
return err
446443
}
447444
// Ensure the map is not nil, even if the default `values.yaml` is empty ---
@@ -470,7 +467,7 @@ func renderCRDs(ctx context.Context, k *k8s.KubernetesAPI, w io.Writer, options
470467
}
471468

472469
defaultValues = updateDefaultValues(installed, defaultValues)
473-
finalValues := charts.MergeMaps(defaultValues, valuesOverrides)
470+
finalValues := chartspkg.MergeMaps(defaultValues, valuesOverrides)
474471

475472
if err := validateFinalValues(installed, finalValues); err != nil {
476473
return err
@@ -492,7 +489,7 @@ func renderControlPlane(w io.Writer, values *l5dcharts.Values, valuesOverrides m
492489
for _, template := range TemplatesControlPlane {
493490
files = append(files, &loader.BufferedFile{Name: template})
494491
}
495-
if err := charts.FilesReader(static.Templates, l5dcharts.HelmChartDirCP+"/", files); err != nil {
492+
if err := chartspkg.FilesReader(charts.Templates, l5dcharts.HelmChartDirCP+"/", files); err != nil {
496493
return err
497494
}
498495

cli/cmd/install_helm_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ import (
55
"path/filepath"
66
"testing"
77

8-
"github.com/linkerd/linkerd2/pkg/charts"
8+
"github.com/linkerd/linkerd2/charts"
9+
chartspkg "github.com/linkerd/linkerd2/pkg/charts"
910
l5dcharts "github.com/linkerd/linkerd2/pkg/charts/linkerd2"
10-
"github.com/linkerd/linkerd2/pkg/charts/static"
1111
"github.com/linkerd/linkerd2/pkg/k8s"
1212
"github.com/linkerd/linkerd2/testutil"
1313
"helm.sh/helm/v3/pkg/chart"
@@ -227,7 +227,7 @@ func chartCrds(t *testing.T) *chart.Chart {
227227

228228
// Load defaults from values.yaml
229229
valuesFile := &loader.BufferedFile{Name: l5dcharts.HelmChartDirCrds + "/values.yaml"}
230-
if err := charts.ReadFile(static.Templates, "/", valuesFile); err != nil {
230+
if err := chartspkg.ReadFile(charts.Templates, "", valuesFile); err != nil {
231231
t.Fatal(err)
232232
}
233233
defaultValues := make(map[string]interface{})

cli/cmd/root.go

Lines changed: 61 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -69,77 +69,79 @@ var (
6969
)
7070

7171
// RootCmd represents the root Cobra command
72-
var RootCmd = &cobra.Command{
73-
Use: "linkerd",
74-
Short: "linkerd manages the Linkerd service mesh",
75-
Long: `linkerd manages the Linkerd service mesh.`,
76-
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
77-
// enable / disable logging
78-
if verbose {
79-
log.SetLevel(log.DebugLevel)
80-
} else {
81-
log.SetLevel(log.PanicLevel)
82-
}
83-
84-
controlPlaneNamespaceFromEnv := os.Getenv(flags.EnvOverrideNamespace)
85-
if controlPlaneNamespace == defaultLinkerdNamespace && controlPlaneNamespaceFromEnv != "" {
86-
controlPlaneNamespace = controlPlaneNamespaceFromEnv
87-
}
88-
89-
if !alphaNumDash.MatchString(controlPlaneNamespace) {
90-
return fmt.Errorf("%s is not a valid namespace", controlPlaneNamespace)
91-
}
92-
93-
return nil
94-
},
95-
}
72+
func NewRootCmd() *cobra.Command {
73+
rootCmd := &cobra.Command{
74+
Use: "linkerd",
75+
Short: "linkerd manages the Linkerd service mesh",
76+
Long: `linkerd manages the Linkerd service mesh.`,
77+
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
78+
// enable / disable logging
79+
if verbose {
80+
log.SetLevel(log.DebugLevel)
81+
} else {
82+
log.SetLevel(log.PanicLevel)
83+
}
84+
85+
controlPlaneNamespaceFromEnv := os.Getenv(flags.EnvOverrideNamespace)
86+
if controlPlaneNamespace == defaultLinkerdNamespace && controlPlaneNamespaceFromEnv != "" {
87+
controlPlaneNamespace = controlPlaneNamespaceFromEnv
88+
}
89+
90+
if !alphaNumDash.MatchString(controlPlaneNamespace) {
91+
return fmt.Errorf("%s is not a valid namespace", controlPlaneNamespace)
92+
}
93+
94+
return nil
95+
},
96+
}
9697

97-
func init() {
98-
RootCmd.PersistentFlags().StringVarP(&controlPlaneNamespace, "linkerd-namespace", "L",
98+
rootCmd.PersistentFlags().StringVarP(&controlPlaneNamespace, "linkerd-namespace", "L",
9999
defaultLinkerdNamespace,
100100
fmt.Sprintf("Namespace in which Linkerd is installed ($%s)", flags.EnvOverrideNamespace))
101-
RootCmd.PersistentFlags().StringVarP(&cniNamespace, "cni-namespace", "", defaultCNINamespace, "Namespace in which the Linkerd CNI plugin is installed")
102-
RootCmd.PersistentFlags().StringVar(&kubeconfigPath, "kubeconfig", "", "Path to the kubeconfig file to use for CLI requests")
103-
RootCmd.PersistentFlags().StringVar(&kubeContext, "context", "", "Name of the kubeconfig context to use")
104-
RootCmd.PersistentFlags().StringVar(&impersonate, "as", "", "Username to impersonate for Kubernetes operations")
105-
RootCmd.PersistentFlags().StringArrayVar(&impersonateGroup, "as-group", []string{}, "Group to impersonate for Kubernetes operations")
106-
RootCmd.PersistentFlags().StringVar(&apiAddr, "api-addr", "", "Override kubeconfig and communicate directly with the control plane at host:port (mostly for testing)")
107-
RootCmd.PersistentFlags().BoolVar(&verbose, "verbose", false, "Turn on debug logging")
108-
RootCmd.AddCommand(newCmdCheck())
109-
RootCmd.AddCommand(newCmdCompletion())
110-
RootCmd.AddCommand(newCmdDiagnostics())
111-
RootCmd.AddCommand(newCmdDoc())
112-
RootCmd.AddCommand(newCmdIdentity())
113-
RootCmd.AddCommand(NewCmdInject(inject.GetOverriddenValues))
114-
RootCmd.AddCommand(newCmdInstall())
115-
RootCmd.AddCommand(newCmdInstallCNIPlugin())
116-
RootCmd.AddCommand(newCmdProfile())
117-
RootCmd.AddCommand(newCmdAuthz())
118-
RootCmd.AddCommand(newCmdUninject())
119-
RootCmd.AddCommand(newCmdUpgrade())
120-
RootCmd.AddCommand(newCmdVersion())
121-
RootCmd.AddCommand(newCmdUninstall())
122-
RootCmd.AddCommand(newCmdPrune())
101+
rootCmd.PersistentFlags().StringVarP(&cniNamespace, "cni-namespace", "", defaultCNINamespace, "Namespace in which the Linkerd CNI plugin is installed")
102+
rootCmd.PersistentFlags().StringVar(&kubeconfigPath, "kubeconfig", "", "Path to the kubeconfig file to use for CLI requests")
103+
rootCmd.PersistentFlags().StringVar(&kubeContext, "context", "", "Name of the kubeconfig context to use")
104+
rootCmd.PersistentFlags().StringVar(&impersonate, "as", "", "Username to impersonate for Kubernetes operations")
105+
rootCmd.PersistentFlags().StringArrayVar(&impersonateGroup, "as-group", []string{}, "Group to impersonate for Kubernetes operations")
106+
rootCmd.PersistentFlags().StringVar(&apiAddr, "api-addr", "", "Override kubeconfig and communicate directly with the control plane at host:port (mostly for testing)")
107+
rootCmd.PersistentFlags().BoolVar(&verbose, "verbose", false, "Turn on debug logging")
108+
rootCmd.AddCommand(newCmdCheck())
109+
rootCmd.AddCommand(newCmdCompletion())
110+
rootCmd.AddCommand(newCmdDiagnostics())
111+
rootCmd.AddCommand(newCmdDoc(rootCmd))
112+
rootCmd.AddCommand(newCmdIdentity())
113+
rootCmd.AddCommand(NewCmdInject(inject.GetOverriddenValues))
114+
rootCmd.AddCommand(newCmdInstall())
115+
rootCmd.AddCommand(newCmdInstallCNIPlugin())
116+
rootCmd.AddCommand(newCmdProfile())
117+
rootCmd.AddCommand(newCmdAuthz())
118+
rootCmd.AddCommand(newCmdUninject())
119+
rootCmd.AddCommand(newCmdUpgrade())
120+
rootCmd.AddCommand(newCmdVersion())
121+
rootCmd.AddCommand(newCmdUninstall())
122+
rootCmd.AddCommand(newCmdPrune())
123123

124124
// Extension Sub Commands
125-
RootCmd.AddCommand(jaeger.NewCmdJaeger())
126-
RootCmd.AddCommand(multicluster.NewCmdMulticluster())
127-
RootCmd.AddCommand(viz.NewCmdViz())
125+
rootCmd.AddCommand(jaeger.NewCmdJaeger())
126+
rootCmd.AddCommand(multicluster.NewCmdMulticluster())
127+
rootCmd.AddCommand(viz.NewCmdViz())
128128

129129
// Viz Extension sub commands
130-
RootCmd.AddCommand(deprecateCmd(viz.NewCmdDashboard()))
131-
RootCmd.AddCommand(deprecateCmd(viz.NewCmdEdges()))
132-
RootCmd.AddCommand(deprecateCmd(viz.NewCmdRoutes()))
133-
RootCmd.AddCommand(deprecateCmd(viz.NewCmdStat()))
134-
RootCmd.AddCommand(deprecateCmd(viz.NewCmdTap()))
135-
RootCmd.AddCommand(deprecateCmd(viz.NewCmdTop()))
130+
rootCmd.AddCommand(deprecateCmd(viz.NewCmdDashboard()))
131+
rootCmd.AddCommand(deprecateCmd(viz.NewCmdEdges()))
132+
rootCmd.AddCommand(deprecateCmd(viz.NewCmdRoutes()))
133+
rootCmd.AddCommand(deprecateCmd(viz.NewCmdStat()))
134+
rootCmd.AddCommand(deprecateCmd(viz.NewCmdTap()))
135+
rootCmd.AddCommand(deprecateCmd(viz.NewCmdTop()))
136136

137137
// resource-aware completion flag configurations
138138
pkgcmd.ConfigureNamespaceFlagCompletion(
139-
RootCmd, []string{"linkerd-namespace", "cni-namespace"},
139+
rootCmd, []string{"linkerd-namespace", "cni-namespace"},
140140
kubeconfigPath, impersonate, impersonateGroup, kubeContext)
141141

142-
pkgcmd.ConfigureKubeContextFlagCompletion(RootCmd, kubeconfigPath)
142+
pkgcmd.ConfigureKubeContextFlagCompletion(rootCmd, kubeconfigPath)
143+
144+
return rootCmd
143145
}
144146

145147
func deprecateCmd(cmd *cobra.Command) *cobra.Command {

0 commit comments

Comments
 (0)