diff mbox series

[2/3] scripts/run-coverity-scan: Script to run Coverity Scan build

Message ID 1497369290-20401-3-git-send-email-peter.maydell@linaro.org
State Superseded
Headers show
Series Automate coverity scan uploads via Travis | expand

Commit Message

Peter Maydell June 13, 2017, 3:54 p.m. UTC
Add a new script to automate the process of running the Coverity
Scan build tools and uploading the resulting tarball to the
website. This is primarily intended to be driven from Travis,
but it can be run locally (if you are a maintainer of the
QEMU project on the Coverity Scan website and have the secret
upload token).

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

---
 scripts/run-coverity-scan | 170 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 170 insertions(+)
 create mode 100755 scripts/run-coverity-scan

-- 
2.7.4

Comments

Alex Bennée June 14, 2017, 3:01 p.m. UTC | #1
Peter Maydell <peter.maydell@linaro.org> writes:

> Add a new script to automate the process of running the Coverity

> Scan build tools and uploading the resulting tarball to the

> website. This is primarily intended to be driven from Travis,

> but it can be run locally (if you are a maintainer of the

> QEMU project on the Coverity Scan website and have the secret

> upload token).

>

> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>


Reviewed-by: Alex Bennée <alex.bennee@linaro.org>


> ---

>  scripts/run-coverity-scan | 170 ++++++++++++++++++++++++++++++++++++++++++++++

>  1 file changed, 170 insertions(+)

>  create mode 100755 scripts/run-coverity-scan

>

> diff --git a/scripts/run-coverity-scan b/scripts/run-coverity-scan

> new file mode 100755

> index 0000000..e6d5fc5

> --- /dev/null

> +++ b/scripts/run-coverity-scan

> @@ -0,0 +1,170 @@

> +#!/bin/sh -e

> +

> +# Upload a created tarball to Coverity Scan, as per

> +# https://scan.coverity.com/projects/qemu/builds/new

> +

> +# This work is licensed under the terms of the GNU GPL version 2,

> +# or (at your option) any later version.

> +# See the COPYING file in the top-level directory.

> +#

> +# Copyright (c) 2017 Linaro Limited

> +# Written by Peter Maydell

> +

> +# Note that this script will automatically download and

> +# run the (closed-source) coverity build tools, so don't

> +# use it if you don't trust them!

> +

> +# This script assumes that you're running it from a QEMU source

> +# tree, and that tree is a fresh clean one, because we do an in-tree

> +# build. (This is necessary so that the filenames that the Coverity

> +# Scan server sees are relative paths that match up with the component

> +# regular expressions it uses; an out-of-tree build won't work for this.)

> +# The host machine should have as many of QEMU's dependencies

> +# installed as possible, for maximum coverity coverage.

> +

> +# You need to pass the following environment variables to the script:

> +#  COVERITY_TOKEN -- this is the secret 8 digit hex string which lets

> +#                    you upload to Coverity Scan. If you're a maintainer

> +#                    in Coverity then the web UI will tell you this.

> +#  COVERITY_EMAIL -- the email address to use for uploads

> +

> +# and optionally

> +#  COVERITY_DRYRUN -- set to not actually do the upload

> +#  COVERITY_BUILD_CMD -- make command (defaults to 'make -j8')

> +#  COVERITY_TOOL_BASE -- set to directory to put coverity tools

> +#                        (defaults to /tmp/coverity-tools)

> +

> +# The primary purpose of this script is to be run as part of

> +# a Travis build, but it is possible to run it manually locally.

> +

> +if [ -z "$COVERITY_TOKEN" ]; then

> +    echo "COVERITY_TOKEN environment variable not set"

> +    exit 1

> +fi

> +

> +if [ -z "$COVERITY_EMAIL" ]; then

> +    echo "COVERITY_EMAIL environment variable not set"

> +    exit 1

> +fi

> +

> +if [ -z "$COVERITY_BUILD_CMD" ]; then

> +    echo "COVERITY_BUILD_CMD: using default 'make -j8'"

> +    COVERITY_BUILD_CMD="make -j8"

> +fi

> +

> +if [ -z "$COVERITY_TOOL_BASE" ]; then

> +    echo "COVERITY_TOOL_BASE: using default /tmp/coverity-tools"

> +    COVERITY_TOOL_BASE=/tmp/coverity-tools

> +fi

> +

> +PROJTOKEN="$COVERITY_TOKEN"

> +PROJNAME=QEMU

