gemnasium-maven fails on Mac OS when using sbt >= 1.4.0
Summary
The gemnasium-maven
analyzer fails to produce a gl-dependency-scanning-report.json
and exits with status code 2
on Mac OS X when using sbt >= 1.4.0
.
Steps to reproduce
$ docker pull registry.gitlab.com/security-products/gemnasium-maven:3
$ git clone https://gitlab.com/gitlab-org/security-products/tests/scala-sbt.git --branch demonstrate-mac-os-x-sbt-bug
$ docker run -it --rm -v "$PWD/scala-sbt/qa/fixtures/scala-sbt/default:/ci-project-dir" \
-e CI_PROJECT_DIR=/ci-project-dir \
-e SECURE_LOG_LEVEL=debug registry.gitlab.com/security-products/gemnasium-maven:3
Using java version 'adoptopenjdk-17.0.2+8'
[INFO] [gemnasium-maven] [2022-05-25T12:09:59Z] ▶ GitLab gemnasium-maven analyzer v3.0.1
[DEBU] [gemnasium-maven] [2022-05-25T12:09:59Z] ▶ inspect directory: .
[DEBU] [gemnasium-maven] [2022-05-25T12:09:59Z] ▶ electing sbt for maven because this is the first match
[DEBU] [gemnasium-maven] [2022-05-25T12:09:59Z] ▶ electing sbt for maven because this is the first match
[INFO] [gemnasium-maven] [2022-05-25T12:09:59Z] ▶ Detected supported dependency files in '.'. Dependency files detected in this directory will be processed. Dependency files in other directories will be skipped.
[DEBU] [gemnasium-maven] [2022-05-25T12:09:59Z] ▶ Exporting dependencies for /ci-project-dir/build.sbt
[DEBU] [gemnasium-maven] [2022-05-25T12:10:01Z] ▶ /opt/asdf/shims/sbt -no-colors dependencyDot
exit status 2
Example Project
https://gitlab.com/gitlab-org/security-products/tests/scala-sbt/-/tree/demonstrate-mac-os-x-sbt-bug
What is the current bug behavior?
gemnasium-maven
fails with status code 2
.
What is the expected correct behavior?
gemnasium-maven
should succeed with status code 0
and produce a gl-dependency-scanning-report.json
file.
Results of GitLab environment info
gemnasium-maven v3.0.1
- Mac OS X 10.15.7
- Intel Processor
- Docker Desktop 4.1.1 (69879)
- Engine: 20.10.8
Possible fixes
gemnasium-maven
relies on the following command to export sbt
dependencies:
sbt -no-colors dependencyDot
This works fine with sbt < 1.4.0
, however, starting with sbt >= 1.4.0
, the behaviour has changed, and when the sbt
command is run, we now receive the following interactive message on Mac OS X:
$ sbt -no-colors dependencyDot
sbt thinks that server is already booting because of this exception:
sbt.internal.ServerAlreadyBootingException: java.io.IOException: org.scalasbt.ipcsocket.NativeErrorException: [22] Invalid argument
at sbt.internal.BootServerSocket.newSocket(BootServerSocket.java:348)
<snip>
Caused by: org.scalasbt.ipcsocket.NativeErrorException: [22] Invalid argument
at org.scalasbt.ipcsocket.JNAUnixDomainSocketLibraryProvider.bind(UnixDomainSocketLibrary.java:178)
at org.scalasbt.ipcsocket.UnixDomainServerSocket.bind(UnixDomainServerSocket.java:136)
... 26 more
Create a new server? y/n (default y) y
[info] welcome to sbt 1.6.1 (Eclipse Adoptium Java 17.0.2)
[info] loading settings for project global-plugins from plugins.sbt ...
[info] loading global plugins from /root/.sbt/1.0/plugins
[info] loading project definition from /ci-project-dir/project
[info] compiling 1 Scala source to /ci-project-dir/project/target/scala-2.12/sbt-1.0/classes ...
[info] Non-compiled module 'compiler-bridge_2.12' for Scala 2.12.15. Compiling...
[info] Compilation completed in 6.338s.
[info] done compiling
[info] loading settings for project root from build.sbt ...
[info] set current project to Hello (in build file:/ci-project-dir/)
[info] Wrote dependency graph to '/ci-project-dir/target/dependencies-compile.dot'
[success] Total time: 25 s, completed May 25, 2022, 12:20:20 PM
If we respond y
to this message, the process continues as expected and generates a dependency list, however, this doesn't work when the command is executed using exec.Command("sbt", args...)
in gemnasium-maven
, since gemnasium-maven
doesn't expect an interactive message requiring input, which causes the command to fail with an exit status 2
.
This is a known issue with sbt
, documented here. It seems that it's caused when sbt
attempts to create a socket on either an NFS-mounted share, or a directory that Docker mounts from a host container using the -v
(Bind mount a volume) flag.
As explained in the linked issue, there are at least two workarounds:
-
Pass the arguments
--batch -Dsbt.server.forcestart=true
to thesbt
command:sbt --batch -Dsbt.server.forcestart=true -no-colors dependencyDot
-
Copy the
CI_PROJECT_DIR
to another location, for example:$ git clone git@gitlab.com:gitlab-org/security-products/analyzers/gemnasium.git $ docker run -it --rm -v "$PWD/gemnasium/qa/fixtures/scala-sbt/default:/shared-dir" \ -e SECURE_LOG_LEVEL=debug registry.gitlab.com/security-products/gemnasium-maven:3 bash root@e6518e337cc9:~# cp -R /shared-dir /ci-project-dir && cd /ci-project-dir root@ce4a97b253fd:/ci-project-dir# sbt -no-colors dependencyDot
I prefer option 1.
because it requires less code changes and is easier to implement.