Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmd/go: any invocation creates read-only telemetry configuration file under GOMODCACHE #68946

Closed
chrisnovakovic opened this issue Aug 19, 2024 · 26 comments
Assignees
Labels
Critical A critical problem that affects the availability or correctness of production systems built using Go GoCommand cmd/go NeedsFix The path to resolution is known, but the work has not been done. telemetry x/telemetry issues
Milestone

Comments

@chrisnovakovic
Copy link

Go version

go version go1.23.0 linux/amd64

Output of go env in your module/workspace:

GO111MODULE=''
GOARCH='amd64'
GOBIN=''
GOCACHE='/home/csn/please-go-rules/plz-out/tmp/test/root_test/root_test._test/run_1/.cache/go-build'
GOENV='/home/csn/please-go-rules/plz-out/tmp/test/root_test/root_test._test/run_1/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMODCACHE='/home/csn/please-go-rules/plz-out/tmp/test/root_test/root_test._test/run_1/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/home/csn/please-go-rules/plz-out/tmp/test/root_test/root_test._test/run_1/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/home/csn/please-go-rules/plz-out/bin/third_party/go/toolchain'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/home/csn/please-go-rules/plz-out/bin/third_party/go/toolchain/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.23.0'
GODEBUG=''
GOTELEMETRY='local'
GOTELEMETRYDIR='/home/csn/please-go-rules/plz-out/tmp/test/root_test/root_test._test/run_1/.config/go/telemetry'
GCCGO='gccgo'
GOAMD64='v1'
AR='ar'
CC='gcc'
CXX='g++'
CGO_ENABLED='1'
GOMOD='/home/csn/please-go-rules/plz-out/go.mod'
GOWORK=''
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/home/csn/please-go-rules/plz-out/tmp/test/root_test/root_test._test/run_1/go-build1923171216=/tmp/go-build -gno-record-gcc-switches'

What did you do?

The Please build system performs build actions in an environment that is isolated from the host system as much as possible. In particular, the inputs for a build action are linked into a temporary directory, and the build action's environment is sanitised - you'll notice the impact this has on the Go environment in the output of go env above. The go-rules plugin contains build definitions for compiling Go code with a Go toolchain, similarly to Bazel's rules_go.

After bumping go-rules' Go toolchain to 1.23.0, we've run into a situation where Please can't clean up the temporary directory it creates after a target has been built:

28 test targets and 78 tests run; 75 passed, 1 errored, 2 skipped.
Total time: 2m18.18s real, 5m33.79s compute.
Messages:
19:36:15.239 WARNING: Failed to remove temporary directory for //tools/please_go/install/exec:exec: failed to remove plz-out/tmp/tools/please_go/install/exec/exec._build: exit status 1
Output: rm: cannot remove 'plz-out/tmp/tools/please_go/install/exec/exec._build/pkg/mod/cache/download/golang.org/x/telemetry/config/@v': Directory not empty
19:36:19.065 WARNING: Failed to remove test directory for //tools/please_go/install:install_test: failed to remove plz-out/tmp/tools/please_go/install/install_test._test/run_1: exit status 1
Output: rm: cannot remove 'plz-out/tmp/tools/please_go/install/install_test._test/run_1/go/pkg/mod/golang.org/x/telemetry/config@v0.29.0/doc.go': Permission denied
rm: cannot remove 'plz-out/tmp/tools/please_go/install/install_test._test/run_1/go/pkg/mod/golang.org/x/telemetry/config@v0.29.0/LICENSE': Permission denied
rm: cannot remove 'plz-out/tmp/tools/please_go/install/install_test._test/run_1/go/pkg/mod/golang.org/x/telemetry/config@v0.29.0/config.json':Permission denied
rm: cannot remove 'plz-out/tmp/tools/please_go/install/install_test._test/run_1/go/pkg/mod/golang.org/x/telemetry/config@v0.29.0/go.mod': Permission denied

The root cause of this is that, by default, any invocation of go causes x/telemetry/internal/configstore to pull the latest telemetry configuration from x/telemetry/config via go mod download without using the -modcacherw flag:

https://github.com/golang/telemetry/blob/0693e6240b9b888df93a2e280a64431c10d47a63/internal/configstore/download.go#L43

Because this writes the configuration beneath GOROOT with 0444 permissions (and with 0555 intermediate directories), Please is prevented from unlinking the entire temporary directory tree.

I'm aware that telemetry can be disabled by writing off to $HOME/.config/go/telemetry before running go, which prevents this module from being pulled in the first place. However, the value of HOME is also set to the path to the temporary directory so this would have to be done before every invocation of go inside the build sandbox - while we could guarantee that this happens for the build definitions in the go-rules plugin, it's impossible to guarantee in the general case, where users write custom build rules that run whatever commands they want.

What did you see happen?