> +TARBALL=cov-int.tar.xz

> +SRCDIR="$(pwd)"

> +

> +echo "Checking this is a QEMU source tree..."

> +if ! [ -e VERSION ]; then

> +    echo "Not in a QEMU source tree?"

> +    exit 1

> +fi

> +

> +echo "Checking upload permissions..."

> +

> +if ! up_perm="$(wget https://scan.coverity.com/api/upload_permitted --post-data "token=$PROJTOKEN&project=$PROJNAME" -q -O -)"; then

> +    echo "Coverity Scan API access denied: bad token?"

> +    exit 1

> +fi

> +

> +# Really up_perm is a JSON response with either

> +# {upload_permitted:true} or {next_upload_permitted_at:<date>}

> +# We do some hacky string parsing instead of properly parsing it.

> +case "$up_perm" in

> +    *upload_permitted*true*)

> +        echo "Coverity Scan: upload permitted"

> +        ;;

> +    *next_upload_permitted_at*)

> +        if [ -z "$COVERITY_DRYRUN" ]; then

> +            echo "Coverity Scan: upload quota reached; stopping here"

> +            # Exit success as this isn't a build error.

> +            exit 0

> +        else

> +            echo "Coverity Scan: upload quota reached, continuing dry run"

> +        fi

> +        ;;

> +    *)

> +        echo "Coverity Scan upload check: unexpected result $up_perm"

> +        exit 1

> +        ;;

> +esac

> +

> +mkdir -p "$COVERITY_TOOL_BASE"

> +cd "$COVERITY_TOOL_BASE"

> +

> +echo "Checking for new version of coverity build tools..."

> +wget https://scan.coverity.com/download/linux64 --post-data "token=$PROJTOKEN&project=$PROJNAME&md5=1" -O coverity_tool.md5.new

> +

> +if ! cmp -s coverity_tool.md5 coverity_tool.md5.new; then

> +    # out of date md5 or no md5: download new build tool

> +    # blow away the old build tool

> +    echo "Downloading coverity build tools..."

> +    rm -rf coverity_tool coverity_tool.tgz

> +    wget https://scan.coverity.com/download/linux64 --post-data "token=$PROJTOKEN&project=$PROJNAME" -O coverity_tool.tgz

> +    if ! (cat coverity_tool.md5.new; echo "  coverity_tool.tgz") | md5sum -c --status; then

> +        echo "Downloaded tarball didn't match md5sum!"

> +        exit 1

> +    fi

> +    # extract the new one, keeping it corralled in a 'coverity_tool' directory

> +    echo "Unpacking coverity build tools..."

> +    mkdir -p coverity_tool

> +    cd coverity_tool

> +    tar xf ../coverity_tool.tgz

> +    cd ..

> +    mv coverity_tool.md5.new coverity_tool.md5

> +fi

> +

> +rm -f coverity_tool.md5.new

> +

> +TOOLBIN="$(echo $(pwd)/coverity_tool/cov-analysis-*/bin)"

> +

> +if ! test -x "$TOOLBIN/cov-build"; then

> +    echo "Couldn't find cov-build in the coverity build-tool directory??"

> +    exit 1

> +fi

> +

> +export PATH="$TOOLBIN:$PATH"

> +

> +cd "$SRCDIR"

> +

> +echo "Doing make distclean..."

> +make distclean

> +

> +echo "Configuring..."

> +./configure --audio-drv-list=oss,alsa,sdl,pa --disable-werror

> +

> +echo "Making libqemustub.a..."

> +make libqemustub.a

> +

> +echo "Running cov-build..."

> +rm -rf cov-int

> +mkdir cov-int

> +cov-build --dir cov-int $COVERITY_BUILD_CMD

> +

> +echo "Creating results tarball..."

> +tar cvf - cov-int | xz > "$TARBALL"

> +

> +echo "Uploading results tarball..."

> +

> +VERSION="$(git describe --always HEAD)"

> +DESCRIPTION="$(git rev-parse HEAD)"

> +

> +if ! [ -z "$COVERITY_DRYRUN" ]; then

> +    echo "Dry run only, not uploading $TARBALL"

> +    exit 0

> +fi

> +

> +curl --form token="$PROJTOKEN" --form email="$COVERITY_EMAIL" \

> +     --form file=@"$TARBALL" --form version="$VERSION" \

> +     --form description="$DESCRIPTION" \

> +     https://scan.coverity.com/builds?project="$PROJNAME"

> +

