golang / go

The Go programming language
https://go.dev
BSD 3-Clause "New" or "Revised" License
124.01k stars 17.68k forks source link

cmd/go: git revision information stamping on CentOS 7 fails with Go 1.18rc1: error obtaining VCS status: exit status 128 #51253

Closed polarina closed 2 years ago

polarina commented 2 years ago

What version of Go are you using (go version)?

$ go version
go version go1.18rc1 linux/amd64
$ cat /etc/os-release 
NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"

CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"

Does this issue reproduce with the latest release?

This issue affects Go 1.18 only. Go 1.17 is unaffected.

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/ava-gabriel/.cache/go-build"
GOENV="/home/ava-gabriel/.config/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/home/ava-gabriel/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/ava-gabriel/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GOVCS=""
GOVERSION="go1.18rc1"
GCCGO="gccgo"
GOAMD64="v1"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/dev/null"
GOWORK=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build3218995411=/tmp/go-build -gno-record-gcc-switches"

What did you do?

[ava-gabriel@proclidev01 ~]$ mkdir hello
[ava-gabriel@proclidev01 ~]$ cd hello
[ava-gabriel@proclidev01 hello]$ git init
Initialized empty Git repository in /home/ava-gabriel/hello/.git/
[ava-gabriel@proclidev01 hello]$ echo 'package main' > main.go
[ava-gabriel@proclidev01 hello]$ go mod init example.com/hello
go: creating new go.mod: module example.com/hello
go: to add module requirements and sums:
    go mod tidy
[ava-gabriel@proclidev01 hello]$ git add .
[ava-gabriel@proclidev01 hello]$ git commit -m 'initial commit'
[master (root-commit) 2d02bea] initial commit
 2 files changed, 4 insertions(+)
 create mode 100644 go.mod
 create mode 100644 main.go
[ava-gabriel@proclidev01 hello]$ go build ./...
error obtaining VCS status: exit status 128
    Use -buildvcs=false to disable VCS stamping.

What did you expect to see?

I expected go build to complain about missing main, but that's only due to the triviality of the reproduction steps.

[ava-gabriel@proclidev01 hello]$ go build ./...
# example.com/hello
runtime.main_main·f: function main is undeclared in the main package

What did you see instead?

[ava-gabriel@proclidev01 hello]$ go build ./...
error obtaining VCS status: exit status 128
    Use -buildvcs=false to disable VCS stamping.

Probable cause

The command line argument --no-show-signature is not supported by Git on CentOS 7:

[ava-gabriel@proclidev01 hello]$ go build -x ./...
WORK=/tmp/go-build592561444
cd /home/ava-gabriel/hello
git status --porcelain
cd /home/ava-gabriel/hello
git show -s --no-show-signature --format=%H:%ct
error obtaining VCS status: exit status 128
    Use -buildvcs=false to disable VCS stamping.
[ava-gabriel@proclidev01 hello]$ git show -s --no-show-signature --format=%H:%ct
fatal: unrecognized argument: --no-show-signature
[ava-gabriel@proclidev01 hello]$ git --version
git version 1.8.3.1
dmitshur commented 2 years ago

Thanks for reporting.

~Can you please also include output from git --version?~ You've just edited this information in, thanks!

Proposal #26746 and issue #38373 are relevant here.

CC @bcmills, @matloob.

dmitshur commented 2 years ago

Git v1.8.3.1 is quite old, released in 2013. Is this representative of the latest version of git available on CentOS 7, or is a one-off instance where this machine just needs to be updated?

polarina commented 2 years ago

Is this representative of the latest version of git available on CentOS 7, or is a one-off instance where this machine just needs to be updated?

This is the latest version of Git available in CentOS 7's official repositories.

bcmills commented 2 years ago

Given that we still don't have a CentOS 7 builder (#29114 has been open without activity since Dec. 2018), I don't have the ability to easily test a fix for this issue. If you'd like to contribute a fix (with a regression test in cmd/go/testdata/script for if/when we do get a builder) I'd be happy to review it.

bcmills commented 2 years ago