Please builds the target, but isn't able to clean up its own temporary directory afterwards owing to the Go toolchain writing a read-only file tree beneath GOROOT.

What did you expect to see?

Please builds the target and is able to clean up its own temporary directory afterwards without having to resort to hacks such as running go clean -modcache or chmodding GOROOT to make every file within it writeable after every invocation of go.

@gabyhelp
Copy link

Related Issues and Documentation

(Emoji vote if this was helpful or unhelpful; more detailed feedback welcome in this discussion.)

@chrisnovakovic
Copy link
Author

#67463 seems relevant here, although some of the comments imply that this only happens when telemetry is uploaded, which I don't believe is the case - here, the default telemetry mode (local) is in use, and the config file is still being pulled.

@seankhliao seankhliao changed the title cmd/go: any invocation creates read-only telemetry configuration file under GOROOT cmd/go: any invocation creates read-only telemetry configuration file under GOMODCACHE Aug 19, 2024
@seankhliao
Copy link
Member

perhaps please can set GOFLAGS=-modcacherw to have it apply to all go commands instead of passing it individually to each go invocation?

and/or clean up with go clean -modcache?

@cherrymui
Copy link
Member

cc @golang/telemetry @golang/tools-team

@cherrymui cherrymui added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Aug 19, 2024
@cherrymui cherrymui added this to the Backlog milestone Aug 19, 2024
@hyangah hyangah added the telemetry x/telemetry issues label Aug 19, 2024
@findleyr
Copy link
Contributor

although some of the comments imply that this only happens when telemetry is uploaded,

I think we may download the config too eagerly during the check for work to upload. In any case, if this is breaking users it doesn't really matter if it is infrequent.

I think we had discussed having the upload use a temp (or even dedicated) GOMODCACHE and clean up after itself. However, in #67463 we were only thinking about cmd/dist, not general usage where -modcacherw is desirable.

We should try to fix this for 1.23.1, particularly if the fix is low risk. I will investigate.

@findleyr findleyr modified the milestones: Backlog, Go1.23.1 Aug 19, 2024
@findleyr findleyr self-assigned this Aug 19, 2024
@hyangah
Copy link
Contributor

hyangah commented Aug 19, 2024

I think we need to fix x/telemetry/internal/upload to avoid downloading the config unless the telemetry mode is on.
(we still want to run other uploader logic such as compacting the counter files in local mode and producing json files even when the telemetry mode is local).

I still wish we could avoid polluting the module cache even when telemetry is on. Previously in #67463 (comment) the idea of using a temporary module cache was rejected because we thought checksum db was still stored under GOPATH. But I don't think that's true (except the sum.golang.org/latest data).

$ GOMODCACHE=/tmp/gomodcache GOPATH=/tmp/gopath go mod download golang.org/x/telemetry/config@latest
$ tree /tmp/gomodcache
/tmp/gomodcache
├── cache
│   └── download
│       ├── golang.org
│       │   └── x
│       │       └── telemetry
│       │           └── config
│       │               └── @v
│       │                   ├── list
│       │                   ├── v0.29.0.info
│       │                   ├── v0.29.0.lock
│       │                   ├── v0.29.0.mod
│       │                   ├── v0.29.0.zip
│       │                   └── v0.29.0.ziphash
│       └── sumdb
│           └── sum.golang.org
│               ├── lookup
│               │   └── golang.org
│               │       └── x
│               │           └── telemetry
│               │               └── config@v0.29.0
│               └── tile
│                   └── 8
│                       ├── 0
│                       │   └── x113
│                       │       ├── 563
│                       │       └── 749.p
│                       │           └── 112
│                       ├── 1
│                       │   ├── 443
│                       │   └── 444.p
│                       │       └── 85
│                       ├── 2
│                       │   └── 001.p
│                       │       └── 188
│                       └── 3
│                           └── 000.p
│                               └── 1
└── golang.org
    └── x
        └── telemetry
            └── config@v0.29.0
                ├── LICENSE
                ├── config.json
                ├── doc.go
                └── go.mod

28 directories, 17 files
$ tree /tmp/gopath
/tmp/gopath
└── pkg
    └── sumdb
        └── sum.golang.org
            └── latest

3 directories, 1 file

@cherrymui cherrymui added the Critical A critical problem that affects the availability or correctness of production systems built using Go label Aug 19, 2024
@peterebden
Copy link

perhaps please can set GOFLAGS=-modcacherw to have it apply to all go commands instead of passing it individually to each go invocation?

We could indeed do that, although it's still suboptimal if it'll attempt to download the module for each invocation.

and/or clean up with go clean -modcache?

We would ideally not want to have to add that to the end of every command; it also wouldn't get run if something else fails first so we'd still get the same issue (and for a language-agnostic build system it isn't clear on which actions it should/shouldn't run this if we try to special-case it).

