github.com/ali-iotechsys/cli@v20.10.0+incompatible/cli/command/image/build_session.go (about) 1 package image 2 3 import ( 4 "context" 5 "crypto/rand" 6 "crypto/sha256" 7 "encoding/hex" 8 "fmt" 9 "io/ioutil" 10 "os" 11 "path/filepath" 12 13 "github.com/docker/cli/cli/command" 14 cliconfig "github.com/docker/cli/cli/config" 15 "github.com/docker/docker/api/types/versions" 16 "github.com/moby/buildkit/session" 17 "github.com/pkg/errors" 18 ) 19 20 const clientSessionRemote = "client-session" 21 22 func isSessionSupported(dockerCli command.Cli, forStream bool) bool { 23 if !forStream && versions.GreaterThanOrEqualTo(dockerCli.Client().ClientVersion(), "1.39") { 24 return true 25 } 26 return dockerCli.ServerInfo().HasExperimental && versions.GreaterThanOrEqualTo(dockerCli.Client().ClientVersion(), "1.31") 27 } 28 29 func trySession(dockerCli command.Cli, contextDir string, forStream bool) (*session.Session, error) { 30 if !isSessionSupported(dockerCli, forStream) { 31 return nil, nil 32 } 33 sharedKey := getBuildSharedKey(contextDir) 34 s, err := session.NewSession(context.Background(), filepath.Base(contextDir), sharedKey) 35 if err != nil { 36 return nil, errors.Wrap(err, "failed to create session") 37 } 38 return s, nil 39 } 40 41 func getBuildSharedKey(dir string) string { 42 // build session is hash of build dir with node based randomness 43 s := sha256.Sum256([]byte(fmt.Sprintf("%s:%s", tryNodeIdentifier(), dir))) 44 return hex.EncodeToString(s[:]) 45 } 46 47 func tryNodeIdentifier() string { 48 out := cliconfig.Dir() // return config dir as default on permission error 49 if err := os.MkdirAll(cliconfig.Dir(), 0700); err == nil { 50 sessionFile := filepath.Join(cliconfig.Dir(), ".buildNodeID") 51 if _, err := os.Lstat(sessionFile); err != nil { 52 if os.IsNotExist(err) { // create a new file with stored randomness 53 b := make([]byte, 32) 54 if _, err := rand.Read(b); err != nil { 55 return out 56 } 57 if err := ioutil.WriteFile(sessionFile, []byte(hex.EncodeToString(b)), 0600); err != nil { 58 return out 59 } 60 } 61 } 62 63 dt, err := ioutil.ReadFile(sessionFile) 64 if err == nil { 65 return string(dt) 66 } 67 } 68 return out 69 }