master
sh 215 lines 6.75 KB
Raw
1 #!/usr/bin/env bash
2 # SPDX-License-Identifier: GPL-3.0-or-later
3 # shellcheck disable=SC1091,SC2230,SC2086
4 #
5 # Coverity scan script
6 #
7 # To run manually, save configuration to .coverity-scan.conf like this:
8 #
9 # the repository to report to coverity - devs can set here their own fork
10 # REPOSITORY="netdata/netdata"
11 #
12 # the email of the developer, as given to coverity
13 # COVERITY_SCAN_SUBMIT_MAIL="you@example.com"
14 #
15 # the token given by coverity to the developer
16 # COVERITY_SCAN_TOKEN="TOKEN taken from Coverity site"
17 #
18 # the absolute path of the cov-build - optional
19 # COVERITY_BUILD_PATH="/opt/cov-analysis-linux64-2021.12/bin/cov-build"
20 #
21 # when set, the script will print on screen the curl command that submits the build to coverity
22 # this includes the token, so the default is not to print it.
23 # COVERITY_SUBMIT_DEBUG=1
24 #
25 # All these variables can also be exported before running this script.
26 #
27 # If the first parameter of this script is "install",
28 # coverity build tools will be downloaded and installed in /opt/coverity
29
30 set -e
31
32 if [ "$(uname -s)" != "Linux" ] || [ "$(uname -m)" != "x86_64" ]; then
33 echo "This script can only be used on a 64-bit x86 Linux system."
34 exit 1
35 fi
36
37 INSTALL_DIR="/opt"
38
39 SCRIPT_SOURCE="$(
40 self=${0}
41 while [ -L "${self}" ]
42 do
43 cd "${self%/*}" || exit 1
44 self=$(readlink "${self}")
45 done
46 cd "${self%/*}" || exit 1
47 echo "$(pwd -P)/${self##*/}"
48 )"
49 REPO_ROOT="$(dirname "${SCRIPT_SOURCE}")/../.."
50
51 . "${REPO_ROOT}/packaging/installer/functions.sh"
52
53 JOBS=$(find_processors)
54 [ -z "${JOBS}" ] && JOBS=1
55
56 if command -v ninja 2>&1; then
57 ninja="$(command -v ninja)"
58 fi
59
60 CMAKE_OPTS="${ninja:+-G Ninja}"
61 BUILD_OPTS="VERBOSE=1"
62 [ -n "${ninja}" ] && BUILD_OPTS="-v"
63 NETDATA_BUILD_DIR="${NETDATA_BUILD_DIR:-./build/}"
64
65 if [ -f ".coverity-scan.conf" ]; then
66 source ".coverity-scan.conf"
67 fi
68
69 repo="${REPOSITORY}"
70 if [ -z "${repo}" ]; then
71 fatal "export variable REPOSITORY or set it in .coverity-scan.conf"
72 fi
73 repo="${repo//\//%2F}"
74
75 email="${COVERITY_SCAN_SUBMIT_MAIL}"
76 if [ -z "${email}" ]; then
77 fatal "export variable COVERITY_SCAN_SUBMIT_MAIL or set it in .coverity-scan.conf"
78 fi
79
80 token="${COVERITY_SCAN_TOKEN}"
81 if [ -z "${token}" ]; then
82 fatal "export variable COVERITY_SCAN_TOKEN or set it in .coverity-scan.conf"
83 fi
84
85 if ! command -v curl > /dev/null 2>&1; then
86 fatal "CURL is required for coverity scan to work"
87 fi
88
89 # only print the output of a command
90 # when debugging is enabled
91 # used to hide the token when debugging is not enabled
92 debugrun() {
93 if [ "${COVERITY_SUBMIT_DEBUG}" = "1" ]; then
94 run "${@}"
95 return $?
96 else
97 "${@}"
98 return $?
99 fi
100 }
101
102 scanit() {
103 progress "Scanning using coverity"
104 COVERITY_PATH=$(find "${INSTALL_DIR}" -maxdepth 1 -name 'cov*linux*')
105 export PATH=${PATH}:${COVERITY_PATH}/bin/
106 covbuild="${COVERITY_BUILD_PATH}"
107 [ -z "${covbuild}" ] && covbuild="$(which cov-build 2> /dev/null || command -v cov-build 2> /dev/null)"
108
109 if [ -z "${covbuild}" ]; then
110 fatal "Cannot find 'cov-build' binary in \$PATH. Export variable COVERITY_BUILD_PATH or set it in .coverity-scan.conf"
111 elif [ ! -x "${covbuild}" ]; then
112 fatal "The command '${covbuild}' is not executable. Export variable COVERITY_BUILD_PATH or set it in .coverity-scan.conf"
113 fi
114
115 cd "${REPO_ROOT}" || exit 1
116
117 version="$(grep "^#define PACKAGE_VERSION" config.h | cut -d '"' -f 2)"
118 progress "Working on netdata version: ${version}"
119
120 progress "Cleaning up old builds..."
121 rm -rf "${NETDATA_BUILD_DIR}"
122
123 [ -d "cov-int" ] && rm -rf "cov-int"
124
125 [ -f netdata-coverity-analysis.tgz ] && run rm netdata-coverity-analysis.tgz
126
127 progress "Configuring netdata source..."
128 USE_SYSTEM_PROTOBUF=1
129 ENABLE_GO=0
130 prepare_cmake_options
131
132 # shellcheck disable=SC2086
133 case "${NETDATA_CMAKE_INSTALL_PREFIX_OPTION:+I}${NETDATA_WINDOWS_PATH_PREFIX_OPTION:+W}" in
134 "IW") run cmake ${NETDATA_CMAKE_OPTIONS} "${NETDATA_CMAKE_INSTALL_PREFIX_OPTION}" "${NETDATA_WINDOWS_PATH_PREFIX_OPTION}" ;;
135 "I") run cmake ${NETDATA_CMAKE_OPTIONS} "${NETDATA_CMAKE_INSTALL_PREFIX_OPTION}" ;;
136 "W") run cmake ${NETDATA_CMAKE_OPTIONS} "${NETDATA_WINDOWS_PATH_PREFIX_OPTION}" ;;
137 *) run cmake ${NETDATA_CMAKE_OPTIONS} ;;
138 esac
139
140 progress "Analyzing netdata..."
141 run "${covbuild}" --dir cov-int cmake --build "${NETDATA_BUILD_DIR}" --parallel ${JOBS} -- ${BUILD_OPTS}
142
143 echo >&2 "Compressing analysis..."
144 run tar czvf netdata-coverity-analysis.tgz cov-int
145
146 echo >&2 "Sending analysis to coverity for netdata version ${version} ..."
147 COVERITY_SUBMIT_RESULT=$(debugrun curl --progress-bar \
148 --form token="${token}" \
149 --form email="${email}" \
150 --form file=@netdata-coverity-analysis.tgz \
151 --form version="${version}" \
152 --form description="netdata, monitor everything, in real-time." \
153 https://scan.coverity.com/builds?project="${repo}")
154
155 echo "${COVERITY_SUBMIT_RESULT}" | grep -q -e 'Build successfully submitted' || echo >&2 "scan results were not pushed to coverity. Message was: ${COVERITY_SUBMIT_RESULT}"
156
157 progress "Coverity scan completed"
158 }
159
160 installit() {
161 TMP_DIR="$(mktemp -d /tmp/netdata-coverity-scan-XXXXX)"
162 progress "Downloading coverity in ${TMP_DIR}..."
163 (cd "${TMP_DIR}" && debugrun curl --remote-name --remote-header-name --show-error --location --data "token=${token}&project=${repo}" https://scan.coverity.com/download/linux64)
164
165 COVERITY_ARCHIVE="$(find "${TMP_DIR}" -maxdepth 1 -mindepth 1 -name 'cov-analysis-linux64-*.tar.gz')"
166
167 if [ -n "${COVERITY_ARCHIVE}" ] && [ -f "${COVERITY_ARCHIVE}" ]; then
168 progress "Installing coverity..."
169 run sudo tar -z -x -f "${COVERITY_ARCHIVE}" -C "${INSTALL_DIR}"
170 rm -f "${COVERITY_ARCHIVE}"
171 COVERITY_PATH=$(find "${INSTALL_DIR}" -maxdepth 1 -name 'cov*linux*')
172 export PATH="${PATH}:${COVERITY_PATH}/bin/"
173 elif find "${TMP_DIR}" -name "*.tar.gz" > /dev/null 2>&1; then
174 ls "${TMP_DIR}"/*.tar.gz
175 fatal "Downloaded coverity tool tarball does not appear to be the file-name we were expecting, exiting."
176 else
177 fatal "Failed to download coverity tool tarball!"
178 fi
179
180 # Validate the installation
181 covbuild="$(which cov-build 2> /dev/null || command -v cov-build 2> /dev/null)"
182 if [ -z "$covbuild" ]; then
183 fatal "Failed to install coverity."
184 fi
185
186 progress "Coverity scan tools are installed."
187
188 # Clean temp directory
189 [ -n "${TMP_DIR}" ] && rm -rf "${TMP_DIR}"
190 return 0
191 }
192
193 FOUND_OPTS="NO"
194 while [ -n "${1}" ]; do
195 if [ "${1}" = "--with-install" ]; then
196 progress "Running coverity install"
197 installit
198 shift 1
199 elif [ -n "${1}" ]; then
200 # Clear the default arguments, once you bump into the first argument
201 if [ "${FOUND_OPTS}" = "NO" ]; then
202 OTHER_OPTIONS="${1}"
203 FOUND_OPTS="YES"
204 else
205 OTHER_OPTIONS+=" ${1}"
206 fi
207
208 shift 1
209 else
210 break
211 fi
212 done
213
214 echo "Running coverity scan with extra options ${OTHER_OPTIONS}"
215 scanit "${OTHER_OPTIONS}"