diff --git a/jenkins/README.md b/jenkins/README.md new file mode 100644 index 0000000..ddb7e6b --- /dev/null +++ b/jenkins/README.md @@ -0,0 +1,12 @@ +# Jenkins pipeline to run performance test + +## Prerequisites + +1. Install a jenkins server +1. Configure the following environment variables in jenkins global configuration + - CNCF_EKS_ACCESS_KEY with the username(access key) and password (secret key), the user must have permission to create/delete eks clusters +1. Add a jenkins node to the jenkins server, add label `aws-ec2` to the node. +1. Create the following three jenkins jobs + - create-cluster -- create/Jenkinsfile + - run-performance-test -- test/Jenkinsfile + - delete-cluster -- delete/Jenkinsfile diff --git a/jenkins/create/Jenkinsfile b/jenkins/create/Jenkinsfile new file mode 100644 index 0000000..5443c91 --- /dev/null +++ b/jenkins/create/Jenkinsfile @@ -0,0 +1,233 @@ +pipeline { + + agent { node { label 'aws-ec2' } } + + parameters { + string(name: 'AWS_REGION', defaultValue: 'us-east-1', description: 'AWS Region') + string(name: 'CLUSTER_NAME', defaultValue: 'demo-eks', description: 'EKS Cluster Name') + string(name: 'NODE_GROUP_NAME', defaultValue: 'demo-nodes', description: 'EKS Node Group Name') + string(name: 'NODE_TYPE', defaultValue: 't3.medium', description: 'EC2 Worker Node Type (Example: t3.medium)') + string(name: 'NODE_COUNT', defaultValue: '2', description: 'Number of Worker Nodes') + string(name: 'HARBOR_HELM_VERSION', defaultValue: '1.18.0', description: 'The Harbor Helm Chart version to install') + booleanParam(name: 'SKIP_CREATE_CLUSTER', defaultValue: false, description: 'Whether skip to create the EKS cluster') + } + + stages { + stage('Install unzip') { + steps { + sh ''' + if ! command -v unzip &> /dev/null; then + echo "Installing unzip..." + sudo apt-get update -y + sudo apt-get install -y unzip + else + echo "unzip already installed" + fi + ''' + } + } + stage('Install AWS CLI') { + steps { + sh """ + if [ ! -x "/usr/local/bin/aws" ]; then + echo "Installing AWS CLI..." + curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" + unzip -o awscliv2.zip + sudo ./aws/install --update + aws --version + else + echo "AWS CLI already installed." + aws --version + fi + """ + } + } + + stage('Setup AWS CLI Credentials') { + steps { + withCredentials([ + usernamePassword(credentialsId: 'CNCF_EKS_ACCESS_KEY', usernameVariable: 's3_access_key', passwordVariable: 's3_secret_key'), + ]){ + sh """ + mkdir -p ~/.aws + cat > ~/.aws/credentials < ~/.aws/config </dev/null; then + echo "Installing kubectl..." + curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" + chmod +x kubectl + sudo mv kubectl /usr/local/bin/ + else + echo "kubectl already installed" + fi + kubectl version --client + ''' + } + } + + stage('Install Helm CLI') { + steps { + sh ''' + if ! command -v helm &>/dev/null; then + echo "Installing Helm..." + curl -L https://get.helm.sh/helm-v3.14.3-linux-amd64.tar.gz -o helm.tar.gz + tar -xzf helm.tar.gz + sudo mv linux-amd64/helm /usr/local/bin/ + else + echo "Helm already installed" + fi + helm version + ''' + } + } + + stage('Download eksctl') { + steps { + sh """ + if ! command -v eksctl &> /dev/null; then + echo "Downloading eksctl..." + curl -L https://github.com/eksctl-io/eksctl/releases/download/v0.215.0/eksctl_Linux_amd64.tar.gz -o eksctl.tar.gz + tar -xzf eksctl.tar.gz + sudo mv eksctl /usr/local/bin/ + fi + eksctl version + """ + } + } + + stage('Create EKS Cluster') { + when { + expression { return params.SKIP_CREATE_CLUSTER == false } + } + steps { + sh """ + eksctl create cluster \\ + --name ${params.CLUSTER_NAME} \\ + --region ${params.AWS_REGION} \\ + --nodegroup-name ${params.NODE_GROUP_NAME} \\ + --node-type ${params.NODE_TYPE} \\ + --nodes ${params.NODE_COUNT} \\ + --managed + """ + } + } + + stage('Add CSI Policy to Node Role') { + when { + expression { return params.SKIP_CREATE_CLUSTER == false } + } + steps { + sh ''' +echo "Attaching AmazonEBSCSIDriverPolicy to Node Role" +cat > set_csi_policy.sh < /dev/null; then + echo "Installing unzip..." + sudo apt-get update -y + sudo apt-get install -y unzip + else + echo "unzip already installed" + fi + ''' + } + } + + stage('Install AWS CLI (if missing)') { + steps { + sh ''' + if ! command -v aws &> /dev/null; then + echo "Installing AWS CLI..." + curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" + unzip -o awscliv2.zip + sudo ./aws/install --update + else + echo "AWS CLI already installed" + fi + aws --version + ''' + } + } + + stage('Setup AWS CLI Credentials') { + steps { + withCredentials([ + usernamePassword(credentialsId: 'CNCF_EKS_ACCESS_KEY', usernameVariable: 's3_access_key', passwordVariable: 's3_secret_key'), + ]){ + sh """ + mkdir -p ~/.aws + cat > ~/.aws/credentials < ~/.aws/config < /dev/null; then + echo "Installing eksctl..." + curl -L "https://github.com/eksctl-io/eksctl/releases/download/v0.215.0/eksctl_Linux_amd64.tar.gz" -o eksctl.tar.gz + tar -xzf eksctl.tar.gz + sudo mv eksctl /usr/local/bin/ + else + echo "eksctl already installed" + fi + eksctl version + ''' + } + } + + stage('Delete EKS Cluster') { + steps { + echo "Preparing to delete EKS cluster: ${params.CLUSTER_NAME} in region: ${params.REGION}" + sh ''' + echo "Deleting EKS cluster ${CLUSTER_NAME}..." + eksctl delete cluster --name ${CLUSTER_NAME} --region ${REGION} --wait + ''' + } + } + } + + post { + always { + echo "Cluster deletion process completed." + } + } +} diff --git a/jenkins/test/Jenkinsfile b/jenkins/test/Jenkinsfile new file mode 100644 index 0000000..1f22170 --- /dev/null +++ b/jenkins/test/Jenkinsfile @@ -0,0 +1,108 @@ +pipeline { + + agent { node { label 'aws-ec2' } } + + parameters { + string(name: 'SIZE', defaultValue: 'ci', description: 'The size need to test, it should be medium, small or ci') + string(name: 'VUS', defaultValue: '100', description: 'The number of virtual users to simulate') + string(name: 'INGRESS_IP', defaultValue: '145.40.81.171', description: 'The ingress IP address') + string(name: 'PERF_REPO', defaultValue: 'https://github.com/goharbor/perf.git', description: 'The performance test repository') + string(name: 'PERF_REPO_BRANCH', defaultValue: 'main', description: 'The performance test branch to use') + booleanParam(name: 'auto_sbom_generation', defaultValue: false, description: 'Whether to enable auto generate sbom') + string(name: 'fake_scanner_url', defaultValue: 'https://fake-scanner.domain', description: 'The fake scanner url to use') + string(name: 'recipient', defaultValue: 'stone.zhang@broadcom.com', description: 'The email address to send notifications to') + } + + environment { + PREPARE="$prepare" + HARBOR_SIZE="${params.SIZE}" + HARBOR_VUS="${params.VUS}" + INGRESSIP="${params.INGRESS_IP}" + HARBOR_URL="https://admin:Harbor12345@core.harbor.domain" + HARBOR_REPORT="true" + KUBECONFIG="/var/lib/jenkins/.kube/config" + GOROOT="/root/go1.25" + PATH="$GOROOT/bin:$PATH" + } + + stages { + + stage('install dependencies') { + steps { + sh """ + sudo apt-get update -y + sudo apt-get install -y zip + """ + } + } + + stage('mapping hostname in /etc/hosts') { + steps { + sh """ + if ! grep -q "core.harbor.domain" /etc/hosts; then + echo "Mapping hostname to /etc/hosts" + echo "${params.INGRESS_IP} core.harbor.domain" | sudo tee -a /etc/hosts + else + echo "Hostname already mapped in /etc/hosts, replacing it" + sudo sed -i.bak "/core.harbor.domain/c\\${params.INGRESS_IP} core.harbor.domain" /etc/hosts + fi + """ + } + } + + stage('Prepare Data') { + steps { + sh """ + rm -rf perf && git clone "${params.PERF_REPO}" && cd perf && git checkout "${params.PERF_REPO_BRANCH}" + AUTO_SBOM_GENERATION="$auto_sbom_generation" FAKE_SCANNER_URL="$fake_scanner_url" go run mage.go prepare + """ + } + } + + stage('Performance Test') { + steps { + sh """ + rm -rf perf && git clone "${params.PERF_REPO}" && cd perf && git checkout "${params.PERF_REPO_BRANCH}" + env + pwd + go run mage.go + # backup results + cp ./outputs/report.md /tmp/report.md + echo "Performance test completed. backup result file: " + zip -r "${JOB_NAME}-${BUILD_NUMBER}.zip" ./outputs/ + mv "${JOB_NAME}-${BUILD_NUMBER}.zip" /var/reports/ + """ + + + script { + sh 'cp /tmp/report.md report.md' + } + } + } + } + post { + success { + echo 'The build was successful!' + + emailext subject: "Harbor performance on the kubernetes #${env.BUILD_NUMBER} - SUCCESS", + body: """ +

Build #${env.BUILD_NUMBER} result: SUCCESS

+

View build details: ${env.BUILD_URL}

+

Performance test report: Performance test report

+ """, + mimeType: 'text/html', + to: "${params.recipient}" + } + + failure { + echo 'The build failed.' + emailext subject: "Harbor performance on the kubernetes #${env.BUILD_NUMBER} - FAILED", + body: """ +

Build #${env.BUILD_NUMBER} result: FAILED

+

View build details: ${env.BUILD_URL}

+ """, + mimeType: 'text/html', + to: "${params.recipient}" + } + } +} \ No newline at end of file