> +echo "Done."



--
Alex Bennée
Eric Blake June 29, 2017, 4:12 p.m. UTC | #2
On 06/13/2017 10:54 AM, Peter Maydell wrote:
> Add a new script to automate the process of running the Coverity

> Scan build tools and uploading the resulting tarball to the

> website. This is primarily intended to be driven from Travis,

> but it can be run locally (if you are a maintainer of the

> QEMU project on the Coverity Scan website and have the secret

> upload token).

> 

> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

> ---

>  scripts/run-coverity-scan | 170 ++++++++++++++++++++++++++++++++++++++++++++++

>  1 file changed, 170 insertions(+)

>  create mode 100755 scripts/run-coverity-scan

> 

> diff --git a/scripts/run-coverity-scan b/scripts/run-coverity-scan

> new file mode 100755

> index 0000000..e6d5fc5

> --- /dev/null

> +++ b/scripts/run-coverity-scan

> @@ -0,0 +1,170 @@

> +#!/bin/sh -e


I'm not a fan of 'set -e'; it seldom does what you think it should do,
especially when shell functions are involved.  It's better to be
explicit about error handling than it is to rely on a crutch that has
well-defined but non-intuitive behavior.

> +mkdir -p "$COVERITY_TOOL_BASE"

> +cd "$COVERITY_TOOL_BASE"

> +


Of course, calls like these are where you have to either be explicit or
rely on the 'set -e' crutch.

Thankfully, I didn't see any bashisms, so you appeared to have stuck to
portable /bin/sh code.

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org
Peter Maydell June 29, 2017, 4:15 p.m. UTC | #3
On 29 June 2017 at 17:12, Eric Blake <eblake@redhat.com> wrote:
> Thankfully, I didn't see any bashisms, so you appeared to have stuck to

> portable /bin/sh code.


My /bin/sh is dash, which catches at least some of the more
obvious bashisms.

thanks
-- PMM
diff mbox series

Patch

