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'