-
Notifications
You must be signed in to change notification settings - Fork 8.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This patch `calculatepackageid` command to calculate the package ID for a packaged chaincode rather than an installed chaincode. The new command will be useful, for example, the following cases: * When multiple chaincode packages with the same label name are installed, it is possible to identify which ID corresponds to which package later. * To check whether a particular chaincode package is installed or not on a peer without installing that package. Signed-off-by: Tatsuya Sato <tatsuya.sato.so@hitachi.com>
- Loading branch information
Showing
8 changed files
with
287 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
114 changes: 114 additions & 0 deletions
114
internal/peer/lifecycle/chaincode/calculatepackageid.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
/* | ||
Copyright Hitachi, Ltd. All Rights Reserved. | ||
SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package chaincode | ||
|
||
import ( | ||
"fmt" | ||
"io" | ||
"os" | ||
|
||
"github.com/hyperledger/fabric/core/chaincode/persistence" | ||
"github.com/pkg/errors" | ||
"github.com/spf13/cobra" | ||
) | ||
|
||
// PackageIDCalculator holds the dependencies needed to calculate | ||
// the package ID for a packaged chaincode | ||
type PackageIDCalculator struct { | ||
Command *cobra.Command | ||
Input *CalculatePackageIDInput | ||
Reader Reader | ||
Writer io.Writer | ||
} | ||
|
||
// CalculatePackageIDInput holds the input parameters for calculating | ||
// the package ID of a packaged chaincode | ||
type CalculatePackageIDInput struct { | ||
PackageFile string | ||
} | ||
|
||
// Validate checks that the required parameters are provided | ||
func (i *CalculatePackageIDInput) Validate() error { | ||
if i.PackageFile == "" { | ||
return errors.New("chaincode install package must be provided") | ||
} | ||
|
||
return nil | ||
} | ||
|
||
// CalculatePackageIDCmd returns the cobra command for calculating | ||
// the package ID for a packaged chaincode | ||
func CalculatePackageIDCmd(p *PackageIDCalculator) *cobra.Command { | ||
calculatePackageIDCmd := &cobra.Command{ | ||
Use: "calculatepackageid packageFile", | ||
Short: "Calculate the package ID for a chaincode.", | ||
Long: "Calculate the package ID for a packaged chaincode.", | ||
ValidArgs: []string{"1"}, | ||
RunE: func(cmd *cobra.Command, args []string) error { | ||
if p == nil { | ||
p = &PackageIDCalculator{ | ||
Reader: &persistence.FilesystemIO{}, | ||
Writer: os.Stdout, | ||
} | ||
} | ||
p.Command = cmd | ||
|
||
return p.CalculatePackageID(args) | ||
}, | ||
} | ||
flagList := []string{ | ||
"peerAddresses", | ||
"tlsRootCertFiles", | ||
"connectionProfile", | ||
} | ||
attachFlags(calculatePackageIDCmd, flagList) | ||
|
||
return calculatePackageIDCmd | ||
} | ||
|
||
// PackageIDCalculator calculates the package ID for a packaged chaincode. | ||
func (p *PackageIDCalculator) CalculatePackageID(args []string) error { | ||
if p.Command != nil { | ||
// Parsing of the command line is done so silence cmd usage | ||
p.Command.SilenceUsage = true | ||
} | ||
|
||
if len(args) != 1 { | ||
return errors.New("invalid number of args. expected only the packaged chaincode file") | ||
} | ||
p.setInput(args[0]) | ||
|
||
return p.PackageID() | ||
} | ||
|
||
// PackageID calculates the package ID for a packaged chaincode and print it. | ||
func (p *PackageIDCalculator) PackageID() error { | ||
err := p.Input.Validate() | ||
if err != nil { | ||
return err | ||
} | ||
pkgBytes, err := p.Reader.ReadFile(p.Input.PackageFile) | ||
if err != nil { | ||
return errors.WithMessagef(err, "failed to read chaincode package at '%s'", p.Input.PackageFile) | ||
} | ||
|
||
metadata, _, err := persistence.ParseChaincodePackage(pkgBytes) | ||
if err != nil { | ||
return errors.WithMessage(err, "could not parse as a chaincode install package") | ||
} | ||
|
||
packageID := persistence.PackageID(metadata.Label, pkgBytes) | ||
|
||
fmt.Fprintf(p.Writer, "Package ID: %s\n", packageID) | ||
return nil | ||
} | ||
|
||
func (p *PackageIDCalculator) setInput(packageFile string) { | ||
p.Input = &CalculatePackageIDInput{ | ||
PackageFile: packageFile, | ||
} | ||
} |
133 changes: 133 additions & 0 deletions
133
internal/peer/lifecycle/chaincode/calculatepackageid_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
/* | ||
Copyright Hitachi, Ltd. All Rights Reserved. | ||
SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package chaincode_test | ||
|
||
import ( | ||
"io/ioutil" | ||
|
||
"github.com/hyperledger/fabric/internal/peer/lifecycle/chaincode" | ||
"github.com/hyperledger/fabric/internal/peer/lifecycle/chaincode/mock" | ||
"github.com/pkg/errors" | ||
"github.com/spf13/cobra" | ||
|
||
. "github.com/onsi/ginkgo" | ||
. "github.com/onsi/gomega" | ||
"github.com/onsi/gomega/gbytes" | ||
) | ||
|
||
var _ = Describe("CalculatePackageID", func() { | ||
Describe("PackageIDCalculator", func() { | ||
var ( | ||
mockReader *mock.Reader | ||
input *chaincode.CalculatePackageIDInput | ||
packageIDCalculator *chaincode.PackageIDCalculator | ||
) | ||
|
||
BeforeEach(func() { | ||
input = &chaincode.CalculatePackageIDInput{ | ||
PackageFile: "pkgFile", | ||
} | ||
|
||
mockReader = &mock.Reader{} | ||
data, err := ioutil.ReadFile("testdata/good-package.tar.gz") | ||
Expect(err).NotTo(HaveOccurred()) | ||
mockReader.ReadFileReturns(data, nil) | ||
|
||
buffer := gbytes.NewBuffer() | ||
|
||
packageIDCalculator = &chaincode.PackageIDCalculator{ | ||
Input: input, | ||
Reader: mockReader, | ||
Writer: buffer, | ||
} | ||
}) | ||
|
||
It("calculates the package IDs for chaincodes", func() { | ||
err := packageIDCalculator.PackageID() | ||
Expect(err).NotTo(HaveOccurred()) | ||
Eventually(packageIDCalculator.Writer).Should(gbytes.Say("Package ID: Real-Label:fb3edf9621c5e3d864079d8c9764205f4db09d7021cfa4124aa79f4edcc2f64a\n")) | ||
}) | ||
|
||
Context("when the chaincode install package is not provided", func() { | ||
BeforeEach(func() { | ||
packageIDCalculator.Input.PackageFile = "" | ||
}) | ||
|
||
It("returns an error", func() { | ||
err := packageIDCalculator.PackageID() | ||
Expect(err).To(MatchError("chaincode install package must be provided")) | ||
}) | ||
}) | ||
|
||
Context("when the package file cannot be read", func() { | ||
BeforeEach(func() { | ||
mockReader.ReadFileReturns(nil, errors.New("coffee")) | ||
}) | ||
|
||
It("returns an error", func() { | ||
err := packageIDCalculator.PackageID() | ||
Expect(err).To(MatchError("failed to read chaincode package at 'pkgFile': coffee")) | ||
}) | ||
}) | ||
|
||
Context("when the package file cannot be parsed", func() { | ||
BeforeEach(func() { | ||
data, err := ioutil.ReadFile("testdata/unparsed-package.tar.gz") | ||
Expect(err).NotTo(HaveOccurred()) | ||
mockReader.ReadFileReturns(data, nil) | ||
}) | ||
|
||
It("returns an error", func() { | ||
err := packageIDCalculator.PackageID() | ||
Expect(err).To(MatchError(ContainSubstring("could not parse as a chaincode install package"))) | ||
}) | ||
}) | ||
}) | ||
|
||
Describe("CalculatePackageIDCmd", func() { | ||
var calculatePackageIDCmd *cobra.Command | ||
|
||
BeforeEach(func() { | ||
calculatePackageIDCmd = chaincode.CalculatePackageIDCmd(nil) | ||
calculatePackageIDCmd.SilenceErrors = true | ||
calculatePackageIDCmd.SilenceUsage = true | ||
calculatePackageIDCmd.SetArgs([]string{ | ||
"testpkg", | ||
}) | ||
}) | ||
|
||
It("sets up the calculator and attempts to calculate the package ID for the chaincode", func() { | ||
err := calculatePackageIDCmd.Execute() | ||
Expect(err).To(MatchError(ContainSubstring("failed to read chaincode package at 'testpkg'"))) | ||
}) | ||
|
||
Context("when more than one argument is provided", func() { | ||
BeforeEach(func() { | ||
calculatePackageIDCmd.SetArgs([]string{ | ||
"testpkg", | ||
"whatthe", | ||
}) | ||
}) | ||
|
||
It("returns an error", func() { | ||
err := calculatePackageIDCmd.Execute() | ||
Expect(err).To(MatchError("invalid number of args. expected only the packaged chaincode file")) | ||
}) | ||
}) | ||
|
||
Context("when no argument is provided", func() { | ||
BeforeEach(func() { | ||
calculatePackageIDCmd.SetArgs([]string{}) | ||
}) | ||
|
||
It("returns an error", func() { | ||
err := calculatePackageIDCmd.Execute() | ||
Expect(err).To(MatchError("invalid number of args. expected only the packaged chaincode file")) | ||
}) | ||
}) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.
Binary file not shown.