As a workaround in the interim, note that you should be able to set -buildvcs=false to explicitly bypass VCS stamping. (Please file a separate issue if you find that doesn't work.)

ooxi commented 2 years ago

@bcmills for your information, this also occurs on git 2.7.4 shipped with Ubuntu 16.04

Calling go build -v reveals

# cd /home/user/project; git show -s --no-show-signature --format=%H:%ct
fatal: unrecognized argument: --no-show-signature

It seems like this option was not introduced until git 2.10. I'm compiling on Ubuntu 16.04 to ensure the generated binaries will work on newer Ubuntu versions.

I don't quite get why go calls an external vcs anyhow instead of bundling this capability.

Edit: I found commit 90066b which fixes a similar issue with go log

gopherbot commented 2 years ago

Change https://go.dev/cl/388194 mentions this issue: cmd/go: fix buildvcs when using older git versions

mpx commented 2 years ago

Yes, I just noticed this is the second time we've hit this too. Sent above CL to workaround the issue.

Using git -c log.showsignature=false show enables Git to ignore unknown configuration options.

gopherbot commented 2 years ago

Change https://go.dev/cl/391354 mentions this issue: [release-branch.go1.18] cmd/go: fix buildvcs when using older git versions

VetSoftKeith commented 2 years ago

so, I'm also getting this since moving to Go 1.18.1 on my local Win10 machine. Tested with Git 2.35.2 and latest 2.36.0 using latest Go1.18.1. Error occurs for me when using go build .. go mod tidy and go get -u ./... both run without issue.

Relevant versions: Go: go version go1.18.1 windows/amd64 Git: git version 2.36.0.windows.1 Windows: Windows 10 Pro 21H2 (19044.1645)

Output of go build -x ./...:

PS D:\Projects\****> go build -x ./...
WORK=C:\Users\****\AppData\Local\Temp\go-build2420220826
cd D:\Projects\****
git status --porcelain
error obtaining VCS status: exit status 128
        Use -buildvcs=false to disable VCS stamping.

When running git status --porcelain by itself I got this output:

PS D:\Projects\****> git status --porcelain
fatal: unsafe repository ('D:/Projects/****' is owned by someone else)
To add an exception for this directory, call:

        git config --global --add safe.directory D:/Projects/***

Running the recommended git config command does solve the problem, but project/file ownership nor git config info hasn't changed in the 2+ years I've been working on it so not sure what changed. Hopefully this helps others that come across this issue as well.

ooxi commented 2 years ago

@VetSoftKeith I'm not sure these are related, since the bug fixed in this issue was caused by using an option introduced in git 2.10 while you are running 2.36

It might however be a mitigation against CVE-2022-24765 / CVE-2022-24767. Could you downgrade to 2.35? If this fixes your problem, then open a new issue (or search for an issue) mentioning these mitigations.

a-h commented 1 year ago

In situations where you have a build server that uses Docker, you can have a situation where the source code is mounted into the build container and is then owned by that Linux user, where the build process is running as a different Linux user.

This is a common situation in self-hosted Github action runners. Github Actions run as root, but the container may not have a "root" user (e.g. the NodeJS container has a "node" user instead).

In these cases, the source code is mounted in, and is owned by root, but attempting to build inside the Docker container will now fail due to changes in git https://github.blog/2022-04-12-git-security-vulnerability-announced/

In @VetSoftKeith's case on Windows, I suspect that the username that checked out the code is now different to the current username, and triggers the change in git behaviour described in the Github blog link.

When trying to build source code in this scenario, Go returns a message which doesn't include any detail:

error obtaining VCS status: exit status 128
    Use -buildvcs=false to disable VCS stamping.

Disabling VCS stamping is not ideal, so the workaround for my team's build container was to add a docker group, and configure the Docker container's "node" user to be part of it. It's possible to find out what the build container's user IDs and names are by running the container locally with docker run -it --rm <container> /bin/sh and executing the ids and whoami commands.

# https://github.com/actions/runner/issues/691
RUN groupadd -g 121 docker
RUN useradd -g docker runner
RUN usermod -a -G docker node

Then to add a global git configuration to the Docker image to ensure that git ignores the fact that the repo is owned by a different Linux user:

# Workaround for https://github.com/golang/go/issues/51253, https://github.com/actions/checkout/issues/760
# The CVE isn't relevant to our github actions runners
COPY gitconfig /etc/gitconfig
RUN chgrp -R docker /etc/gitconfig

The gitconfig is:

[safe]
        directory = *

In terms of what this means for Go, I think that displaying the underlying git error message would have been helpful, since when this happens in CI environments, it's often hard to debug.

Hope that helps someone!

richchurcher commented 1 year ago

That did help, ty @a-h! For completeness, I'll note that if you're using a container that does happen to run the go build as root, simply copying the gitconfig seems to be enough:

COPY gitconfig /etc/gitconfig