@@ -43,33 +43,56 @@ It's possible to override some defaults, by setting the following environment va
43
43
KUBEBUILDER_CONTROLPLANE_START_TIMEOUT (string supported by time.ParseDuration): timeout for test control plane to start. Defaults to 20s.
44
44
KUBEBUILDER_CONTROLPLANE_STOP_TIMEOUT (string supported by time.ParseDuration): timeout for test control plane to start. Defaults to 20s.
45
45
KUBEBUILDER_ATTACH_CONTROL_PLANE_OUTPUT (boolean): if set to true, the control plane's stdout and stderr are attached to os.Stdout and os.Stderr
46
-
47
46
*/
48
47
const (
49
- envUseExistingCluster = "USE_EXISTING_CLUSTER"
50
- envKubeAPIServerBin = "TEST_ASSET_KUBE_APISERVER"
51
- envEtcdBin = "TEST_ASSET_ETCD"
52
- envKubectlBin = "TEST_ASSET_KUBECTL"
53
- envKubebuilderPath = "KUBEBUILDER_ASSETS"
54
- envStartTimeout = "KUBEBUILDER_CONTROLPLANE_START_TIMEOUT"
55
- envStopTimeout = "KUBEBUILDER_CONTROLPLANE_STOP_TIMEOUT"
56
- envAttachOutput = "KUBEBUILDER_ATTACH_CONTROL_PLANE_OUTPUT"
57
- defaultKubebuilderPath = "/usr/local/kubebuilder/bin"
58
- StartTimeout = 60
59
- StopTimeout = 60
60
-
48
+ envUseExistingClusterEnvVar = "USE_EXISTING_CLUSTER"
49
+ envKubeAPIServerBinEnvVar = "TEST_ASSET_KUBE_APISERVER"
50
+ envEtcdBinEnvVar = "TEST_ASSET_ETCD"
51
+ envKubectlBinEnvVar = "TEST_ASSET_KUBECTL"
52
+ envKubebuilderPathEnvVar = "KUBEBUILDER_ASSETS"
53
+ envStartTimeoutEnvVar = "KUBEBUILDER_CONTROLPLANE_START_TIMEOUT"
54
+ envStopTimeoutEnvVar = "KUBEBUILDER_CONTROLPLANE_STOP_TIMEOUT"
55
+ envAttachOutputEnvVar = "KUBEBUILDER_ATTACH_CONTROL_PLANE_OUTPUT"
56
+
57
+ // Default values
58
+ defaultKubebuilderPath = "/usr/local/kubebuilder/bin"
59
+ StartTimeout = 60
60
+ StopTimeout = 60
61
61
defaultKubebuilderControlPlaneStartTimeout = 20 * time .Second
62
62
defaultKubebuilderControlPlaneStopTimeout = 20 * time .Second
63
+
64
+ // required binaries to run env test
65
+ kubeApiserverBinName = "kube-apiserver"
66
+ etcdBinName = "etcd"
67
+ kubectlBinName = "kubectl"
63
68
)
64
69
65
- // Default binary path for test framework
66
- func defaultAssetPath (binary string ) string {
67
- assetPath := os .Getenv (envKubebuilderPath )
68
- if assetPath == "" {
69
- assetPath = defaultKubebuilderPath
70
+ // getBinAssetPath will return the path for the binary informed or an error if not be possible.
71
+ // to fid the bin. It will try first check if the bin exists in the path informed then if not,
72
+ // it will be looking for to try find the bin in the other config options as in the default path.
73
+ func (te * Environment ) getBinAssetPath (binary , path string ) (string , error ) {
74
+ // If found the bin in the path informed return this path
75
+ if strings .TrimSpace (path ) != "" && hasBinary (binary , path ) {
76
+ return filepath .Join (path , binary ), nil
70
77
}
71
- return filepath .Join (assetPath , binary )
72
78
79
+ // If a Binary directory as informed in the EnvTest setup try to get the bin from it
80
+ if strings .TrimSpace (te .BinaryDirectoryPath ) != "" && hasBinary (binary , te .BinaryDirectoryPath ) {
81
+ return filepath .Join (te .BinaryDirectoryPath , binary ), nil
82
+ }
83
+
84
+ // If envKubebuilderPathEnvVar was set via ENV VAR then check if the bin can be found there
85
+ valueFromEnvVar := os .Getenv (envKubebuilderPathEnvVar )
86
+ if strings .TrimSpace (valueFromEnvVar ) != "" && hasBinary (binary , valueFromEnvVar ) {
87
+ return filepath .Join (valueFromEnvVar , binary ), nil
88
+ }
89
+
90
+ // Check if the bin can be found in the default path
91
+ if hasBinary (binary , defaultKubebuilderPath ) {
92
+ return filepath .Join (defaultKubebuilderPath , binary ), nil
93
+ }
94
+
95
+ return "" , fmt .Errorf ("unable to found the required binary %v" , binary )
73
96
}
74
97
75
98
// ControlPlane is the re-exported ControlPlane type from the internal integration package
@@ -113,6 +136,10 @@ type Environment struct {
113
136
// values are merged.
114
137
CRDDirectoryPaths []string
115
138
139
+ // BinaryDirectoryPath is the path where the binaries required for the envtest are
140
+ // locate in the environment
141
+ BinaryDirectoryPath string
142
+
116
143
// UseExisting indicates that this environments should use an
117
144
// existing kubeconfig, instead of trying to stand up a new control plane.
118
145
// This is useful in cases that need aggregated API servers and the like.
@@ -200,7 +227,7 @@ func (te *Environment) Start() (*rest.Config, error) {
200
227
te .ControlPlane .Etcd = & integration.Etcd {}
201
228
}
202
229
203
- if os .Getenv (envAttachOutput ) == "true" {
230
+ if os .Getenv (envAttachOutputEnvVar ) == "true" {
204
231
te .AttachControlPlaneOutput = true
205
232
}
206
233
if te .ControlPlane .APIServer .Out == nil && te .AttachControlPlaneOutput {
@@ -216,17 +243,26 @@ func (te *Environment) Start() (*rest.Config, error) {
216
243
te .ControlPlane .Etcd .Err = os .Stderr
217
244
}
218
245
219
- if os .Getenv (envKubeAPIServerBin ) == "" {
220
- te .ControlPlane .APIServer .Path = defaultAssetPath ("kube-apiserver" )
246
+ // set binaries location and then, if the bin not found throw issue
247
+ path , err := te .getBinAssetPath (kubeApiserverBinName , os .Getenv (envKubeAPIServerBinEnvVar ))
248
+ if err != nil {
249
+ return nil , err
250
+ }
251
+ te .ControlPlane .APIServer .Path = path
252
+
253
+ path , err = te .getBinAssetPath (etcdBinName , os .Getenv (envEtcdBinEnvVar ))
254
+ if err != nil {
255
+ return nil , err
221
256
}
222
- if os .Getenv (envEtcdBin ) == "" {
223
- te .ControlPlane .Etcd .Path = defaultAssetPath ("etcd" )
257
+ te .ControlPlane .Etcd .Path = path
258
+
259
+ path , err = te .getBinAssetPath (kubectlBinName , os .Getenv (envKubectlBinEnvVar ))
260
+ if err != nil {
261
+ return nil , err
224
262
}
225
- if os .Getenv (envKubectlBin ) == "" {
226
- // we can't just set the path manually (it's behind a function), so set the environment variable instead
227
- if err := os .Setenv (envKubectlBin , defaultAssetPath ("kubectl" )); err != nil {
228
- return nil , err
229
- }
263
+ // we can't just set the path manually (it's behind a function), so set the environment variable instead
264
+ if err := os .Setenv (envKubectlBinEnvVar , path ); err != nil {
265
+ return nil , err
230
266
}
231
267
232
268
if err := te .defaultTimeouts (); err != nil {
@@ -267,6 +303,14 @@ func (te *Environment) Start() (*rest.Config, error) {
267
303
return te .Config , err
268
304
}
269
305
306
+ // hasBinary will return true when the binary was found in the path
307
+ func hasBinary (bin , path string ) bool {
308
+ if _ , err := os .Stat (filepath .Join (path , bin )); os .IsNotExist (err ) {
309
+ return false
310
+ }
311
+ return true
312
+ }
313
+
270
314
func (te * Environment ) startControlPlane () error {
271
315
numTries , maxRetries := 0 , 5
272
316
var err error
@@ -287,7 +331,7 @@ func (te *Environment) startControlPlane() error {
287
331
func (te * Environment ) defaultTimeouts () error {
288
332
var err error
289
333
if te .ControlPlaneStartTimeout == 0 {
290
- if envVal := os .Getenv (envStartTimeout ); envVal != "" {
334
+ if envVal := os .Getenv (envStartTimeoutEnvVar ); envVal != "" {
291
335
te .ControlPlaneStartTimeout , err = time .ParseDuration (envVal )
292
336
if err != nil {
293
337
return err
@@ -298,7 +342,7 @@ func (te *Environment) defaultTimeouts() error {
298
342
}
299
343
300
344
if te .ControlPlaneStopTimeout == 0 {
301
- if envVal := os .Getenv (envStopTimeout ); envVal != "" {
345
+ if envVal := os .Getenv (envStopTimeoutEnvVar ); envVal != "" {
302
346
te .ControlPlaneStopTimeout , err = time .ParseDuration (envVal )
303
347
if err != nil {
304
348
return err
@@ -312,7 +356,7 @@ func (te *Environment) defaultTimeouts() error {
312
356
313
357
func (te * Environment ) useExistingCluster () bool {
314
358
if te .UseExistingCluster == nil {
315
- return strings .ToLower (os .Getenv (envUseExistingCluster )) == "true"
359
+ return strings .ToLower (os .Getenv (envUseExistingClusterEnvVar )) == "true"
316
360
}
317
361
return * te .UseExistingCluster
318
362
}
0 commit comments