Skip to content

Commit 1ee9386

Browse files
authored
Golang E2E in Openshift API-CI (#1384)
* *: reworking for openshift-ci * test/e2e/_incluster-test-code/memcached_test.go: don't use parallel tests Travis still doesn't like running these tests in parallel, so keep them sequential until we fully migrate to api-ci * scaffold,pkg/{metrics,leader,k8sutil}: add force local mode * cmd/.../{test,up}/local: set env var for commands
1 parent f4dd3b1 commit 1ee9386

File tree

13 files changed

+105
-8
lines changed

13 files changed

+105
-8
lines changed

Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,9 @@ test/e2e: test/e2e/go test/e2e/ansible test/e2e/ansible-molecule test/e2e/helm
124124
test/e2e/go:
125125
./hack/tests/e2e-go.sh $(ARGS)
126126

127+
test/e2e/go2:
128+
./ci/tests/e2e-go.sh $(ARGS)
129+
127130
test/e2e/ansible: image/build/ansible
128131
./hack/tests/e2e-ansible.sh
129132

ci/dockerfiles/builder.Dockerfile

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
FROM openshift/origin-release:golang-1.12
22

33
WORKDIR /go/src/github.com/operator-framework/operator-sdk
4-
# Set gopath before build and include build destination in PATH
5-
ENV GOPATH=/go PATH=/go/src/github.com/operator-framework/operator-sdk/build:$PATH
4+
ENV GOPATH=/go PATH=/go/src/github.com/operator-framework/operator-sdk/build:$PATH GOPROXY=https://proxy.golang.org/ GO111MODULE=on
65

76
COPY . .
87

ci/dockerfiles/go-e2e.Dockerfile

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
FROM osdk-builder as builder
2+
3+
RUN ci/tests/e2e-go-scaffold.sh
4+
5+
FROM registry.access.redhat.com/ubi7/ubi-minimal:latest
6+
7+
ENV OPERATOR=/usr/local/bin/memcached-operator \
8+
USER_UID=1001 \
9+
USER_NAME=memcached-operator
10+
11+
# install operator binary
12+
COPY --from=builder /memcached-operator ${OPERATOR}
13+
COPY test/test-framework/build/bin /usr/local/bin
14+
15+
RUN /usr/local/bin/user_setup
16+
17+
ENTRYPOINT ["/usr/local/bin/entrypoint"]
18+
19+
USER ${USER_UID}

ci/tests/e2e-go-scaffold.sh

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#!/usr/bin/env bash
2+
set -ex
3+
4+
# Scaffold project (image name and local image args don't matter at this stage as those only affect the operator manifest)
5+
source ./hack/tests/scaffolding/e2e-go-scaffold.sh
6+
7+
pushd $BASEPROJECTDIR/memcached-operator
8+
go build -gcflags "all=-trimpath=${GOPATH}" -asmflags "all=-trimpath=${GOPATH}" -o /memcached-operator $BASEPROJECTDIR/memcached-operator/cmd/manager
9+
popd

ci/tests/e2e-go.sh

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#!/usr/bin/env bash
2+
set -ex
3+
4+
make install
5+
# this configures the image correctly for memcached-operator
6+
component="memcached-operator"
7+
eval IMAGE=$IMAGE_FORMAT
8+
set -- "--image-name=$IMAGE --local-image=false"
9+
source ./hack/tests/scaffolding/e2e-go-scaffold.sh
10+
11+
pushd $BASEPROJECTDIR/memcached-operator
12+
operator-sdk test local ./test/e2e
13+
popd
14+
15+
go test ./test/e2e/... -root=. -globalMan=testdata/empty.yaml

cmd/operator-sdk/test/local.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
"github.com/operator-framework/operator-sdk/internal/util/fileutil"
2727
"github.com/operator-framework/operator-sdk/internal/util/projutil"
2828
"github.com/operator-framework/operator-sdk/internal/util/yamlutil"
29+
"github.com/operator-framework/operator-sdk/pkg/k8sutil"
2930
"github.com/operator-framework/operator-sdk/pkg/test"
3031

3132
"github.com/ghodss/yaml"
@@ -207,7 +208,9 @@ func testLocalGoFunc(cmd *cobra.Command, args []string) error {
207208
if tlConfig.namespace != "" || tlConfig.noSetup {
208209
testArgs = append(testArgs, "-"+test.SingleNamespaceFlag, "-parallel=1")
209210
}
211+
env := append(os.Environ(), fmt.Sprintf("%v=%v", test.TestNamespaceEnv, tlConfig.namespace))
210212
if tlConfig.upLocal {
213+
env = append(env, fmt.Sprintf("%s=%s", k8sutil.ForceRunModeEnv, k8sutil.LocalRunMode))
211214
testArgs = append(testArgs, "-"+test.LocalOperatorFlag)
212215
if tlConfig.localOperatorFlags != "" {
213216
testArgs = append(testArgs, "-"+test.LocalOperatorArgs, tlConfig.localOperatorFlags)
@@ -216,7 +219,7 @@ func testLocalGoFunc(cmd *cobra.Command, args []string) error {
216219
opts := projutil.GoTestOptions{
217220
GoCmdOptions: projutil.GoCmdOptions{
218221
PackagePath: args[0] + "/...",
219-
Env: append(os.Environ(), fmt.Sprintf("%v=%v", test.TestNamespaceEnv, tlConfig.namespace)),
222+
Env: env,
220223
Dir: projutil.MustGetwd(),
221224
GoMod: projutil.IsDepManagerGoMod(),
222225
},

cmd/operator-sdk/up/local.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ func upLocal() error {
139139
os.Exit(0)
140140
}()
141141
dc.Env = os.Environ()
142+
dc.Env = append(dc.Env, fmt.Sprintf("%s=%s", k8sutil.ForceRunModeEnv, k8sutil.LocalRunMode))
142143
// only set env var if user explicitly specified a kubeconfig path
143144
if kubeConfig != "" {
144145
dc.Env = append(dc.Env, fmt.Sprintf("%v=%v", k8sutil.KubeConfigEnvVar, kubeConfig))

hack/tests/scaffolding/e2e-go-scaffold.sh

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@ set -ex
55
source hack/lib/test_lib.sh
66

77
ROOTDIR="$(pwd)"
8-
# TODO: remove once PR 1566 is merged
9-
trap_add 'rm -f $ROOTDIR/go.mod' EXIT
108
BASEPROJECTDIR="$(mktemp -d)"
119
IMAGE_NAME="quay.io/example/memcached-operator:v0.0.1"
1210

pkg/k8sutil/k8sutil.go

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,17 @@ import (
2929
logf "sigs.k8s.io/controller-runtime/pkg/runtime/log"
3030
)
3131

32+
// ForceRunModeEnv indicates if the operator should be forced to run in either local
33+
// or cluster mode (currently only used for local mode)
34+
var ForceRunModeEnv = "OSDK_FORCE_RUN_MODE"
35+
36+
type RunModeType string
37+
38+
const (
39+
LocalRunMode RunModeType = "local"
40+
ClusterRunMode RunModeType = "cluster"
41+
)
42+
3243
var log = logf.Log.WithName("k8sutil")
3344

3445
// GetWatchNamespace returns the namespace the operator should be watching for changes
@@ -40,12 +51,19 @@ func GetWatchNamespace() (string, error) {
4051
return ns, nil
4152
}
4253

43-
// errNoNS indicates that a namespace could not be found for the current
54+
// ErrNoNamespace indicates that a namespace could not be found for the current
4455
// environment
4556
var ErrNoNamespace = fmt.Errorf("namespace not found for current environment")
4657

58+
// ErrRunLocal indicates that the operator is set to run in local mode (this error
59+
// is returned by functions that only work on operators running in cluster mode)
60+
var ErrRunLocal = fmt.Errorf("operator run mode forced to local")
61+
4762
// GetOperatorNamespace returns the namespace the operator should be running in.
4863
func GetOperatorNamespace() (string, error) {
64+
if isRunModeLocal() {
65+
return "", ErrRunLocal
66+
}
4967
nsBytes, err := ioutil.ReadFile("/var/run/secrets/kubernetes.io/serviceaccount/namespace")
5068
if err != nil {
5169
if os.IsNotExist(err) {
@@ -93,6 +111,9 @@ func ResourceExists(dc discovery.DiscoveryInterface, apiGroupVersion, kind strin
93111
// is currently running.
94112
// It expects the environment variable POD_NAME to be set by the downwards API.
95113
func GetPod(ctx context.Context, client crclient.Client, ns string) (*corev1.Pod, error) {
114+
if isRunModeLocal() {
115+
return nil, ErrRunLocal
116+
}
96117
podName := os.Getenv(PodNameEnvVar)
97118
if podName == "" {
98119
return nil, fmt.Errorf("required env %s not set, please configure downward API", PodNameEnvVar)
@@ -156,3 +177,7 @@ func isKubeMetaKind(kind string) bool {
156177

157178
return false
158179
}
180+
181+
func isRunModeLocal() bool {
182+
return os.Getenv(ForceRunModeEnv) == string(LocalRunMode)
183+
}

pkg/leader/leader.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ func Become(ctx context.Context, lockName string) error {
4747

4848
ns, err := k8sutil.GetOperatorNamespace()
4949
if err != nil {
50-
if err == k8sutil.ErrNoNamespace {
50+
if err == k8sutil.ErrNoNamespace || err == k8sutil.ErrRunLocal {
5151
log.Info("Skipping leader election; not running in a cluster.")
5252
return nil
5353
}

pkg/metrics/metrics.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ func CreateMetricsService(ctx context.Context, cfg *rest.Config, servicePorts []
5353
}
5454
s, err := initOperatorService(ctx, client, servicePorts)
5555
if err != nil {
56-
if err == k8sutil.ErrNoNamespace {
56+
if err == k8sutil.ErrNoNamespace || err == k8sutil.ErrRunLocal {
5757
log.Info("Skipping metrics Service creation; not running in a cluster.")
5858
return nil, nil
5959
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#!/bin/sh -e
2+
3+
# This is documented here:
4+
# https://docs.openshift.com/container-platform/3.11/creating_images/guidelines.html#openshift-specific-guidelines
5+
6+
if ! whoami &>/dev/null; then
7+
if [ -w /etc/passwd ]; then
8+
echo "${USER_NAME:-memcached-operator}:x:$(id -u):$(id -g):${USER_NAME:-memcached-operator} user:${HOME}:/sbin/nologin" >> /etc/passwd
9+
fi
10+
fi
11+
12+
exec ${OPERATOR} $@
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#!/bin/sh
2+
set -x
3+
4+
# ensure $HOME exists and is accessible by group 0 (we don't know what the runtime UID will be)
5+
mkdir -p ${HOME}
6+
chown ${USER_UID}:0 ${HOME}
7+
chmod ug+rwx ${HOME}
8+
9+
# runtime user will need to be able to self-insert in /etc/passwd
10+
chmod g+rw /etc/passwd
11+
12+
# no need for this script to remain in the image after running
13+
rm $0

0 commit comments

Comments
 (0)