Skip to content
This repository was archived by the owner on Dec 12, 2025. It is now read-only.

Commit cc7821b

Browse files
authored
CLOUDP-58851: Include readiness probe in Agent image (#25)
1 parent 48570db commit cc7821b

File tree

15 files changed

+338
-137
lines changed

15 files changed

+338
-137
lines changed

.evergreen.yml

Lines changed: 48 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -63,28 +63,16 @@ functions:
6363
env:
6464
KUBECONFIG: ${workdir}/kube_config
6565

66-
deploy_operator:
67-
- command: subprocess.exec
68-
type: setup
69-
params:
70-
add_to_path:
71-
- ${workdir}/bin
72-
working_dir: mongodb-kubernetes-operator
73-
binary: scripts/ci/deploy_operator.sh
74-
include_expansions_in_env:
75-
- version_id
76-
env:
77-
KUBECONFIG: ${workdir}/kube_config
78-
7966
run_e2e_test:
8067
- command: subprocess.exec
81-
type: setup
68+
type: test
8269
params:
8370
add_to_path:
8471
- ${workdir}/bin
8572
working_dir: mongodb-kubernetes-operator
8673
include_expansions_in_env:
8774
- version_id
75+
- test
8876
binary: scripts/ci/run_test.sh
8977
env:
9078
KUBECONFIG: ${workdir}/kube_config
@@ -103,25 +91,47 @@ functions:
10391
binary: scripts/ci/build_and_push_image.sh
10492

10593
tasks:
106-
- name: unit_tests
94+
- name: build_operator_image
95+
priority: 60
96+
exec_timeout_secs: 600
10797
commands:
10898
- func: clone
109-
- func: go_test
99+
- func: build_and_push_image
100+
vars:
101+
dockerfile: docker/Dockerfile.operator
102+
image: quay.io/mongodb/community-operator-dev:${version_id}
110103

111-
- name: e2e_test
104+
- name: build_e2e_image
105+
priority: 60
106+
exec_timeout_secs: 600
112107
commands:
113108
- func: clone
114109
- func: build_and_push_image
115110
vars:
116-
dockerfile: docker/Dockerfile.operator
117-
image: quay.io/mongodb/community-operator-dev:${version_id}
111+
dockerfile: docker/Dockerfile.e2e
112+
image: quay.io/mongodb/community-operator-e2e:${version_id}
113+
114+
- name: unit_tests
115+
commands:
116+
- func: clone
117+
- func: go_test
118+
119+
- name: e2e_test_replica_set
120+
commands:
121+
- func: clone
118122
- func: setup_kubernetes_environment
119-
- func: deploy_operator
120-
- func: build_and_push_image
123+
- func: run_e2e_test
121124
vars:
122-
dockerfile: docker/Dockerfile.e2e
123-
image: quay.io/mongodb/community-operator-e2e:${version_id}
125+
test: replica_set
126+
127+
- name: e2e_test_replica_set_readiness_probe
128+
commands:
129+
- func: clone
130+
- func: setup_kubernetes_environment
124131
- func: run_e2e_test
132+
vars:
133+
test: replica_set_readiness_probe
134+
125135

126136
buildvariants:
127137
- name: go_unit_tests
@@ -133,7 +143,21 @@ buildvariants:
133143

134144
- name: e2e_tests
135145
display_name: e2e_tests
146+
run_on:
147+
- ubuntu1604-build
148+
depends_on:
149+
- name: build_operator_image
150+
variant: init_test_run
151+
- name: build_e2e_image
152+
variant: init_test_run
153+
tasks:
154+
- name: e2e_test_replica_set
155+
- name: e2e_test_replica_set_readiness_probe
156+
157+
- name: init_test_run
158+
display_name: init_test_run
136159
run_on:
137160
- ubuntu1604-build
138161
tasks:
139-
- name: e2e_test
162+
- name: build_operator_image
163+
- name: build_e2e_image

agent/Dockerfile

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,11 @@ RUN curl -LO http://downloads.mongodb.org/linux/mongodb-linux-x86_64-ubuntu1604-
2626
mv mongodb-linux-x86_64-ubuntu1604-4.0.6/bin/mongo /usr/bin && \
2727
rm -rf mongodb-linux-x86_64-ubuntu1604-4.0.6.tgz mongodb-linux-x86_64-ubuntu1604-4.0.6
2828

29+
30+
RUN mkdir -p /var/lib/mongodb-mms-automation/probes/ \
31+
&& curl --retry 3 https://readinessprobe.s3-us-west-1.amazonaws.com/readinessprobe -o /var/lib/mongodb-mms-automation/probes/readinessprobe \
32+
&& chmod +x /var/lib/mongodb-mms-automation/probes/readinessprobe \
33+
&& mkdir -p /var/log/mongodb-mms-automation/ \
34+
&& chmod -R +wr /var/log/mongodb-mms-automation/
35+
2936
CMD ["agent/mongodb-agent", "-cluster=/var/lib/automation/config/automation-config.json"]

cmd/testrunner/crds/crds.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ func allCrds(deployDir string) ([]string, error) {
6464
crdDir := path.Join(deployDir, "crds")
6565
var crdFilePaths []string
6666
err := filepath.Walk(crdDir, func(path string, info os.FileInfo, err error) error {
67-
if strings.HasSuffix(info.Name(), "_crd.yaml") {
67+
if info != nil && strings.HasSuffix(info.Name(), "_crd.yaml") {
6868
fmt.Printf("Found CRD: %s\n", info.Name())
6969
crdFilePaths = append(crdFilePaths, path)
7070
}

cmd/testrunner/main.go

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,21 +34,24 @@ type flags struct {
3434
namespace string
3535
operatorImage string
3636
testImage string
37+
test string
3738
}
3839

3940
func parseFlags() flags {
40-
var namespace, deployDir, operatorImage, testImage *string
41+
var namespace, deployDir, operatorImage, testImage, test *string
4142
namespace = flag.String("namespace", "default", "the namespace the operator and tests should be deployed in")
4243
deployDir = flag.String("deployDir", "deploy/", "the path to the directory which contains the yaml deployment files")
4344
operatorImage = flag.String("operatorImage", "quay.io/mongodb/community-operator-dev:latest", "the image which should be used for the operator deployment")
4445
testImage = flag.String("testImage", "quay.io/mongodb/community-operator-e2e:latest", "the image which should be used for the operator e2e tests")
46+
test = flag.String("test", "", "test e2e test that should be run. (name of folder containing the test)")
4547
flag.Parse()
4648

4749
return flags{
4850
deployDir: *deployDir,
4951
namespace: *namespace,
5052
operatorImage: *operatorImage,
5153
testImage: *testImage,
54+
test: *test,
5255
}
5356
}
5457

@@ -87,13 +90,12 @@ func runCmd(f flags) error {
8790
}
8891
fmt.Println("Successfully deployed the operator")
8992

90-
testToRun := "test/replica_set_test.yaml" // TODO: this should be configurable
91-
if err := buildKubernetesResourceFromYamlFile(c, testToRun, &corev1.Pod{}, withNamespace(f.namespace), withTestImage(f.testImage)); err != nil {
93+
testToRun := "test/operator-sdk-test.yaml"
94+
if err := buildKubernetesResourceFromYamlFile(c, testToRun, &corev1.Pod{}, withNamespace(f.namespace), withTestImage(f.testImage), withTest(f.test)); err != nil {
9295
return fmt.Errorf("error deploying test: %v", err)
9396
}
9497

95-
// TODO: configurable
96-
nsName := types.NamespacedName{Name: "my-replica-set-test", Namespace: f.namespace}
98+
nsName := types.NamespacedName{Name: "operator-sdk-test", Namespace: f.namespace}
9799

98100
fmt.Println("Waiting for pod to be ready...")
99101
testPod, err := pod.WaitForPhase(c, nsName, time.Second*5, time.Minute*5, corev1.PodRunning)
@@ -183,6 +185,8 @@ func withNamespace(ns string) func(runtime.Object) {
183185
v.Namespace = ns
184186
case *corev1.Pod:
185187
v.Namespace = ns
188+
case *appsv1.Deployment:
189+
v.Namespace = ns
186190
}
187191
}
188192
}
@@ -208,6 +212,26 @@ func withOperatorImage(image string) func(runtime.Object) {
208212
}
209213
}
210214

215+
// withTest configures the test Pod to launch with the correct
216+
// command which will target the given test
217+
func withTest(test string) func(obj runtime.Object) {
218+
return func(obj runtime.Object) {
219+
if testPod, ok := obj.(*corev1.Pod); ok {
220+
testPod.Spec.Containers[0].Command = []string{
221+
"/bin/operator-sdk",
222+
"test",
223+
"local",
224+
fmt.Sprintf("./test/e2e/%s", test),
225+
"--namespace",
226+
testPod.Namespace,
227+
"--verbose",
228+
"--kubeconfig",
229+
"/etc/config/kubeconfig",
230+
}
231+
}
232+
}
233+
}
234+
211235
// buildKubernetesResourceFromYamlFile will create the kubernetes resource defined in yamlFilePath. All of the functional options
212236
// provided will be applied before creation.
213237
func buildKubernetesResourceFromYamlFile(c client.Client, yamlFilePath string, obj runtime.Object, options ...func(obj runtime.Object)) error {

docker/Dockerfile.testrunner

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,8 @@ FROM registry.access.redhat.com/ubi8/ubi-minimal:latest
2323
# copy the testrunner binary
2424
COPY --from=builder /go/main runner
2525

26+
# add yaml files required by the test runner
27+
ADD deploy/ deploy/
28+
ADD test/ test/
29+
2630
CMD ["./runner"]

pkg/controller/mongodb/mongodb_controller.go

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,13 @@ import (
2727
)
2828

2929
const (
30-
AutomationConfigKey = "automation-config"
31-
agentName = "mongodb-agent"
32-
mongodbName = "mongod"
33-
agentImageEnvVariable = "AGENT_IMAGE"
30+
AutomationConfigKey = "automation-config"
31+
agentName = "mongodb-agent"
32+
mongodbName = "mongod"
33+
agentImageEnvVariable = "AGENT_IMAGE"
34+
readinessProbePath = "/var/lib/mongodb-mms-automation/probes/readinessprobe"
35+
agentHealthStatusFilePath = "/var/log/mongodb-mms-automation/agent-health-status.json"
36+
clusterFilePath = "/var/lib/automation/config/automation-config"
3437
)
3538

3639
// Add creates a new MongoDB Controller and adds it to the Manager. The Manager will set fields on the Controller
@@ -210,16 +213,21 @@ func buildAutomationConfigConfigMap(mdb mdbv1.MongoDB) (corev1.ConfigMap, error)
210213
func buildContainers(mdb mdbv1.MongoDB) ([]corev1.Container, error) {
211214
agentCommand := []string{
212215
"agent/mongodb-agent",
213-
"-cluster=/var/lib/automation/config/automation-config",
216+
"-cluster=" + clusterFilePath,
214217
"-skipMongoStart",
215218
"-noDaemonize",
219+
"-healthCheckFilePath=" + agentHealthStatusFilePath,
220+
"-serveStatusPort=5000",
216221
}
222+
223+
readinessProbe := defaultReadinessProbe()
217224
agentContainer := corev1.Container{
218225
Name: agentName,
219226
Image: os.Getenv(agentImageEnvVariable),
220227
ImagePullPolicy: corev1.PullAlways,
221228
Resources: resourcerequirements.Defaults(),
222229
Command: agentCommand,
230+
ReadinessProbe: &readinessProbe,
223231
}
224232

225233
mongoDbCommand := []string{
@@ -236,6 +244,19 @@ func buildContainers(mdb mdbv1.MongoDB) ([]corev1.Container, error) {
236244
return []corev1.Container{agentContainer, mongodbContainer}, nil
237245
}
238246

247+
func defaultReadinessProbe() corev1.Probe {
248+
return corev1.Probe{
249+
Handler: corev1.Handler{
250+
Exec: &corev1.ExecAction{Command: []string{readinessProbePath}},
251+
},
252+
// Setting the failure threshold to quite big value as the agent may spend some time to reach the goal
253+
FailureThreshold: 240,
254+
// The agent may be not on time to write the status file right after the container is created - we need to wait
255+
// for some time
256+
InitialDelaySeconds: 5,
257+
}
258+
}
259+
239260
// buildStatefulSet takes a MongoDB resource and converts it into
240261
// the corresponding stateful set
241262
func buildStatefulSet(mdb mdbv1.MongoDB) (appsv1.StatefulSet, error) {

pkg/controller/mongodb/replicaset_controller_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package mongodb
33
import (
44
"context"
55
"os"
6+
"reflect"
67
"testing"
78

89
mdbv1 "github.com/mongodb/mongodb-kubernetes-operator/pkg/apis/mongodb/v1"
@@ -68,6 +69,8 @@ func TestStatefulSet_IsCorrectlyConfigured(t *testing.T) {
6869
agentContainer := sts.Spec.Template.Spec.Containers[0]
6970
assert.Equal(t, agentName, agentContainer.Name)
7071
assert.Equal(t, os.Getenv(agentImageEnvVariable), agentContainer.Image)
72+
expectedProbe := defaultReadinessProbe()
73+
assert.True(t, reflect.DeepEqual(&expectedProbe, agentContainer.ReadinessProbe))
7174

7275
mongodbContainer := sts.Spec.Template.Spec.Containers[1]
7376
assert.Equal(t, mongodbName, mongodbContainer.Name)

scripts/ci/deploy_operator.sh

Lines changed: 0 additions & 7 deletions
This file was deleted.

scripts/ci/run_test.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,16 @@ contents="$(cat ${temp})"
1212
kubectl create cm kube-config --from-literal=kubeconfig="${contents}"
1313
rm ${temp}
1414

15-
1615
# create roles and service account required for the test runner
1716
kubectl apply -f deploy/testrunner
1817

1918
# start the test runner pod
2019
kubectl run test-runner --generator=run-pod/v1 \
2120
--restart=Never \
21+
--image-pull-policy=Always \
2222
--image=quay.io/chatton/test-runner \
2323
--serviceaccount=test-runner \
24-
--command -- ./runner --operatorImage quay.io/mongodb/community-operator-dev:${version_id} --testImage quay.io/mongodb/community-operator-e2e:${version_id}
24+
--command -- ./runner --operatorImage quay.io/mongodb/community-operator-dev:${version_id} --testImage quay.io/mongodb/community-operator-e2e:${version_id} --test=${test}
2525

2626

2727
echo "Test pod is ready to begin"

0 commit comments

Comments
 (0)