From d86794662bb62871974e646ad52ca784223d004f Mon Sep 17 00:00:00 2001
From: Navin Chandra <navinchandra772@gmail.com>
Date: Sun, 18 Aug 2024 18:56:11 +0000
Subject: [PATCH 1/8] Update `main_test.go` for coverage calc

Signed-off-by: Navin Chandra <navinchandra772@gmail.com>
---
 KubeArmor/main_test.go | 38 +++++++++++++++++++++++---------------
 1 file changed, 23 insertions(+), 15 deletions(-)

diff --git a/KubeArmor/main_test.go b/KubeArmor/main_test.go
index 36d69dcfff..adf21aeb33 100644
--- a/KubeArmor/main_test.go
+++ b/KubeArmor/main_test.go
@@ -5,18 +5,19 @@ package main
 
 import (
 	"flag"
+	"fmt"
 	"os"
 	"strconv"
 	"testing"
 )
 
 var clusterPtr, gRPCPtr, logPathPtr *string
-var enableKubeArmorPolicyPtr, enableKubeArmorHostPolicyPtr, enableKubeArmorVMPtr, coverageTestPtr *bool
+var enableKubeArmorPolicyPtr, enableKubeArmorHostPolicyPtr, enableKubeArmorVMPtr, coverageTestPtr, enableK8sEnv, tlsEnabled *bool
 var defaultFilePosturePtr, defaultCapabilitiesPosturePtr, defaultNetworkPosturePtr, hostDefaultCapabilitiesPosturePtr, hostDefaultNetworkPosturePtr, hostDefaultFilePosturePtr *string
 
 func init() {
 	// options (string)
-	clusterPtr = flag.String("cluster", "", "cluster name")
+	clusterPtr = flag.String("cluster", "default", "cluster name")
 
 	// options (string)
 	gRPCPtr = flag.String("gRPC", "32767", "gRPC port number")
@@ -36,8 +37,11 @@ func init() {
 	enableKubeArmorHostPolicyPtr = flag.Bool("enableKubeArmorHostPolicy", true, "enabling KubeArmorHostPolicy")
 	enableKubeArmorVMPtr = flag.Bool("enableKubeArmorVm", false, "enabling KubeArmorVM")
 
+	enableK8sEnv = flag.Bool("k8s", true, "is k8s env?")
+	tlsEnabled = flag.Bool("tlsEnabled", false, "enable tls for secure connection?")
+
 	// options (boolean)
-	coverageTestPtr = flag.Bool("coverageTest", true, "enabling CoverageTest")
+	coverageTestPtr = flag.Bool("coverageTest", false, "enabling CoverageTest")
 }
 
 // TestMain - test to drive external testing coverage
@@ -45,18 +49,22 @@ func TestMain(t *testing.T) {
 	// Reset Test Flags before executing main
 	flag.CommandLine = flag.NewFlagSet(os.Args[0], flag.ExitOnError)
 
-	// Set os args to set flags in main
-	os.Args = []string{"cmd", "--cluster", *clusterPtr, "--gRPC", *gRPCPtr, "--logPath", *logPathPtr,
-		"--defaultFilePosture", *defaultFilePosturePtr,
-		"--defaultNetworkPosture", *defaultNetworkPosturePtr,
-		"--defaultCapabilitiesPosture", *defaultCapabilitiesPosturePtr,
-		"--hostDefaultFilePosture", *hostDefaultFilePosturePtr,
-		"--hostDefaultNetworkPosture", *hostDefaultNetworkPosturePtr,
-		"--hostDefaultCapabilitiesPosture", *hostDefaultCapabilitiesPosturePtr,
-		"--enableKubeArmorPolicy", strconv.FormatBool(*enableKubeArmorPolicyPtr),
-		"--enableKubeArmorHostPolicy", strconv.FormatBool(*enableKubeArmorHostPolicyPtr),
-		"--enableKubeArmorVm", strconv.FormatBool(*enableKubeArmorVMPtr),
-		"--coverageTest", strconv.FormatBool(*coverageTestPtr)}
+	os.Args = []string{
+		fmt.Sprintf("-cluster=%s", *clusterPtr),
+		fmt.Sprintf("-gRPC=%s", *gRPCPtr),
+		fmt.Sprintf("-logPath=%s", *logPathPtr),
+		fmt.Sprintf("-defaultFilePosture=%s", *defaultFilePosturePtr),
+		fmt.Sprintf("-defaultNetworkPosture=%s", *defaultNetworkPosturePtr),
+		fmt.Sprintf("-defaultCapabilitiesPosture=%s", *defaultCapabilitiesPosturePtr),
+		fmt.Sprintf("-hostDefaultFilePosture=%s", *hostDefaultFilePosturePtr),
+		fmt.Sprintf("-hostDefaultNetworkPosture=%s", *hostDefaultNetworkPosturePtr),
+		fmt.Sprintf("-hostDefaultCapabilitiesPosture=%s", *hostDefaultCapabilitiesPosturePtr),
+		fmt.Sprintf("-k8s=%s", strconv.FormatBool(*enableK8sEnv)),
+		fmt.Sprintf("-enableKubeArmorPolicy=%s", strconv.FormatBool(*enableKubeArmorPolicyPtr)),
+		fmt.Sprintf("-enableKubeArmorHostPolicy=%s", strconv.FormatBool(*enableKubeArmorHostPolicyPtr)),
+		fmt.Sprintf("-coverageTest=%s", strconv.FormatBool(*coverageTestPtr)),
+		fmt.Sprintf("-tlsEnabled=%s", strconv.FormatBool(*tlsEnabled)),
+	}
 
 	t.Log("[INFO] Executed KubeArmor")
 	main()

From e7ce43ec20710296becc6b4ae79aff225256fc1c Mon Sep 17 00:00:00 2001
From: Navin Chandra <navinchandra772@gmail.com>
Date: Sun, 18 Aug 2024 18:59:15 +0000
Subject: [PATCH 2/8] Create docker targets for test images

Signed-off-by: Navin Chandra <navinchandra772@gmail.com>
---
 Dockerfile                                    | 19 ++++++++---
 KubeArmor/build/build_kubearmor.sh            | 29 ++++++++++++++++
 .../config/samples/kubearmor-coverage.yaml    | 33 +++++++++++++++++++
 3 files changed, 76 insertions(+), 5 deletions(-)
 create mode 100644 pkg/KubeArmorOperator/config/samples/kubearmor-coverage.yaml

diff --git a/Dockerfile b/Dockerfile
index 04729c768c..f72b1b592e 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -3,7 +3,7 @@
 
 ### Builder
 
-FROM golang:1.22-alpine3.20 as builder
+FROM golang:1.22-alpine3.20 AS builder
 
 RUN apk --no-cache update
 RUN apk add --no-cache git clang llvm make gcc protobuf
@@ -38,9 +38,15 @@ COPY ./KubeArmor/BPF .
 
 RUN make
 
+### Builder test
+
+FROM builder AS builder-test
+WORKDIR /usr/src/KubeArmor/KubeArmor
+RUN go test -covermode=atomic -coverpkg=./... -c . -o kubearmor-test
+
 ### Make executable image
 
-FROM alpine:3.20 as kubearmor
+FROM alpine:3.20 AS kubearmor
 
 RUN echo "@community http://dl-cdn.alpinelinux.org/alpine/edge/community" | tee -a /etc/apk/repositories
 
@@ -53,6 +59,11 @@ COPY --from=builder /usr/src/KubeArmor/KubeArmor/templates/* /KubeArmor/template
 
 ENTRYPOINT ["/KubeArmor/kubearmor"]
 
+FROM kubearmor AS kubearmor-test
+COPY --from=builder-test /usr/src/KubeArmor/KubeArmor/kubearmor-test /KubeArmor/kubearmor-test
+
+ENTRYPOINT ["/KubeArmor/kubearmor-test"]
+
 ### TODO ###
 
 ### build apparmor_parser binary
@@ -65,7 +76,7 @@ ENTRYPOINT ["/KubeArmor/kubearmor"]
 
 ### Make UBI-based executable image
 
-FROM redhat/ubi9-minimal as kubearmor-ubi
+FROM redhat/ubi9-minimal AS kubearmor-ubi
 
 ARG VERSION=latest
 ENV KUBEARMOR_UBI=true
@@ -99,5 +110,3 @@ RUN setcap "cap_sys_admin=ep cap_sys_ptrace=ep cap_ipc_lock=ep cap_sys_resource=
 
 USER 1000
 ENTRYPOINT ["/KubeArmor/kubearmor"]
-
-
diff --git a/KubeArmor/build/build_kubearmor.sh b/KubeArmor/build/build_kubearmor.sh
index 50529ccd6d..b75e59771b 100755
--- a/KubeArmor/build/build_kubearmor.sh
+++ b/KubeArmor/build/build_kubearmor.sh
@@ -44,6 +44,35 @@ echo "[INFO] Removed existing $REPO images"
 unset LABEL
 [[ "$GITHUB_SHA" != "" ]] && LABEL="--label github_sha=$GITHUB_SHA"
 
+# set the $IS_COVERAGE env var to 'true' to build the kubearmor-test image for coverage calculation
+if [[ "$IS_COVERAGE" == "true" ]]; then
+    REPO="kubearmor/kubearmor-test"
+    
+    # build a kubearmor-test image
+    DTAG="-t $REPO:$VERSION"
+    echo "[INFO] Building $DTAG"
+    cd $ARMOR_HOME/..; docker build $DTAG -f Dockerfile --target kubearmor-test . $LABEL
+
+    if [ $? != 0 ]; then
+        echo "[FAILED] Failed to build $REPO:$VERSION"
+        exit 1
+    fi
+    echo "[PASSED] Built $REPO:$VERSION"
+    
+    # build a kubearmor-test-init image
+    DTAGINI="-t $REPO-init:$VERSION"
+    echo "[INFO] Building $DTAGINI"
+    cd $ARMOR_HOME/..; docker build $DTAGINI -f Dockerfile.init --build-arg VERSION=$VERSION --target kubearmor-init . $LABEL
+
+    if [ $? != 0 ]; then
+        echo "[FAILED] Failed to build $REPO-init:$VERSION"
+        exit 1
+    fi
+    echo "[PASSED] Built $REPO-init:$VERSION"
+
+    exit 0
+fi
+
 # build a kubearmor image
 DTAG="-t $REPO:$VERSION"
 echo "[INFO] Building $DTAG"
diff --git a/pkg/KubeArmorOperator/config/samples/kubearmor-coverage.yaml b/pkg/KubeArmorOperator/config/samples/kubearmor-coverage.yaml
new file mode 100644
index 0000000000..ec67b6b964
--- /dev/null
+++ b/pkg/KubeArmorOperator/config/samples/kubearmor-coverage.yaml
@@ -0,0 +1,33 @@
+apiVersion: operator.kubearmor.com/v1
+kind: KubeArmorConfig
+metadata:
+  labels:
+    app.kubernetes.io/name: kubearmorconfig
+    app.kubernetes.io/instance: kubearmorconfig-sample
+    app.kubernetes.io/part-of: kubearmoroperator
+    app.kubernetes.io/managed-by: kustomize
+    app.kubernetes.io/created-by: kubearmoroperator
+  name: kubearmorconfig-test
+  namespace: kubearmor
+spec:
+  defaultCapabilitiesPosture: block
+  defaultFilePosture: block
+  defaultNetworkPosture: block
+  defaultVisibility: process,file,network,capabilities
+  seccompEnabled: false
+  alertThrottling: false
+  maxAlertPerSec: 10
+  throttleSec: 30
+  kubearmorImage:
+    image: kubearmor/kubearmor-test:latest
+    imagePullPolicy: Never
+  kubearmorInitImage:
+    image: kubearmor/kubearmor-test-init:latest
+    imagePullPolicy: Never
+  kubearmorRelayImage:
+    image: kubearmor/kubearmor-relay-server:latest
+    imagePullPolicy: Always
+  kubearmorControllerImage:
+    image: kubearmor/kubearmor-controller:latest
+    imagePullPolicy: Always
+

From 88434c117f20af9815a8fd186c2094299b22070c Mon Sep 17 00:00:00 2001
From: Navin Chandra <navinchandra772@gmail.com>
Date: Sun, 18 Aug 2024 18:59:44 +0000
Subject: [PATCH 3/8] Add `codecov.yml` file

Signed-off-by: Navin Chandra <navinchandra772@gmail.com>
---
 codecov.yml | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)
 create mode 100644 codecov.yml

diff --git a/codecov.yml b/codecov.yml
new file mode 100644
index 0000000000..39c5d5e789
--- /dev/null
+++ b/codecov.yml
@@ -0,0 +1,29 @@
+coverage:
+  status:
+    project:
+      default:
+        target: auto
+        threshold: 5%
+        base: auto
+
+ignore:
+  - "KubeArmor/enforcer/SELinuxEnforcer.go"
+  - "KubeArmor/enforcer/SELinuxEnforcer_test.go"
+  - "KubeArmor/enforcer/SELinuxHostProfile.go"
+  - "KubeArmor/kvmAgent"
+  - "KubeArmor/state"
+
+comment:
+  layout: "reach, diff, files"
+  behavior: default
+  require_changes: false
+  show_changes: true
+  show_critical_paths: true
+
+parsers:
+  gcov:
+    branch_detection:
+      conditional: yes
+      loop: yes
+      method: no
+      macro: no
\ No newline at end of file

From 210febbf703d4acbc7c90ae324b4f3a48545fec0 Mon Sep 17 00:00:00 2001
From: Navin Chandra <navinchandra772@gmail.com>
Date: Sun, 18 Aug 2024 19:01:16 +0000
Subject: [PATCH 4/8] Configure ci-test-ginkgo to generate coverage files

Signed-off-by: Navin Chandra <navinchandra772@gmail.com>
---
 .github/workflows/ci-test-ginkgo.yml | 89 ++++++++++++++++++++++++----
 1 file changed, 78 insertions(+), 11 deletions(-)

diff --git a/.github/workflows/ci-test-ginkgo.yml b/.github/workflows/ci-test-ginkgo.yml
index 5243c182f9..8392628a95 100644
--- a/.github/workflows/ci-test-ginkgo.yml
+++ b/.github/workflows/ci-test-ginkgo.yml
@@ -62,6 +62,8 @@ jobs:
 
       - name: Generate KubeArmor artifacts
         run: |
+          #set the $IS_COVERAGE env var to 'true' to build the kubearmor-test image for coverage calculation
+          export IS_COVERAGE=true
           GITHUB_SHA=$GITHUB_SHA ./KubeArmor/build/build_kubearmor.sh
 
       - name: Build Kubearmor-Operator
@@ -82,8 +84,8 @@ jobs:
       - name: Run KubeArmor
         run: |
           if [[ ${{ matrix.runtime }} == "containerd" ]]; then
-            docker save kubearmor/kubearmor-init:latest | sudo k3s ctr images import -
-            docker save kubearmor/kubearmor:latest | sudo k3s ctr images import -
+            docker save kubearmor/kubearmor-test-init:latest | sudo k3s ctr images import -
+            docker save kubearmor/kubearmor-test:latest | sudo k3s ctr images import -
             docker save kubearmor/kubearmor-operator:latest | sudo k3s ctr images import -
             docker save kubearmor/kubearmor-snitch:latest | sudo k3s ctr images import -
             
@@ -92,9 +94,9 @@ jobs:
             fi
           else
             if [ ${{ matrix.runtime }} == "crio" ]; then
-              docker save kubearmor/kubearmor-init:latest | sudo podman load
+              docker save kubearmor/kubearmor-test-init:latest | sudo podman load
               sudo podman tag localhost/latest:latest docker.io/kubearmor/kubearmor-init:latest
-              docker save kubearmor/kubearmor:latest | sudo podman load
+              docker save kubearmor/kubearmor-test:latest | sudo podman load
               sudo podman tag localhost/latest:latest docker.io/kubearmor/kubearmor:latest
               docker save kubearmor/kubearmor-operator:latest | sudo podman load
               sudo podman tag localhost/latest:latest docker.io/kubearmor/kubearmor-operator:latest
@@ -112,11 +114,11 @@ jobs:
           kubectl wait --for=condition=ready --timeout=5m -n kubearmor pod -l kubearmor-app=kubearmor-operator
           kubectl get pods -A
           if [[ ${{ steps.filter.outputs.controller }} == 'true' ]]; then
-            kubectl apply -f pkg/KubeArmorOperator/config/samples/kubearmor-test.yaml --dry-run=client -o json | \
+            kubectl apply -f pkg/KubeArmorOperator/config/samples/kubearmor-coverage.yaml --dry-run=client -o json | \
             jq '.spec.kubearmorControllerImage.imagePullPolicy = "Never"' | \
             kubectl apply -f -
           else 
-            kubectl apply -f pkg/KubeArmorOperator/config/samples/kubearmor-test.yaml
+            kubectl apply -f pkg/KubeArmorOperator/config/samples/kubearmor-coverage.yaml
           fi
 
           kubectl wait -n kubearmor --timeout=5m --for=jsonpath='{.status.phase}'=Running kubearmorconfigs/kubearmorconfig-test
@@ -124,13 +126,77 @@ jobs:
           kubectl wait --timeout=1m --for=condition=ready pod -l kubearmor-app=kubearmor-controller -n kubearmor
           kubectl get pods -A
 
+          sleep 10
+          DAEMONSET_NAME=$(kubectl get daemonset -n kubearmor -o jsonpath='{.items[0].metadata.name}')
+          echo "DaemonSet: $DAEMONSET_NAME"
+
+          kubectl patch daemonset $DAEMONSET_NAME -n kubearmor --type='json' -p='[
+            {
+              "op": "add",
+              "path": "/spec/template/spec/volumes/-",
+              "value": {
+                "name": "coverage-storage",
+                "hostPath": {
+                  "path": "/coverage",
+                  "type": "DirectoryOrCreate"
+                }
+              }
+            },
+            {
+              "op": "add",
+              "path": "/spec/template/spec/containers/0/volumeMounts/-",
+              "value": {
+                "mountPath": "/coverage",
+                "name": "coverage-storage"
+              }
+            },
+            {
+              "op": "add",
+              "path": "/spec/template/spec/containers/0/args/-",
+              "value": "-test.coverprofile=/coverage/coverage_k8s_${{ matrix.os }}_${{ matrix.runtime }}.out"
+            }
+          ]'
+
+          sleep 15
+
+      - name: Get KubeArmor POD info
+        run: |
+          DAEMONSET_NAME=$(kubectl get daemonset -n kubearmor -o jsonpath='{.items[0].metadata.name}')
+          LABEL_SELECTOR=$(kubectl get daemonset $DAEMONSET_NAME -n kubearmor -o jsonpath='{.spec.selector.matchLabels}' | jq -r 'to_entries[] | "\(.key)=\(.value)"' | paste -sd, -)
+          POD_NAME=$(kubectl get pods -n kubearmor -l "$LABEL_SELECTOR" -o jsonpath='{.items[*].metadata.name}')
+          echo "Pod: $POD_NAME"
+          echo "POD_NAME=$POD_NAME" >> $GITHUB_ENV
+
       - name: Test KubeArmor using Ginkgo
         run: |
+          kubectl logs $POD_NAME -n kubearmor
           go install -mod=mod github.com/onsi/ginkgo/v2/ginkgo
           make
         working-directory: ./tests/k8s_env
         timeout-minutes: 30
+        env:
+          POD_NAME: ${{ env.POD_NAME }}
 
+      - name: Kill KubeArmor prcoess in the pod
+        run: |
+          KUBEARMOR_PID=$(kubectl exec ${{ env.POD_NAME }} -n kubearmor -c kubearmor -- sh -c "ps aux | grep '[K]ubeArmor/kubearmor-test' | awk '{print \$1}'")
+          kubectl exec ${{ env.POD_NAME }} -n kubearmor -c kubearmor -- sh -c "kill -s SIGINT $KUBEARMOR_PID"
+          sleep 10
+        env:
+          POD_NAME: ${{ env.POD_NAME }}
+
+      - name: Extract coverage file
+        run: |
+          for i in {1..24}; do
+            if [ -f /coverage/coverage_k8s_${{ matrix.os }}_${{ matrix.runtime }}.out ]; then
+              cp /coverage/coverage_k8s_${{ matrix.os }}_${{ matrix.runtime }}.out coverage_k8s_${{ matrix.os }}_${{ matrix.runtime }}.out
+              break
+            fi
+            sleep 5
+          done
+          ls -l
+        working-directory: KubeArmor
+        
       - name: Get karmor sysdump
         if: ${{ failure() }}
         run: |
@@ -150,14 +216,15 @@ jobs:
       - name: Measure code coverage
         if: ${{ always() }}
         run: |
-          go install github.com/modocache/gover@latest
-          gover
-          go tool cover -func=gover.coverprofile
+          ls -l
+          go tool cover -func coverage_k8s_${{ matrix.os }}_${{ matrix.runtime }}.out
         working-directory: KubeArmor
         env:
           GOPATH: /home/runner/go
 
-      - uses: codecov/codecov-action@v3
+      - name: Upload coverage file
         if: ${{ always() }}
+        uses: actions/upload-artifact@v4
         with:
-          files: ./KubeArmor/gover.coverprofile
+          name: coverage-k8s-${{ matrix.os }}-${{ matrix.runtime }}
+          path: KubeArmor/coverage_k8s_${{ matrix.os }}_${{ matrix.runtime }}.out

From 4a82519827607b6ec7a74a9299ccc2614e1ab513 Mon Sep 17 00:00:00 2001
From: Navin Chandra <navinchandra772@gmail.com>
Date: Sun, 18 Aug 2024 19:02:06 +0000
Subject: [PATCH 5/8] download coverage artifacts and send to codecov

Signed-off-by: Navin Chandra <navinchandra772@gmail.com>
---
 .github/workflows/ci-merge-coverage.yaml | 83 ++++++++++++++++++++++++
 1 file changed, 83 insertions(+)
 create mode 100644 .github/workflows/ci-merge-coverage.yaml

diff --git a/.github/workflows/ci-merge-coverage.yaml b/.github/workflows/ci-merge-coverage.yaml
new file mode 100644
index 0000000000..bdd9a00e58
--- /dev/null
+++ b/.github/workflows/ci-merge-coverage.yaml
@@ -0,0 +1,83 @@
+name: ci-merge-coverage
+
+on:
+  workflow_run:
+    workflows: ["ci-test-ginkgo"]
+    types:
+      - completed
+
+jobs:
+  merge-coverage-files:
+    name: Download and merge files
+    runs-on: ubuntu-latest
+    timeout-minutes: 60
+    steps:
+      - uses: actions/checkout@v3
+        with:
+          submodules: true
+
+      - name: Check if all required workflows completed successfully
+        id: check-workflows
+        run: |
+            workflows=("ci-test-ginkgo")
+            max_retries=20  # Set a max retry limit (e.g., 20 retries with 120-second intervals)
+            interval=120    # Set interval in seconds between retries
+            all_completed=false
+
+            commit_sha=$(git rev-parse HEAD)
+
+            for workflow in "${workflows[@]}"; do
+            echo "${workflow}_status=pending" >> $GITHUB_ENV
+            done
+
+            for (( i=0; i<$max_retries; i++ )); do
+            all_completed=true
+
+            for workflow in "${workflows[@]}"; do
+                conclusion=$(gh run list --workflow=$workflow --branch=main --json conclusion,headSha | jq -r --arg sha "$commit_sha" '.[] | select(.headSha == $sha) | .conclusion')
+
+                if [[ -z "$conclusion" ]]; then
+                conclusion="pending"
+                fi
+
+                if [[ "$conclusion" != "success" ]]; then
+                all_completed=false
+                fi
+
+                echo "${workflow}_status=$conclusion" >> $GITHUB_ENV
+            done
+
+            if [[ "$all_completed" == "true" ]]; then
+                echo "All workflows completed successfully for commit $commit_sha."
+                echo "all_succeeded=true" >> $GITHUB_ENV
+                break
+            fi
+
+            if [[ "$i" -eq $((max_retries - 1)) ]]; then
+                echo "Timeout waiting for workflows to complete for commit $commit_sha."
+                exit 1
+            else
+                sleep $interval
+            fi
+            done
+        env:
+            GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+
+
+      - uses: actions/setup-go@v5
+        with:
+          go-version-file: 'KubeArmor/go.mod'
+
+      - name: Download k8s coverage files from ci-test-ginkgo
+        if: ${{ env.ci-test-ginkgo_status == 'success' }}
+        uses: dawidd6/action-download-artifact@v6
+        with:
+          workflow: ci-test-ginkgo.yml
+          name: coverage.*
+          path: KubeArmor/
+          name_is_regexp: true
+          search_artifacts: true
+
+      - uses: codecov/codecov-action@v4
+        with:
+          token: ${{ secrets.CODECOV_TOKEN }}
\ No newline at end of file

From 35dca9913881e0f1c27bf6946c46914a13857a5b Mon Sep 17 00:00:00 2001
From: Navin Chandra <navinchandra772@gmail.com>
Date: Mon, 19 Aug 2024 10:49:20 +0000
Subject: [PATCH 6/8] fix crio runs

Signed-off-by: Navin Chandra <navinchandra772@gmail.com>
---
 .github/workflows/ci-test-ginkgo.yml | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/.github/workflows/ci-test-ginkgo.yml b/.github/workflows/ci-test-ginkgo.yml
index 8392628a95..553b5e68f7 100644
--- a/.github/workflows/ci-test-ginkgo.yml
+++ b/.github/workflows/ci-test-ginkgo.yml
@@ -95,9 +95,9 @@ jobs:
           else
             if [ ${{ matrix.runtime }} == "crio" ]; then
               docker save kubearmor/kubearmor-test-init:latest | sudo podman load
-              sudo podman tag localhost/latest:latest docker.io/kubearmor/kubearmor-init:latest
+              sudo podman tag localhost/latest:latest docker.io/kubearmor/kubearmor-test-init:latest
               docker save kubearmor/kubearmor-test:latest | sudo podman load
-              sudo podman tag localhost/latest:latest docker.io/kubearmor/kubearmor:latest
+              sudo podman tag localhost/latest:latest docker.io/kubearmor/kubearmor-test:latest
               docker save kubearmor/kubearmor-operator:latest | sudo podman load
               sudo podman tag localhost/latest:latest docker.io/kubearmor/kubearmor-operator:latest
               docker save kubearmor/kubearmor-snitch:latest | sudo podman load
@@ -169,13 +169,10 @@ jobs:
 
       - name: Test KubeArmor using Ginkgo
         run: |
-          kubectl logs $POD_NAME -n kubearmor
           go install -mod=mod github.com/onsi/ginkgo/v2/ginkgo
           make
         working-directory: ./tests/k8s_env
         timeout-minutes: 30
-        env:
-          POD_NAME: ${{ env.POD_NAME }}
 
       - name: Kill KubeArmor prcoess in the pod
         run: |

From c04b43e1af325c66dc2af571d8fc432b8d8e29af Mon Sep 17 00:00:00 2001
From: Navin Chandra <navinchandra772@gmail.com>
Date: Tue, 20 Aug 2024 15:21:55 +0000
Subject: [PATCH 7/8] build UBI based coverage image

Signed-off-by: Navin Chandra <navinchandra772@gmail.com>
---
 Dockerfile                         | 35 +++++++++++++++++++++++++++++-
 KubeArmor/build/build_kubearmor.sh | 11 ++++++++++
 2 files changed, 45 insertions(+), 1 deletion(-)

diff --git a/Dockerfile b/Dockerfile
index f72b1b592e..b0ace30dc1 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -42,7 +42,7 @@ RUN make
 
 FROM builder AS builder-test
 WORKDIR /usr/src/KubeArmor/KubeArmor
-RUN go test -covermode=atomic -coverpkg=./... -c . -o kubearmor-test
+RUN CGO_ENABLED=0 go test -covermode=atomic -coverpkg=./... -c . -o kubearmor-test
 
 ### Make executable image
 
@@ -110,3 +110,36 @@ RUN setcap "cap_sys_admin=ep cap_sys_ptrace=ep cap_ipc_lock=ep cap_sys_resource=
 
 USER 1000
 ENTRYPOINT ["/KubeArmor/kubearmor"]
+
+### Make UBI-based test executable image for coverage calculation
+FROM redhat/ubi9-minimal AS kubearmor-ubi-test
+
+ARG VERSION=latest
+ENV KUBEARMOR_UBI=true
+
+LABEL name="kubearmor" \
+      vendor="Accuknox" \
+      version=${VERSION} \
+      release=${VERSION} \
+      summary="kubearmor container image based on redhat ubi" \
+      description="KubeArmor is a cloud-native runtime security enforcement system that restricts the behavior \
+                  (such as process execution, file access, and networking operations) of pods, containers, and nodes (VMs) \
+                  at the system level."
+
+RUN microdnf -y update && \
+    microdnf -y install --nodocs --setopt=install_weak_deps=0 --setopt=keepcache=0 shadow-utils procps libcap && \
+    microdnf clean all
+
+RUN groupadd --gid 1000 default \
+  && useradd --uid 1000 --gid default --shell /bin/bash --create-home default
+
+COPY LICENSE /licenses/license.txt
+COPY --from=builder --chown=default:default /usr/src/KubeArmor/KubeArmor/kubearmor /KubeArmor/kubearmor
+COPY --from=builder --chown=default:default /usr/src/KubeArmor/BPF/*.o /opt/kubearmor/BPF/
+COPY --from=builder --chown=default:default /usr/src/KubeArmor/KubeArmor/templates/* /KubeArmor/templates/
+COPY --from=builder-test --chown=default:default /usr/src/KubeArmor/KubeArmor/kubearmor-test /KubeArmor/kubearmor-test
+
+RUN setcap "cap_sys_admin=ep cap_sys_ptrace=ep cap_ipc_lock=ep cap_sys_resource=ep cap_dac_override=ep cap_dac_read_search=ep" /KubeArmor/kubearmor-test
+
+USER 1000
+ENTRYPOINT ["/KubeArmor/kubearmor-test"]
\ No newline at end of file
diff --git a/KubeArmor/build/build_kubearmor.sh b/KubeArmor/build/build_kubearmor.sh
index b75e59771b..3a58c13919 100755
--- a/KubeArmor/build/build_kubearmor.sh
+++ b/KubeArmor/build/build_kubearmor.sh
@@ -70,6 +70,17 @@ if [[ "$IS_COVERAGE" == "true" ]]; then
     fi
     echo "[PASSED] Built $REPO-init:$VERSION"
 
+    # build kubearmor-ubi-test image
+    DTAGUBITEST="-t $UBIREPO-test:$VERSION"
+    echo "[INFO] Building $DTAGUBITEST"
+    cd $ARMOR_HOME/..; docker build $DTAGUBITEST -f Dockerfile --target kubearmor-ubi-test . $LABEL
+
+    if [ $? != 0 ]; then
+        echo "[FAILED] Failed to build $DTAGUBITEST:$VERSION"
+        exit 1
+    fi
+    echo "[PASSED] Built $DTAGUBITEST:$VERSION"
+    
     exit 0
 fi
 

From 753934ba920d36f4a5e6942bd0100df248cfa3c7 Mon Sep 17 00:00:00 2001
From: Navin Chandra <navinchandra772@gmail.com>
Date: Tue, 20 Aug 2024 16:36:41 +0000
Subject: [PATCH 8/8] Remove retry logic and check for completed workflows

Signed-off-by: Navin Chandra <navinchandra772@gmail.com>
---
 .github/workflows/ci-merge-coverage.yaml | 68 +++++++++---------------
 1 file changed, 26 insertions(+), 42 deletions(-)

diff --git a/.github/workflows/ci-merge-coverage.yaml b/.github/workflows/ci-merge-coverage.yaml
index bdd9a00e58..d26d37bd4e 100644
--- a/.github/workflows/ci-merge-coverage.yaml
+++ b/.github/workflows/ci-merge-coverage.yaml
@@ -2,7 +2,7 @@ name: ci-merge-coverage
 
 on:
   workflow_run:
-    workflows: ["ci-test-ginkgo"]
+    workflows: [ci-test-ginkgo]
     types:
       - completed
 
@@ -12,58 +12,42 @@ jobs:
     runs-on: ubuntu-latest
     timeout-minutes: 60
     steps:
-      - uses: actions/checkout@v3
-        with:
-          submodules: true
-
       - name: Check if all required workflows completed successfully
         id: check-workflows
         run: |
-            workflows=("ci-test-ginkgo")
-            max_retries=20  # Set a max retry limit (e.g., 20 retries with 120-second intervals)
-            interval=120    # Set interval in seconds between retries
-            all_completed=false
-
-            commit_sha=$(git rev-parse HEAD)
-
-            for workflow in "${workflows[@]}"; do
-            echo "${workflow}_status=pending" >> $GITHUB_ENV
-            done
+          workflows=("ci-test-ginkgo")
+          all_completed=true
 
-            for (( i=0; i<$max_retries; i++ )); do
-            all_completed=true
+          commit_sha=$(git rev-parse HEAD)
 
-            for workflow in "${workflows[@]}"; do
-                conclusion=$(gh run list --workflow=$workflow --branch=main --json conclusion,headSha | jq -r --arg sha "$commit_sha" '.[] | select(.headSha == $sha) | .conclusion')
+          for workflow in "${workflows[@]}"; do
+              conclusion=$(gh run list --workflow=$workflow --json conclusion,headSha,event,headBranch | jq -r --arg sha "$commit_sha" --arg event "pull_request" '.[] | select(.headSha == $sha and .event == $event) | .conclusion')
 
-                if [[ -z "$conclusion" ]]; then
-                conclusion="pending"
-                fi
+              if [[ -z "$conclusion" ]]; then
+                  conclusion="pending"
+              fi
 
-                if [[ "$conclusion" != "success" ]]; then
-                all_completed=false
-                fi
+              if [[ "$conclusion" != "success" ]]; then
+                  all_completed=false
+              fi
 
-                echo "${workflow}_status=$conclusion" >> $GITHUB_ENV
-            done
+              echo "${workflow}_status=$conclusion" >> $GITHUB_ENV
+          done
 
-            if [[ "$all_completed" == "true" ]]; then
-                echo "All workflows completed successfully for commit $commit_sha."
-                echo "all_succeeded=true" >> $GITHUB_ENV
-                break
-            fi
-
-            if [[ "$i" -eq $((max_retries - 1)) ]]; then
-                echo "Timeout waiting for workflows to complete for commit $commit_sha."
-                exit 1
-            else
-                sleep $interval
-            fi
-            done
+          if [[ "$all_completed" == "true" ]]; then
+              echo "All workflows completed successfully for commit $commit_sha."
+              echo "all_succeeded=true" >> $GITHUB_ENV
+          else
+              echo "Not all workflows completed successfully for commit $commit_sha."
+              exit 1
+          fi
         env:
-            GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-
+          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
 
+      - uses: actions/checkout@v3
+        with:
+          submodules: true
+          
       - uses: actions/setup-go@v5
         with:
           go-version-file: 'KubeArmor/go.mod'