Skip to content
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
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: 2 additions & 1 deletion Jenkinsfile
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,8 @@ pipeline {
// }

parameters {
string(name: 'dockerImage', defaultValue: 'ml-docker-db-dev-tierpoint.bed-artifactory.bedford.progress.com/marklogic/marklogic-server-ubi:latest-11', description: 'Docker image to use for tests.', trim: true)
string(name: 'E2E_MARKLOGIC_IMAGE_VERSION', defaultValue: 'ml-docker-db-dev-tierpoint.bed-artifactory.bedford.progress.com/marklogic/marklogic-server-ubi-rootless:latest-12', description: 'Docker image to use for tests.', trim: true)
string(name: 'IMG', defaultValue: 'testrepo/marklogic-operator-image-dev:internal', description: 'Docker image for Running Operator Container', trim: true)
string(name: 'emailList', defaultValue: emailList, description: 'List of email for build notification', trim: true)
}

Expand Down
33 changes: 19 additions & 14 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ VERIFY_HUGE_PAGES ?= false
export E2E_DOCKER_IMAGE ?= $(IMG)
export E2E_KUSTOMIZE_VERSION ?= $(KUSTOMIZE_VERSION)
export E2E_CONTROLLER_TOOLS_VERSION ?= $(CONTROLLER_TOOLS_VERSION)
export E2E_MARKLOGIC_IMAGE_VERSION ?= progressofficial/marklogic-db:11.3.1-ubi-rootless-2.1.0
export E2E_MARKLOGIC_IMAGE_VERSION ?= progressofficial/marklogic-db:11.3.1-ubi-rootless-2.1.3
export E2E_KUBERNETES_VERSION ?= v1.31.0

# ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary.
Expand Down Expand Up @@ -65,7 +65,8 @@ OPERATOR_SDK_VERSION ?= v1.34.2

# Image URL to use all building/pushing image targets
# Image for dev: ml-marklogic-operator-dev.bed-artifactory.bedford.progress.com/marklogic-operator-kubernetes
IMG ?= progressofficial/marklogic-operator-kubernetes:$(VERSION)
# IMG ?= progressofficial/marklogic-operator-kubernetes:$(VERSION)
IMG = "testrepo/marklogic-operator-image-dev:1.0.0"


# Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set)
Expand Down Expand Up @@ -134,22 +135,23 @@ test: manifests generate fmt vet envtest ## Run tests.
e2e-test:
@echo "=====Check Huges pages test is enabled or not for e2e test"
ifeq ($(VERIFY_HUGE_PAGES), true)
@echo "=====Setting hugepages value to 1280 for hugepages-e2e test"
sudo sysctl -w vm.nr_hugepages=1280
# @echo "=====Setting hugepages value to 1280 for hugepages-e2e test"
Copy link
Collaborator

Choose a reason for hiding this comment

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

setting huge pages is required to verify the huge pages.
please comment if I am missing anything here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@barkhachoithani , I accidentally commit these comments for my local test. I've revert chose changes back

# sudo sysctl -w vm.nr_hugepages=1280

@echo "=====Restart minikube cluster to apply hugepages value"
minikube stop
minikube start
# @echo "=====Restart minikube cluster to apply hugepages value"
# minikube stop
# minikube start

@echo "=====Running e2e test including hugepages test"
go test -v -count=1 -timeout 30m ./test/e2e -verifyHugePages
# go test -v -count=1 -timeout 30m ./test/e2e -verifyHugePages
go test -v -count=1 -timeout 30m ./test/e2e -args --labels="type=cluster-test"

@echo "=====Resetting hugepages value to 0"
sudo sysctl -w vm.nr_hugepages=0
# @echo "=====Resetting hugepages value to 0"
# sudo sysctl -w vm.nr_hugepages=0

@echo "=====Restart minikube cluster"
minikube stop
minikube start
# @echo "=====Restart minikube cluster"
# minikube stop
# minikube start
else
@echo "=====Running e2e test without hugepages test"
go test -v -count=1 -timeout 30m ./test/e2e
Expand All @@ -162,6 +164,9 @@ e2e-setup-minikube: kustomize controller-gen build docker-build
minikube start --driver=docker --kubernetes-version=$(E2E_KUBERNETES_VERSION) --memory=8192 --cpus=2
minikube addons enable ingress
minikube image load $(IMG)
minikube image load $(E2E_MARKLOGIC_IMAGE_VERSION)
minikube image load "docker.io/haproxytech/haproxy-alpine:3.2"
minikube image ls

.PHONY: e2e-cleanup-minikube
e2e-cleanup-minikube:
Expand Down Expand Up @@ -200,7 +205,7 @@ run: manifests generate fmt vet ## Run a controller from your host.
# More info: https://docs.docker.com/develop/develop-images/build_enhancements/
.PHONY: docker-build
docker-build: ## Build docker image with the manager. to build for linux, add --platform="linux/amd64"
$(CONTAINER_TOOL) buildx build -t ${IMG} .
$(CONTAINER_TOOL) buildx build --no-cache -t ${IMG} .

.PHONY: docker-push
docker-push: ## Push docker image with the manager.
Expand Down
2 changes: 1 addition & 1 deletion api/v1/marklogiccluster_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import (

// MarklogicClusterSpec defines the desired state of MarklogicCluster

// +kubebuilder:validation:XValidation:rule="!(self.haproxy.enabled == true && self.haproxy.pathBasedRouting == true) || int(self.image.split(':')[1].split('.')[0] + self.image.split(':')[1].split('.')[1]) >= 111", message="HAProxy and Pathbased Routing is enabled. PathBasedRouting is only supported for MarkLogic 11.1 and above"
// +kubebuilder:validation:XValidation:rule="!(self.haproxy.enabled == true && self.haproxy.pathBasedRouting == true) || self.image.split(':')[1].matches('.*latest.*') || int(self.image.split(':')[1].split('.')[0] + self.image.split(':')[1].split('.')[1]) >= 111", message="HAProxy and Pathbased Routing is enabled. PathBasedRouting is only supported for MarkLogic 11.1 and above"
type MarklogicClusterSpec struct {
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
// Important: Run "make" to regenerate code after modifying this file
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11037,7 +11037,8 @@ spec:
- message: HAProxy and Pathbased Routing is enabled. PathBasedRouting
is only supported for MarkLogic 11.1 and above
rule: '!(self.haproxy.enabled == true && self.haproxy.pathBasedRouting
== true) || int(self.image.split('':'')[1].split(''.'')[0] + self.image.split('':'')[1].split(''.'')[1])
== true) || self.image.split('':'')[1].matches(''.*latest.*'') ||
int(self.image.split('':'')[1].split(''.'')[0] + self.image.split('':'')[1].split(''.'')[1])
>= 111'
status:
description: MarklogicClusterStatus defines the observed state of MarklogicCluster
Expand Down
31 changes: 0 additions & 31 deletions pkg/k8sutil/scripts/liveness-probe.sh

This file was deleted.

23 changes: 21 additions & 2 deletions pkg/k8sutil/scripts/poststart-hook.sh
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,25 @@ log () {
echo $message >> /tmp/script.log
}

# Function to retry a command based on the return code
# $1: The number of retries
# $2: The command to run
retry() {
local retries=$1
shift
local count=0
until "$@"; do
exit_code=$?
count=$((count + 1))
if [ $count -ge $retries ]; then
echo "Command failed after $retries attempts."
return $exit_code
fi
echo "Attempt $count failed. Retrying..."
Comment on lines +67 to +70
Copy link

Copilot AI Jul 8, 2025

Choose a reason for hiding this comment

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

[nitpick] Use the existing log function instead of echo so retries are recorded in the pod log and /tmp/script.log.

Suggested change
echo "Command failed after $retries attempts."
return $exit_code
fi
echo "Attempt $count failed. Retrying..."
log "Error" "Command failed after $retries attempts."
return $exit_code
fi
log "Info" "Attempt $count failed. Retrying..."

Copilot uses AI. Check for mistakes.
Copy link

Copilot AI Jul 8, 2025

Choose a reason for hiding this comment

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

[nitpick] Replace this echo with the log helper to ensure consistent logging with timestamps and PID handling.

Suggested change
echo "Attempt $count failed. Retrying..."
info "Attempt $count failed. Retrying..."

Copilot uses AI. Check for mistakes.
sleep 5
done
}

###############################################################
# Function to get the current host protocol
# $1: The host name
Expand Down Expand Up @@ -699,10 +718,10 @@ if [[ "$IS_BOOTSTRAP_HOST" == "true" ]]; then
if [[ "${MARKLOGIC_CLUSTER_TYPE}" == "bootstrap" ]]; then
log "Info: bootstrap host is ready"
init_security_db
configure_group
retry 5 configure_group
else
log "Info: bootstrap host is ready"
configure_group
retry 5 configure_group
join_cluster $HOST_FQDN
fi
configure_path_based_routing
Expand Down
7 changes: 5 additions & 2 deletions pkg/k8sutil/statefulset.go
Original file line number Diff line number Diff line change
Expand Up @@ -696,8 +696,11 @@ func getLivenessProbe(probe marklogicv1.ContainerProbe) *corev1.Probe {
TimeoutSeconds: probe.TimeoutSeconds,
SuccessThreshold: probe.SuccessThreshold,
ProbeHandler: corev1.ProbeHandler{
Exec: &corev1.ExecAction{
Command: []string{"/bin/bash", "/tmp/helm-scripts/liveness-probe.sh"},
TCPSocket: &corev1.TCPSocketAction{
Port: intstr.IntOrString{
Type: intstr.Int,
IntVal: 8001,
},
},
},
}
Expand Down
15 changes: 11 additions & 4 deletions test/e2e/2_marklogic_cluster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,14 +134,17 @@ func TestMarklogicCluster(t *testing.T) {
if err != nil {
t.Fatalf("Failed to install grafana helm chart: %v", err)
}

// Wait for Grafana pod to be ready
time.Sleep(5 * time.Second) // Give some time for Grafana to start
podList := &corev1.PodList{}
if err := client.Resources().List(ctx, podList, func(lo *metav1.ListOptions) {
lo.FieldSelector = "metadata.namespace=" + "grafana"
}); err != nil {
t.Fatal(err)
}

if len(podList.Items) == 0 {
t.Fatal("No Grafana pods found")
}
grafanaPodName := podList.Items[0].Name
err = utils.WaitForPod(ctx, t, client, "grafana", grafanaPodName, 120*time.Second)
if err != nil {
Expand Down Expand Up @@ -228,7 +231,7 @@ func TestMarklogicCluster(t *testing.T) {
client := c.Client()

podName := "node-0"
err := utils.WaitForPod(ctx, t, client, mlNamespace, podName, 180*time.Second)
err := utils.WaitForPod(ctx, t, client, mlNamespace, podName, 240*time.Second)
if err != nil {
t.Fatalf("Failed to wait for pod creation: %v", err)
}
Expand All @@ -245,6 +248,10 @@ func TestMarklogicCluster(t *testing.T) {
}); err != nil {
t.Fatal(err)
}
time.Sleep(5 * time.Second) // Wait for Grafana to be fully ready
if len(podList.Items) == 0 {
t.Fatal("No Grafana pods found")
}
grafanaPodName := podList.Items[0].Name
grafanaAdminUser, grafanaAdminPassword, err := utils.GetSecretData(ctx, client, "grafana", "grafana", "admin-user", "admin-password")
if err != nil {
Expand Down Expand Up @@ -337,7 +344,7 @@ func TestMarklogicCluster(t *testing.T) {
if err := client.Resources().Get(ctx, "marklogicclusters", mlNamespace, &mlcluster); err != nil {
t.Fatal(err)
}

mlcluster.Spec.MarkLogicGroups[0].Resources = &resources
if err := client.Resources().Update(ctx, &mlcluster); err != nil {
t.Log("Failed to update MarkLogic group resources")
Expand Down
7 changes: 7 additions & 0 deletions test/e2e/4_tls_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,9 @@ func TestTlsWithNamedCert(t *testing.T) {
}
certURIs := gjson.Get(certs, `certificate-default-list.list-items.list-item.#.uriref`).Array()
t.Log("Certificates URL list", certURIs)
if len(certURIs) < 2 {
t.Fatalf("Expected at least 2 certificates, found %d", len(certURIs))
}
cert0Url := fmt.Sprintf("https://localhost:8002%s?format=json", certURIs[0])
cert1Url := fmt.Sprintf("https://localhost:8002%s?format=json", certURIs[1])
command = fmt.Sprintf("curl -k --anyauth -u %s:%s %s", adminUsername, adminPassword, cert0Url)
Expand Down Expand Up @@ -404,8 +407,12 @@ func TestTlsWithMultiNode(t *testing.T) {
if err != nil {
t.Fatalf("Failed to get certificates list: %v", err)
}
t.Log("Certificates list", certs)
certURIs := gjson.Get(certs, `certificate-default-list.list-items.list-item.#.uriref`).Array()
t.Log("Dnode Cert Url", certURIs)
if len(certURIs) < 2 {
t.Fatalf("Expected at least 2 certificates, found %d", len(certURIs))
}
cert0Url := fmt.Sprintf("https://localhost:8002%s?format=json", certURIs[0])
cert1Url := fmt.Sprintf("https://localhost:8002%s?format=json", certURIs[1])
command = fmt.Sprintf("curl -k --anyauth -u %s:%s %s", adminUsername, adminPassword, cert0Url)
Expand Down
4 changes: 2 additions & 2 deletions test/e2e/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,8 @@ func TestMain(m *testing.M) {
log.Println("Deploying controller-manager resources...")
p := utils.RunCommand(`kubectl version`)
log.Printf("Output of kubectl: %s", p.Result())
p = utils.RunCommand(`bash -c "kustomize build config/default | kubectl apply --server-side -f -"`)
log.Printf("Output: %s", p.Result())
p = utils.RunCommand(`make deploy`)
log.Printf("Output of make deploy: %s", p.Result())
if p.Err() != nil {
log.Printf("Failed to deploy resource configurations: %s: %s", p.Err(), p.Result())
return ctx, p.Err()
Expand Down
3 changes: 3 additions & 0 deletions test/utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,9 @@ func WaitForPod(ctx context.Context, t *testing.T, client klient.Client, namespa
pod := &corev1.Pod{}
p := utils.RunCommand(`kubectl get ns`)
t.Logf("Kubernetes namespace: %s", p.Result())
p = utils.RunCommand("kubectl get pods --namespace " + "marklogic-operator-system" + " -o wide")
t.Logf("Kubernetes Operator Running Status: %s", p.Result())

for {
t.Logf("Waiting for pod %s in namespace %s ", podName, namespace)
p := utils.RunCommand("kubectl get pods --namespace " + namespace)
Expand Down