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…

Hi,

Finally I was able to run sonar scanner on docker through this way:

  1. download and unzip build-wrapper by dockerfile
  2. download and unzip sonar-scanner by dockerfile
  3. add proper paths to build-wrapper and sonar-scanner bin directory in PATH by dockerfile
  4. run the docker container by the command:
docker run \
      --name <name> \
      --rm \
      --volume <imagePath> \
      --env SONAR_SCANNER_OPTS="-Xmx1024m -Xms512m" \
      --env SONAR_RUNNER_OPTS="-Xmx1024m -XX:MaxPermSize=512m" \
      --env JAVA_OPTS="-Xmx1024m -Xms512m" \
      --env JAVA_EXEC="-Xmx1024m -XX:MaxPermSize=512m -XX:ReservedCodeCacheSize=128m" \
      <imageName> /bin/bash -c \
      "build-wrapper-linux-x86-64 --out-dir <containerHomeDirectory>/build-wrapper/build-wrapper-linux-x86 \
       <pathToBuildScript>
      && sonar-scanner -X"

Now, I’ve got another error: Java heap space at the end of sonar scan:

2023-09-27T12:10:59.7232822Z 12:10:59.722 INFO: Hit the cache for 0 out of 0
2023-09-27T12:10:59.7236300Z 12:10:59.723 INFO: Miss the cache for 0 out of 0
2023-09-27T12:10:59.7401480Z 12:10:59.739 DEBUG: the bridge server will shutdown
2023-09-27T12:11:04.7428624Z 12:11:04.742 DEBUG: the bridge server closed
2023-09-27T12:11:04.7428903Z 12:11:04.742 INFO: Time spent writing ucfgs 0ms
2023-09-27T12:11:05.3032575Z 12:11:05.302 INFO: ------------------------------------------------------------------------
2023-09-27T12:11:05.3032826Z 12:11:05.302 INFO: EXECUTION FAILURE
2023-09-27T12:11:05.3033214Z 12:11:05.302 INFO: ------------------------------------------------------------------------
2023-09-27T12:11:05.3033383Z 12:11:05.302 INFO: Total time: 17:48.562s
2023-09-27T12:11:05.4011755Z 12:11:05.400 ERROR: Error during SonarScanner execution
2023-09-27T12:11:05.4011979Z 12:11:05.400 INFO: Final Memory: 84M/512M
2023-09-27T12:11:05.4012568Z 12:11:05.400 INFO: ------------------------------------------------------------------------
2023-09-27T12:11:05.4012731Z java.lang.OutOfMemoryError: Java heap space
2023-09-27T12:11:05.4046575Z at java.base/java.lang.StringCoding.encodeASCII(Unknown Source)
2023-09-27T12:11:05.4046851Z at java.base/java.lang.StringCoding.encode(Unknown Source)
2023-09-27T12:11:05.4047032Z at java.base/java.lang.String.getBytes(Unknown Source)
2023-09-27T12:11:05.4047184Z at java.base/java.io.UnixFileSystem.getBooleanAttributes0(Native Method)
2023-09-27T12:11:05.4047357Z at java.base/java.io.UnixFileSystem.getBooleanAttributes(Unknown Source)
2023-09-27T12:11:05.4050774Z at java.base/java.io.File.isDirectory(Unknown Source)
2023-09-27T12:11:05.4051061Z at org.sonar.plugins.javascript.bridge.TsConfigProvider$LookupTsConfigProvider.tsconfigs(TsConfigProvider.java:181)
2023-09-27T12:11:05.4051330Z at org.sonar.plugins.javascript.bridge.TsConfigProvider.tsconfigs(TsConfigProvider.java:94)
2023-09-27T12:11:05.4051770Z at org.sonar.plugins.javascript.bridge.TsConfigProvider.getTsConfigs(TsConfigProvider.java:89)
2023-09-27T12:11:05.4051998Z at org.sonar.plugins.javascript.bridge.JsTsSensor.analyzeFiles(JsTsSensor.java:109)
2023-09-27T12:11:05.4052226Z at org.sonar.plugins.javascript.bridge.AbstractBridgeSensor.execute(AbstractBridgeSensor.java:73)
2023-09-27T12:11:05.4055097Z at org.sonar.scanner.sensor.AbstractSensorWrapper.analyse(AbstractSensorWrapper.java:62)
2023-09-27T12:11:05.4055380Z at org.sonar.scanner.sensor.ModuleSensorsExecutor.execute(ModuleSensorsExecutor.java:75)
2023-09-27T12:11:05.4055644Z at org.sonar.scanner.sensor.ModuleSensorsExecutor.lambda$execute$1(ModuleSensorsExecutor.java:48)
2023-09-27T12:11:05.4056940Z at org.sonar.scanner.sensor.ModuleSensorsExecutor$$Lambda$1246/0x0000000100ab8440.run(Unknown Source)
2023-09-27T12:11:05.4057300Z at org.sonar.scanner.sensor.ModuleSensorsExecutor.withModuleStrategy(ModuleSensorsExecutor.java:66)
2023-09-27T12:11:05.4057533Z at org.sonar.scanner.sensor.ModuleSensorsExecutor.execute(ModuleSensorsExecutor.java:48)
2023-09-27T12:11:05.4057841Z at org.sonar.scanner.scan.ModuleScanContainer.doAfterStart(ModuleScanContainer.java:64)
2023-09-27T12:11:05.4058627Z at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:123)
2023-09-27T12:11:05.4058921Z at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:109)
2023-09-27T12:11:05.4059158Z at org.sonar.scanner.scan.ProjectScanContainer.scan(ProjectScanContainer.java:163)
2023-09-27T12:11:05.4059371Z at org.sonar.scanner.scan.ProjectScanContainer.scanRecursively(ProjectScanContainer.java:159)
2023-09-27T12:11:05.4059599Z at org.sonar.scanner.scan.ProjectScanContainer.doAfterStart(ProjectScanContainer.java:130)
2023-09-27T12:11:05.4059818Z at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:123)
2023-09-27T12:11:05.4060028Z at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:109)
2023-09-27T12:11:05.4060341Z at org.sonar.scanner.bootstrap.ScannerContainer.doAfterStart(ScannerContainer.java:396)
2023-09-27T12:11:05.4060557Z at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:123)
2023-09-27T12:11:05.4064921Z at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:109)
2023-09-27T12:11:05.4065130Z at org.sonar.scanner.bootstrap.GlobalContainer.doAfterStart(GlobalContainer.java:127)
2023-09-27T12:11:05.4065354Z at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:123)
2023-09-27T12:11:05.4065565Z at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:109)
2023-09-27T12:11:05.4065864Z at org.sonar.batch.bootstrapper.Batch.doExecute(Batch.java:57)
2023-09-27T12:11:08.2308770Z ##[error]Bash exited with code ‘1’.
2023-09-27T12:11:08.2718355Z ##[section]Finishing: Build image

Even if I tried to set up proper env variables to increase memory (see above) I’ve got the same Java heap space error.

I’ve also configured sonar.exculusions property inside sonar-project.proporties file with the extensions which I don’t needed for analyze.

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.