github.com/SophiaGitHub/hello@v1.7.1-rc3/runconfig/config.go (about)

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