@@ -18,6 +18,7 @@ package dockercontroller
18
18
19
19
import (
20
20
"bytes"
21
+ "encoding/hex"
21
22
"fmt"
22
23
"io"
23
24
"strings"
@@ -29,6 +30,7 @@ import (
29
30
30
31
"github.com/fsouza/go-dockerclient"
31
32
"github.com/hyperledger/fabric/common/flogging"
33
+ "github.com/hyperledger/fabric/common/util"
32
34
container "github.com/hyperledger/fabric/core/container/api"
33
35
"github.com/hyperledger/fabric/core/container/ccintf"
34
36
cutil "github.com/hyperledger/fabric/core/container/util"
@@ -40,6 +42,8 @@ import (
40
42
var (
41
43
dockerLogger = flogging .MustGetLogger ("dockercontroller" )
42
44
hostConfig * docker.HostConfig
45
+ vmRegExp = regexp .MustCompile ("[^a-zA-Z0-9-_.]" )
46
+ imageRegExp = regexp .MustCompile ("^[a-z0-9]+(([._-][a-z0-9]+)+)?$" )
43
47
)
44
48
45
49
// getClient returns an instance that implements dockerClient interface
@@ -163,7 +167,7 @@ func (vm *DockerVM) createContainer(ctxt context.Context, client dockerClient,
163
167
164
168
func (vm * DockerVM ) deployImage (client dockerClient , ccid ccintf.CCID ,
165
169
args []string , env []string , reader io.Reader ) error {
166
- id , err := vm .GetVMName (ccid )
170
+ id , err := vm .GetVMName (ccid , formatImageName )
167
171
if err != nil {
168
172
return err
169
173
}
@@ -208,7 +212,7 @@ func (vm *DockerVM) Deploy(ctxt context.Context, ccid ccintf.CCID,
208
212
//Start starts a container using a previously created docker image
209
213
func (vm * DockerVM ) Start (ctxt context.Context , ccid ccintf.CCID ,
210
214
args []string , env []string , builder container.BuildSpecFactory , prelaunchFunc container.PrelaunchFunc ) error {
211
- imageID , err := vm .GetVMName (ccid )
215
+ imageID , err := vm .GetVMName (ccid , formatImageName )
212
216
if err != nil {
213
217
return err
214
218
}
@@ -219,7 +223,11 @@ func (vm *DockerVM) Start(ctxt context.Context, ccid ccintf.CCID,
219
223
return err
220
224
}
221
225
222
- containerID := strings .Replace (imageID , ":" , "_" , - 1 )
226
+ containerID , err := vm .GetVMName (ccid , nil )
227
+ if err != nil {
228
+ return err
229
+ }
230
+
223
231
attachStdout := viper .GetBool ("vm.docker.attachStdout" )
224
232
225
233
//stop,force remove if necessary
@@ -349,7 +357,7 @@ func (vm *DockerVM) Start(ctxt context.Context, ccid ccintf.CCID,
349
357
350
358
//Stop stops a running chaincode
351
359
func (vm * DockerVM ) Stop (ctxt context.Context , ccid ccintf.CCID , timeout uint , dontkill bool , dontremove bool ) error {
352
- id , err := vm .GetVMName (ccid )
360
+ id , err := vm .GetVMName (ccid , nil )
353
361
if err != nil {
354
362
return err
355
363
}
@@ -395,7 +403,7 @@ func (vm *DockerVM) stopInternal(ctxt context.Context, client dockerClient,
395
403
396
404
//Destroy destroys an image
397
405
func (vm * DockerVM ) Destroy (ctxt context.Context , ccid ccintf.CCID , force bool , noprune bool ) error {
398
- id , err := vm .GetVMName (ccid )
406
+ id , err := vm .GetVMName (ccid , formatImageName )
399
407
if err != nil {
400
408
return err
401
409
}
@@ -418,34 +426,48 @@ func (vm *DockerVM) Destroy(ctxt context.Context, ccid ccintf.CCID, force bool,
418
426
return err
419
427
}
420
428
421
- //GetVMName generates the docker image from peer information given the hashcode. This is needed to
422
- //keep image name's unique in a single host, multi-peer environment (such as a development environment)
423
- func (vm * DockerVM ) GetVMName (ccid ccintf.CCID ) (string , error ) {
429
+ // GetVMName generates the VM name from peer information. It accepts a format
430
+ // function parameter to allow different formatting based on the desired use of
431
+ // the name.
432
+ func (vm * DockerVM ) GetVMName (ccid ccintf.CCID , format func (string ) (string , error )) (string , error ) {
424
433
name := ccid .GetName ()
425
434
426
- //Convert to lowercase and replace any invalid characters with "-"
427
- r := regexp .MustCompile ("[^a-zA-Z0-9-_.]" )
428
-
435
+ // replace any invalid characters with "-"
429
436
if ccid .NetworkID != "" && ccid .PeerID != "" {
430
- name = strings .ToLower (
431
- r .ReplaceAllString (
432
- fmt .Sprintf ("%s-%s-%s" , ccid .NetworkID , ccid .PeerID , name ), "-" ))
437
+ name = vmRegExp .ReplaceAllString (
438
+ fmt .Sprintf ("%s-%s-%s" , ccid .NetworkID , ccid .PeerID , name ), "-" )
433
439
} else if ccid .NetworkID != "" {
434
- name = strings .ToLower (
435
- r .ReplaceAllString (
436
- fmt .Sprintf ("%s-%s" , ccid .NetworkID , name ), "-" ))
440
+ name = vmRegExp .ReplaceAllString (
441
+ fmt .Sprintf ("%s-%s" , ccid .NetworkID , name ), "-" )
437
442
} else if ccid .PeerID != "" {
438
- name = strings .ToLower (
439
- r .ReplaceAllString (
440
- fmt .Sprintf ("%s-%s" , ccid .PeerID , name ), "-" ))
443
+ name = vmRegExp .ReplaceAllString (
444
+ fmt .Sprintf ("%s-%s" , ccid .PeerID , name ), "-" )
441
445
}
442
446
443
- // Check name complies with Docker's repository naming rules
444
- r = regexp .MustCompile ("^[a-z0-9]+(([._-][a-z0-9]+)+)?$" )
447
+ if format != nil {
448
+ formattedName , err := format (name )
449
+ if err != nil {
450
+ return formattedName , err
451
+ }
452
+ // check to ensure format function didn't add any invalid characters
453
+ name = vmRegExp .ReplaceAllString (formattedName , "-" )
454
+ }
455
+ return name , nil
456
+ }
445
457
446
- if ! r .MatchString (name ) {
458
+ // formatImageName formats the docker image from peer information. This is
459
+ // needed to keep image (repository) names unique in a single host, multi-peer
460
+ // environment (such as a development environment). It computes the hash for the
461
+ // supplied image name and then appends it to the lowercase image name to ensure
462
+ // uniqueness.
463
+ func formatImageName (name string ) (string , error ) {
464
+ imageName := strings .ToLower (fmt .Sprintf ("%s-%s" , name , hex .EncodeToString (util .ComputeSHA256 ([]byte (name )))))
465
+
466
+ // Check that name complies with Docker's repository naming rules
467
+ if ! imageRegExp .MatchString (imageName ) {
447
468
dockerLogger .Errorf ("Error constructing Docker VM Name. '%s' breaks Docker's repository naming rules" , name )
448
- return name , fmt .Errorf ("Error constructing Docker VM Name. '%s' breaks Docker's repository naming rules" , name )
469
+ return imageName , fmt .Errorf ("Error constructing Docker VM Name. '%s' breaks Docker's repository naming rules" , imageName )
449
470
}
450
- return name , nil
471
+
472
+ return imageName , nil
451
473
}
0 commit comments