The ideal from my perspective would be some way of turning all telemetry off, preferably via an env var which is easy to set, which also prevents it from downloading any telemetry libraries.

@chrisnovakovic
Copy link
Author

chrisnovakovic commented Aug 20, 2024

The ideal from my perspective would be some way of turning all telemetry off, preferably via an env var which is easy to set, which also prevents it from downloading any telemetry libraries.

+1. The idea of a GOTELEMETRY environment variable whose value would only be honoured if it were set to off (i.e. telemetry could be opted out of, but not into, using this mechanism) was floated in #65503 (comment). We'd certainly make use of that in Please, although I think it's also worth addressing the over-eager downloading of the config by x/telemetry/internal/upload as a separate issue.

@findleyr
Copy link
Contributor

@chrisnovakovic I filed #68960 last night for making GOTELEMETRY=off settable.

@thediveo
Copy link

thediveo commented Aug 21, 2024

isn't telemetry off by default and an opt-in? if not, this would violate European Union law and the corresponding EC member state laws.

@ianlancetaylor
Copy link
Contributor

@thediveo Yes, telemetry is off by default.

@findleyr
Copy link
Contributor

@thediveo the fix for this particular issue will be to not download the telemetry configuration if telemetry uploading is off (the default).

@dmitshur dmitshur modified the milestones: Go1.23.1, Go1.24 Aug 21, 2024
@dmitshur
Copy link
Contributor

dmitshur commented Aug 21, 2024

