coverity-scan.sh 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. #!/usr/bin/env bash
  2. #
  3. # Coverity scan script
  4. #
  5. # Copyright: SPDX-License-Identifier: GPL-3.0-or-later
  6. #
  7. # Author : Costa Tsaousis (costa@netdata.cloud)
  8. # Author : Pawel Krupa (paulfantom)
  9. # Author : Pavlos Emm. Katsoulakis (paul@netdata.cloud)
  10. # shellcheck disable=SC1091,SC2230,SC2086
  11. # To run manually, save configuration to .coverity-scan.conf like this:
  12. #
  13. # the repository to report to coverity - devs can set here their own fork
  14. # REPOSITORY="netdata/netdata"
  15. #
  16. # the email of the developer, as given to coverity
  17. # COVERITY_SCAN_SUBMIT_MAIL="you@example.com"
  18. #
  19. # the token given by coverity to the developer
  20. # COVERITY_SCAN_TOKEN="TOKEN taken from Coverity site"
  21. #
  22. # the absolute path of the cov-build - optional
  23. # COVERITY_BUILD_PATH="/opt/cov-analysis-linux64-2021.12/bin/cov-build"
  24. #
  25. # when set, the script will print on screen the curl command that submits the build to coverity
  26. # this includes the token, so the default is not to print it.
  27. # COVERITY_SUBMIT_DEBUG=1
  28. #
  29. # Override the standard coverity build version we know is supported
  30. # COVERITY_BUILD_VERSION="cov-analysis-linux64-2019.03"
  31. #
  32. # All these variables can also be exported before running this script.
  33. #
  34. # If the first parameter of this script is "install",
  35. # coverity build tools will be downloaded and installed in /opt/coverity
  36. set -e
  37. INSTALL_DIR="/opt"
  38. # the version of coverity to use
  39. COVERITY_BUILD_VERSION="${COVERITY_BUILD_VERSION:-cov-analysis-linux64-2021.12}"
  40. # TODO: For some reasons this does not fully load on Debian 10 (Haven't checked if it happens on other distros yet), it breaks
  41. source packaging/installer/functions.sh || echo "Failed to fully load the functions library"
  42. cpus=$(find_processors)
  43. [ -z "${cpus}" ] && cpus=1
  44. if [ -f ".coverity-scan.conf" ]; then
  45. source ".coverity-scan.conf"
  46. fi
  47. repo="${REPOSITORY}"
  48. if [ -z "${repo}" ]; then
  49. fatal "export variable REPOSITORY or set it in .coverity-scan.conf"
  50. fi
  51. repo="${repo//\//%2F}"
  52. email="${COVERITY_SCAN_SUBMIT_MAIL}"
  53. if [ -z "${email}" ]; then
  54. fatal "export variable COVERITY_SCAN_SUBMIT_MAIL or set it in .coverity-scan.conf"
  55. fi
  56. token="${COVERITY_SCAN_TOKEN}"
  57. if [ -z "${token}" ]; then
  58. fatal "export variable COVERITY_SCAN_TOKEN or set it in .coverity-scan.conf"
  59. fi
  60. if ! command -v curl > /dev/null 2>&1; then
  61. fatal "CURL is required for coverity scan to work"
  62. fi
  63. # only print the output of a command
  64. # when debugging is enabled
  65. # used to hide the token when debugging is not enabled
  66. debugrun() {
  67. if [ "${COVERITY_SUBMIT_DEBUG}" = "1" ]; then
  68. run "${@}"
  69. return $?
  70. else
  71. "${@}"
  72. return $?
  73. fi
  74. }
  75. scanit() {
  76. progress "Scanning using coverity"
  77. COVERITY_PATH=$(find "${INSTALL_DIR}" -maxdepth 1 -name 'cov*linux*')
  78. export PATH=${PATH}:${COVERITY_PATH}/bin/
  79. covbuild="${COVERITY_BUILD_PATH}"
  80. [ -z "${covbuild}" ] && covbuild="$(which cov-build 2> /dev/null || command -v cov-build 2> /dev/null)"
  81. if [ -z "${covbuild}" ]; then
  82. fatal "Cannot find 'cov-build' binary in \$PATH. Export variable COVERITY_BUILD_PATH or set it in .coverity-scan.conf"
  83. elif [ ! -x "${covbuild}" ]; then
  84. fatal "The command '${covbuild}' is not executable. Export variable COVERITY_BUILD_PATH or set it in .coverity-scan.conf"
  85. fi
  86. version="$(grep "^#define PACKAGE_VERSION" config.h | cut -d '"' -f 2)"
  87. progress "Working on netdata version: ${version}"
  88. progress "Cleaning up old builds..."
  89. run make clean || echo >&2 "Nothing to clean"
  90. [ -d "cov-int" ] && rm -rf "cov-int"
  91. [ -f netdata-coverity-analysis.tgz ] && run rm netdata-coverity-analysis.tgz
  92. progress "Configuring netdata source..."
  93. run autoreconf -ivf
  94. run ./configure ${OTHER_OPTIONS}
  95. progress "Analyzing netdata..."
  96. run "${covbuild}" --dir cov-int make -j${cpus}
  97. echo >&2 "Compressing analysis..."
  98. run tar czvf netdata-coverity-analysis.tgz cov-int
  99. echo >&2 "Sending analysis to coverity for netdata version ${version} ..."
  100. COVERITY_SUBMIT_RESULT=$(debugrun curl --progress-bar \
  101. --form token="${token}" \
  102. --form email="${email}" \
  103. --form file=@netdata-coverity-analysis.tgz \
  104. --form version="${version}" \
  105. --form description="netdata, monitor everything, in real-time." \
  106. https://scan.coverity.com/builds?project="${repo}")
  107. echo "${COVERITY_SUBMIT_RESULT}" | grep -q -e 'Build successfully submitted' || echo >&2 "scan results were not pushed to coverity. Message was: ${COVERITY_SUBMIT_RESULT}"
  108. progress "Coverity scan completed"
  109. }
  110. installit() {
  111. ORIGINAL_DIR="${PWD}"
  112. TMP_DIR="$(mktemp -d /tmp/netdata-coverity-scan-XXXXX)"
  113. progress "Downloading coverity in ${TMP_DIR}..."
  114. cd "${TMP_DIR}"
  115. debugrun curl --remote-name --remote-header-name --show-error --location --data "token=${token}&project=${repo}" https://scan.coverity.com/download/linux64
  116. if [ -f "${COVERITY_BUILD_VERSION}.tar.gz" ]; then
  117. progress "Installing coverity..."
  118. cd "${INSTALL_DIR}"
  119. run sudo tar -z -x -f "${TMP_DIR}/${COVERITY_BUILD_VERSION}.tar.gz" || exit 1
  120. rm "${TMP_DIR}/${COVERITY_BUILD_VERSION}.tar.gz"
  121. COVERITY_PATH=$(find "${INSTALL_DIR}" -maxdepth 1 -name 'cov*linux*')
  122. export PATH=${PATH}:${COVERITY_PATH}/bin/
  123. elif find . -name "*.tar.gz" > /dev/null 2>&1; then
  124. fatal "Downloaded coverity tool tarball does not appear to be the version we were expecting, exiting."
  125. else
  126. fatal "Failed to download coverity tool tarball!"
  127. fi
  128. # Validate the installation
  129. covbuild="$(which cov-build 2> /dev/null || command -v cov-build 2> /dev/null)"
  130. if [ -z "$covbuild" ]; then
  131. fatal "Failed to install coverity."
  132. fi
  133. progress "Coverity scan tools are installed."
  134. cd "$ORIGINAL_DIR"
  135. # Clean temp directory
  136. [ -n "${TMP_DIR}" ] && rm -rf "${TMP_DIR}"
  137. return 0
  138. }
  139. OTHER_OPTIONS="--disable-lto"
  140. OTHER_OPTIONS+=" --with-zlib"
  141. OTHER_OPTIONS+=" --with-math"
  142. OTHER_OPTIONS+=" --enable-https"
  143. OTHER_OPTIONS+=" --enable-jsonc"
  144. OTHER_OPTIONS+=" --enable-plugin-nfacct"
  145. OTHER_OPTIONS+=" --enable-plugin-freeipmi"
  146. OTHER_OPTIONS+=" --enable-plugin-cups"
  147. OTHER_OPTIONS+=" --enable-exporting-prometheus-remote-write"
  148. # TODO: enable these plugins too
  149. #OTHER_OPTIONS+=" --enable-plugin-xenstat"
  150. #OTHER_OPTIONS+=" --enable-exporting-kinesis"
  151. #OTHER_OPTIONS+=" --enable-exporting-mongodb"
  152. FOUND_OPTS="NO"
  153. while [ -n "${1}" ]; do
  154. if [ "${1}" = "--with-install" ]; then
  155. progress "Running coverity install"
  156. installit
  157. shift 1
  158. elif [ -n "${1}" ]; then
  159. # Clear the default arguments, once you bump into the first argument
  160. if [ "${FOUND_OPTS}" = "NO" ]; then
  161. OTHER_OPTIONS="${1}"
  162. FOUND_OPTS="YES"
  163. else
  164. OTHER_OPTIONS+=" ${1}"
  165. fi
  166. shift 1
  167. else
  168. break
  169. fi
  170. done
  171. echo "Running coverity scan with extra options ${OTHER_OPTIONS}"
  172. scanit "${OTHER_OPTIONS}"