From c20602e0d969b37f60d538111b80cd3a470fcfc6 Mon Sep 17 00:00:00 2001 From: Will Lahti Date: Wed, 26 Jul 2017 16:09:58 -0400 Subject: [PATCH] [FAB-5485]Compute image name hash before replacing This CR computes the hash of the Docker image name before replacing any invalid characters in order to avoid the chance of any name collisions due to replacement of invalid characters. Change-Id: I164bb4236fcdba4c0d6dd369fb62f747309d353c Signed-off-by: Will Lahti --- .../dockercontroller/dockercontroller.go | 22 ++++++++++--------- .../dockercontroller/dockercontroller_test.go | 9 ++++---- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/core/container/dockercontroller/dockercontroller.go b/core/container/dockercontroller/dockercontroller.go index 9e7df67746c..2394b7e223b 100644 --- a/core/container/dockercontroller/dockercontroller.go +++ b/core/container/dockercontroller/dockercontroller.go @@ -432,16 +432,12 @@ func (vm *DockerVM) Destroy(ctxt context.Context, ccid ccintf.CCID, force bool, func (vm *DockerVM) GetVMName(ccid ccintf.CCID, format func(string) (string, error)) (string, error) { name := ccid.GetName() - // replace any invalid characters with "-" if ccid.NetworkID != "" && ccid.PeerID != "" { - name = vmRegExp.ReplaceAllString( - fmt.Sprintf("%s-%s-%s", ccid.NetworkID, ccid.PeerID, name), "-") + name = fmt.Sprintf("%s-%s-%s", ccid.NetworkID, ccid.PeerID, name) } else if ccid.NetworkID != "" { - name = vmRegExp.ReplaceAllString( - fmt.Sprintf("%s-%s", ccid.NetworkID, name), "-") + name = fmt.Sprintf("%s-%s", ccid.NetworkID, name) } else if ccid.PeerID != "" { - name = vmRegExp.ReplaceAllString( - fmt.Sprintf("%s-%s", ccid.PeerID, name), "-") + name = fmt.Sprintf("%s-%s", ccid.PeerID, name) } if format != nil { @@ -449,9 +445,13 @@ func (vm *DockerVM) GetVMName(ccid ccintf.CCID, format func(string) (string, err if err != nil { return formattedName, err } - // check to ensure format function didn't add any invalid characters - name = vmRegExp.ReplaceAllString(formattedName, "-") + name = formattedName } + + // replace any invalid characters with "-" (either in network id, peer id, or in the + // entire name returned by any format function) + name = vmRegExp.ReplaceAllString(name, "-") + return name, nil } @@ -461,7 +461,9 @@ func (vm *DockerVM) GetVMName(ccid ccintf.CCID, format func(string) (string, err // supplied image name and then appends it to the lowercase image name to ensure // uniqueness. func formatImageName(name string) (string, error) { - imageName := strings.ToLower(fmt.Sprintf("%s-%s", name, hex.EncodeToString(util.ComputeSHA256([]byte(name))))) + hash := hex.EncodeToString(util.ComputeSHA256([]byte(name))) + name = vmRegExp.ReplaceAllString(name, "-") + imageName := strings.ToLower(fmt.Sprintf("%s-%s", name, hash)) // Check that name complies with Docker's repository naming rules if !imageRegExp.MatchString(imageName) { diff --git a/core/container/dockercontroller/dockercontroller_test.go b/core/container/dockercontroller/dockercontroller_test.go index ddbd47cf0cb..9aca26c3c04 100644 --- a/core/container/dockercontroller/dockercontroller_test.go +++ b/core/container/dockercontroller/dockercontroller_test.go @@ -241,9 +241,10 @@ func TestGetVMName(t *testing.T) { tc = append(tc, testCase{"mycc", ccintf.CCID{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: &pb.ChaincodeID{Name: "mycc"}}, NetworkID: "dev", PeerID: "peer0", Version: "1.0"}, formatImageName, fmt.Sprintf("%s-%s", "dev-peer0-mycc-1.0", hex.EncodeToString(util.ComputeSHA256([]byte("dev-peer0-mycc-1.0"))))}, testCase{"mycc-nonetworkid", ccintf.CCID{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: &pb.ChaincodeID{Name: "mycc"}}, PeerID: "peer1", Version: "1.0"}, formatImageName, fmt.Sprintf("%s-%s", "peer1-mycc-1.0", hex.EncodeToString(util.ComputeSHA256([]byte("peer1-mycc-1.0"))))}, - testCase{"myCC", ccintf.CCID{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: &pb.ChaincodeID{Name: "myCC"}}, NetworkID: "Dev", PeerID: "Peer0", Version: "1.0"}, formatImageName, fmt.Sprintf("%s-%s", "dev-peer0-mycc-1.0", hex.EncodeToString(util.ComputeSHA256([]byte("Dev-Peer0-myCC-1.0"))))}, + testCase{"myCC-UCids", ccintf.CCID{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: &pb.ChaincodeID{Name: "myCC"}}, NetworkID: "Dev", PeerID: "Peer0", Version: "1.0"}, formatImageName, fmt.Sprintf("%s-%s", "dev-peer0-mycc-1.0", hex.EncodeToString(util.ComputeSHA256([]byte("Dev-Peer0-myCC-1.0"))))}, + testCase{"myCC-idsWithSpecialChars", ccintf.CCID{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: &pb.ChaincodeID{Name: "myCC"}}, NetworkID: "Dev$dev", PeerID: "Peer*0", Version: "1.0"}, formatImageName, fmt.Sprintf("%s-%s", "dev-dev-peer-0-mycc-1.0", hex.EncodeToString(util.ComputeSHA256([]byte("Dev$dev-Peer*0-myCC-1.0"))))}, testCase{"mycc-nopeerid", ccintf.CCID{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: &pb.ChaincodeID{Name: "mycc"}}, NetworkID: "dev", Version: "1.0"}, formatImageName, fmt.Sprintf("%s-%s", "dev-mycc-1.0", hex.EncodeToString(util.ComputeSHA256([]byte("dev-mycc-1.0"))))}, - testCase{"myCC", ccintf.CCID{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: &pb.ChaincodeID{Name: "myCC"}}, NetworkID: "dev", PeerID: "peer0", Version: "1.0"}, formatImageName, fmt.Sprintf("%s-%s", "dev-peer0-mycc-1.0", hex.EncodeToString(util.ComputeSHA256([]byte("dev-peer0-myCC-1.0"))))}, + testCase{"myCC-LCids", ccintf.CCID{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: &pb.ChaincodeID{Name: "myCC"}}, NetworkID: "dev", PeerID: "peer0", Version: "1.0"}, formatImageName, fmt.Sprintf("%s-%s", "dev-peer0-mycc-1.0", hex.EncodeToString(util.ComputeSHA256([]byte("dev-peer0-myCC-1.0"))))}, testCase{"myCC-preserveCase", ccintf.CCID{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: &pb.ChaincodeID{Name: "myCC"}}, NetworkID: "Dev", PeerID: "Peer0", Version: "1.0"}, nil, fmt.Sprintf("%s", "Dev-Peer0-myCC-1.0")}, testCase{"invalidCharsFormatFunction", ccintf.CCID{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: &pb.ChaincodeID{Name: "myCC"}}, NetworkID: "Dev", PeerID: "Peer0", Version: "1.0"}, formatInvalidChars, fmt.Sprintf("%s", "inv-lid-character--")}) @@ -255,10 +256,10 @@ func TestGetVMName(t *testing.T) { } -func TestFormatImageName_invalidChars(t *testing.T) { +/*func TestFormatImageName_invalidChars(t *testing.T) { _, err := formatImageName("invalid*chars") assert.NotNil(t, err, "Expected error") -} +}*/ func getCodeChainBytesInMem() io.Reader { startTime := time.Now()