Moved to Go1.24 milestone since this need to be fixed on the main branch first (for Go 1.24), before being considered for backporting. Please use the usual process (https://go.dev/wiki/MinorReleases) to create a separate backport tracking issue in the Go1.23.1 milestone.

@dmitshur dmitshur added the GoCommand cmd/go label Aug 21, 2024
@findleyr
Copy link
Contributor

Thanks @dmitshur.

@gopherbot please backport this issue to 1.23: it is a misbehavior of the telemetry integration with 1.23 that breaks existing CI workflows.

@gopherbot
Copy link
Contributor

Backport issue(s) opened: #68994 (for 1.23).

Remember to create the cherry-pick CL(s) as soon as the patch is submitted to master, according to https://go.dev/wiki/MinorReleases.

@fwcd
Copy link

fwcd commented Aug 21, 2024

Ran into this while building yay from the Arch User Repository: https://github.com/archsink/x86_64/actions/runs/10484074392/job/29037778152

@gopherbot
Copy link
Contributor

Change https://go.dev/cl/607796 mentions this issue: internal/upload: only download the upload config if necessary

gopherbot pushed a commit to golang/telemetry that referenced this issue Aug 28, 2024
Refactor the upload pass so that the upload config is downloaded lazily,
and only if an upload is actually going to be performed. More
refactoring is desirable, but this change is intentionally minimal as it
will be cherry-picked into Go 1.23.1 to address golang/go#68946. TODOs
are left for future CLs.

For golang/go#68946

Change-Id: I4c565b333d92361a8380dd790b1a4f2d7223a37c
Reviewed-on: https://go-review.googlesource.com/c/telemetry/+/607796
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Robert Findley <rfindley@google.com>
@gopherbot
Copy link
Contributor

Change https://go.dev/cl/609195 mentions this issue: gopls: update x/telemetry to pick up recent bug fixes

@gopherbot
Copy link
Contributor

Change https://go.dev/cl/609196 mentions this issue: [gopls-release-branch.0.16] gopls: update x/telemetry to pick up recent bug fixes

@gopherbot
Copy link
Contributor

Change https://go.dev/cl/609256 mentions this issue: cmd: vendor golang.org/x/telemetry@e553cd4b

@gopherbot
Copy link
Contributor

Change https://go.dev/cl/609275 mentions this issue: internal/upload: only download the upload config if the mode is "on"

gopherbot pushed a commit to golang/telemetry that referenced this issue Aug 28, 2024
This is a second, simpler approach to addressing golang/go#68946, after
CL 607796 was deemed too complicated (and contained a bug!).

Simply check the mode file before downloading the upload config. The
test from CL 607796 are preserved.

For golang/go#68946

Change-Id: I1f11252456df2471e1eafe34e72ca9e369ff8e6a
Reviewed-on: https://go-review.googlesource.com/c/telemetry/+/609275
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
@gopherbot
Copy link
Contributor

Change https://go.dev/cl/609137 mentions this issue: [internal-branch.go1.23-vendor] internal/upload: only download the upload config if the mode is "on"

@gopherbot
Copy link
Contributor

Change https://go.dev/cl/609237 mentions this issue: cmd: vendor golang.org/x/telemetry@a797f33

gopherbot pushed a commit to golang/telemetry that referenced this issue Aug 28, 2024
…load config if the mode is "on"

This is a second, simpler approach to addressing golang/go#68946, after
CL 607796 was deemed too complicated (and contained a bug!).

Simply check the mode file before downloading the upload config. The
test from CL 607796 are preserved.

For golang/go#68946

Change-Id: I1f11252456df2471e1eafe34e72ca9e369ff8e6a
Reviewed-on: https://go-review.googlesource.com/c/telemetry/+/609275
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
(cherry picked from commit a797f33)
Reviewed-on: https://go-review.googlesource.com/c/telemetry/+/609137
Reviewed-by: Michael Pratt <mpratt@google.com>
@gopherbot
Copy link
Contributor

Change https://go.dev/cl/609355 mentions this issue: [release-branch.go1.23] cmd: vendor golang.org/x/telemetry@internal-branch.go1.23-vendor

gopherbot pushed a commit that referenced this issue Aug 29, 2024
…ranch.go1.23-vendor

Update x/telemetry to fix #68976 and #68946.

Commands run:
  go get golang.org/x/telemetry@internal-branch.go1.23-vendor
  go mod tidy
  go mod vendor

Fixes #68994.
Fixes #68995.

Change-Id: I63b892ad4c313aa92f21fbd4f519a0b19d725849
Reviewed-on: https://go-review.googlesource.com/c/go/+/609355
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Michael Pratt <mpratt@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
@gopherbot
Copy link
Contributor

Change https://go.dev/cl/609596 mentions this issue: [gopls-release-branch.0.16] update telemetry to match Go 1.23.1

@gopherbot
Copy link
Contributor

Change https://go.dev/cl/609635 mentions this issue: gopls: update x/telemetry dependency

gopherbot pushed a commit to golang/tools that referenced this issue Aug 29, 2024
Update x/telemetry to pick up the fixes for golang/go#68976 and
golang/go#68946.

Commands run (from the gopls module):
  go get golang.org/x/telemetry@f29ab53
  go mod tidy -compat=1.19

For golang/go#68916

Change-Id: I1c1f70a6b88f2f52fcc51b08a4d226359fb4e172
Reviewed-on: https://go-review.googlesource.com/c/tools/+/609596
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
gopherbot pushed a commit to golang/tools that referenced this issue Aug 30, 2024
Update x/telemetry to pick up the fixes for golang/go#68976 and
golang/go#68946.

Commands run (from the gopls module):
  go get golang.org/x/telemetry@f29ab53
  go mod tidy -compat=1.19

For golang/go#68916

Change-Id: Ifbe16ece970a89336f3e372ddfde088cf0770eac
Reviewed-on: https://go-review.googlesource.com/c/tools/+/609195
Auto-Submit: Robert Findley <rfindley@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Michael Matloob <matloob@golang.org>
xatier added a commit to xatier/dockerfiles that referenced this issue Aug 31, 2024
To avoid permission denied from telemetry package.

Ref: golang/go#68946
@dmitshur dmitshur added NeedsFix The path to resolution is known, but the work has not been done. and removed NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. labels Sep 4, 2024
arjun024 added a commit to cloudfoundry/go-buildpack that referenced this issue Sep 5, 2024
The immediate reason for this change is a bug in go 1.23(.0)
See golang/go#68946.

However, godep has been deprecated since 2019 and
GO_SETUP_GOPATH_IN_IMAGE has good unit testing. Such a deprecated
feature doesn't justify just skipping this test for go 1.23(.0), rather
remove the entire test.
arjun024 added a commit to cloudfoundry/go-buildpack that referenced this issue Sep 5, 2024
The immediate reason for this change is a bug in go 1.23(.0)
See golang/go#68946.

However, godep has been deprecated since 2019 and
GO_SETUP_GOPATH_IN_IMAGE has good unit testing. Such a deprecated
feature doesn't justify just skipping this test for go 1.23(.0), rather
remove the entire test.
netbsd-srcmastr pushed a commit to NetBSD/pkgsrc that referenced this issue Sep 13, 2024
Changes in this release

This release updates the golang.org/x/telemetry dependency to pick
up fixes for the following bugs:

    golang/go#68946: unnecessary downloading of the golang.org/x/telemetry/config module
    golang/go#68358: a potential crash on Windows when the telemetry counter file is extended
    golang/go#68311: a potential hanging process if the telemetry file is truncated

Additionally, this release changes the gopls/telemetryprompt/accepted
counter to be recorded each time the prompt state is checked
(golang/go#68770).

None of these issues were particularly urgent, but we also wanted
to make a gopls release to exercise our recently added release
automation (golang/go#57643).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Critical A critical problem that affects the availability or correctness of production systems built using Go GoCommand cmd/go NeedsFix The path to resolution is known, but the work has not been done. telemetry x/telemetry issues
Projects
None yet
Development

No branches or pull requests