Skip to content

Commit e1ec091

Browse files
committed
Modify CI Test to Fetch kubebuilder Release Binary
This commit modifies CI test to fetch kubebuilder release binary before test runs. This enables to run go test using envtest package from kubernetes-sig/controller-runtime.
1 parent 7408725 commit e1ec091

File tree

10 files changed

+165
-36
lines changed

10 files changed

+165
-36
lines changed
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
#!/bin/bash
2+
3+
# Copyright 2020 The Kubernetes Authors.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
18+
# This shell fetches kubebuilder release binary and puts it under
19+
# /tmp/kubebuilder_bin/kubebuilder/bin/
20+
# Then sets KUBEBUILDER_ASSETS to that path to make go test using
21+
# envtest package in kubernetes-sigs/controller-runtime work properly.
22+
#
23+
# This script is largely based on CI script file "chek-everything.sh"
24+
# of kubernetes-sigs/controller-runtime
25+
26+
# Version of kubebuilder release binary which this script attempts to fetch
27+
kubebuilder_release_version="2.3.1"
28+
29+
goos=$(go env GOHOSTOS)
30+
goarch=$(go env GOHOSTARCH)
31+
32+
# Supported arch under above release version
33+
# See source code of standard library "build" ("go/build") for os&arch constant
34+
os_darwin='darwin'
35+
darwin_supported_arch=('amd64')
36+
37+
# Supported arch under above release version
38+
# See source code of standard library "build" ("go/build") for os&arch constant
39+
os_linux='linux'
40+
linux_supported_arch=('amd64' 'arm64' 'ppc64le')
41+
42+
kubebuilder_release_base_url='https://github.com/kubernetes-sigs/kubebuilder/releases/download'
43+
fetch_url_base="${kubebuilder_release_base_url}/v${kubebuilder_release_version}"
44+
45+
46+
# Fetch kubebuilder release binaries and place them under "<argument>/kubebuilder/bin/"
47+
function fetch_kb_bin () {
48+
local dest_dir="${1}/kubebuilder"
49+
local archive_file
50+
local checksum_file="checksums.txt"
51+
local found
52+
53+
# Check whether kubebuilder release binary is provided for current environment's OS & Arch
54+
if [[ ${goos} == ${os_darwin} ]]; then
55+
for (( i=0; i < ${#darwin_supported_arch[@]}; i++ )); do
56+
if [[ ${goarch} == ${darwin_supported_arch[${i}]} ]]; then
57+
found="true"
58+
break
59+
fi
60+
done
61+
62+
if [[ -z ${found} ]]; then
63+
echo "No kubebuilder supported arch under ${goos}: ${goarch}"
64+
exit 1
65+
fi
66+
67+
elif [[ ${goos} == ${os_linux} ]]; then
68+
for (( i=0; i < ${#linux_supported_arch[@]}; i++ )); do
69+
if [[ ${goarch} == ${linux_supported_arch[${i}]} ]]; then
70+
found="true"
71+
break
72+
fi
73+
done
74+
75+
if [[ -z ${found} ]]; then
76+
echo "No kubebuilder supported arch under ${goos}: ${goarch}"
77+
exit 1
78+
fi
79+
80+
else
81+
echo "Not kubebuilder supported os: ${goos}"
82+
exit 1
83+
fi
84+
85+
archive_file="kubebuilder_${kubebuilder_release_version}_${goos}_${goarch}.tar.gz"
86+
87+
mkdir -p ${dest_dir}
88+
89+
# Fetch kubebuilder release binary
90+
curl -fsL "${fetch_url_base}/${archive_file}" -o "/tmp/${archive_file}"
91+
if [[ ${?} != 0 ]]; then
92+
echo "Failed to curl kubebuilder release binary"
93+
exit 1
94+
fi
95+
96+
# Fetch checksum file
97+
curl -fsL "${fetch_url_base}/${checksum_file}" -o "/tmp/${checksum_file}"
98+
if [[ ${?} != 0 ]]; then
99+
echo "Failed to curl checksum file"
100+
exit 1
101+
fi
102+
103+
# Hash & check fetched binary
104+
(
105+
cd /tmp
106+
sha256sum -c --quiet --ignore-missing "/tmp/${checksum_file}"
107+
if [[ ${?} != 0 ]]; then
108+
echo "Maybe, kubebuilder release binary got broken & doesn't match hash value in ${checksum_file}"
109+
exit 1
110+
fi
111+
)
112+
113+
# Unpack
114+
tar -C ${dest_dir} -xzf "/tmp/${archive_file}" --strip-components=1
115+
116+
# Check expected binaries exist
117+
if [[ !(-x ${dest_dir}/bin/etcd && -x ${dest_dir}/bin/kubectl && -x ${dest_dir}/bin/kube-apiserver) ]]; then
118+
echo "There are no expected binaries at ${dset_dir}/bin : etcd, kubectl & kube-apiserver"
119+
exit 1
120+
fi
121+
122+
# Set KUBEBUILDER_ASSETS environment variable
123+
export KUBEBUILDER_ASSETS="${dest_dir}/bin"
124+
}
125+
126+
fetch_kb_bin "/tmp"

hack/ci/test.sh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,11 @@ set -o errexit
1818
set -o nounset
1919
set -o pipefail
2020

21+
CI_ROOT=$(dirname "${BASH_SOURCE}")
2122
REPO_ROOT=$(dirname "${BASH_SOURCE}")/../..
23+
24+
source "${CI_ROOT}/fetch_kubebuilder_release_bin.sh"
25+
2226
cd "${REPO_ROOT}"
2327

2428
export GO111MODULE=on

hack/smoketest.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -283,22 +283,22 @@ func verifyOrTimeout(operators []AddonTest, duration time.Duration, desc string,
283283
}
284284

285285
func verifyExistRole(clientset kubernetes.Interface, namespace string, role string) error {
286-
if _, err := clientset.RbacV1().Roles(namespace).Get(context.TODO(),role, metav1.GetOptions{}); err != nil {
286+
if _, err := clientset.RbacV1().Roles(namespace).Get(context.TODO(), role, metav1.GetOptions{}); err != nil {
287287
return err
288288
}
289289
return nil
290290
}
291291

292292
func verifyExistClusterRole(clientset kubernetes.Interface, name string) error {
293-
if _, err := clientset.RbacV1().ClusterRoles().Get(context.TODO(),name, metav1.GetOptions{}); err != nil {
293+
if _, err := clientset.RbacV1().ClusterRoles().Get(context.TODO(), name, metav1.GetOptions{}); err != nil {
294294
return err
295295
}
296296

297297
return nil
298298
}
299299

300300
func verifyExistClusterRoleBinding(clientset kubernetes.Interface, name string) error {
301-
if _, err := clientset.RbacV1().ClusterRoleBindings().Get(context.TODO(),name, metav1.GetOptions{}); err != nil {
301+
if _, err := clientset.RbacV1().ClusterRoleBindings().Get(context.TODO(), name, metav1.GetOptions{}); err != nil {
302302
return err
303303
}
304304

@@ -317,7 +317,7 @@ func verifySteps(clientset kubernetes.Interface, steps []verifyStep) error {
317317
type PodSet []corev1.Pod
318318

319319
func Pods(h TestHarness, namespace string) PodSet {
320-
pods, err := h.Clientset().CoreV1().Pods(namespace).List(context.TODO(),metav1.ListOptions{})
320+
pods, err := h.Clientset().CoreV1().Pods(namespace).List(context.TODO(), metav1.ListOptions{})
321321
if err != nil {
322322
h.Fatalf("error listing pods: %v", err)
323323
}

pkg/patterns/addon/pkg/loaders/http.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ func (r *HTTPRepository) LoadChannel(ctx context.Context, name string) (*Channel
6464
return channel, nil
6565
}
6666

67-
func (r *HTTPRepository) LoadManifest(ctx context.Context, packageName string, id string) (map[string] string, error) {
67+
func (r *HTTPRepository) LoadManifest(ctx context.Context, packageName string, id string) (map[string]string, error) {
6868
if !allowedManifestId(packageName) {
6969
return nil, fmt.Errorf("invalid package name: %q", id)
7070
}
@@ -81,7 +81,7 @@ func (r *HTTPRepository) LoadManifest(ctx context.Context, packageName string, i
8181
if err != nil {
8282
return nil, fmt.Errorf("error reading package %s: %v", p, err)
8383
}
84-
result := map[string]string {
84+
result := map[string]string{
8585
p: string(b),
8686
}
8787
return result, nil

pkg/patterns/declarative/pkg/applier/direct.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@ package applier
22

33
import (
44
"context"
5+
"os"
6+
"strings"
7+
58
"k8s.io/cli-runtime/pkg/genericclioptions"
69
"k8s.io/cli-runtime/pkg/printers"
710
"k8s.io/cli-runtime/pkg/resource"
811
"k8s.io/kubectl/pkg/cmd/apply"
912
cmdDelete "k8s.io/kubectl/pkg/cmd/delete"
1013
cmdutil "k8s.io/kubectl/pkg/cmd/util"
11-
"os"
12-
"strings"
1314
)
1415

1516
type DirectApplier struct {
@@ -55,4 +56,3 @@ func (d *DirectApplier) Apply(ctx context.Context,
5556

5657
return applyOpts.Run()
5758
}
58-

pkg/patterns/declarative/pkg/applier/exec.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,4 +88,3 @@ func (c *ExecKubectl) Apply(ctx context.Context, namespace string, manifest stri
8888

8989
return nil
9090
}
91-

pkg/patterns/declarative/pkg/manifest/objects_test.go

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,17 @@ package manifest
22

33
import (
44
"context"
5-
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
65
"testing"
6+
7+
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
78
)
89

910
func Test_Object(t *testing.T) {
10-
tests := []struct{
11-
name string
12-
inputManifest string
11+
tests := []struct {
12+
name string
13+
inputManifest string
1314
expectedObject []*Object
14-
expectedBlobs []string
15+
expectedBlobs []string
1516
}{
1617
{
1718
name: "simple applied manifest",
@@ -21,14 +22,14 @@ kind: ServiceAccount
2122
metadata:
2223
name: foo-operator
2324
namespace: kube-system`,
24-
expectedObject: []*Object{
25+
expectedObject: []*Object{
2526
{
2627
object: &unstructured.Unstructured{
2728
Object: map[string]interface{}{
2829
"apiVersion": "v1",
29-
"kind": "ServiceAccount",
30+
"kind": "ServiceAccount",
3031
"metadata": map[string]interface{}{
31-
"name": "foo-operator",
32+
"name": "foo-operator",
3233
"namespace": "kube-system",
3334
},
3435
},
@@ -49,8 +50,8 @@ configMapGenerator:
4950
files:
5051
- Corefile`,
5152
expectedObject: []*Object{},
52-
expectedBlobs:[]string{
53-
`resources:
53+
expectedBlobs: []string{
54+
`resources:
5455
- services.yaml
5556
- deployment.yaml
5657
configMapGenerator:
@@ -83,17 +84,17 @@ configMapGenerator:
8384
object: &unstructured.Unstructured{
8485
Object: map[string]interface{}{
8586
"apiVersion": "v1",
86-
"kind": "ServiceAccount",
87+
"kind": "ServiceAccount",
8788
"metadata": map[string]interface{}{
88-
"name": "foo-operator",
89+
"name": "foo-operator",
8990
"namespace": "kube-system",
9091
},
9192
},
9293
},
9394
},
9495
},
95-
expectedBlobs:[]string{
96-
`resources:
96+
expectedBlobs: []string{
97+
`resources:
9798
- services.yaml
9899
- deployment.yaml
99100
configMapGenerator:
@@ -150,6 +151,3 @@ configMapGenerator:
150151
})
151152
}
152153
}
153-
154-
155-

pkg/test/mocks/cache.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,11 @@ func (FakeCache) List(ctx context.Context, list runtime.Object, opts ...client.L
2121
panic("implement me")
2222
}
2323

24-
func (FakeCache) GetInformer(ctx context.Context,obj runtime.Object) (toolscache.Informer, error) {
24+
func (FakeCache) GetInformer(ctx context.Context, obj runtime.Object) (toolscache.Informer, error) {
2525
panic("implement me")
2626
}
2727

28-
func (FakeCache) GetInformerForKind(gctx context.Context,vk schema.GroupVersionKind) (toolscache.Informer, error) {
28+
func (FakeCache) GetInformerForKind(gctx context.Context, vk schema.GroupVersionKind) (toolscache.Informer, error) {
2929
panic("implement me")
3030
}
3131

@@ -37,6 +37,6 @@ func (FakeCache) WaitForCacheSync(stop <-chan struct{}) bool {
3737
panic("implement me")
3838
}
3939

40-
func (FakeCache) IndexField(ctx context.Context,obj runtime.Object, field string, extractValue client.IndexerFunc) error {
40+
func (FakeCache) IndexField(ctx context.Context, obj runtime.Object, field string, extractValue client.IndexerFunc) error {
4141
panic("implement me")
4242
}

pkg/test/mocks/manager.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,12 @@ limitations under the License.
1717
package mocks
1818

1919
import (
20+
"net/http"
21+
2022
"k8s.io/apimachinery/pkg/api/meta"
2123
"k8s.io/apimachinery/pkg/runtime"
2224
"k8s.io/client-go/rest"
2325
"k8s.io/client-go/tools/record"
24-
"net/http"
2526
"sigs.k8s.io/controller-runtime/pkg/cache"
2627
"sigs.k8s.io/controller-runtime/pkg/client"
2728
"sigs.k8s.io/controller-runtime/pkg/healthz"
@@ -120,4 +121,4 @@ func (Manager) AddMetricsExtraHandler(path string, handler http.Handler) error {
120121

121122
func (Manager) Elected() <-chan struct{} {
122123
panic("implement me")
123-
}
124+
}

utils/utils.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,17 @@ package utils
22

33
import (
44
"context"
5-
"github.com/pkg/errors"
65
"strings"
76

7+
"github.com/pkg/errors"
8+
9+
"net"
10+
811
corev1 "k8s.io/api/core/v1"
912
apierrors "k8s.io/apimachinery/pkg/api/errors"
1013
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
11-
"sigs.k8s.io/controller-runtime/pkg/client"
1214
"k8s.io/klog"
13-
"net"
15+
"sigs.k8s.io/controller-runtime/pkg/client"
1416
)
1517

1618
const (
@@ -29,7 +31,6 @@ func getCoreDNSService(ctx context.Context, c client.Client) (*corev1.Service, e
2931
return kubernetesService, err
3032
}
3133

32-
3334
// FindDNSClusterIP tries to find the Cluster IP to be used by the DNS service
3435
// It is usually the 10th address to the Kubernetes Service Cluster IP
3536
// If the Kubernetes Service Cluster IP is not found, we default it to be "10.96.0.10"

0 commit comments

Comments
 (0)