Skip to content

Commit 6e6c6bf

Browse files
committed
[FAB-4819] Fix locating system packages in vendoring
This patchset fixes some bugs addressed in [FAB-4819]. When the GOROOT environment variable is not set (i.e. Go is installed in the standard location), Go uses its default value for GOROOT. This patch introduces getGoEnv() to properly get GOROOT by using the "go env" command instead of directly reading an environment variable. This patch also fixes list() to prevent from obtaining empty string in error from the output of the "go list" command. Change-Id: Ie8007087aff40d5f8eab6021e4e184534d3074e4 Signed-off-by: Taku Shimosawa <[email protected]>
1 parent f20846c commit 6e6c6bf

File tree

4 files changed

+67
-16
lines changed

4 files changed

+67
-16
lines changed

core/chaincode/platforms/golang/env.go

+23-1
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,15 @@ import (
2020
"os"
2121
"path/filepath"
2222
"strings"
23+
"time"
2324
)
2425

2526
type Env map[string]string
2627

2728
func getEnv() Env {
2829
env := make(Env)
2930
for _, entry := range os.Environ() {
30-
tokens := strings.Split(entry, "=")
31+
tokens := strings.SplitN(entry, "=", 2)
3132
if len(tokens) > 1 {
3233
env[tokens[0]] = tokens[1]
3334
}
@@ -36,6 +37,27 @@ func getEnv() Env {
3637
return env
3738
}
3839

40+
func getGoEnv() (Env, error) {
41+
env := getEnv()
42+
43+
goenvbytes, err := runProgram(env, 10*time.Second, "go", "env")
44+
if err != nil {
45+
return nil, err
46+
}
47+
48+
goenv := make(Env)
49+
50+
envout := strings.Split(string(goenvbytes), "\n")
51+
for _, entry := range envout {
52+
tokens := strings.SplitN(entry, "=", 2)
53+
if len(tokens) > 1 {
54+
goenv[tokens[0]] = strings.Trim(tokens[1], "\"")
55+
}
56+
}
57+
58+
return goenv, nil
59+
}
60+
3961
func flattenEnv(env Env) []string {
4062
result := make([]string, 0)
4163
for k, v := range env {

core/chaincode/platforms/golang/env_test.go

+11
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,14 @@ func Test_splitEnvPath(t *testing.T) {
2727
paths := splitEnvPaths("foo" + string(os.PathListSeparator) + "bar" + string(os.PathListSeparator) + "baz")
2828
assert.Equal(t, len(paths), 3)
2929
}
30+
31+
func Test_getGoEnv(t *testing.T) {
32+
goenv, err := getGoEnv()
33+
assert.NilError(t, err)
34+
35+
_, ok := goenv["GOPATH"]
36+
assert.Equal(t, ok, true)
37+
38+
_, ok = goenv["GOROOT"]
39+
assert.Equal(t, ok, true)
40+
}

core/chaincode/platforms/golang/list.go

+23-11
Original file line numberDiff line numberDiff line change
@@ -25,17 +25,15 @@ import (
2525
"time"
2626
)
2727

28-
// Logic inspired by: https://dave.cheney.net/2014/09/14/go-list-your-swiss-army-knife
29-
func list(env Env, template, pkg string) ([]string, error) {
30-
28+
//runProgram non-nil Env, timeout (typically secs or millisecs), program name and args
29+
func runProgram(env Env, timeout time.Duration, pgm string, args ...string) ([]byte, error) {
3130
if env == nil {
32-
env = getEnv()
31+
return nil, fmt.Errorf("<%s, %v>: nil env provided", pgm, args)
3332
}
34-
3533
var stdOut bytes.Buffer
3634
var stdErr bytes.Buffer
3735

38-
cmd := exec.Command("go", "list", "-f", template, pkg)
36+
cmd := exec.Command(pgm, args...)
3937
cmd.Env = flattenEnv(env)
4038
cmd.Stdout = &stdOut
4139
cmd.Stderr = &stdErr
@@ -48,21 +46,35 @@ func list(env Env, template, pkg string) ([]string, error) {
4846
}()
4947

5048
select {
51-
case <-time.After(60 * time.Second):
49+
case <-time.After(timeout):
5250
if err = cmd.Process.Kill(); err != nil {
53-
return nil, fmt.Errorf("go list: failed to kill: %s", err)
51+
return nil, fmt.Errorf("<%s, %v>: failed to kill: %s", pgm, args, err)
5452
} else {
55-
return nil, errors.New("go list: timeout")
53+
return nil, errors.New(fmt.Sprintf("<%s, %v>: timeout(%d msecs)", pgm, args, timeout/time.Millisecond))
5654
}
5755
case err = <-done:
5856
if err != nil {
59-
return nil, fmt.Errorf("go list: failed with error: \"%s\"\n%s", err, string(stdErr.Bytes()))
57+
return nil, fmt.Errorf("<%s, %v>: failed with error: \"%s\"\n%s", pgm, args, err, string(stdErr.Bytes()))
6058
}
6159

62-
return strings.Split(string(stdOut.Bytes()), "\n"), nil
60+
return stdOut.Bytes(), nil
6361
}
6462
}
6563

64+
// Logic inspired by: https://dave.cheney.net/2014/09/14/go-list-your-swiss-army-knife
65+
func list(env Env, template, pkg string) ([]string, error) {
66+
if env == nil {
67+
env = getEnv()
68+
}
69+
70+
lst, err := runProgram(env, 60*time.Second, "go", "list", "-f", template, pkg)
71+
if err != nil {
72+
return nil, err
73+
}
74+
75+
return strings.Split(strings.Trim(string(lst), "\n"), "\n"), nil
76+
}
77+
6678
func listDeps(env Env, pkg string) ([]string, error) {
6779
return list(env, "{{ join .Deps \"\\n\"}}", pkg)
6880
}

core/chaincode/platforms/golang/platform.go

+10-4
Original file line numberDiff line numberDiff line change
@@ -73,11 +73,14 @@ func decodeUrl(spec *pb.ChaincodeSpec) (string, error) {
7373
}
7474

7575
func getGopath() (string, error) {
76-
gopath := os.Getenv("GOPATH")
76+
env, err := getGoEnv()
77+
if err != nil {
78+
return "", err
79+
}
7780
// Only take the first element of GOPATH
78-
splitGoPath := filepath.SplitList(gopath)
81+
splitGoPath := filepath.SplitList(env["GOPATH"])
7982
if len(splitGoPath) == 0 {
80-
return "", fmt.Errorf("invalid GOPATH environment variable value:[%s]", gopath)
83+
return "", fmt.Errorf("invalid GOPATH environment variable value:[%s]", env["GOPATH"])
8184
}
8285
return splitGoPath[0], nil
8386
}
@@ -194,7 +197,10 @@ func (goPlatform *Platform) GetDeploymentPayload(spec *pb.ChaincodeSpec) ([]byte
194197
// --------------------------------------------------------------------------------------
195198
// Update our environment for the purposes of executing go-list directives
196199
// --------------------------------------------------------------------------------------
197-
env := getEnv()
200+
env, err := getGoEnv()
201+
if err != nil {
202+
return nil, err
203+
}
198204
gopaths := splitEnvPaths(env["GOPATH"])
199205
goroots := splitEnvPaths(env["GOROOT"])
200206
gopaths[code.Gopath] = true

0 commit comments

Comments
 (0)