Skip to content

Commit

Permalink
[FAB-18028] Create new PropagateEnvironment key
Browse files Browse the repository at this point in the history
Creates a new PropagateEnvironment to supersede the
existing key. If the new key is used, it supersedes
the existing key.

Signed-off-by: Brett Logan <[email protected]>
(cherry picked from commit f12f80c)
  • Loading branch information
Brett Logan committed Jun 29, 2020
1 parent c44e603 commit a7dc1d4
Show file tree
Hide file tree
Showing 16 changed files with 101 additions and 41 deletions.
6 changes: 3 additions & 3 deletions core/chaincode/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ type Config struct {
LogFormat string
LogLevel string
ShimLogLevel string
SCCWhitelist map[string]bool
SCCAllowlist map[string]bool
}

func GlobalConfig() *Config {
Expand Down Expand Up @@ -58,9 +58,9 @@ func (c *Config) load() {
c.StartupTimeout = minimumStartupTimeout
}

c.SCCWhitelist = map[string]bool{}
c.SCCAllowlist = map[string]bool{}
for k, v := range viper.GetStringMapString("chaincode.system") {
c.SCCWhitelist[k] = parseBool(v)
c.SCCAllowlist[k] = parseBool(v)
}

c.LogFormat = viper.GetString("chaincode.logging.format")
Expand Down
44 changes: 22 additions & 22 deletions core/container/externalbuilder/externalbuilder.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ import (
)

var (
// DefaultEnvWhitelist enumerates the list of environment variables that are
// DefaultPropagateEnvironment enumerates the list of environment variables that are
// implicitly propagated to external builder and launcher commands.
DefaultEnvWhitelist = []string{"LD_LIBRARY_PATH", "LIBPATH", "PATH", "TMPDIR"}
DefaultPropagateEnvironment = []string{"LD_LIBRARY_PATH", "LIBPATH", "PATH", "TMPDIR"}

logger = flogging.MustGetLogger("chaincode.externalbuilder")
)
Expand Down Expand Up @@ -263,23 +263,23 @@ func SanitizeCCIDPath(ccid string) string {

// A Builder is used to interact with an external chaincode builder and launcher.
type Builder struct {
EnvWhitelist []string
Location string
Logger *flogging.FabricLogger
Name string
MSPID string
PropagateEnvironment []string
Location string
Logger *flogging.FabricLogger
Name string
MSPID string
}

// CreateBuilders will construct builders from the peer configuration.
func CreateBuilders(builderConfs []peer.ExternalBuilder, mspid string) []*Builder {
var builders []*Builder
for _, builderConf := range builderConfs {
builders = append(builders, &Builder{
Location: builderConf.Path,
Name: builderConf.Name,
EnvWhitelist: builderConf.EnvironmentWhitelist,
Logger: logger.Named(builderConf.Name),
MSPID: mspid,
Location: builderConf.Path,
Name: builderConf.Name,
PropagateEnvironment: builderConf.PropagateEnvironment,
Logger: logger.Named(builderConf.Name),
MSPID: mspid,
})
}
return builders
Expand Down Expand Up @@ -397,29 +397,29 @@ func (b *Builder) runCommand(cmd *exec.Cmd) error {

// NewCommand creates an exec.Cmd that is configured to prune the calling
// environment down to the environment variables specified in the external
// builder's EnvironmentWhitelist and the DefaultEnvWhitelist.
// builder's PropagateEnvironment and the DefaultPropagateEnvironment.
func (b *Builder) NewCommand(name string, args ...string) *exec.Cmd {
cmd := exec.Command(name, args...)
whitelist := appendDefaultWhitelist(b.EnvWhitelist)
for _, key := range whitelist {
propagationList := appendDefaultPropagateEnvironment(b.PropagateEnvironment)
for _, key := range propagationList {
if val, ok := os.LookupEnv(key); ok {
cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%s", key, val))
}
}
return cmd
}

func appendDefaultWhitelist(envWhitelist []string) []string {
for _, variable := range DefaultEnvWhitelist {
if !contains(envWhitelist, variable) {
envWhitelist = append(envWhitelist, variable)
func appendDefaultPropagateEnvironment(propagateEnvironment []string) []string {
for _, variable := range DefaultPropagateEnvironment {
if !contains(propagateEnvironment, variable) {
propagateEnvironment = append(propagateEnvironment, variable)
}
}
return envWhitelist
return propagateEnvironment
}

func contains(envWhiteList []string, key string) bool {
for _, variable := range envWhiteList {
func contains(propagateEnvironment []string, key string) bool {
for _, variable := range propagateEnvironment {
if key == variable {
return true
}
Expand Down
2 changes: 1 addition & 1 deletion core/container/externalbuilder/externalbuilder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ var _ = Describe("externalbuilder", func() {
Describe("NewCommand", func() {
It("only propagates expected variables", func() {
var expectedEnv []string
for _, key := range externalbuilder.DefaultEnvWhitelist {
for _, key := range externalbuilder.DefaultPropagateEnvironment {
if val, ok := os.LookupEnv(key); ok {
expectedEnv = append(expectedEnv, fmt.Sprintf("%s=%s", key, val))
}
Expand Down
13 changes: 10 additions & 3 deletions core/peer/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,11 @@ import (
// ExternalBuilder represents the configuration structure of
// a chaincode external builder
type ExternalBuilder struct {
EnvironmentWhitelist []string `yaml:"environmentWhitelist"`
// TODO: Remove Environment in 3.0
// Deprecated: Environment is retained for backwards compatibility.
// New deployments should use the new PropagateEnvironment field
Environment []string `yaml:"environmentWhitelist"`
PropagateEnvironment []string `yaml:"propagateEnvironment"`
Name string `yaml:"name"`
Path string `yaml:"path"`
}
Expand Down Expand Up @@ -276,15 +280,18 @@ func (c *Config) load() error {
if err != nil {
return err
}
for _, builder := range externalBuilders {
c.ExternalBuilders = externalBuilders
for builderIndex, builder := range c.ExternalBuilders {
if builder.Path == "" {
return fmt.Errorf("invalid external builder configuration, path attribute missing in one or more builders")
}
if builder.Name == "" {
return fmt.Errorf("external builder at path %s has no name attribute", builder.Path)
}
if builder.Environment != nil && builder.PropagateEnvironment == nil {
c.ExternalBuilders[builderIndex].PropagateEnvironment = builder.Environment
}
}
c.ExternalBuilders = externalBuilders

c.OperationsListenAddress = viper.GetString("operations.listenAddress")
c.OperationsTLSEnabled = viper.GetBool("operations.tls.enabled")
Expand Down
53 changes: 53 additions & 0 deletions core/peer/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,59 @@ func TestGlobalConfigDefault(t *testing.T) {
assert.Equal(t, expectedConfig, coreConfig)
}

func TestPropagateEnvironment(t *testing.T) {
defer viper.Reset()
viper.Set("peer.address", "localhost:8080")
viper.Set("chaincode.externalBuilders", &[]ExternalBuilder{
{
Name: "testName",
Environment: []string{"KEY=VALUE"},
Path: "/testPath",
},
{
Name: "testName",
PropagateEnvironment: []string{"KEY=VALUE"},
Path: "/testPath",
},
{
Name: "testName",
Environment: []string{"KEY=VALUE"},
PropagateEnvironment: []string{"KEY=VALUE2"},
Path: "/testPath",
},
})
coreConfig, err := GlobalConfig()
assert.NoError(t, err)

expectedConfig := &Config{
AuthenticationTimeWindow: 15 * time.Minute,
PeerAddress: "localhost:8080",
ValidatorPoolSize: runtime.NumCPU(),
VMNetworkMode: "host",
DeliverClientKeepaliveOptions: comm.DefaultKeepaliveOptions,
ExternalBuilders: []ExternalBuilder{
{
Name: "testName",
Environment: []string{"KEY=VALUE"},
PropagateEnvironment: []string{"KEY=VALUE"},
Path: "/testPath",
},
{
Name: "testName",
PropagateEnvironment: []string{"KEY=VALUE"},
Path: "/testPath",
},
{
Name: "testName",
Environment: []string{"KEY=VALUE"},
PropagateEnvironment: []string{"KEY=VALUE2"},
Path: "/testPath",
},
},
}
assert.Equal(t, expectedConfig, coreConfig)
}

func TestMissingExternalBuilderPath(t *testing.T) {
defer viper.Reset()
viper.Set("peer.address", "localhost:8080")
Expand Down
4 changes: 2 additions & 2 deletions docs/source/cc_launcher.md
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ chaincode:
externalBuilders:
- name: my-golang-builder
path: /builders/golang
environmentWhitelist:
propagateEnvironment:
- GOPROXY
- GONOPROXY
- GOSUMDB
Expand All @@ -185,7 +185,7 @@ chaincode:
path: /builders/binary
```
In this example, the implementation of "my-golang-builder" is contained within the `/builders/golang` directory and its build scripts are located in `/builders/golang/bin`. When the peer invokes any of the build scripts associated with "my-golang-builder", it will propagate only the values of the environment variables in the `environmentWhitelist`.
In this example, the implementation of "my-golang-builder" is contained within the `/builders/golang` directory and its build scripts are located in `/builders/golang/bin`. When the peer invokes any of the build scripts associated with "my-golang-builder", it will propagate only the values of the environment variables in the `propagateEnvironment`.

Note: The following environment variables are always propagated to external builders:

Expand Down
2 changes: 1 addition & 1 deletion integration/e2e/e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ var _ = Describe("EndToEnd", func() {
runArtifactsFilePath = filepath.Join(testDir, "run-artifacts.txt")
os.Setenv("RUN_ARTIFACTS_FILE", runArtifactsFilePath)
for i, e := range network.ExternalBuilders {
e.EnvironmentWhitelist = append(e.EnvironmentWhitelist, "RUN_ARTIFACTS_FILE")
e.PropagateEnvironment = append(e.PropagateEnvironment, "RUN_ARTIFACTS_FILE")
network.ExternalBuilders[i] = e
}

Expand Down
2 changes: 1 addition & 1 deletion integration/ledger/couchdb_indexes_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ var _ = Describe("CouchDB indexes", func() {
network.ExternalBuilders = append(network.ExternalBuilders, fabricconfig.ExternalBuilder{
Path: filepath.Join(cwd, "..", "externalbuilders", "golang"),
Name: "external-golang",
EnvironmentWhitelist: []string{"GOPATH", "GOCACHE", "GOPROXY", "HOME", "PATH"},
PropagateEnvironment: []string{"GOPATH", "GOCACHE", "GOPROXY", "HOME", "PATH"},
})

network.GenerateConfigTree()
Expand Down
2 changes: 1 addition & 1 deletion integration/lifecycle/install_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ var _ = Describe("chaincode install", func() {
network.ExternalBuilders = append(network.ExternalBuilders, fabricconfig.ExternalBuilder{
Path: filepath.Join(cwd, "..", "externalbuilders", "golang"),
Name: "external-golang",
EnvironmentWhitelist: []string{"GOPATH", "GOCACHE", "GOPROXY", "HOME", "PATH"},
PropagateEnvironment: []string{"GOPATH", "GOCACHE", "GOPROXY", "HOME", "PATH"},
})
network.GenerateConfigTree()
network.Bootstrap()
Expand Down
2 changes: 1 addition & 1 deletion integration/lifecycle/lifecycle_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ var _ = Describe("Lifecycle", func() {
os.Setenv(envKey, termFile)
for i, e := range externalBuilders {
if e.Name == "binary" {
e.EnvironmentWhitelist = append(e.EnvironmentWhitelist, envKey)
e.PropagateEnvironment = append(e.PropagateEnvironment, envKey)
externalBuilders[i] = e
}
}
Expand Down
2 changes: 1 addition & 1 deletion integration/nwo/core_template.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ chaincode:
externalBuilders: {{ range .ExternalBuilders }}
- path: {{ .Path }}
name: {{ .Name }}
environmentWhitelist: {{ range .EnvironmentWhitelist }}
propagateEnvironment: {{ range .PropagateEnvironment }}
- {{ . }}
{{- end }}
{{- end }}
Expand Down
2 changes: 1 addition & 1 deletion integration/nwo/fabricconfig/core.go
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ type Node struct {
}

type ExternalBuilder struct {
EnvironmentWhitelist []string `yaml:"environmentWhitelist,omitempty"`
PropagateEnvironment []string `yaml:"propagateEnvironment,omitempty"`
Name string `yaml:"name,omitempty"`
Path string `yaml:"path,omitempty"`
}
Expand Down
2 changes: 1 addition & 1 deletion integration/nwo/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ func New(c *Config, rootDir string, client *docker.Client, startPort int, compon
network.ExternalBuilders = []fabricconfig.ExternalBuilder{{
Path: filepath.Join(cwd, "..", "externalbuilders", "binary"),
Name: "binary",
EnvironmentWhitelist: []string{"GOPROXY"},
PropagateEnvironment: []string{"GOPROXY"},
}}

if network.Templates == nil {
Expand Down
2 changes: 1 addition & 1 deletion internal/peer/node/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -745,7 +745,7 @@ func serve(args []string) error {

// deploy system chaincodes
for _, cc := range []scc.SelfDescribingSysCC{lsccInst, csccInst, qsccInst, lifecycleSCC} {
if enabled, ok := chaincodeConfig.SCCWhitelist[cc.Name()]; !ok || !enabled {
if enabled, ok := chaincodeConfig.SCCAllowlist[cc.Name()]; !ok || !enabled {
logger.Infof("not deploying chaincode %s as it is not enabled", cc.Name())
continue
}
Expand Down
2 changes: 1 addition & 1 deletion protoutil/blockutils.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ func BlockHeaderBytes(b *cb.BlockHeader) []byte {
if err != nil {
// Errors should only arise for types which cannot be encoded, since the
// BlockHeader type is known a-priori to contain only encodable types, an
// error here is fatal and should not be propogated
// error here is fatal and should not be propagated
panic(err)
}
return result
Expand Down
2 changes: 1 addition & 1 deletion sampleconfig/core.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -549,7 +549,7 @@ chaincode:
externalBuilders: []
# - path: /path/to/directory
# name: descriptive-builder-name
# environmentWhitelist:
# propagateEnvironment:
# - ENVVAR_NAME_TO_PROPAGATE_FROM_PEER
# - GOPROXY

Expand Down

0 comments on commit a7dc1d4

Please sign in to comment.