github.com/guilhermebr/docker@v1.4.2-0.20150428121140-67da055cebca/runconfig/config.go (about) 1 package runconfig 2 3 import ( 4 "encoding/json" 5 "io" 6 7 "github.com/docker/docker/nat" 8 ) 9 10 // Entrypoint encapsulates the container entrypoint. 11 // It might be represented as a string or an array of strings. 12 // We need to override the json decoder to accept both options. 13 // The JSON decoder will fail if the api sends an string and 14 // we try to decode it into an array of string. 15 type Entrypoint struct { 16 parts []string 17 } 18 19 func (e *Entrypoint) MarshalJSON() ([]byte, error) { 20 if e == nil { 21 return []byte{}, nil 22 } 23 return json.Marshal(e.Slice()) 24 } 25 26 // UnmarshalJSON decoded the entrypoint whether it's a string or an array of strings. 27 func (e *Entrypoint) UnmarshalJSON(b []byte) error { 28 if len(b) == 0 { 29 return nil 30 } 31 32 p := make([]string, 0, 1) 33 if err := json.Unmarshal(b, &p); err != nil { 34 p = append(p, string(b)) 35 } 36 e.parts = p 37 return nil 38 } 39 40 func (e *Entrypoint) Len() int { 41 if e == nil { 42 return 0 43 } 44 return len(e.parts) 45 } 46 47 func (e *Entrypoint) Slice() []string { 48 if e == nil { 49 return nil 50 } 51 return e.parts 52 } 53 54 func NewEntrypoint(parts ...string) *Entrypoint { 55 return &Entrypoint{parts} 56 } 57 58 type Command struct { 59 parts []string 60 } 61 62 func (e *Command) MarshalJSON() ([]byte, error) { 63 if e == nil { 64 return []byte{}, nil 65 } 66 return json.Marshal(e.Slice()) 67 } 68 69 // UnmarshalJSON decoded the entrypoint whether it's a string or an array of strings. 70 func (e *Command) UnmarshalJSON(b []byte) error { 71 if len(b) == 0 { 72 return nil 73 } 74 75 p := make([]string, 0, 1) 76 if err := json.Unmarshal(b, &p); err != nil { 77 p = append(p, string(b)) 78 } 79 e.parts = p 80 return nil 81 } 82 83 func (e *Command) Len() int { 84 if e == nil { 85 return 0 86 } 87 return len(e.parts) 88 } 89 90 func (e *Command) Slice() []string { 91 if e == nil { 92 return nil 93 } 94 return e.parts 95 } 96 97 func NewCommand(parts ...string) *Command { 98 return &Command{parts} 99 } 100 101 // Note: the Config structure should hold only portable information about the container. 102 // Here, "portable" means "independent from the host we are running on". 103 // Non-portable information *should* appear in HostConfig. 104 type Config struct { 105 Hostname string 106 Domainname string 107 User string 108 AttachStdin bool 109 AttachStdout bool 110 AttachStderr bool 111 PortSpecs []string // Deprecated - Can be in the format of 8080/tcp 112 ExposedPorts map[nat.Port]struct{} 113 Tty bool // Attach standard streams to a tty, including stdin if it is not closed. 114 OpenStdin bool // Open stdin 115 StdinOnce bool // If true, close stdin after the 1 attached client disconnects. 116 Env []string 117 Cmd *Command 118 Image string // Name of the image as it was passed by the operator (eg. could be symbolic) 119 Volumes map[string]struct{} 120 WorkingDir string 121 Entrypoint *Entrypoint 122 NetworkDisabled bool 123 MacAddress string 124 OnBuild []string 125 Labels map[string]string 126 } 127 128 type ContainerConfigWrapper struct { 129 *Config 130 *hostConfigWrapper 131 } 132 133 func (c ContainerConfigWrapper) HostConfig() *HostConfig { 134 if c.hostConfigWrapper == nil { 135 return new(HostConfig) 136 } 137 138 return c.hostConfigWrapper.GetHostConfig() 139 } 140 141 func DecodeContainerConfig(src io.Reader) (*Config, *HostConfig, error) { 142 decoder := json.NewDecoder(src) 143 144 var w ContainerConfigWrapper 145 if err := decoder.Decode(&w); err != nil { 146 return nil, nil, err 147 } 148 149 return w.Config, w.HostConfig(), nil 150 }