Commit 82cf8bca authored by Russ Cox's avatar Russ Cox

cmd/go: add GOPRIVATE environment variable

It is too confusing to have to set GONOSUMDB and GONOPROXY
in common use cases, but one cannot be guaranteed to be a
subset of the other.

This CL adds GOPRIVATE, which takes the same kind of pattern list
but is defined as "these patterns are private (non-public) modules".
Today the implication is that GOPRIVATE is the default setting for
GONOSUMDB and GONOPROXY. If there are other accommodations
to make for private packages in the future or in other tools,
having this clear statement of intent will let us do that.
(For example maybe an IDE integration would hyperlink an import
path to godoc.org; consulting GOPRIVATE would be a reasonable
way to decide not to do that for certain imports. In contrast,
consulting GONOPROXY or GONOSUMDB clearly would not.)

Fixes #32184.

Change-Id: If54c12d353c7a0a5c0e0273764140cce3c154a02
Reviewed-on: https://go-review.googlesource.com/c/go/+/181719
Run-TryBot: Russ Cox <rsc@golang.org>
Reviewed-by: default avatarBryan C. Mills <bcmills@google.com>
Reviewed-by: default avatarJay Conrod <jayconrod@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent f44404eb
This diff is collapsed.
...@@ -265,6 +265,7 @@ var knownEnv = ` ...@@ -265,6 +265,7 @@ var knownEnv = `
GOOS GOOS
GOPATH GOPATH
GOPPC64 GOPPC64
GOPRIVATE
GOPROXY GOPROXY
GOROOT GOROOT
GOSUMDB GOSUMDB
...@@ -291,30 +292,13 @@ var ( ...@@ -291,30 +292,13 @@ var (
GOPPC64 = envOr("GOPPC64", fmt.Sprintf("%s%d", "power", objabi.GOPPC64)) GOPPC64 = envOr("GOPPC64", fmt.Sprintf("%s%d", "power", objabi.GOPPC64))
GOWASM = envOr("GOWASM", fmt.Sprint(objabi.GOWASM)) GOWASM = envOr("GOWASM", fmt.Sprint(objabi.GOWASM))
GOPROXY = goproxy() GOPROXY = envOr("GOPROXY", "https://proxy.golang.org,direct")
GOSUMDB = gosumdb() GOSUMDB = envOr("GOSUMDB", "sum.golang.org")
GONOPROXY = Getenv("GONOPROXY") GOPRIVATE = Getenv("GOPRIVATE")
GONOSUMDB = Getenv("GONOSUMDB") GONOPROXY = envOr("GONOPROXY", GOPRIVATE)
GONOSUMDB = envOr("GONOSUMDB", GOPRIVATE)
) )
func goproxy() string {
v := Getenv("GOPROXY")
if v != "" {
return v
}
return "https://proxy.golang.org,direct"
}
func gosumdb() string {
v := Getenv("GOSUMDB")
if v != "" {
return v
}
return "sum.golang.org"
}
// GetArchEnv returns the name and setting of the // GetArchEnv returns the name and setting of the
// GOARCH-specific architecture environment variable. // GOARCH-specific architecture environment variable.
// If the current architecture has no GOARCH-specific variable, // If the current architecture has no GOARCH-specific variable,
......
...@@ -79,6 +79,7 @@ func MkEnv() []cfg.EnvVar { ...@@ -79,6 +79,7 @@ func MkEnv() []cfg.EnvVar {
{Name: "GONOSUMDB", Value: cfg.GONOSUMDB}, {Name: "GONOSUMDB", Value: cfg.GONOSUMDB},
{Name: "GOOS", Value: cfg.Goos}, {Name: "GOOS", Value: cfg.Goos},
{Name: "GOPATH", Value: cfg.BuildContext.GOPATH}, {Name: "GOPATH", Value: cfg.BuildContext.GOPATH},
{Name: "GOPRIVATE", Value: cfg.GOPRIVATE},
{Name: "GOPROXY", Value: cfg.GOPROXY}, {Name: "GOPROXY", Value: cfg.GOPROXY},
{Name: "GOROOT", Value: cfg.GOROOT}, {Name: "GOROOT", Value: cfg.GOROOT},
{Name: "GOSUMDB", Value: cfg.GOSUMDB}, {Name: "GOSUMDB", Value: cfg.GOSUMDB},
......
...@@ -510,19 +510,16 @@ General-purpose environment variables: ...@@ -510,19 +510,16 @@ General-purpose environment variables:
For more details see: 'go help gopath'. For more details see: 'go help gopath'.
GOPROXY GOPROXY
URL of Go module proxy. See 'go help modules'. URL of Go module proxy. See 'go help modules'.
GONOPROXY GOPRIVATE, GONOPROXY, GONOSUMDB
Comma-separated list of glob patterns (in the syntax of Go's path.Match) Comma-separated list of glob patterns (in the syntax of Go's path.Match)
of module path prefixes that should always be fetched directly, ignoring of module path prefixes that should always be fetched directly
the GOPROXY setting. See 'go help modules'. or that should not be compared against the checksum database.
See 'go help module-private'.
GOROOT
The root of the go tree.
GOSUMDB GOSUMDB
The name of checksum database to use and optionally its public key and The name of checksum database to use and optionally its public key and
URL. See 'go help module-auth'. URL. See 'go help module-auth'.
GONOSUMDB
Comma-separated list of glob patterns (in the syntax of Go's path.Match)
of module path prefixes that should not be compared against the checksum
database. See 'go help module-auth'.
GOROOT
The root of the go tree.
GOTMPDIR GOTMPDIR
The directory where the go command will write The directory where the go command will write
temporary source files, packages, and binaries. temporary source files, packages, and binaries.
......
...@@ -631,7 +631,7 @@ For more information, see 'go help module-auth'. ...@@ -631,7 +631,7 @@ For more information, see 'go help module-auth'.
` `
var HelpSum = &base.Command{ var HelpModuleAuth = &base.Command{
UsageLine: "module-auth", UsageLine: "module-auth",
Short: "module authentication using go.sum", Short: "module authentication using go.sum",
Long: ` Long: `
...@@ -712,18 +712,56 @@ If GOSUMDB is set to "off", or if "go get" is invoked with the -insecure flag, ...@@ -712,18 +712,56 @@ If GOSUMDB is set to "off", or if "go get" is invoked with the -insecure flag,
the checksum database is not consulted, and all unrecognized modules are the checksum database is not consulted, and all unrecognized modules are
accepted, at the cost of giving up the security guarantee of verified repeatable accepted, at the cost of giving up the security guarantee of verified repeatable
downloads for all modules. A better way to bypass the checksum database downloads for all modules. A better way to bypass the checksum database
for specific modules is to use the GONOSUMDB environment variable. for specific modules is to use the GOPRIVATE or GONOSUMDB environment
variables. See 'go help module-private' for details.
The GONOSUMDB environment variable is a comma-separated list of The 'go env -w' command (see 'go help env') can be used to set these variables
glob patterns (in the syntax of Go's path.Match) of module path prefixes for future go command invocations.
that should not be compared against the checksum database. `,
}
var HelpModulePrivate = &base.Command{
UsageLine: "module-private",
Short: "module configuration for non-public modules",
Long: `
The go command defaults to downloading modules from the public Go module
mirror at proxy.golang.org. It also defaults to validating downloaded modules,
regardless of source, against the public Go checksum database at sum.golang.org.
These defaults work well for publicly available source code.
The GOPRIVATE environment variable controls which modules the go command
considers to be private (not available publicly) and should therefore not use the
proxy or checksum database. The variable is a comma-separated list of
glob patterns (in the syntax of Go's path.Match) of module path prefixes.
For example, For example,
GONOSUMDB=*.corp.example.com,rsc.io/private GOPRIVATE=*.corp.example.com,rsc.io/private
causes the go command to treat as private any module with a path prefix
matching either pattern, including git.corp.example.com/xyzzy, rsc.io/private,
and rsc.io/private/quux.
The GOPRIVATE environment variable may be used by other tools as well to
identify non-public modules. For example, an editor could use GOPRIVATE
to decide whether to hyperlink a package import to a godoc.org page.
For fine-grained control over module download and validation, the GONOPROXY
and GONOSUMDB environment variables accept the same kind of glob list
and override GOPRIVATE for the specific decision of whether to use the proxy
and checksum database, respectively.
For example, if a company ran a module proxy serving private modules,
users would configure go using:
GOPRIVATE=*.corp.example.com
GOPROXY=proxy.example.com
GONOPROXY=none
disables checksum database lookups for modules with path prefixes matching This would tell the go comamnd and other tools that modules beginning with
either pattern, including "git.corp.example.com/xyzzy", "rsc.io/private", a corp.example.com subdomain are private but that the company proxy should
and "rsc.io/private/quux". be used for downloading both public and private modules, because
GONOPROXY has been set to a pattern that won't match any modules,
overriding GOPRIVATE.
The 'go env -w' command (see 'go help env') can be used to set these variables The 'go env -w' command (see 'go help env') can be used to set these variables
for future go command invocations. for future go command invocations.
......
...@@ -241,8 +241,8 @@ func lookup(proxy, path string) (r Repo, err error) { ...@@ -241,8 +241,8 @@ func lookup(proxy, path string) (r Repo, err error) {
var ( var (
errModVendor = errors.New("module lookup disabled by -mod=vendor") errModVendor = errors.New("module lookup disabled by -mod=vendor")
errProxyOff = errors.New("module lookup disabled by GOPROXY=off") errProxyOff = errors.New("module lookup disabled by GOPROXY=off")
errNoproxy error = notExistError("disabled by GONOPROXY") errNoproxy error = notExistError("disabled by GOPRIVATE/GONOPROXY")
errUseProxy error = notExistError("path does not match GONOPROXY") errUseProxy error = notExistError("path does not match GOPRIVATE/GONOPROXY")
) )
func lookupDirect(path string) (Repo, error) { func lookupDirect(path string) (Repo, error) {
......
...@@ -348,19 +348,8 @@ HTTP response. The string "direct" may appear in the proxy list, ...@@ -348,19 +348,8 @@ HTTP response. The string "direct" may appear in the proxy list,
to cause a direct connection to be attempted at that point in the search. to cause a direct connection to be attempted at that point in the search.
Any proxies listed after "direct" are never consulted. Any proxies listed after "direct" are never consulted.
The GONOPROXY environment variable is a comma-separated list of The GOPRIVATE and GONOPROXY environment variables allow bypassing
glob patterns (in the syntax of Go's path.Match) of module path prefixes the proxy for selected modules. See 'go help module-private' for details.
that should always be fetched directly, ignoring the GOPROXY setting.
For example,
GONOPROXY=*.corp.example.com,rsc.io/private
forces a direct connection to download modules with path prefixes matching
either pattern, including "git.corp.example.com/xyzzy", "rsc.io/private",
and "rsc.io/private/quux".
The 'go env -w' command (see 'go help env') can be used to set these variables
for future go command invocations.
No matter the source of the modules, the go command checks downloads against No matter the source of the modules, the go command checks downloads against
known checksums, to detect unexpected changes in the content of any specific known checksums, to detect unexpected changes in the content of any specific
......
...@@ -71,8 +71,9 @@ func init() { ...@@ -71,8 +71,9 @@ func init() {
help.HelpImportPath, help.HelpImportPath,
modload.HelpModules, modload.HelpModules,
modget.HelpModuleGet, modget.HelpModuleGet,
modfetch.HelpModuleAuth,
modfetch.HelpModulePrivate,
help.HelpPackages, help.HelpPackages,
modfetch.HelpSum,
test.HelpTestflag, test.HelpTestflag,
test.HelpTestfunc, test.HelpTestfunc,
} }
......
...@@ -111,6 +111,7 @@ func (ts *testScript) setup() { ...@@ -111,6 +111,7 @@ func (ts *testScript) setup() {
"GOOS=" + runtime.GOOS, "GOOS=" + runtime.GOOS,
"GOPATH=" + filepath.Join(ts.workdir, "gopath"), "GOPATH=" + filepath.Join(ts.workdir, "gopath"),
"GOPROXY=" + proxyURL, "GOPROXY=" + proxyURL,
"GOPRIVATE=",
"GOROOT=" + testGOROOT, "GOROOT=" + testGOROOT,
"GOSUMDB=" + testSumDBVerifierKey, "GOSUMDB=" + testSumDBVerifierKey,
"GONOPROXY=", "GONOPROXY=",
......
env GO111MODULE=on env GO111MODULE=on
env sumdb=$GOSUMDB env sumdb=$GOSUMDB
env proxy=$GOPROXY env proxy=$GOPROXY
env GOPROXY GONOPROXY GOSUMDB GONOSUMDB env GOPRIVATE GOPROXY GONOPROXY GOSUMDB GONOSUMDB
env dbname=localhost.localdev/sumdb env dbname=localhost.localdev/sumdb
# disagree with sumdb fails # disagree with sumdb fails
...@@ -13,20 +13,25 @@ stderr 'SECURITY ERROR' ...@@ -13,20 +13,25 @@ stderr 'SECURITY ERROR'
# but GONOSUMDB bypasses sumdb, for rsc.io/quote, rsc.io/sampler, golang.org/x/text # but GONOSUMDB bypasses sumdb, for rsc.io/quote, rsc.io/sampler, golang.org/x/text
env GONOSUMDB='*/quote,*/*mple*,golang.org/x' env GONOSUMDB='*/quote,*/*mple*,golang.org/x'
go get rsc.io/quote go get rsc.io/quote
rm go.sum
env GOPRIVATE='*/quote,*/*mple*,golang.org/x'
env GONOPROXY=none # that is, proxy all despite GOPRIVATE
go get rsc.io/quote
# and GONOPROXY bypasses proxy # and GONOPROXY bypasses proxy
[!net] skip [!net] skip
[!exec:git] skip [!exec:git] skip
env GOPRIVATE=none
env GONOPROXY='*/fortune' env GONOPROXY='*/fortune'
! go get rsc.io/fortune # does not exist in real world, only on test proxy ! go get rsc.io/fortune # does not exist in real world, only on test proxy
stderr 'git ls-remote' stderr 'git ls-remote'
env GOSUMDB= env GOSUMDB=
env GONOPROXY='*/x' env GONOPROXY=
env GOPRIVATE='*/x'
go get golang.org/x/text go get golang.org/x/text
go list -m all go list -m all
! stdout 'text.*v0.0.0-2017' # should not have the version from the proxy ! stdout 'text.*v0.0.0-2017' # should not have the version from the proxy
-- go.mod.orig -- -- go.mod.orig --
module m module m
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment