Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Golang E2E in Openshift API-CI #1384

Merged
merged 33 commits into from
Jul 17, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
f7e24f8
*: reworking for openshift-ci
AlexNPavel May 15, 2019
c32dbe0
Dockerfile.e2e-go: bump to golang 1.12
AlexNPavel May 23, 2019
5b758c4
test/e2e/memcached_test.go: don't use parallel tests
AlexNPavel May 24, 2019
5880b15
hack/tests,ci: reorganize
AlexNPavel May 30, 2019
0ef1599
Merge branch 'master' into e2e-prow
AlexNPavel May 30, 2019
5962cf4
Makefile: add missing make commands
AlexNPavel May 31, 2019
65a8f92
Update internal/test/flags.go
AlexNPavel Jun 4, 2019
2070197
scaffold,pkg/{metrics,leader,k8sutil}: add force local mode
AlexNPavel Jun 5, 2019
6f56b96
Merge branch 'e2e-prow' of github.com:AlexNPavel/operator-sdk into e2…
AlexNPavel Jun 5, 2019
7eb299a
test/e2e/memcached_test.go: remove old local flags
AlexNPavel Jun 5, 2019
00ba830
cmd/.../{test,up}/local: set env var for commands
AlexNPavel Jun 5, 2019
66bf196
Merge branch 'master' into e2e-prow
AlexNPavel Jun 5, 2019
3d3bb7a
Merge branch 'master' into e2e-prow
AlexNPavel Jun 10, 2019
6b8d72b
ci/dockerfiles,test/e2e: fix vendor problems
AlexNPavel Jun 11, 2019
5615d9f
ci/dockerfiles: rename 'intermediate' image
AlexNPavel Jun 11, 2019
0ad1613
Merge branch 'master' into e2e-prow
AlexNPavel Jun 12, 2019
435cdfc
Makefile,ci/tests: fix build issues
AlexNPavel Jun 12, 2019
455ab76
Merge branch 'master' into e2e-prow
AlexNPavel Jun 26, 2019
25d9d05
Merge branch 'master' into e2e-prow
AlexNPavel Jul 1, 2019
e3cc22e
ci/tests/e2e-go.sh: use existing go test scaffolder
AlexNPavel Jul 1, 2019
71206b2
internal,pkg/test,test/e2e: remove old workarounds
AlexNPavel Jul 1, 2019
1232663
Merge branch 'master' into e2e-prow
AlexNPavel Jul 10, 2019
6a4226a
ci: update e2e-go test image scaffolding
AlexNPavel Jul 10, 2019
206eb96
Merge branch 'master' into e2e-prow
AlexNPavel Jul 10, 2019
a6a8bf2
ci/dockerfiles: enable GO111MODULE in builder image
AlexNPavel Jul 10, 2019
0cabce7
ci/tests/e2e-go: add correct args for go test
AlexNPavel Jul 10, 2019
1a307bc
cmd/.../test,up,pkg/k8sutil: make new func and consts for run mode
AlexNPavel Jul 15, 2019
8041d49
hack/tests/scaffolding: remove trap for rm go.mod
AlexNPavel Jul 15, 2019
06ea958
Merge branch 'master' into e2e-prow
AlexNPavel Jul 15, 2019
c3f69b6
ci/dockerfiles/builder: make sure GOPATH is set for builds
AlexNPavel Jul 16, 2019
7a0dd70
ci/dockerfiles: rename e2e-go to make e2e image names consistent
AlexNPavel Jul 16, 2019
7927677
pkg/k8sutil: remove local check in getOperatorName
AlexNPavel Jul 16, 2019
1bb44c2
ci/tests/e2e-go: remove old debugging cat statement
AlexNPavel Jul 16, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,9 @@ test/e2e: test/e2e/go test/e2e/ansible test/e2e/ansible-molecule test/e2e/helm
test/e2e/go:
./hack/tests/e2e-go.sh $(ARGS)

test/e2e/go2:
./ci/tests/e2e-go.sh $(ARGS)

test/e2e/ansible: image/build/ansible
./hack/tests/e2e-ansible.sh

Expand Down
3 changes: 1 addition & 2 deletions ci/dockerfiles/builder.Dockerfile
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
FROM openshift/origin-release:golang-1.12

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

COPY . .

Expand Down
19 changes: 19 additions & 0 deletions ci/dockerfiles/go-e2e.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
FROM osdk-builder as builder

RUN ci/tests/e2e-go-scaffold.sh

FROM registry.access.redhat.com/ubi7/ubi-minimal:latest

ENV OPERATOR=/usr/local/bin/memcached-operator \
USER_UID=1001 \
USER_NAME=memcached-operator

# install operator binary
COPY --from=builder /memcached-operator ${OPERATOR}
COPY test/test-framework/build/bin /usr/local/bin

RUN /usr/local/bin/user_setup

ENTRYPOINT ["/usr/local/bin/entrypoint"]

USER ${USER_UID}
9 changes: 9 additions & 0 deletions ci/tests/e2e-go-scaffold.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/usr/bin/env bash
set -ex

# Scaffold project (image name and local image args don't matter at this stage as those only affect the operator manifest)
source ./hack/tests/scaffolding/e2e-go-scaffold.sh

pushd $BASEPROJECTDIR/memcached-operator
go build -gcflags "all=-trimpath=${GOPATH}" -asmflags "all=-trimpath=${GOPATH}" -o /memcached-operator $BASEPROJECTDIR/memcached-operator/cmd/manager
popd
15 changes: 15 additions & 0 deletions ci/tests/e2e-go.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/usr/bin/env bash
set -ex

make install
# this configures the image correctly for memcached-operator
component="memcached-operator"
eval IMAGE=$IMAGE_FORMAT
set -- "--image-name=$IMAGE --local-image=false"
source ./hack/tests/scaffolding/e2e-go-scaffold.sh

pushd $BASEPROJECTDIR/memcached-operator
operator-sdk test local ./test/e2e
popd

go test ./test/e2e/... -root=. -globalMan=testdata/empty.yaml
5 changes: 4 additions & 1 deletion cmd/operator-sdk/test/local.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"github.com/operator-framework/operator-sdk/internal/util/fileutil"
"github.com/operator-framework/operator-sdk/internal/util/projutil"
"github.com/operator-framework/operator-sdk/internal/util/yamlutil"
"github.com/operator-framework/operator-sdk/pkg/k8sutil"
"github.com/operator-framework/operator-sdk/pkg/test"

