[proxy] all request modification is done through map[string]interface{}

That way we are less likely fall victim to go-dockerclient, or the API changing.
This commit is contained in:
Paul Bellamy committed 2015-10-12 15:53:07 +01:00
1 parent d323de3c21
commit fbb2c213a9
9 files changed
+298 -78

No files matched your search

+98 -40
View File
@@ -17,12 +17,6 @@ var (
type createContainerInterceptor struct{ proxy *Proxy }
type createContainerRequestBody struct {
*docker.Config
HostConfig *docker.HostConfig `json:"HostConfig,omitempty" yaml:"HostConfig,omitempty"`
MacAddress string `json:"MacAddress,omitempty" yaml:"MacAddress,omitempty"`
}
// ErrNoSuchImage replaces docker.NoSuchImage, which does not contain the image
// name, which in turn breaks docker clients post 1.7.0 since they expect the
// image name to be present in errors.
@@ -35,35 +29,45 @@ func (err *ErrNoSuchImage) Error() string {
}
func (i *createContainerInterceptor) InterceptRequest(r *http.Request) error {
container := createContainerRequestBody{}
container := jsonObject{}
if err := unmarshalRequestBody(r, &container); err != nil {
return err
}
if cidrs, err := i.proxy.weaveCIDRsFromConfig(container.Config, container.HostConfig); err != nil {
hostConfig, err := container.Object("HostConfig")
if err != nil {
return err
}
networkMode, err := hostConfig.String("NetworkMode")
if err != nil {
return err
}
env, err := container.StringArray("Env")
if err != nil {
return err
}
if cidrs, err := i.proxy.weaveCIDRs(networkMode, env); err != nil {
Log.Infof("Leaving container alone because %s", err)
} else {
Log.Infof("Creating container with WEAVE_CIDR \"%s\"", strings.Join(cidrs, " "))
if container.HostConfig == nil {
container.HostConfig = &docker.HostConfig{}
}
if container.Config == nil {
container.Config = &docker.Config{}
}
i.proxy.addWeaveWaitVolume(container.HostConfig)
if err := i.setWeaveWaitEntrypoint(container.Config); err != nil {
if err := i.proxy.addWeaveWaitVolume(hostConfig); err != nil {
return err
}
hostname := r.URL.Query().Get("name")
if i.proxy.Config.HostnameFromLabel != "" {
if labelValue, ok := container.Labels[i.proxy.Config.HostnameFromLabel]; ok {
hostname = labelValue
}
if err := i.setWeaveWaitEntrypoint(container); err != nil {
return err
}
hostname, err := i.containerHostname(r, container)
if err != nil {
return err
}
hostname = i.proxy.hostnameMatchRegexp.ReplaceAllString(hostname, i.proxy.HostnameReplacement)
if dnsDomain := i.proxy.getDNSDomain(); dnsDomain != "" {
i.setHostname(&container, hostname, dnsDomain)
if err := i.proxy.setWeaveDNS(container.HostConfig, container.Hostname, dnsDomain); err != nil {
if err := i.setHostname(container, hostname, dnsDomain); err != nil {
return err
}
if err := i.proxy.setWeaveDNS(hostConfig, hostname, dnsDomain); err != nil {
return err
}
}
@@ -74,50 +78,104 @@ func (i *createContainerInterceptor) InterceptRequest(r *http.Request) error {
return nil
}
func (i *createContainerInterceptor) setWeaveWaitEntrypoint(container *docker.Config) error {
if len(container.Entrypoint) == 0 {
image, err := i.proxy.client.InspectImage(container.Image)
func (i *createContainerInterceptor) setWeaveWaitEntrypoint(container jsonObject) error {
var entrypoint []string
entrypoint, err := container.StringArray("Entrypoint")
if err != nil {
err, ok := err.(*UnmarshalWrongTypeError)
if !ok {
return err
}
got, ok := err.Got.(string)
if !ok {
return err
}
entrypoint = []string{got}
}
cmd, err := container.StringArray("Cmd")
if err != nil {
return err
}
if len(entrypoint) == 0 {
containerImage, err := container.String("Image")
if err != nil {
return err
}
image, err := i.proxy.client.InspectImage(containerImage)
if err == docker.ErrNoSuchImage {
return &ErrNoSuchImage{container.Image}
return &ErrNoSuchImage{containerImage}
} else if err != nil {
return err
}
if len(container.Cmd) == 0 {
container.Cmd = image.Config.Cmd
if len(cmd) == 0 {
cmd = image.Config.Cmd
container["Cmd"] = cmd
}
if container.Entrypoint == nil {
container.Entrypoint = image.Config.Entrypoint
if entrypoint == nil {
entrypoint = image.Config.Entrypoint
container["Entrypoint"] = entrypoint
}
}
if len(container.Entrypoint) == 0 && len(container.Cmd) == 0 {
if len(entrypoint) == 0 && len(cmd) == 0 {
return ErrNoCommandSpecified
}
if len(container.Entrypoint) == 0 || container.Entrypoint[0] != weaveWaitEntrypoint[0] {
container.Entrypoint = append(weaveWaitEntrypoint, container.Entrypoint...)
if len(entrypoint) == 0 || entrypoint[0] != weaveWaitEntrypoint[0] {
container["Entrypoint"] = append(weaveWaitEntrypoint, entrypoint...)
}
return nil
}
func (i *createContainerInterceptor) setHostname(container *createContainerRequestBody, name, dnsDomain string) {
if container.Hostname == "" && name != "" {
func (i *createContainerInterceptor) setHostname(container jsonObject, name, dnsDomain string) error {
hostname, err := container.String("Hostname")
if err != nil {
return err
}
if hostname == "" && name != "" {
// Strip trailing period because it's unusual to see it used on the end of a host name
trimmedDNSDomain := strings.TrimSuffix(dnsDomain, ".")
if len(name)+1+len(trimmedDNSDomain) > MaxDockerHostname {
Log.Warningf("Container name [%s] too long to be used as hostname", name)
} else {
container.Hostname = name
container.Domainname = trimmedDNSDomain
hostname = name
container["Hostname"] = name
container["Domainname"] = trimmedDNSDomain
}
}
return
return nil
}
func (i *createContainerInterceptor) InterceptResponse(r *http.Response) error {
return nil
}
func (i *createContainerInterceptor) containerHostname(r *http.Request, container jsonObject) (hostname string, err error) {
hostname = r.URL.Query().Get("name")
if i.proxy.Config.HostnameFromLabel != "" {
hostname, err = i.hostnameFromLabel(hostname, container)
}
hostname = i.proxy.hostnameMatchRegexp.ReplaceAllString(hostname, i.proxy.HostnameReplacement)
return
}
func (i *createContainerInterceptor) hostnameFromLabel(hostname string, container jsonObject) (string, error) {
label, err := container.String("Labels", i.proxy.Config.HostnameFromLabel)
if err != nil {
return "", err
}
if label == "" {
return hostname, nil
}
return label, nil
}