diff --git a/scripts/run-coverity-scan b/scripts/run-coverity-scan
new file mode 100755
index 0000000..e6d5fc5
--- /dev/null
+++ b/scripts/run-coverity-scan
@@ -0,0 +1,170 @@ 
+#!/bin/sh -e
+
+# Upload a created tarball to Coverity Scan, as per
+# https://scan.coverity.com/projects/qemu/builds/new
+
+# This work is licensed under the terms of the GNU GPL version 2,
+# or (at your option) any later version.
+# See the COPYING file in the top-level directory.
+#
+# Copyright (c) 2017 Linaro Limited
+# Written by Peter Maydell
+
+# Note that this script will automatically download and
+# run the (closed-source) coverity build tools, so don't
+# use it if you don't trust them!
+
+# This script assumes that you're running it from a QEMU source
+# tree, and that tree is a fresh clean one, because we do an in-tree
+# build. (This is necessary so that the filenames that the Coverity
+# Scan server sees are relative paths that match up with the component
+# regular expressions it uses; an out-of-tree build won't work for this.)
+# The host machine should have as many of QEMU's dependencies
+# installed as possible, for maximum coverity coverage.
+
+# You need to pass the following environment variables to the script:
+#  COVERITY_TOKEN -- this is the secret 8 digit hex string which lets
+#                    you upload to Coverity Scan. If you're a maintainer
+#                    in Coverity then the web UI will tell you this.
+#  COVERITY_EMAIL -- the email address to use for uploads
+
+# and optionally
+#  COVERITY_DRYRUN -- set to not actually do the upload
+#  COVERITY_BUILD_CMD -- make command (defaults to 'make -j8')
+#  COVERITY_TOOL_BASE -- set to directory to put coverity tools
+#                        (defaults to /tmp/coverity-tools)
+
+# The primary purpose of this script is to be run as part of
+# a Travis build, but it is possible to run it manually locally.
+
+if [ -z "$COVERITY_TOKEN" ]; then
+    echo "COVERITY_TOKEN environment variable not set"
+    exit 1
+fi
+
+if [ -z "$COVERITY_EMAIL" ]; then
+    echo "COVERITY_EMAIL environment variable not set"
+    exit 1
+fi
+
+if [ -z "$COVERITY_BUILD_CMD" ]; then
+    echo "COVERITY_BUILD_CMD: using default 'make -j8'"
+    COVERITY_BUILD_CMD="make -j8"
+fi
+
+if [ -z "$COVERITY_TOOL_BASE" ]; then
+    echo "COVERITY_TOOL_BASE: using default /tmp/coverity-tools"
+    COVERITY_TOOL_BASE=/tmp/coverity-tools
+fi
+
+PROJTOKEN="$COVERITY_TOKEN"
+PROJNAME=QEMU
+TARBALL=cov-int.tar.xz
+SRCDIR="$(pwd)"
+
+echo "Checking this is a QEMU source tree..."
+if ! [ -e VERSION ]; then
+    echo "Not in a QEMU source tree?"
+    exit 1
+fi
+
+echo "Checking upload permissions..."
+
+if ! up_perm="$(wget https://scan.coverity.com/api/upload_permitted --post-data "token=$PROJTOKEN&project=$PROJNAME" -q -O -)"; then
+    echo "Coverity Scan API access denied: bad token?"
+    exit 1
+fi
+
+# Really up_perm is a JSON response with either
+# {upload_permitted:true} or {next_upload_permitted_at:<date>}
+# We do some hacky string parsing instead of properly parsing it.
+case "$up_perm" in
+    *upload_permitted*true*)
+        echo "Coverity Scan: upload permitted"
+        ;;
+    *next_upload_permitted_at*)
+        if [ -z "$COVERITY_DRYRUN" ]; then
+            echo "Coverity Scan: upload quota reached; stopping here"
+            # Exit success as this isn't a build error.
+            exit 0
+        else
+            echo "Coverity Scan: upload quota reached, continuing dry run"
+        fi
+        ;;
+    *)
+        echo "Coverity Scan upload check: unexpected result $up_perm"
+        exit 1
+        ;;
+esac
+
+mkdir -p "$COVERITY_TOOL_BASE"
+cd "$COVERITY_TOOL_BASE"
+
+echo "Checking for new version of coverity build tools..."
+wget https://scan.coverity.com/download/linux64 --post-data "token=$PROJTOKEN&project=$PROJNAME&md5=1" -O coverity_tool.md5.new
+
+if ! cmp -s coverity_tool.md5 coverity_tool.md5.new; then
+    # out of date md5 or no md5: download new build tool
+    # blow away the old build tool
+    echo "Downloading coverity build tools..."
+    rm -rf coverity_tool coverity_tool.tgz
+    wget https://scan.coverity.com/download/linux64 --post-data "token=$PROJTOKEN&project=$PROJNAME" -O coverity_tool.tgz
+    if ! (cat coverity_tool.md5.new; echo "  coverity_tool.tgz") | md5sum -c --status; then
+        echo "Downloaded tarball didn't match md5sum!"
+        exit 1
+    fi
+    # extract the new one, keeping it corralled in a 'coverity_tool' directory
+    echo "Unpacking coverity build tools..."
+    mkdir -p coverity_tool
+    cd coverity_tool
+    tar xf ../coverity_tool.tgz
+    cd ..
+    mv coverity_tool.md5.new coverity_tool.md5
+fi
+
+rm -f coverity_tool.md5.new
+
+TOOLBIN="$(echo $(pwd)/coverity_tool/cov-analysis-*/bin)"
+
+if ! test -x "$TOOLBIN/cov-build"; then
+    echo "Couldn't find cov-build in the coverity build-tool directory??"
+    exit 1
+fi
+
+export PATH="$TOOLBIN:$PATH"
+
+cd "$SRCDIR"
+
+echo "Doing make distclean..."
+make distclean
+
+echo "Configuring..."
+./configure --audio-drv-list=oss,alsa,sdl,pa --disable-werror
+
+echo "Making libqemustub.a..."
+make libqemustub.a
+
+echo "Running cov-build..."
+rm -rf cov-int
+mkdir cov-int
+cov-build --dir cov-int $COVERITY_BUILD_CMD
+
+echo "Creating results tarball..."
+tar cvf - cov-int | xz > "$TARBALL"
+
+echo "Uploading results tarball..."
+
+VERSION="$(git describe --always HEAD)"
+DESCRIPTION="$(git rev-parse HEAD)"
+
+if ! [ -z "$COVERITY_DRYRUN" ]; then
+    echo "Dry run only, not uploading $TARBALL"
+    exit 0
+fi
+
+curl --form token="$PROJTOKEN" --form email="$COVERITY_EMAIL" \
+     --form file=@"$TARBALL" --form version="$VERSION" \
+     --form description="$DESCRIPTION" \
+     https://scan.coverity.com/builds?project="$PROJNAME"
+
+echo "Done."