[proxy] Override sneaky /start HostConfig params
This commit is contained in:
1 parent
846aa98a9c
commit
74c3b0d079
5 files changed
+103
-70
No files matched your search
@@ -50,6 +50,10 @@ func unmarshalRequestBody(r *http.Request, target interface{}) error {
|
||||
}
|
||||
r.Body = ioutil.NopCloser(bytes.NewReader(body))
|
||||
|
||||
if len(body) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
d := json.NewDecoder(bytes.NewReader(body))
|
||||
d.UseNumber() // don't want large numbers in scientific format
|
||||
return d.Decode(&target)
|
||||
@@ -62,6 +66,7 @@ func marshalRequestBody(r *http.Request, body interface{}) error {
|
||||
}
|
||||
r.Body = ioutil.NopCloser(bytes.NewReader(newBody))
|
||||
r.ContentLength = int64(len(newBody))
|
||||
r.Header.Set("Content-Type", "application/json")
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -2,16 +2,11 @@ package proxy
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/fsouza/go-dockerclient"
|
||||
|
||||
. "github.com/weaveworks/weave/common"
|
||||
"github.com/weaveworks/weave/nameserver"
|
||||
"github.com/weaveworks/weave/router"
|
||||
)
|
||||
|
||||
const MaxDockerHostname = 64
|
||||
@@ -55,7 +50,7 @@ func (i *createContainerInterceptor) InterceptRequest(r *http.Request) error {
|
||||
if container.Config == nil {
|
||||
container.Config = &docker.Config{}
|
||||
}
|
||||
i.addWeaveWaitVolume(container.HostConfig)
|
||||
i.proxy.addWeaveWaitVolume(container.HostConfig)
|
||||
if err := i.setWeaveWaitEntrypoint(container.Config); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -66,8 +61,11 @@ func (i *createContainerInterceptor) InterceptRequest(r *http.Request) error {
|
||||
}
|
||||
}
|
||||
hostname = i.proxy.hostnameMatchRegexp.ReplaceAllString(hostname, i.proxy.HostnameReplacement)
|
||||
if err := i.setWeaveDNS(&container, hostname); err != nil {
|
||||
return err
|
||||
if dnsDomain, withDNS := i.proxy.getDNSDomain(); withDNS {
|
||||
i.setHostname(&container, hostname, dnsDomain)
|
||||
if err := i.proxy.setWeaveDNS(container.HostConfig, container.Hostname, dnsDomain); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return marshalRequestBody(r, container)
|
||||
@@ -76,18 +74,6 @@ func (i *createContainerInterceptor) InterceptRequest(r *http.Request) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *createContainerInterceptor) addWeaveWaitVolume(hostConfig *docker.HostConfig) {
|
||||
var binds []string
|
||||
for _, bind := range hostConfig.Binds {
|
||||
s := strings.Split(bind, ":")
|
||||
if len(s) >= 2 && s[1] == "/w" {
|
||||
continue
|
||||
}
|
||||
binds = append(binds, bind)
|
||||
}
|
||||
hostConfig.Binds = append(binds, fmt.Sprintf("%s:/w:ro", i.proxy.weaveWaitVolume))
|
||||
}
|
||||
|
||||
func (i *createContainerInterceptor) setWeaveWaitEntrypoint(container *docker.Config) error {
|
||||
if len(container.Entrypoint) == 0 {
|
||||
image, err := i.proxy.client.InspectImage(container.Image)
|
||||
@@ -117,18 +103,7 @@ func (i *createContainerInterceptor) setWeaveWaitEntrypoint(container *docker.Co
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *createContainerInterceptor) setWeaveDNS(container *createContainerRequestBody, name string) error {
|
||||
if i.proxy.WithoutDNS {
|
||||
return nil
|
||||
}
|
||||
|
||||
dnsDomain, dnsRunning := i.getDNSDomain()
|
||||
if !(dnsRunning || i.proxy.WithDNS) {
|
||||
return nil
|
||||
}
|
||||
|
||||
container.HostConfig.DNS = append(container.HostConfig.DNS, i.proxy.dockerBridgeIP)
|
||||
|
||||
func (i *createContainerInterceptor) setHostname(container *createContainerRequestBody, name, dnsDomain string) {
|
||||
if container.Hostname == "" && name != "" {
|
||||
// Strip trailing period because it's unusual to see it used on the end of a host name
|
||||
trimmedDNSDomain := strings.TrimSuffix(dnsDomain, ".")
|
||||
@@ -140,39 +115,7 @@ func (i *createContainerInterceptor) setWeaveDNS(container *createContainerReque
|
||||
}
|
||||
}
|
||||
|
||||
if len(container.HostConfig.DNSSearch) == 0 {
|
||||
if container.Hostname == "" {
|
||||
container.HostConfig.DNSSearch = []string{dnsDomain}
|
||||
} else {
|
||||
container.HostConfig.DNSSearch = []string{"."}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *createContainerInterceptor) getDNSDomain() (domain string, running bool) {
|
||||
domain = nameserver.DefaultDomain
|
||||
weaveContainer, err := i.proxy.client.InspectContainer("weave")
|
||||
if err != nil ||
|
||||
weaveContainer.NetworkSettings == nil ||
|
||||
weaveContainer.NetworkSettings.IPAddress == "" {
|
||||
return
|
||||
}
|
||||
|
||||
url := fmt.Sprintf("http://%s:%d/domain", weaveContainer.NetworkSettings.IPAddress, router.HTTPPort)
|
||||
resp, err := http.Get(url)
|
||||
if err != nil || resp.StatusCode != http.StatusOK {
|
||||
return
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
b, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return string(b), true
|
||||
return
|
||||
}
|
||||
|
||||
func (i *createContainerInterceptor) InterceptResponse(r *http.Response) error {
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
@@ -15,6 +16,8 @@ import (
|
||||
docker "github.com/fsouza/go-dockerclient"
|
||||
. "github.com/weaveworks/weave/common"
|
||||
weavedocker "github.com/weaveworks/weave/common/docker"
|
||||
"github.com/weaveworks/weave/nameserver"
|
||||
"github.com/weaveworks/weave/router"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -365,3 +368,54 @@ func (proxy *Proxy) weaveCIDRsFromConfig(config *docker.Config, hostConfig *dock
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (proxy *Proxy) addWeaveWaitVolume(hostConfig *docker.HostConfig) {
|
||||
var binds []string
|
||||
for _, bind := range hostConfig.Binds {
|
||||
s := strings.Split(bind, ":")
|
||||
if len(s) >= 2 && s[1] == "/w" {
|
||||
continue
|
||||
}
|
||||
binds = append(binds, bind)
|
||||
}
|
||||
hostConfig.Binds = append(binds, fmt.Sprintf("%s:/w:ro", proxy.weaveWaitVolume))
|
||||
}
|
||||
|
||||
func (proxy *Proxy) setWeaveDNS(hostConfig *docker.HostConfig, hostname, dnsDomain string) error {
|
||||
hostConfig.DNS = append(hostConfig.DNS, proxy.dockerBridgeIP)
|
||||
|
||||
if len(hostConfig.DNSSearch) == 0 {
|
||||
if hostname == "" {
|
||||
hostConfig.DNSSearch = []string{dnsDomain}
|
||||
} else {
|
||||
hostConfig.DNSSearch = []string{"."}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (proxy *Proxy) getDNSDomain() (domain string, running bool) {
|
||||
domain = nameserver.DefaultDomain
|
||||
running = proxy.WithDNS
|
||||
weaveContainer, err := proxy.client.InspectContainer("weave")
|
||||
if err != nil ||
|
||||
weaveContainer.NetworkSettings == nil ||
|
||||
weaveContainer.NetworkSettings.IPAddress == "" {
|
||||
return
|
||||
}
|
||||
|
||||
url := fmt.Sprintf("http://%s:%d/domain", weaveContainer.NetworkSettings.IPAddress, router.HTTPPort)
|
||||
resp, err := http.Get(url)
|
||||
if err != nil || resp.StatusCode != http.StatusOK {
|
||||
return
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
b, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return string(b), true
|
||||
}
|
||||
@@ -2,16 +2,41 @@ package proxy
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/fsouza/go-dockerclient"
|
||||
)
|
||||
|
||||
type startContainerInterceptor struct{ proxy *Proxy }
|
||||
|
||||
type startContainerRequestBody struct {
|
||||
HostConfig *docker.HostConfig `json:"HostConfig,omitempty" yaml:"HostConfig,omitempty"`
|
||||
}
|
||||
|
||||
func (i *startContainerInterceptor) InterceptRequest(r *http.Request) error {
|
||||
container, err := inspectContainerInPath(i.proxy.client, r.URL.Path)
|
||||
if err == nil && containerShouldAttach(container) {
|
||||
i.proxy.createWait(r, container.ID)
|
||||
if err != nil || !containerShouldAttach(container) {
|
||||
return err
|
||||
}
|
||||
return err
|
||||
|
||||
if r.Header.Get("Content-Type") != "application/json" {
|
||||
i.proxy.createWait(r, container.ID)
|
||||
return nil
|
||||
}
|
||||
|
||||
hostConfig := &docker.HostConfig{}
|
||||
if err := unmarshalRequestBody(r, &hostConfig); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
i.proxy.addWeaveWaitVolume(hostConfig)
|
||||
if dnsDomain, withDNS := i.proxy.getDNSDomain(); withDNS {
|
||||
if err := i.proxy.setWeaveDNS(hostConfig, container.Config.Hostname, dnsDomain); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
i.proxy.createWait(r, container.ID)
|
||||
return marshalRequestBody(r, hostConfig)
|
||||
}
|
||||
|
||||
func (i *startContainerInterceptor) InterceptResponse(r *http.Response) error {
|
||||
|
||||
@@ -9,7 +9,13 @@ weave_on $HOST1 launch
|
||||
proxy_start_container $HOST1 --name=c1
|
||||
proxy docker_on $HOST1 create --name=c2 $SMALL_IMAGE grep "^1$" /sys/class/net/ethwe/carrier
|
||||
# Now start c2 with a sneaky HostConfig
|
||||
curl -X POST -H Content-Type:application/json -d '{"HostConfig": {"NetworkMode": "container:c1"}}' http://$HOST1:12375/containers/c2/start
|
||||
assert "docker_on $HOST1 inspect -f '{{.State.Running}} {{.State.ExitCode}}' c2" "false 0"
|
||||
curl -X POST -H Content-Type:application/json -d '{"NetworkMode": "container:c1"}' http://$HOST1:12375/v1.20/containers/c2/start
|
||||
docker_bridge_ip=$(weave_on $HOST1 docker-bridge-ip)
|
||||
assert "docker_on $HOST1 inspect -f '{{.State.Running}} {{.State.ExitCode}} {{.HostConfig.Dns}}' c2" "false 0 [$docker_bridge_ip]"
|
||||
|
||||
# Now start c3 with a mostly null HostConfig
|
||||
proxy docker_on $HOST1 create --name=c3 -v /tmp:/hosttmp $SMALL_IMAGE grep "^1$" /sys/class/net/ethwe/carrier
|
||||
curl -X POST -H Content-Type:application/json -d '{"Binds":[],"ContainerIDFile":"","LxcConf":null,"Memory":0,"MemorySwap":0,"CpuShares":0,"CpuPeriod":0,"CpusetCpus":"","CpusetMems":"","CpuQuota":0,"BlkioWeight":0,"OomKillDisable":false,"Privileged":false,"PortBindings":null,"Links":[],"PublishAllPorts":false,"Dns":null,"DnsSearch":null,"ExtraHosts":null,"VolumesFrom":null,"Devices":null,"NetworkMode":"","IpcMode":"","PidMode":"","UTSMode":"","CapAdd":null,"CapDrop":null,"RestartPolicy":{"Name":"","MaximumRetryCount":0},"SecurityOpt":null,"ReadonlyRootfs":false,"Ulimits":null,"LogConfig":{"type":"","config":null},"CgroupParent":""}' http://$HOST1:12375/v1.20/containers/c3/start
|
||||
assert "docker_on $HOST1 inspect -f '{{.State.Running}} {{.State.ExitCode}} {{.HostConfig.Dns}} {{index .HostConfig.Binds 0}}' c3" "false 0 [$docker_bridge_ip] /tmp:/hosttmp"
|
||||
|
||||
end_suite
|
||||
Reference in new issue
Block a user