Skip to content

Commit 2b6dcd6

Browse files
committed
Implement setup-envtest use in controller-runtime
1 parent 11ed5ff commit 2b6dcd6

File tree

8 files changed

+168
-126
lines changed

8 files changed

+168
-126
lines changed

pkg/envtest/setup/env/assets.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,29 +17,29 @@ var expectedExecutables = []string{
1717
"kubectl",
1818
}
1919

20-
// CanUseAssetsFromPath attempts to use the assets from the provided path if they match the spec.
20+
// TryUseAssetsFromPath attempts to use the assets from the provided path if they match the spec.
2121
// If they do not, or if some executable is missing, it returns an empty string.
22-
func (e *Env) CanUseAssetsFromPath(ctx context.Context, spec versions.Spec, path string) bool {
22+
func (e *Env) TryUseAssetsFromPath(ctx context.Context, spec versions.Spec, path string) (*versions.Concrete, bool) {
2323
v, err := versions.FromPath(path)
2424
if err != nil {
2525
log.FromContext(ctx).Error(err, "Unable to use assets from path, ignoring", "path", path)
26-
return false
26+
return nil, false
2727
}
2828

2929
if !spec.Matches(*v) {
3030
log.FromContext(ctx).Error(nil, "Assets path does not match spec, ignoring", "path", path, "spec", spec)
31-
return false
31+
return nil, false
3232
}
3333

3434
if ok, err := e.hasAllExecutables(path); err != nil {
3535
log.FromContext(ctx).Error(err, "Failed checking if assets path has all binaries, ignoring", "path", path)
36-
return false
36+
return nil, false
3737
} else if !ok {
3838
log.FromContext(ctx).Error(nil, "Assets path is missing some executables, ignoring", "path", path)
39-
return false
39+
return nil, false
4040
}
4141

42-
return true
42+
return v, true
4343
}
4444

4545
func (e *Env) hasAllExecutables(path string) (bool, error) {

pkg/envtest/setup/setup-envtest.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ import (
1111
// Use implements the use workflow for selecting and using a version of the environment.
1212
//
1313
// It will download a remote version if required (and options allow), and return the path to the binary asset directory.
14-
func Use(ctx context.Context, version string, options ...use.Option) (string, error) {
14+
func Use(ctx context.Context, version string, options ...use.Option) (use.Result, error) {
1515
spec, err := readSpec(version)
1616
if err != nil {
17-
return "", err
17+
return use.Result{}, err
1818
}
1919

2020
return use.Use(ctx, spec, options...)

pkg/envtest/setup/use/config.go

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import (
99
"sigs.k8s.io/controller-runtime/pkg/envtest/setup/versions"
1010
)
1111

12+
const kubebuilderAssets = "KUBEBUILDER_ASSETS"
13+
1214
type config struct {
1315
platform versions.Platform
1416
assetPath string
@@ -28,15 +30,19 @@ func WithAssetsAt(dir string) Option {
2830
}
2931

3032
// WithAssetsFromEnv sets the path to the assets directory from the environment.
31-
func WithAssetsFromEnv() Option {
32-
return func(c *config) { c.assetPath = cmp.Or(os.Getenv(kubebuilderAssets), c.assetPath) }
33+
func WithAssetsFromEnv(useEnv bool) Option {
34+
return func(c *config) {
35+
if useEnv {
36+
c.assetPath = cmp.Or(os.Getenv(kubebuilderAssets), c.assetPath)
37+
}
38+
}
3339
}
3440

3541
// ForceDownload forces the download of the specified version, even if it's already present.
36-
func ForceDownload() Option { return func(c *config) { c.forceDownload = true } }
42+
func ForceDownload(force bool) Option { return func(c *config) { c.forceDownload = force } }
3743

3844
// NoDownload ensures only local versions are considered
39-
func NoDownload() Option { return func(c *config) { c.noDownload = true } }
45+
func NoDownload(noDownload bool) Option { return func(c *config) { c.noDownload = noDownload } }
4046

4147
// WithPlatform sets the target OS and architecture for the download.
4248
func WithPlatform(os string, arch string) Option {
@@ -49,7 +55,7 @@ func WithEnvOption(o env.Option) Option {
4955
}
5056

5157
// VerifySum turns on md5 verification of the downloaded package
52-
func VerifySum() Option { return func(c *config) { c.verifySum = true } }
58+
func VerifySum(verify bool) Option { return func(c *config) { c.verifySum = !verify } }
5359

5460
func configure(options ...Option) *config {
5561
cfg := &config{}

pkg/envtest/setup/use/use.go

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,42 +8,64 @@ import (
88
"sigs.k8s.io/controller-runtime/pkg/envtest/setup/versions"
99
)
1010

11-
const kubebuilderAssets = "KUBEBUILDER_ASSETS"
11+
// Result summarizes the output of the Use workflow
12+
type Result struct {
13+
Version versions.Concrete
14+
Platform versions.Platform
15+
MD5 string
16+
Path string
17+
}
1218

1319
// Use selects an appropriate version based on the user's spec, downloads it if needed,
1420
// and returns the path to the binary asset directory.
15-
func Use(ctx context.Context, version versions.Spec, options ...Option) (string, error) {
21+
func Use(ctx context.Context, version versions.Spec, options ...Option) (Result, error) {
1622
cfg := configure(options...)
1723

1824
env, err := env.New(cfg.envOpts...)
1925
if err != nil {
20-
return "", err
26+
return Result{}, err
2127
}
2228

23-
if cfg.assetPath != "" && env.CanUseAssetsFromPath(ctx, version, cfg.assetPath) {
24-
return cfg.assetPath, nil
29+
if cfg.assetPath != "" {
30+
if v, ok := env.TryUseAssetsFromPath(ctx, version, cfg.assetPath); ok {
31+
return Result{
32+
Version: *v,
33+
Platform: cfg.platform,
34+
Path: cfg.assetPath,
35+
}, nil
36+
}
2537
}
2638

2739
if !cfg.forceDownload && !version.CheckLatest {
2840
if selected, err := env.SelectLocalVersion(ctx, version, cfg.platform); err != nil {
29-
return "", err
41+
return Result{}, err
3042
} else if selected != nil {
31-
return env.PathTo(selected, cfg.platform), nil
43+
return Result{
44+
Path: env.PathTo(selected, cfg.platform),
45+
Version: *selected,
46+
Platform: cfg.platform,
47+
}, nil
48+
3249
}
3350
}
3451

3552
if cfg.noDownload {
36-
return "", fmt.Errorf("no local version matching %s found, but you specified NoDownload()", version)
53+
return Result{}, fmt.Errorf("no local version matching %s found, but you specified NoDownload()", version)
3754
}
3855

3956
selectedVersion, selectedPlatform, err := env.SelectRemoteVersion(ctx, version, cfg.platform)
4057
if err != nil {
41-
return "", err
58+
return Result{}, err
4259
}
4360

4461
if err := env.FetchRemoteVersion(ctx, selectedVersion, selectedPlatform, cfg.verifySum); err != nil {
45-
return "", err
62+
return Result{}, err
4663
}
4764

48-
return env.PathTo(selectedVersion, selectedPlatform.Platform), nil
65+
return Result{
66+
Version: *selectedVersion,
67+
Platform: selectedPlatform.Platform,
68+
Path: env.PathTo(selectedVersion, selectedPlatform.Platform),
69+
MD5: selectedPlatform.MD5,
70+
}, nil
4971
}

tools/setup-envtest/env/helpers.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ package env
55

66
import (
77
"fmt"
8+
"io"
9+
"strings"
810

911
"sigs.k8s.io/controller-runtime/tools/setup-envtest/versions"
1012
)
@@ -66,3 +68,40 @@ func (f *PrintFormat) Set(val string) error {
6668
func (PrintFormat) Type() string {
6769
return "{overview|path|env}"
6870
}
71+
72+
// Sprint returns the string to be printed
73+
func (f PrintFormat) Sprintf(out io.Writer, version versions.Concrete, platform versions.Platform, md5 string, path string) (err error) {
74+
switch f {
75+
case PrintOverview:
76+
if _, e := fmt.Fprintf(out, "Version: %s\n", version); e != nil {
77+
return e
78+
}
79+
if _, e := fmt.Fprintf(out, "OS/Arch: %s\n", platform); e != nil {
80+
return e
81+
}
82+
if md5 != "" {
83+
if _, e := fmt.Fprintf(out, "md5: %s\n", md5); e != nil {
84+
return e
85+
}
86+
}
87+
if _, e := fmt.Fprintf(out, "Path: %s\n", path); e != nil {
88+
return e
89+
}
90+
return nil
91+
case PrintPath:
92+
_, e := fmt.Fprint(out, path) // NB(directxman12): no newline -- want the bare path here
93+
return e
94+
case PrintEnv:
95+
// quote in case there are spaces, etc in the path
96+
// the weird string below works like this:
97+
// - you can't escape quotes in shell
98+
// - shell strings that are next to each other are concatenated (so "a""b""c" == "abc")
99+
// - you can intermix quote styles using the above
100+
// - so `'"'"'` --> CLOSE_QUOTE + "'" + OPEN_QUOTE
101+
shellQuoted := strings.ReplaceAll(path, "'", `'"'"'`)
102+
_, e := fmt.Fprintf(out, "export KUBEBUILDER_ASSETS='%s'\n", shellQuoted)
103+
return e
104+
default:
105+
return fmt.Errorf("unexpected print format %v", f)
106+
}
107+
}

tools/setup-envtest/go.mod

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,30 @@ module sigs.k8s.io/controller-runtime/tools/setup-envtest
22

33
go 1.22.0
44

5+
replace sigs.k8s.io/controller-runtime => ../../
6+
57
require (
6-
github.com/go-logr/logr v1.2.4
7-
github.com/go-logr/zapr v1.2.4
8-
github.com/onsi/ginkgo/v2 v2.12.1
9-
github.com/onsi/gomega v1.27.10
10-
github.com/spf13/afero v1.6.0
8+
github.com/go-logr/logr v1.4.1
9+
github.com/go-logr/zapr v1.3.0
10+
github.com/onsi/ginkgo/v2 v2.17.1
11+
github.com/onsi/gomega v1.32.0
12+
github.com/spf13/afero v1.11.0
1113
github.com/spf13/pflag v1.0.5
1214
go.uber.org/zap v1.26.0
15+
sigs.k8s.io/controller-runtime v0.0.0-00010101000000-000000000000
1316
)
1417

1518
require (
1619
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
17-
github.com/golang/protobuf v1.5.3 // indirect
18-
github.com/google/go-cmp v0.5.9 // indirect
19-
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 // indirect
20-
go.uber.org/multierr v1.10.0 // indirect
21-
golang.org/x/net v0.14.0 // indirect
22-
golang.org/x/sys v0.12.0 // indirect
23-
golang.org/x/text v0.12.0 // indirect
24-
golang.org/x/tools v0.12.0 // indirect
25-
google.golang.org/protobuf v1.28.0 // indirect
20+
github.com/google/go-cmp v0.6.0 // indirect
21+
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 // indirect
22+
github.com/kr/pretty v0.1.0 // indirect
23+
go.uber.org/multierr v1.11.0 // indirect
24+
golang.org/x/net v0.23.0 // indirect
25+
golang.org/x/sys v0.18.0 // indirect
26+
golang.org/x/text v0.14.0 // indirect
27+
golang.org/x/tools v0.18.0 // indirect
28+
google.golang.org/protobuf v1.33.0 // indirect
29+
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
2630
gopkg.in/yaml.v3 v3.0.1 // indirect
2731
)

0 commit comments

Comments
 (0)