scalameta / metals

Scala language server with rich IDE features šŸš€
https://scalameta.org/metals/
Apache License 2.0
2.09k stars 330 forks source link

Improve handling of proxies and mirrors #2485

Open tgodzik opened 3 years ago

tgodzik commented 3 years ago

Issue

Currently it is really hard to setup Metals to work in the different corporate environments and people need to get through a lot of hoops to get it working properly mainly due to the fact there are 4 places where where specifying additional settings is needed:

Having so many different places to specify additional settings, makes the barrier of entry quite high.

Those settings might be:

I propose that we expose user settings which would be:

We would then use those settings in the VS Code extension itself. Try to forward all those settings to the the build tool, Metals server and Bloop by modifying automatically the ~/.bloop/bloop.json. Modifying the Bloop global config manually might not seem a perfect solution, but I don't really see a better way currently. We would also need to make sure that the server is restarted when those settings are modified.

I am in no way an expert in terms of proxies or anything related, so if anyone is able to help out, test some ideas or even tell me that I am doing something completely wrong, it would be greatly appreciated.

Additional context

This popped up for example here:

https://github.com/scalameta/metals/issues/2475

Search terms

proxy mirrors coursier

ekrich commented 3 years ago

My particular issue is with a Basic Auth proxy, in particular when the original request in redirected as shown in the error below. Coursier, Metals, and sbt seem to honor properties set in JAVA_OPTS and seem to be working fine post this PR: https://github.com/coursier/coursier/issues/930 Bloop seems to be the issue in this case. Prior to this fix Metals would not install.

It also tends to get even more tricky when using other build tools such as Maven, Gradle etc. but this is outside the scope of this issue.

2021.02.04 18:41:39 INFO  Attempting to connect to the build server...
2021.02.04 18:41:39 INFO  tracing is disabled for protocol BSP, to enable tracing of incoming and outgoing JSON messages create an empty file at /home/eric/.cache/metals/bsp.trace.json
2021.02.04 18:41:44 WARN  Stopped configuration of SemanticDB in Scala 2.12.12 projects: Error downloading org.scalameta:semanticdb-scalac_2.12.12:4.4.6
  not found: /home/eric/.ivy2/local/org.scalameta/semanticdb-scalac_2.12.12/4.4.6/ivys/ivy.xml
  download error: Caught java.net.ConnectException: Connection refused (Connection refused) (Connection refused (Connection refused)) while downloading https://repo1.maven.org/maven2/org/scalameta/semanticdb-scalac_2.12.12/4.4.6/semanticdb-scalac_2.12.12-4.4.6.pom
  not found: https://dl.bintray.com/scalacenter/releases/org/scalameta/semanticdb-scalac_2.12.12/4.4.6/semanticdb-scalac_2.12.12-4.4.6.pom
2021.02.04 18:41:44 INFO  time: connected to build server in 13s
2021.02.04 18:41:44 INFO  Connected to Build server v1.4.6-33-1c6f6712
ekrich commented 3 years ago

The first thing I noticed when trying to install Coursier via the directions https://get-coursier.io/docs/cli-installation is that the curl command did fine using env vars for the proxy as shown in step one below.

$ curl -fLo cs https://git.io/coursier-cli-"$(uname | tr LD ld)"
$ chmod +x cs

When trying to run the third command it seems the JAVA_OPTS containing the -D properties is not supported. Combining with the directions https://get-coursier.io/docs/other-proxy worked fine for a standard proxy as shown in the second ./cs shown below. The third option with the Basic Auth did not work.

$ ./cs install cs
-- or --
$ ./cs -J-Dhttps.proxyHost=proxy.foo.com -J-Dhttps.proxyPort=8080 install cs
-- or --
$  ./cs -J-Dhttps.proxyHost=proxy.foo.com -J-Dhttps.proxyPort=8080 -J-Dhttps.proxyUser=abc -J-DproxyPassword=123 install cs
$ rm cs

The third option I got the following which can't be found via a browser either.

Error downloading https://github.com/coursier/coursier/releases/download/v2.0.9/cs-x86_64-pc-linux

I believe this should work as coursier seems to work in sbt which seems to honor JAVA_OPTS. It is very important that all the tools honor for example JAVA_OPTS as scripts are usually created in house and passed along and used in shell initialization.

what-the-functor commented 3 years ago

I can validate that this is indeed necessary.

Many Scala developers at my (undisclosed) org are:

what-the-functor commented 3 years ago

