github.com/verrazzano/verrazzano@v1.7.1/ci/generic/Jenkinsfile-singletarget (about)

     1  // Copyright (c) 2023, 2024, Oracle and/or its affiliates.
     2  // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
     3  
     4  def DOCKER_IMAGE_TAG
     5  def agentLabel = env.JOB_NAME.contains('master') ? "2.0-large-phx" : "2.0-large"
     6  def EFFECTIVE_DUMP_K8S_CLUSTER_ON_SUCCESS = false
     7  
     8  pipeline {
     9      options {
    10          timeout(time: 1, unit: 'HOURS')
    11          skipDefaultCheckout true
    12          timestamps ()
    13      }
    14  
    15      agent {
    16         docker {
    17              image "${RUNNER_DOCKER_IMAGE}"
    18              args "${RUNNER_DOCKER_ARGS}"
    19              registryUrl "${RUNNER_DOCKER_REGISTRY_URL}"
    20              registryCredentialsId 'ocir-pull-and-push-account'
    21              label "${agentLabel}"
    22          }
    23      }
    24  
    25      parameters {
    26          choice (name: 'KUBERNETES_CLUSTER_VERSION',
    27                  description: 'Kubernetes Version for KinD Cluster',
    28                  // 1st choice is the default value
    29                  choices: ["1.27", "1.26", "1.25", "1.24" ])
    30          string (name: 'GIT_COMMIT_TO_USE',
    31                          defaultValue: 'NONE',
    32                          description: 'This is the full git commit hash from the source build to be used for all jobs',
    33                          trim: true)
    34          string (name: 'TEST_TARGET',
    35                  defaultValue: 'kind-acceptance-tests',
    36                  description: 'Test target to execute',
    37                  trim: true)
    38          string (name: 'VERRAZZANO_OPERATOR_IMAGE',
    39                          defaultValue: 'NONE',
    40                          description: 'Verrazzano platform operator image name (in ghcr.io repo).  If not specified, the operator.yaml from Verrazzano repo will be used to create Verrazzano platform operator',
    41                          trim: true)
    42          choice (name: 'WILDCARD_DNS_DOMAIN',
    43                  description: 'This is the wildcard DNS domain',
    44                  // 1st choice is the default value
    45                  choices: [ "nip.io", "sslip.io"])
    46          choice (name: 'CRD_API_VERSION',
    47                  description: 'This is the API crd version.',
    48                  // 1st choice is the default value
    49                  choices: [ "v1beta1", "v1alpha1"])
    50          booleanParam (description: 'Whether to create the cluster with Calico for AT testing (defaults to true)', name: 'CREATE_CLUSTER_USE_CALICO', defaultValue: true)
    51          booleanParam (description: 'Whether to dump k8s cluster on success (off by default can be useful to capture for comparing to failed cluster)', name: 'DUMP_K8S_CLUSTER_ON_SUCCESS', defaultValue: false)
    52          string (name: 'CONSOLE_REPO_BRANCH',
    53                  defaultValue: '',
    54                  description: 'The branch to check out after cloning the console repository.',
    55                  trim: true)
    56          booleanParam (description: 'Whether to enable debug logging of the istio envoy in the VZ API pod', name: 'ENABLE_API_ENVOY_LOGGING', defaultValue: true)
    57          string (name: 'TAGGED_TESTS',
    58                  defaultValue: '',
    59                  description: 'A comma separated list of build tags for tests that should be executed (e.g. unstable_test). Default:',
    60                  trim: true)
    61          string (name: 'INCLUDED_TESTS',
    62                  defaultValue: '.*',
    63                  description: 'A regex matching any fully qualified test file that should be executed (e.g. examples/helidon/). Default: .*',
    64                  trim: true)
    65          string (name: 'EXCLUDED_TESTS',
    66                  defaultValue: '_excluded_test',
    67                  description: 'A regex matching any fully qualified test file that should not be executed (e.g. multicluster/|_excluded_test). Default: _excluded_test',
    68                  trim: true)
    69      }
    70  
    71      environment {
    72          DOCKER_PLATFORM_CI_IMAGE_NAME = 'verrazzano-platform-operator-jenkins'
    73          DOCKER_PLATFORM_PUBLISH_IMAGE_NAME = 'verrazzano-platform-operator'
    74          GOPATH = '/home/opc/go'
    75          GO_REPO_PATH = "${GOPATH}/src/github.com/verrazzano"
    76  
    77          // Env vars for Image pull/docker secrets
    78          IMAGE_PULL_SECRET = 'verrazzano-container-registry'
    79          DOCKER_CREDS = credentials('github-packages-credentials-rw')
    80          DOCKER_EMAIL = credentials('github-packages-email')
    81          DOCKER_REPO = 'ghcr.io'
    82          OCR_CREDS = credentials('ocr-pull-and-push-account')
    83          OCR_REPO = 'container-registry.oracle.com'
    84  
    85          NETRC_FILE = credentials('netrc')
    86  
    87          CLUSTER_NAME = 'verrazzano'
    88          KUBECONFIG = "${WORKSPACE}/test_kubeconfig"
    89          VERRAZZANO_KUBECONFIG = "${KUBECONFIG}"
    90  
    91          TEST_ROOT = "${WORKSPACE}/tests/e2e"
    92          POST_INSTALL_DUMP="true"
    93          POST_DUMP_FAILED_FILE = "${WORKSPACE}/post_dump_failed_file.tmp"
    94          TESTS_EXECUTED_FILE = "${WORKSPACE}/tests_executed_file.tmp"
    95  
    96          VERRAZZANO_OPERATOR_IMAGE="${params.VERRAZZANO_OPERATOR_IMAGE}"
    97  
    98          INSTALL_PROFILE = "dev"
    99          VZ_ENVIRONMENT_NAME = "default"
   100          INSTALL_CONFIG_FILE_KIND = "${TEST_SCRIPTS_DIR}/${params.CRD_API_VERSION}/install-verrazzano-kind.yaml"
   101          WEBLOGIC_PSW = credentials('weblogic-example-domain-password') // required by WebLogic application and console ingress test
   102          DATABASE_PSW = credentials('todo-mysql-password') // required by console ingress test
   103  
   104          // used for console artifact capture on failure
   105          JENKINS_READ = credentials('jenkins-auditor')
   106          OCI_CLI_AUTH="instance_principal"
   107          OCI_OS_NAMESPACE = credentials('oci-os-namespace')
   108          OCI_OS_ARTIFACT_BUCKET="build-failure-artifacts"
   109  
   110          // used to emit metrics
   111          PROMETHEUS_CREDENTIALS = credentials('prometheus-credentials')
   112          TEST_ENV_LABEL = "kind"
   113          TEST_ENV = "KIND"
   114          K8S_VERSION_LABEL = "${params.KUBERNETES_CLUSTER_VERSION}"
   115      }
   116  
   117      stages {
   118          stage('Clean workspace and checkout') {
   119              steps {
   120                  pipelineSetup()
   121              }
   122          }
   123  
   124          stage('Run Acceptance Tests') {
   125              environment {
   126                  KUBERNETES_CLUSTER_VERSION="${params.KUBERNETES_CLUSTER_VERSION}"
   127                  OCI_CLI_AUTH="instance_principal"
   128                  OCI_OS_NAMESPACE = credentials('oci-os-namespace')
   129                  OCI_OS_LOCATION="ephemeral/${env.BRANCH_NAME}/${SHORT_COMMIT_HASH}"
   130              }
   131              steps {
   132                  echo "Executing pipeline configuration ${env.PIPELINE_CONFIG}"
   133                  runMakeCommand(params.TEST_TARGET)
   134              }
   135          }
   136      }
   137      post {
   138          failure {
   139              script {
   140                  if ( fileExists(env.TESTS_EXECUTED_FILE) ) {
   141                      dumpK8sCluster('new-kind-acceptance-tests-cluster-snapshot')
   142                  }
   143                  postFailureProcessing()
   144              }
   145          }
   146          success {
   147              script {
   148                  if (EFFECTIVE_DUMP_K8S_CLUSTER_ON_SUCCESS == true && fileExists(env.TESTS_EXECUTED_FILE) ) {
   149                      dumpK8sCluster('new-kind-acceptance-tests-cluster-snapshot')
   150                  }
   151              }
   152          }
   153          always {
   154              archiveArtifacts artifacts: "**/coverage.html,**/logs/**,**/verrazzano_images.txt,**/*cluster-snapshot*/**,**/Screenshot*.png,**/ConsoleLog*.log,**/*${TEST_REPORT}", allowEmptyArchive: true
   155              junit testResults: "**/${TEST_REPORT}", allowEmptyResults: true
   156          }
   157          cleanup {
   158              script {
   159                  runMakeCommand("cleanup")
   160              }
   161              deleteDir()
   162          }
   163      }
   164  }
   165  
   166  def runTestTarget(testSuitePath, runParallel = "true", randomize = "true") {
   167      return script {
   168          sh """
   169             export TEST_SUITES="${testSuitePath}/..."
   170             export RANDOMIZE_TESTS=${randomize}
   171             export RUN_PARALLEL=${runParallel}
   172             cd ${GO_REPO_PATH}/verrazzano/ci/generic
   173             make test
   174          """
   175      }
   176  }
   177  
   178  def runMakeCommand(makeTarget) {
   179      sh """
   180         cd ${GO_REPO_PATH}/verrazzano/ci/generic
   181         make ${makeTarget}
   182      """
   183  }
   184  
   185  def pipelineSetup() {
   186      sh """
   187          echo "${NODE_LABELS}"
   188      """
   189  
   190      script {
   191          EFFECTIVE_DUMP_K8S_CLUSTER_ON_SUCCESS = getEffectiveDumpOnSuccess()
   192          if (params.GIT_COMMIT_TO_USE == "NONE") {
   193              echo "Specific GIT commit was not specified, use current head"
   194              def scmInfo = checkout scm
   195              env.GIT_COMMIT = scmInfo.GIT_COMMIT
   196              env.GIT_BRANCH = scmInfo.GIT_BRANCH
   197          } else {
   198              echo "SCM checkout of ${params.GIT_COMMIT_TO_USE}"
   199              def scmInfo = checkout([
   200                  $class: 'GitSCM',
   201                  branches: [[name: params.GIT_COMMIT_TO_USE]],
   202                  doGenerateSubmoduleConfigurations: false,
   203                  extensions: [],
   204                  submoduleCfg: [],
   205                  userRemoteConfigs: [[url: env.SCM_VERRAZZANO_GIT_URL]]])
   206              env.GIT_COMMIT = scmInfo.GIT_COMMIT
   207              env.GIT_BRANCH = scmInfo.GIT_BRANCH
   208              // If the commit we were handed is not what the SCM says we are using, fail
   209              if (!env.GIT_COMMIT.equals(params.GIT_COMMIT_TO_USE)) {
   210                  echo "SCM didn't checkout the commit we expected. Expected: ${params.GIT_COMMIT_TO_USE}, Found: ${scmInfo.GIT_COMMIT}"
   211                  exit 1
   212              }
   213          }
   214          echo "SCM checkout of ${env.GIT_BRANCH} at ${env.GIT_COMMIT}"
   215      }
   216  
   217      sh """
   218          cp -f "${NETRC_FILE}" $HOME/.netrc
   219          chmod 600 $HOME/.netrc
   220      """
   221  
   222      script {
   223          try {
   224          sh """
   225              echo "${DOCKER_CREDS_PSW}" | docker login ${env.DOCKER_REPO} -u ${DOCKER_CREDS_USR} --password-stdin
   226          """
   227          } catch(error) {
   228              echo "docker login failed, retrying after sleep"
   229              retry(4) {
   230                  sleep(30)
   231                  sh """
   232                      echo "${DOCKER_CREDS_PSW}" | docker login ${env.DOCKER_REPO} -u ${DOCKER_CREDS_USR} --password-stdin
   233                  """
   234              }
   235          }
   236      }
   237      sh """
   238          rm -rf ${GO_REPO_PATH}/verrazzano
   239          mkdir -p ${GO_REPO_PATH}/verrazzano
   240          tar cf - . | (cd ${GO_REPO_PATH}/verrazzano/ ; tar xf -)
   241      """
   242  
   243      script {
   244          def props = readProperties file: '.verrazzano-development-version'
   245          VERRAZZANO_DEV_VERSION = props['verrazzano-development-version']
   246          TIMESTAMP = sh(returnStdout: true, script: "date +%Y%m%d%H%M%S").trim()
   247          SHORT_COMMIT_HASH = sh(returnStdout: true, script: "git rev-parse --short=8 HEAD").trim()
   248          DOCKER_IMAGE_TAG = "${VERRAZZANO_DEV_VERSION}-${TIMESTAMP}-${SHORT_COMMIT_HASH}"
   249          // update the description with some meaningful info
   250          setDisplayName()
   251          currentBuild.description = params.KUBERNETES_CLUSTER_VERSION + " : " + SHORT_COMMIT_HASH + " : " + env.GIT_COMMIT + " : " + params.GIT_COMMIT_TO_USE
   252      }
   253  }
   254  
   255  def postFailureProcessing() {
   256      sh """
   257          curl -k -u ${JENKINS_READ_USR}:${JENKINS_READ_PSW} -o ${WORKSPACE}/build-console-output.log ${BUILD_URL}consoleText
   258      """
   259      archiveArtifacts artifacts: '**/build-console-output.log', allowEmptyArchive: true
   260      sh """
   261          curl -k -u ${JENKINS_READ_USR}:${JENKINS_READ_PSW} -o archive.zip ${BUILD_URL}artifact/*zip*/archive.zip
   262          oci --region us-phoenix-1 os object put --force --namespace ${OCI_OS_NAMESPACE} -bn ${OCI_OS_ARTIFACT_BUCKET} --name ${env.JOB_NAME}/${env.BRANCH_NAME}/${env.BUILD_NUMBER}/archive.zip --file archive.zip
   263          rm archive.zip
   264      """
   265      script {
   266          if (env.BRANCH_NAME == "master" || env.BRANCH_NAME ==~ "release-.*" || env.BRANCH_NAME ==~ "mark/*") {
   267              slackSend ( message: "Job Failed - \"${env.JOB_NAME}\" build: ${env.BUILD_NUMBER}\n\nView the log at:\n ${env.BUILD_URL}\n\nBlue Ocean:\n${env.RUN_DISPLAY_URL}" )
   268          }
   269      }
   270  }
   271  
   272  def getEffectiveDumpOnSuccess() {
   273      def effectiveValue = params.DUMP_K8S_CLUSTER_ON_SUCCESS
   274      if (FORCE_DUMP_K8S_CLUSTER_ON_SUCCESS.equals("true") && (env.BRANCH_NAME.equals("master"))) {
   275          effectiveValue = true
   276          echo "Forcing dump on success based on global override setting"
   277      }
   278      return effectiveValue
   279  }
   280  
   281  def setDisplayName() {
   282      echo "Start setDisplayName"
   283      def causes = currentBuild.getBuildCauses()
   284      echo "causes: " + causes.toString()
   285      for (cause in causes) {
   286          def causeString = cause.toString()
   287          echo "current cause: " + causeString
   288          if (causeString.contains("UpstreamCause") && causeString.contains("Started by upstream project")) {
   289               echo "This job was caused by " + causeString
   290               if (causeString.contains("verrazzano-periodic-triggered-tests")) {
   291                   currentBuild.displayName = env.BUILD_NUMBER + " : PERIODIC"
   292               } else if (causeString.contains("verrazzano-flaky-tests")) {
   293                   currentBuild.displayName = env.BUILD_NUMBER + " : FLAKY"
   294               }
   295           }
   296      }
   297      echo "End setDisplayName"
   298  }