Skip to content

Commit 5d846e4

Browse files
author
Aleksandar Likic
committed
[FAB-6613] Build golang chaincode dynamically
Fabric currently forces static build of golang chaincode. This prevents user chaincode to use extensions (e.g. pkcs11) which require dynamic linking. This code change keeps static linking the default. Dynamic chaincode linking is enabled by setting chaincode.golang.dynamicLink to true in core.yaml. NOTE: Dynamic linking requires a custom image. Currently, hyperledger/fabric-baseos image does not include the C libraries required for dynamic linking. Change-Id: I189e9f30d12abb107d03d212561cf137b7fa724a Signed-off-by: Aleksandar Likic <aleksandar.likic@securekey.com>
1 parent 9cea8c7 commit 5d846e4

File tree

3 files changed

+30
-2
lines changed

3 files changed

+30
-2
lines changed

core/chaincode/platforms/golang/platform.go

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import (
3434
"github.com/hyperledger/fabric/core/chaincode/platforms/util"
3535
cutil "github.com/hyperledger/fabric/core/container/util"
3636
pb "github.com/hyperledger/fabric/protos/peer"
37+
"github.com/spf13/viper"
3738
)
3839

3940
// Platform for chaincodes written in Go
@@ -449,6 +450,16 @@ func (goPlatform *Platform) GenerateDockerfile(cds *pb.ChaincodeDeploymentSpec)
449450
return dockerFileContents, nil
450451
}
451452

453+
const staticLDFlagsOpts = "-ldflags \"-linkmode external -extldflags '-static'\""
454+
const dynamicLDFlagsOpts = ""
455+
456+
func getLDFlagsOpts() string {
457+
if viper.GetBool("chaincode.golang.dynamicLink") {
458+
return dynamicLDFlagsOpts
459+
}
460+
return staticLDFlagsOpts
461+
}
462+
452463
func (goPlatform *Platform) GenerateDockerBuild(cds *pb.ChaincodeDeploymentSpec, tw *tar.Writer) error {
453464
spec := cds.ChaincodeSpec
454465

@@ -457,7 +468,9 @@ func (goPlatform *Platform) GenerateDockerBuild(cds *pb.ChaincodeDeploymentSpec,
457468
return fmt.Errorf("could not decode url: %s", err)
458469
}
459470

460-
const ldflags = "-linkmode external -extldflags '-static'"
471+
ldflagsOpt := getLDFlagsOpts()
472+
logger.Infof("building chaincode with ldflagsOpt: '%s'", ldflagsOpt)
473+
461474
var gotags string
462475
// check if experimental features are enabled
463476
if metadata.Experimental == "true" {
@@ -468,7 +481,7 @@ func (goPlatform *Platform) GenerateDockerBuild(cds *pb.ChaincodeDeploymentSpec,
468481
codepackage := bytes.NewReader(cds.CodePackage)
469482
binpackage := bytes.NewBuffer(nil)
470483
err = util.DockerBuild(util.DockerBuildOptions{
471-
Cmd: fmt.Sprintf("GOPATH=/chaincode/input:$GOPATH go build -tags \"%s\" -ldflags \"%s\" -o /chaincode/output/chaincode %s", gotags, ldflags, pkgname),
484+
Cmd: fmt.Sprintf("GOPATH=/chaincode/input:$GOPATH go build -tags \"%s\" %s -o /chaincode/output/chaincode %s", gotags, ldflagsOpt, pkgname),
472485
InputStream: codepackage,
473486
OutputStream: binpackage,
474487
})

core/chaincode/platforms/golang/platform_go19_test.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,18 @@ func TestGetDeploymentPayload(t *testing.T) {
242242
}
243243
}
244244

245+
//TestGetLDFlagsOpts tests handling of chaincode.golang.dynamicLink
246+
func TestGetLDFlagsOpts(t *testing.T) {
247+
viper.Set("chaincode.golang.dynamicLink", true)
248+
if getLDFlagsOpts() != dynamicLDFlagsOpts {
249+
t.Error("Error handling chaincode.golang.dynamicLink configuration. ldflags should be for dynamic linkink")
250+
}
251+
viper.Set("chaincode.golang.dynamicLink", false)
252+
if getLDFlagsOpts() != staticLDFlagsOpts {
253+
t.Error("Error handling chaincode.golang.dynamicLink configuration. ldflags should be for static linkink")
254+
}
255+
}
256+
245257
//TestGenerateDockerBuild goes through the functions needed to do docker build
246258
func TestGenerateDockerBuild(t *testing.T) {
247259
platform := &Platform{}

sampleconfig/core.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,9 @@ chaincode:
391391
# golang will never need more than baseos
392392
runtime: $(BASE_DOCKER_NS)/fabric-baseos:$(ARCH)-$(BASE_VERSION)
393393

394+
# whether or not golang chaincode should be linked dynamically
395+
dynamicLink: false
396+
394397
car:
395398
# car may need more facilities (JVM, etc) in the future as the catalog
396399
# of platforms are expanded. For now, we can just use baseos

0 commit comments

Comments
 (0)