Skip to content

proposal: cmd/go: support selecting a VCS transport #30304

Closed
@draftcode

Description

@draftcode

Problem

Git supports multiple transports. The built-in transports are git://, ssh://, https://, but it can support a custom transport, such as persistent-https://. Git repository hosting services typically support multiple transports.

With #26232, it will become possible to support private Git repositories with go-get. A server that supports ?go-get=1 URLs needs to return one <meta name="go-import"> tag. However, the server cannot tell which Git transport URL it should return.

For example, https://git.mycompany.com/private-repo is a Git repository that can be accessed with git clone https://... and git clone ssh://.... Both require an authentication. A user may choose to use https:// or ssh:// for git clone. When https://git.mycompany.com/private-repo?go-get=1 returns a tag <meta name="go-import" content="git.mycompany.com/private-repo git https://git.mycompany.com/private-repo">, users who set up credentials only for SSH cannot run go get because it internally tries to run git clone https://git.mycompany.com/private-repo and it fails because of the lack of credentials. The opposite is also true. If the server returns a tag with ssh://..., users who use https://... cannot run go get.

Multiple workarounds exist for this problem.

  • Use Git's url.insteadOf
  • Use a different go-import URL for a different transport (like golang.org for go.googlesource.com. Though, probably with cmd/go: define HTTP authentication extension mechanism #26232, we can support go-get=1 directly on googlesource.com.)
  • Encourage users to set up credentials for the transport that go-get=1 URL returns
  • Abuse GOAUTH so that it sends an indicator for the transport preference, assuming that the user can change the server side

Because of these workarounds, this problem is not critical. But it's nice if it's addressed.

Goal

Let users choose a VCS transport for go get git.mycompany.com/private-repo.

Idea 1 (add a query param for selecting a transport)

In addition to go-get=1, go get will add another query parameter so that the server can decide which go-import URL it returns. A user specifies GOGET_VCS_TRANSPORT=git-ssh in the environment variables, then go get will fetch "https://git.mycompany.com/private-repo?go-get=1&vcs-transport=git-ssh". The server returns a different URL based on the added query param.

A nice part of this option is that this is compatible with old/new client/server. A new server that supports this new query param can be compatible with the old go toolchains. When the new go toolchains that support GOGET_VCS_TRANSPORT fetch a URL with a new query param, as long as the server ignore unknown params, it's compatible with old servers.

We can abuse GOAUTH mechanism for this purpose. GOAUTH is meant for auth, but users can add any HTTP header that is not related to auth. A user can write a GOAUTH program that adds a special HTTP header that specifies their VCS transport preference and a supported server can return a different go-import URL based on that.

Idea 2 (let the server return multiple go-import URLs)

Let servers return multiple go-import tags with a different transport. The go toolchains need to choose which one it uses.

This might lose the backward compatibility, so I'm not sure if this is a good option.

Metadata

Metadata

Assignees

No one assigned

    Labels

    FrozenDueToAgeNeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.Proposal

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions