github.com/ouraigua/jenkins-library@v0.0.0-20231028010029-fbeaf2f3aa9b/src/com/sap/piper/DebugReport.groovy (about)

     1  package com.sap.piper
     2  
     3  import com.cloudbees.groovy.cps.NonCPS
     4  import groovy.text.SimpleTemplateEngine
     5  
     6  @Singleton
     7  class DebugReport implements Serializable {
     8      static final long serialVersionUID = 1L
     9  
    10      String projectIdentifier = null
    11      Map environment = ['environment': 'custom']
    12      String buildTool = null
    13      Map modulesMap = [:]
    14      List npmModules = []
    15      Set plugins = []
    16      Map gitRepo = [:]
    17      Map localExtensions = [:]
    18      String globalExtensionRepository = null
    19      Map globalExtensions = [:]
    20      String globalExtensionConfigurationFilePath = null
    21      String sharedConfigFilePath = null
    22      Set additionalSharedLibraries = []
    23      Map failedBuild = [:]
    24  
    25      /**
    26       * Initialize debug report information from the environment variables.
    27       *
    28       * @param env The Jenkins global 'env' variable.
    29       */
    30      void initFromEnvironment(def env) {
    31          Set buildDetails = []
    32          buildDetails.add('Jenkins Version | ' + env.JENKINS_VERSION)
    33          buildDetails.add('JAVA Version | ' + env.JAVA_VERSION)
    34          environment.put('build_details', buildDetails)
    35  
    36          if (!Boolean.valueOf(env.ON_K8S) && EnvironmentUtils.cxServerDirectoryExists()) {
    37              environment.put('environment', 'cx-server')
    38  
    39              String serverConfigContents = getServerConfigContents(
    40                  '/var/cx-server/server.cfg',
    41                  '/workspace/var/cx-server/server.cfg')
    42              String dockerImage = EnvironmentUtils.getDockerFile(serverConfigContents)
    43              environment.put('docker_image', dockerImage)
    44          }
    45          else if(Boolean.valueOf(env.ON_K8S)){
    46              DebugReport.instance.environment.put("environment", "Kubernetes")
    47          }
    48      }
    49  
    50      private static String getServerConfigContents(String... possibleFileLocations) {
    51          for (String location in possibleFileLocations) {
    52              File file = new File(location)
    53              if (file.exists())
    54                  return file.getText('UTF-8')
    55          }
    56          return ''
    57      }
    58  
    59      /**
    60       * Pulls and stores repository information from the provided Map for later inclusion in the debug report.
    61       *
    62       * @param scmCheckoutResult A Map including information about the checked out project,
    63       * i.e. as returned by the Jenkins checkout() function.
    64       */
    65      void setGitRepoInfo(Map scmCheckoutResult) {
    66          if (!scmCheckoutResult.GIT_URL)
    67              return
    68  
    69          gitRepo.put('URI', scmCheckoutResult.GIT_URL)
    70          if (scmCheckoutResult.GIT_LOCAL_BRANCH) {
    71              gitRepo.put('branch', scmCheckoutResult.GIT_LOCAL_BRANCH)
    72          } else {
    73              gitRepo.put('branch', scmCheckoutResult.GIT_BRANCH)
    74          }
    75      }
    76  
    77      /**
    78       * Stores crash information for a failed step. Multiple calls to this method overwrite already
    79       * stored information, only the information stored last will appear in the debug report. In the
    80       * current use-case where this can be called multiple times, all 'unstable' steps are listed in
    81       * the 'unstableSteps' entry of the commonPipelineEnvironment.
    82       *
    83       * @param stepName      The name of the crashed step or stage
    84       * @param err           The Throwable that was thrown
    85       * @param failedOnError Whether the failure was deemed fatal at the time of calling this method.
    86       */
    87      void storeStepFailure(String stepName, Throwable err, boolean failedOnError) {
    88          failedBuild.put('step', stepName)
    89          failedBuild.put('reason', err)
    90          failedBuild.put('stack_trace', err.getStackTrace())
    91          failedBuild.put('fatal', failedOnError ? 'true' : 'false')
    92      }
    93  
    94      Map generateReport(Script script, boolean shareConfidentialInformation) {
    95          String template = script.libraryResource 'com.sap.piper/templates/debug_report.txt'
    96  
    97          if (!projectIdentifier) {
    98              projectIdentifier = 'NOT_SET'
    99          }
   100  
   101          try {
   102              Jenkins.instance.getPluginManager().getPlugins().each {
   103                  plugins.add("${it.getShortName()} | ${it.getVersion()} | ${it.getDisplayName()}")
   104              }
   105          } catch (Throwable t) {
   106              script.echo "Failed to retrieve Jenkins plugins for debug report  (${t.getMessage()})"
   107          }
   108  
   109          Date now = new Date()
   110  
   111          Map binding = [
   112              'projectIdentifier' : projectIdentifier,
   113              'environment' : environment,
   114              'buildTool': buildTool,
   115              'modulesMap' : modulesMap,
   116              'npmModules' : npmModules,
   117              'plugins' : plugins,
   118              'gitRepo' : gitRepo,
   119              'localExtensions' : localExtensions,
   120              'globalExtensionRepository' : globalExtensionRepository,
   121              'globalExtensions' : globalExtensions,
   122              'globalExtensionConfigurationFilePath' : globalExtensionConfigurationFilePath,
   123              'sharedConfigFilePath' : sharedConfigFilePath,
   124              'additionalSharedLibraries' : additionalSharedLibraries,
   125              'failedBuild' : failedBuild,
   126              'shareConfidentialInformation' : shareConfidentialInformation,
   127              'utcTimestamp' : now.format('yyyy-MM-dd HH:mm', TimeZone.getTimeZone('UTC'))
   128          ]
   129  
   130          String fileNameTimestamp = now.format('yyyy-MM-dd-HH-mm', TimeZone.getTimeZone('UTC'))
   131          String fileNamePrefix = shareConfidentialInformation ? 'confidential' : 'redacted'
   132  
   133          Map result = [:]
   134          result.fileName = "${fileNamePrefix}_debug_log_${fileNameTimestamp}_${projectIdentifier}.txt"
   135          result.contents = fillTemplate(template, binding)
   136          return result
   137      }
   138  
   139      @NonCPS
   140      private String fillTemplate(String template, binding) {
   141          def engine = new SimpleTemplateEngine()
   142          return engine.createTemplate(template).make(binding)
   143      }
   144  }