"github.com/ghodss/yaml"
Expand Down Expand Up @@ -207,7 +208,9 @@ func testLocalGoFunc(cmd *cobra.Command, args []string) error {
if tlConfig.namespace != "" || tlConfig.noSetup {
testArgs = append(testArgs, "-"+test.SingleNamespaceFlag, "-parallel=1")
}
env := append(os.Environ(), fmt.Sprintf("%v=%v", test.TestNamespaceEnv, tlConfig.namespace))
if tlConfig.upLocal {
env = append(env, fmt.Sprintf("%s=%s", k8sutil.ForceRunModeEnv, k8sutil.LocalRunMode))
testArgs = append(testArgs, "-"+test.LocalOperatorFlag)
if tlConfig.localOperatorFlags != "" {
testArgs = append(testArgs, "-"+test.LocalOperatorArgs, tlConfig.localOperatorFlags)
Expand All @@ -216,7 +219,7 @@ func testLocalGoFunc(cmd *cobra.Command, args []string) error {
opts := projutil.GoTestOptions{
GoCmdOptions: projutil.GoCmdOptions{
PackagePath: args[0] + "/...",
Env: append(os.Environ(), fmt.Sprintf("%v=%v", test.TestNamespaceEnv, tlConfig.namespace)),
Env: env,
Dir: projutil.MustGetwd(),
GoMod: projutil.IsDepManagerGoMod(),
},
Expand Down
1 change: 1 addition & 0 deletions cmd/operator-sdk/up/local.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ func upLocal() error {
os.Exit(0)
}()
dc.Env = os.Environ()
dc.Env = append(dc.Env, fmt.Sprintf("%s=%s", k8sutil.ForceRunModeEnv, k8sutil.LocalRunMode))
// only set env var if user explicitly specified a kubeconfig path
if kubeConfig != "" {
dc.Env = append(dc.Env, fmt.Sprintf("%v=%v", k8sutil.KubeConfigEnvVar, kubeConfig))
Expand Down
2 changes: 0 additions & 2 deletions hack/tests/scaffolding/e2e-go-scaffold.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ set -ex
source hack/lib/test_lib.sh

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

Expand Down
27 changes: 26 additions & 1 deletion pkg/k8sutil/k8sutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,17 @@ import (
logf "sigs.k8s.io/controller-runtime/pkg/runtime/log"
)

// ForceRunModeEnv indicates if the operator should be forced to run in either local
// or cluster mode (currently only used for local mode)
var ForceRunModeEnv = "OSDK_FORCE_RUN_MODE"

type RunModeType string

const (
LocalRunMode RunModeType = "local"
ClusterRunMode RunModeType = "cluster"
)

var log = logf.Log.WithName("k8sutil")

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

// errNoNS indicates that a namespace could not be found for the current
// ErrNoNamespace indicates that a namespace could not be found for the current
// environment
var ErrNoNamespace = fmt.Errorf("namespace not found for current environment")

// ErrRunLocal indicates that the operator is set to run in local mode (this error
// is returned by functions that only work on operators running in cluster mode)
var ErrRunLocal = fmt.Errorf("operator run mode forced to local")

// GetOperatorNamespace returns the namespace the operator should be running in.
func GetOperatorNamespace() (string, error) {
if isRunModeLocal() {
return "", ErrRunLocal
}
nsBytes, err := ioutil.ReadFile("/var/run/secrets/kubernetes.io/serviceaccount/namespace")
if err != nil {
if os.IsNotExist(err) {
Expand Down Expand Up @@ -93,6 +111,9 @@ func ResourceExists(dc discovery.DiscoveryInterface, apiGroupVersion, kind strin
// is currently running.
// It expects the environment variable POD_NAME to be set by the downwards API.
func GetPod(ctx context.Context, client crclient.Client, ns string) (*corev1.Pod, error) {
if isRunModeLocal() {
return nil, ErrRunLocal
}
podName := os.Getenv(PodNameEnvVar)
if podName == "" {
return nil, fmt.Errorf("required env %s not set, please configure downward API", PodNameEnvVar)
Expand Down Expand Up @@ -156,3 +177,7 @@ func isKubeMetaKind(kind string) bool {

return false
}

func isRunModeLocal() bool {
return os.Getenv(ForceRunModeEnv) == string(LocalRunMode)
}
2 changes: 1 addition & 1 deletion pkg/leader/leader.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func Become(ctx context.Context, lockName string) error {

ns, err := k8sutil.GetOperatorNamespace()
if err != nil {
if err == k8sutil.ErrNoNamespace {
if err == k8sutil.ErrNoNamespace || err == k8sutil.ErrRunLocal {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One question: At this point is there ever a case where err == k8sutil.ErrNoNamespace and err != k8sutil.ErrRunLocal?

Looking at the errors returned by cluster specific functions such as initOperatorService() and GetOperatorNamespace(), GetOperatorName() it seems they will all return ErrRunLocal if running locally.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If a user is using our commands, ErrNoNamespace probably shouldn't be hit since we manually force the run mode. I do assume it's possible if a user manually runs it themselves with go run cmd/manager/main.go.

log.Info("Skipping leader election; not running in a cluster.")
return nil
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/metrics/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ func CreateMetricsService(ctx context.Context, cfg *rest.Config, servicePorts []
}
s, err := initOperatorService(ctx, client, servicePorts)
if err != nil {
if err == k8sutil.ErrNoNamespace {
if err == k8sutil.ErrNoNamespace || err == k8sutil.ErrRunLocal {
log.Info("Skipping metrics Service creation; not running in a cluster.")
return nil, nil
}
Expand Down
12 changes: 12 additions & 0 deletions test/test-framework/build/bin/entrypoint
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/bin/sh -e

# This is documented here:
# https://docs.openshift.com/container-platform/3.11/creating_images/guidelines.html#openshift-specific-guidelines

if ! whoami &>/dev/null; then
if [ -w /etc/passwd ]; then
echo "${USER_NAME:-memcached-operator}:x:$(id -u):$(id -g):${USER_NAME:-memcached-operator} user:${HOME}:/sbin/nologin" >> /etc/passwd
fi
fi

exec ${OPERATOR} $@
13 changes: 13 additions & 0 deletions test/test-framework/build/bin/user_setup
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/bin/sh
set -x

# ensure $HOME exists and is accessible by group 0 (we don't know what the runtime UID will be)
mkdir -p ${HOME}
chown ${USER_UID}:0 ${HOME}
chmod ug+rwx ${HOME}

# runtime user will need to be able to self-insert in /etc/passwd
chmod g+rw /etc/passwd

# no need for this script to remain in the image after running
rm $0