What works in my corporate environment? Curl, with the usual proxy and cert configuration : YES Wget, with the usual proxy and cert configuration : YES Download Metals Extension from marketplace within VS Code: YES Download Metals server, with JVM system properties set in VS Code setting, Metals Server Properties: YES Bloop build import (sbt ... bloopInstall), with JVM system properties set in VS Code setting, Metals Server Properties: NO Bloop build import (sbt ... bloopInstall), with JVM system properties set in JVM_OPTS env var (Windows): NO Bloop build import (sbt ... bloopInstall), with JVM system properties set in .sbtopts: NO Bloop build import (sbt ... bloopInstall), with JVM system properties set in .jvmopts: NO

JVM system properties used: -Dhttps.proxyHost=< host > -Dhttps.proxyPort=< port > -Dhttps.proxyUser=< user > -Dhttps.proxyPassword=< password > -Djavax.net.ssl.trustStore=<path to truststore w/ internal cert>

skakker commented 3 years ago

Hey @tonylotts Great to know that you were able to get it working in your corporate environment.

We are also able to get the metals server from marketplace (using coursier bootstrap), but when we try to start the server, it still tries to download from the open-source marketplace.

The output here is after getting the metals executable and then trying to start it:

metals Error while downloading https://repo1.maven.org/maven2/com/google/code/gson/gson/2.7/gson-2.7.jar: Connection refused (Connection refused), ignoring it Error while downloading https://repo1.maven.org/maven2/com/google/guava/failureaccess/1.0.1/failureaccess-1.0.1.jar: Connection refused (Connection refused), ignoring it Error while downloading https://repo1.maven.org/maven2/com/google/code/findbugs/jsr305/3.0.2/jsr305-3.0.2.jar: Connection refused (Connection refused), ignoring it Error while downloading https://repo1.maven.org/maven2/com/google/errorprone/error_prone_annotations/2.2.0/error_prone_annotations-2.2.0.jar: Connection refused (Connection refused), ignoring it Error while downloading https://repo1.maven.org/maven2/ch/epfl/scala/bsp4j/2.0.0-M4/bsp4j-2.0.0-M4.jar: Connection refused (Connection refused), ignoring it Error while downloading https://repo1.maven.org/maven2/com/geirsson/coursier-small_2.12/1.3.3/coursier-small_2.12-1.3.3.jar: Connection refused (Connection refused), ignoring it

Were you able to find a way where we can download everything before and it doesn't try to download from the open-source on server start?

what-the-functor commented 3 years ago

@skakker I wouldn't say it's completely working for me, as sbt bloopInstall does not work. It fails with a proxy authentication error; which tells me that the proxy host property is being picked up, but not the credentials.

If you're trying to download from internal mirror(s), that needs to be set for SBT, and/or Coursier.

skakker commented 3 years ago

We are fine with getting everything from the marketplace "before" server start. We just don't want it to connect to the market place on starting the server.

Is there a way we can achieve that?

Like get everything before hand and then just start the server without contacting the opensource marketplace?

what-the-functor commented 3 years ago

@skakker I think that's achievable; if you set the mirrors, and you mirror all of your project dependencies, as well as all of the Metals dependencies.

kcwill2 commented 3 years ago

I don't know if it's possible but it would be nice to be able to specify mirrors and repos once. In our environment, we need to specify repos in mirrors.properties for Coursier and in metals-config Custom-repos not to mention overriding SBT repositories for both project-resolvers and boot-resolvers.

It's a mess and it's hard to know if we are even doing it correctly because it is regarded as an edge case and there is little documentation.

Maybe the install process can read that information from one place and configure it for all components?

I think the most difficult thing about it is that you don't get much feedback. Metals, Coursier and SBT do not tell you much about where they are getting the repos that they are using. This leads to a lot of trial and error.

tgodzik commented 3 years ago

@kcwill2 that's exactly what I plan to do in this issue. Metals would most likely want to configure it for all tools that are being used if possible.

kcwill2 commented 3 years ago

That would be fantastic!

skakker commented 3 years ago

For anyone following this thread, this is what worked for our usecase:

./coursier bootstrap org.scalameta:metals_2.12:0.9.8 --no-default -r "ivy:http://artifactory-link/[orgPath]/[module]/[revision]/[module]-[revision].[ext]|http://artifactory-link/[orgPath]/[module]/[revision]/[module]-[revision].ivy" -o metals -f

ScalaWilliam commented 3 years ago

@skakker at which stage did you run this?

@tgodzik would be ideal to be able to specify an Artifactory/Nexus repository, rather than an http proxy. Most corporate http proxies block maven central, and you need to go through an Artifactory/nexus instead which caches+proxies maven central.

Also to note many of these Artifactories also need authentication.

skakker commented 3 years ago

Hi, @ScalaWilliam I have this command in the docker file. The docker file is used to spawn hosted containerized environments. With this command, metals became available in the respective environments.

tgodzik commented 2 years ago

It should now be possible to download coursier jars from an alternate repository using the new coursierMirror setting (in the prerelease version currently). Please do report if it's not working.

I am looking into some other issues now.