Skip to content

Commit

Permalink
initial
Browse files Browse the repository at this point in the history
  • Loading branch information
rlfnb authored and Ralf committed Apr 24, 2024
1 parent da6130e commit aa85178
Show file tree
Hide file tree
Showing 13 changed files with 1,013 additions and 1 deletion.
19 changes: 18 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ dist: dist-clean dist/$(MARCH)

.PHONY: dist-all
dist-all: dist-clean $(RELEASE_PLATFORMS:%=dist/%)
dist/%: release/% ccaasbuilder
dist/%: release/% externalbuilder ccaasbuilder
mkdir -p release/$(@F)/config
cp -r sampleconfig/*.yaml release/$(@F)/config
cd release/$(@F) && tar -czvf hyperledger-fabric-$(@F).$(PROJECT_VERSION).tar.gz *
Expand Down Expand Up @@ -351,6 +351,11 @@ ccaasbuilder-clean/%:
$(eval platform = $(patsubst ccaasbuilder/%,%,$@) )
cd ccaas_builder && rm -rf $(strip $(platform))

.PHONY: externalbuilder-clean
externalbuilder-clean/%:
$(eval platform = $(patsubst externalbuilder/%,%,$@) )
cd external_builder && rm -rf $(strip $(platform))

.PHONY: ccaasbuilder
ccaasbuilder/%: ccaasbuilder-clean
$(eval platform = $(patsubst ccaasbuilder/%,%,$@) )
Expand All @@ -361,8 +366,20 @@ ccaasbuilder/%: ccaasbuilder-clean
cd ccaas_builder && go test -v ./cmd/build && GOOS=$(GOOS) GOARCH=$(GOARCH) go build -buildvcs=false -o ../release/$(strip $(platform))/builders/ccaas/bin/ ./cmd/build/
cd ccaas_builder && go test -v ./cmd/release && GOOS=$(GOOS) GOARCH=$(GOARCH) go build -buildvcs=false -o ../release/$(strip $(platform))/builders/ccaas/bin/ ./cmd/release/

.PHONY: externalbuilder
externalbuilder/%: externalbuilder-clean
$(eval platform = $(patsubst externalbuilder/%,%,$@) )
$(eval GOOS = $(word 1,$(subst -, ,$(platform))))
$(eval GOARCH = $(word 2,$(subst -, ,$(platform))))
@mkdir -p release/$(strip $(platform))/builders/external/bin
cd external_builder && go test -v ./cmd/detect && GOOS=$(GOOS) GOARCH=$(GOARCH) go build -buildvcs=false -o ../release/$(strip $(platform))/builders/external/bin/ ./cmd/detect/
cd external_builder && go test -v ./cmd/build && GOOS=$(GOOS) GOARCH=$(GOARCH) go build -buildvcs=false -o ../release/$(strip $(platform))/builders/external/bin/ ./cmd/build/
cd external_builder && go test -v ./cmd/release && GOOS=$(GOOS) GOARCH=$(GOARCH) go build -buildvcs=false -o ../release/$(strip $(platform))/builders/external/bin/ ./cmd/release/

ccaasbuilder: ccaasbuilder/$(MARCH)

externalbuilder: externalbuilder/$(MARCH)

.PHONY: scan
scan: scan-govulncheck

Expand Down
2 changes: 2 additions & 0 deletions external_builder/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#SPDX-License-Identifier: Apache-2.0
bin/*
193 changes: 193 additions & 0 deletions external_builder/cmd/build/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
/*
Copyright IBM Corp. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/

package main

import (
"bytes"
"encoding/json"
"fmt"
"log"
"os"
"path/filepath"
"strings"
"text/template"

"github.com/otiai10/copy"
"github.com/pkg/errors"
)

var logger = log.New(os.Stderr, "", 0)

type chaincodeMetadata struct {
Type string `json:"type"`
}

// Connection structure is used to represent the
// connection.json file that is supplied in the
// chaincode package.
type connection struct {
Address string `json:"address"`
DialTimeout string `json:"dial_timeout"`
TLS bool `json:"tls_required"`
ClientAuth bool `json:"client_auth_required"`
RootCert string `json:"root_cert"`
ClientKey string `json:"client_key"`
ClientCert string `json:"client_cert"`
}

type Config struct {
PeerName string
}

func main() {
logger.Println("::Build")

if err := run(); err != nil {
logger.Printf("::Error: %v\n", err)
os.Exit(1)
}

logger.Printf("::Build phase completed")

}

func run() error {
if len(os.Args) < 4 {
return fmt.Errorf("incorrect number of arguments")
}

sourceDir, metadataDir, outputDir := os.Args[1], os.Args[2], os.Args[3]

connectionSrcFile := filepath.Join(sourceDir, "/connection.json")
metadataFile := filepath.Clean(filepath.Join(metadataDir, "metadata.json"))
connectionDestFile := filepath.Join(outputDir, "/connection.json")
metainfoSrcDir := filepath.Join(sourceDir, "META-INF")
metainfoDestDir := filepath.Join(outputDir, "META-INF")

// Process and check the metadata file, then copy to the output location
if _, err := os.Stat(metadataFile); err != nil {
return errors.WithMessagef(err, "%s not found ", metadataFile)
}

metadataFileContents, cause := os.ReadFile(metadataFile)
if cause != nil {
return errors.WithMessagef(cause, "%s file not readable", metadataFile)
}

var metadata chaincodeMetadata
if err := json.Unmarshal(metadataFileContents, &metadata); err != nil {
return errors.WithMessage(err, "Unable to parse JSON")
}

if strings.ToLower(metadata.Type) != "external" {
return fmt.Errorf("chaincode type should be external, it is %s", metadata.Type)
}

if err := copy.Copy(metadataDir, outputDir); err != nil {
return fmt.Errorf("failed to copy build metadata folder: %s", err)
}

if _, err := os.Stat(metainfoSrcDir); !os.IsNotExist(err) {
if err := copy.Copy(metainfoSrcDir, metainfoDestDir); err != nil {
return fmt.Errorf("failed to copy build META-INF folder: %s", err)
}
}

// Process and update the connections file
fileInfo, err := os.Stat(connectionSrcFile)
if err != nil {
return errors.WithMessagef(err, "%s not found ", connectionSrcFile)
}

connectionFileContents, err := os.ReadFile(connectionSrcFile)
if err != nil {
return err
}

// read the connection.json file into structure to process
var connectionData connection
if err := json.Unmarshal(connectionFileContents, &connectionData); err != nil {
return err
}

// Treat each of the string fields in the connection.json as Go template
// strings. They can be fixed strings, but if they are templates
// then the JSON string that is defined in CHAINCODE_AS_A_SERVICE_BUILDER_CONFIG
// is used as the 'context' to parse the string

updatedConnection := connection{}
var cfg map[string]interface{}

cfgString := os.Getenv("CHAINCODE_AS_A_SERVICE_BUILDER_CONFIG")
if cfgString != "" {
if err := json.Unmarshal([]byte(cfgString), &cfg); err != nil {
return fmt.Errorf("Failed to unmarshal %s", err)
}
}

updatedConnection.Address, err = execTempl(cfg, connectionData.Address)
if err != nil {
return fmt.Errorf("Failed to parse the Address field template: %s", err)
}

updatedConnection.DialTimeout, err = execTempl(cfg, connectionData.DialTimeout)
if err != nil {
return fmt.Errorf("Failed to parse the DialTimeout field template: %s", err)
}

// if connection is TLS Enabled, updated with the correct information
// no other information is needed for the no-TLS case, so the default can be assumed
// to be good
if connectionData.TLS {
updatedConnection.TLS = true
updatedConnection.ClientAuth = connectionData.ClientAuth

updatedConnection.RootCert, err = execTempl(cfg, connectionData.RootCert)
if err != nil {
return fmt.Errorf("Failed to parse the RootCert field template: %s", err)
}
updatedConnection.ClientKey, err = execTempl(cfg, connectionData.ClientKey)
if err != nil {
return fmt.Errorf("Failed to parse the ClientKey field template: %s", err)
}
updatedConnection.ClientCert, err = execTempl(cfg, connectionData.ClientCert)
if err != nil {
return fmt.Errorf("Failed to parse the ClientCert field template: %s", err)
}
}

updatedConnectionBytes, err := json.Marshal(updatedConnection)
if err != nil {
return fmt.Errorf("failed to marshal updated connection.json file: %s", err)
}

err = os.WriteFile(connectionDestFile, updatedConnectionBytes, fileInfo.Mode())
if err != nil {
return err
}

return nil

}

// execTempl is a helper function to process a template against a string, and return a string
func execTempl(cfg map[string]interface{}, inputStr string) (string, error) {

t, err := template.New("").Option("missingkey=error").Parse(inputStr)
if err != nil {
fmt.Printf("Failed to parse the template: %s", err)
return "", err
}

buf := &bytes.Buffer{}
err = t.Execute(buf, cfg)
if err != nil {
return "", err
}

return buf.String(), nil
}
Loading

0 comments on commit aa85178

Please sign in to comment.