2015-10-08 3 views

ответ

4

Вот фрагмент кода из функции Docker демона для создания контейнеров:

func (daemon *Daemon) newContainer(name string, config *runconfig.Config, imgID string) (*Container, error) { 
    var (
     id string 
     err error 
    ) 
    id, name, err = daemon.generateIDAndName(name) 
    if err != nil { 
     return nil, err 
    } 

    … 

    base := daemon.newBaseContainer(id) 

    … 

    base.ExecDriver = daemon.execDriver.Name() 

    return &base, err 
} 

Таким образом, логика создания идентификатора и имени в функции generateIDAndName:

func (daemon *Daemon) generateIDAndName(name string) (string, string, error) { 
    var (
     err error 
     id = stringid.GenerateNonCryptoID() 
    ) 

    if name == "" { 
     if name, err = daemon.generateNewName(id); err != nil { 
      return "", "", err 
     } 
     return id, name, nil 
    } 

    if name, err = daemon.reserveName(id, name); err != nil { 
     return "", "", err 
    } 

    return id, name, nil 
} 

Вот stringid sources и конкретный метод генерируетID с ложным в качестве входного параметра:

func generateID(crypto bool) string { 
    b := make([]byte, 32) 
    var r io.Reader = random.Reader 
    if crypto { 
     r = rand.Reader 
    } 
    for { 
     if _, err := io.ReadFull(r, b); err != nil { 
      panic(err) // This shouldn't happen 
     } 
     id := hex.EncodeToString(b) 
     // if we try to parse the truncated for as an int and we don't have 
     // an error then the value is all numberic and causes issues when 
     // used as a hostname. ref #3869 
     if _, err := strconv.ParseInt(TruncateID(id), 10, 64); err == nil { 
      continue 
     } 
     return id 
    } 
} 

Как вы можете видеть, это значение генерируется случайным образом random

// Reader is a global, shared instance of a pseudorandom bytes generator. 
// It doesn't consume entropy. 
var Reader io.Reader = &reader{rnd: Rand}