SonarCloud scan on Docker image

  • ALM used (Azure DevOps)
  • CI system used (Azure DevOps)
  • Languages of the repository (C/C++)

Hello,

I need to do the entire SonarCloud analyze (SonarCloud scan, coverage, quality gate etc) of C/C++ code which is compiling on a specific Docker image. Such docker image is builded up inside Azure DevOps pipeline task and the tests are executed on agent directly (instead of the same docker image than build) in different pipeline stage.

I’ve investigate it a little bit and I am ready to put building the project and executing the tests to one docker image or make an additional docker image for executing tests and then export application and tests results directly to agent. As it is realized by Azure DevOps pipeline I’ve got no access to the Dockerfile in a simple way so I probably would have to prepare configuration of SonarCloud properties inside pipeline step or some script step before running the build/compiling the code pipeline step.

Until now, I’ve tried to do it as it should be done for .NET code compiled out using Docker (like here: SonarQubePublish when built and analysed in docker - SonarQube - Sonar Community (sonarsource.com)) but It seems to me that this is wrong way.

Do you have any tips or suggestions??

Hello Sophie,
Actually, how is the c++ build started?
Do you build with docker exec cmd to launch the make file?

First I am creating the image file by docker build with parameters, then I am running this image by docker run and execute build.sh script with parameters to compile c/c++ application inside

Not sure if I catch all.
The way I did with Azure DevOps container, not a c++ build, was the following, let’s see if that helps you.

  1. install the correct sonar cloud build wrapper, you have to adapt for the correct c++ wrapper
- task: PowerShell@2
  displayName: 'Download and expand build wrapper'
  enabled: true
  inputs:
    targetType: 'inline'
    script: |
      Invoke-WebRequest -Uri '$(SonarCloud_Build_Wrapper_url)' -OutFile '$(Agent.TempDirectory)\build-wrapper.zip'
      Expand-Archive -Path '$(Agent.TempDirectory)\build-wrapper.zip' -DestinationPath 'VisualBasic/buildWrapper' -Force
  1. Start your c++ container, for my case it was vb6
   - script: | 
        docker run -d --name vb6 -v $(Build.SourcesDirectory):"C:\vbapp" -w "C:\vbapp" -it $(DockerContainerName)
      failOnStderr: true
      displayName: 'Start Container'
  1. Build and analyze your code inside the container by calling the build wrapper.

  - script: >
        docker exec -e PATH="c:\vbapp\VisualBasic\buildWrapper\sonar-scanner-4.7.0.2747-windows\bin" vb6 cmd.exe /s /c set 
        docker exec -e SONAR_TOKEN=$(SONAR_TOKEN) -e PATH="c:\vbapp\VisualBasic\buildWrapper\sonar-scanner-4.7.0.2747-windows\bin" vb6 
        cmd.exe /s /c sonar-scanner.bat -D"sonar.organization=yous-sonar-organization" -D"sonar.projectKey=projectkeyname"
        -D"sonar.sources=." 
        -D"sonar.sourceEncoding=UTF-8"
        -D"sonar.host.url=https://sonarcloud.io"
        -D"sonar.scm.disabled=true"
        -D"sonar.docker.activate=false" 
        -D"sonar.coverage.exclusions = **/*" 
        -D"sonar.cpd.exclusions = **/*" 
        -D"sonar.exclusions = **/*.cfg,**/*.bat,**/*.txt,**/*.xml,**/*.yml,**/*.json,**/*.csv"

      failOnStderr: false
      continueOnError: true
      displayName: 'Start SonarCloud analysis'
  1. build it with docker exec “c++ build script”

Tips: the script to use is displayed when you create the SonarCloud project. Use the same script, for me it was : sonar-scanner.bat -D"sonar.organization=yous-sonar-organization" …

Hope, that’s will help

I’ve got my environment on Linux so the way to achieve it is a liitle bit different.

What have been done so far:

  1. Download, unzip and add build-wrapper to the PATH in Dockerfile
  2. Download, unzip and add sonar-scanner to the PATH (bin dir) in Dockerfile
  3. Execute my build script (shell script with line arguments) with prefix like: build-wrapper-linux-x86-64 --out-dir during running the Docker container or even before make command inside this build shell script.
  4. Directly after execute build script/make command inside the script I’ve tried to run sonar-scanner (followed by SC documentation) but looks like it doesn’t start any time.
  5. Instead of executing sonar-scanner just after the build/make I’ve also tried to separate execution to different pipeline step or even run the docker with sonarcource/sonar-scanner-cli image like:
- script: |
    docker run --rm -e SONAR_PROJECT_KEY=<projectName> -e SONAR_OGRANIZAION_KEY=<organization> -e SONAR_SCANNER_OPTS=<options> -e SONAR_HOST_URL=https://sonarcloud.io -e SONAR_TOKEN=<token> -v <localRepoDir> sonarsource/sonar-scanner-cli
  displayName: 'Start SonarCloud analysis'

Am I doing it right way?

I’ve got no 100% sure if the step 4 or 5 is correct in this case.

I am trying to do as it is in documentation or on the SonarCloud config page but looks like it’s a little bit complicated if entire process have to be run on Docker. Am I right?

Hi Szymon,
For info I’m a SonarCloud user and I’m as well some time in trouble with SC doc. I never worked on Linux with SC.
I guess, that in your command, you need to add in your docker path, the path of the the sc scanner.
docker … no idea if we can do that with docker run -e PATH=$PATH:$sonar-scanner path.

I already added path to the sonar-scanner bin directory into docker PATH inside Dockerfile. It has been done like below:

RUN cd <build-wrapper-directory-path>  \
    && curl -sL https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-4.7.0.2747-linux.zip  --output sonar-scanner.zip  \
    && unzip sonar-scanner.zip
ENV PATH="${PATH}:<build-wrapper-directory-path>/sonar-scanner-4.7.0.2747-linux/bin"

and it looks good because if I execute the command like:

docker exec -it <container-name> env

I can see the path to the bin directory of sonar-scanner between others.

Well, sounds good for the path.
what make by docker works for me, is the -w to set the working directory were the code repos is located

yeah, but the question is should I run the sonar-scanner on docker or it will be enough to run sonar-scanner on local with the local path to the files used by docker container?

I am building an C++ app on Docker but so far it looks like even if I am trying to run sonar-scanner on this Docker container directly or run the build script with build-wrapper “prefix” (follow documentation) on this Docker then I can’t find anything inside the build log confirms that the build-wrapper or sonar-scanner works properly.

Sonar-scanner and Build-wrapper are properly download and uznipped through Dockerfile and its paths are properly added to the PATH env var (also through Dockerfile).

For me I ran sonar-scanner in the running container.
For the c++, the sonar-scanner have to be run first and then on the same running container the cc++ build have to be started.
The step to follow should be this, I do not have example as I never did it.

  1. docker exec sonarscanner begin -/k:“…” /o:“…” /d:sonar.login=“$(EXAMPLE-TOKEN)” /d:sonar.host.url=“https://sonarcloud.io” /d:sonar… /d:sonar…
  2. docker exec build c++ project
  3. docker exec sonarscanner end /d:sonar.login=“$(EXAMPLE-TOKEN)”

something like this…