proxy needs to add weavewait to execs as well
Bug came up in a test where we are restarting and doing an exec checking a network interface right away. weavewait is only added if the container has a WEAVE_CIDR var set, the same as at container creation.
This commit is contained in:
1 parent
70b595c4a2
commit
e6b587ea8d
7 files changed
+106
-18
No files matched your search
@@ -1,13 +1,24 @@
|
||||
package proxy
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os/exec"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/fsouza/go-dockerclient"
|
||||
. "github.com/weaveworks/weave/common"
|
||||
)
|
||||
|
||||
var (
|
||||
containerIDRegexp = regexp.MustCompile("^/v[0-9\\.]*/containers/([^/]*)/.*")
|
||||
weaveWaitEntrypoint = []string{"/home/weavewait/weavewait"}
|
||||
)
|
||||
|
||||
func callWeave(args ...string) ([]byte, error) {
|
||||
args = append([]string{"--local"}, args...)
|
||||
Debug.Print("Calling weave", args)
|
||||
@@ -26,3 +37,29 @@ func weaveCIDRsFromConfig(config *docker.Config) ([]string, bool) {
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func marshalRequestBody(r *http.Request, body interface{}) error {
|
||||
newBody, err := json.Marshal(body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
r.Body = ioutil.NopCloser(bytes.NewReader(newBody))
|
||||
r.ContentLength = int64(len(newBody))
|
||||
return nil
|
||||
}
|
||||
|
||||
func inspectContainerInPath(client *docker.Client, path string) (*docker.Container, error) {
|
||||
subs := containerIDRegexp.FindStringSubmatch(path)
|
||||
if subs == nil {
|
||||
err := fmt.Errorf("No container id found in request with path %s", path)
|
||||
Warning.Println(err)
|
||||
return nil, err
|
||||
}
|
||||
containerID := subs[1]
|
||||
|
||||
container, err := client.InspectContainer(containerID)
|
||||
if err != nil {
|
||||
Warning.Printf("Error inspecting container %s: %v", containerID, err)
|
||||
}
|
||||
return container, err
|
||||
}
|
||||
@@ -75,7 +75,7 @@ func (i *createContainerInterceptor) setWeaveWaitEntrypoint(container *docker.Co
|
||||
command = image.Cmd
|
||||
}
|
||||
|
||||
container.Entrypoint = []string{"/home/weavewait/weavewait"}
|
||||
container.Entrypoint = weaveWaitEntrypoint
|
||||
container.Cmd = append(entry, command...)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
package proxy
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
|
||||
"github.com/fsouza/go-dockerclient"
|
||||
)
|
||||
|
||||
type createExecInterceptor struct {
|
||||
client *docker.Client
|
||||
}
|
||||
|
||||
type createExecRequestBody struct {
|
||||
*docker.Config
|
||||
HostConfig *docker.HostConfig `json:"HostConfig,omitempty" yaml:"HostConfig,omitempty"`
|
||||
MacAddress string `json:"MacAddress,omitempty" yaml:"MacAddress,omitempty"`
|
||||
}
|
||||
|
||||
func (i *createExecInterceptor) InterceptRequest(r *http.Request) error {
|
||||
body, err := ioutil.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
r.Body.Close()
|
||||
|
||||
options := docker.CreateExecOptions{}
|
||||
if err := json.Unmarshal(body, &options); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
container, err := inspectContainerInPath(i.client, r.URL.Path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, ok := weaveCIDRsFromConfig(container.Config); ok {
|
||||
options.Cmd = append(weaveWaitEntrypoint, options.Cmd...)
|
||||
}
|
||||
|
||||
if err := marshalRequestBody(r, options); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *createExecInterceptor) InterceptResponse(r *http.Response) error {
|
||||
return nil
|
||||
}
|
||||
@@ -14,6 +14,7 @@ import (
|
||||
var (
|
||||
containerCreateRegexp = regexp.MustCompile("/v[0-9\\.]*/containers/create")
|
||||
containerStartRegexp = regexp.MustCompile("^/v[0-9\\.]*/containers/[^/]*/(re)?start$")
|
||||
execCreateRegexp = regexp.MustCompile("^/v[0-9\\.]*/containers/[^/]*/exec$")
|
||||
)
|
||||
|
||||
type Proxy struct {
|
||||
@@ -68,6 +69,8 @@ func (proxy *Proxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
proxy.serveWithInterceptor(&createContainerInterceptor{proxy.client, proxy.withDNS, proxy.dockerBridgeIP}, w, r)
|
||||
case containerStartRegexp.MatchString(path):
|
||||
proxy.serveWithInterceptor(&startContainerInterceptor{proxy.client, proxy.withDNS}, w, r)
|
||||
case execCreateRegexp.MatchString(path):
|
||||
proxy.serveWithInterceptor(&createExecInterceptor{proxy.client}, w, r)
|
||||
case strings.HasPrefix(path, "/weave"):
|
||||
w.WriteHeader(http.StatusOK)
|
||||
default:
|
||||
|
||||
@@ -2,15 +2,12 @@ package proxy
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/fsouza/go-dockerclient"
|
||||
. "github.com/weaveworks/weave/common"
|
||||
)
|
||||
|
||||
var containerIDRegexp = regexp.MustCompile("^/v[0-9\\.]*/containers/([^/]*)/.*")
|
||||
|
||||
type startContainerInterceptor struct {
|
||||
client *docker.Client
|
||||
withDNS bool
|
||||
@@ -21,17 +18,9 @@ func (i *startContainerInterceptor) InterceptRequest(r *http.Request) error {
|
||||
}
|
||||
|
||||
func (i *startContainerInterceptor) InterceptResponse(r *http.Response) error {
|
||||
subs := containerIDRegexp.FindStringSubmatch(r.Request.URL.Path)
|
||||
if subs == nil {
|
||||
Warning.Printf("No container id found in request with path %s", r.Request.URL.Path)
|
||||
return nil
|
||||
}
|
||||
containerID := subs[1]
|
||||
|
||||
container, err := i.client.InspectContainer(containerID)
|
||||
container, err := inspectContainerInPath(i.client, r.Request.URL.Path)
|
||||
if err != nil {
|
||||
Warning.Printf("Error inspecting container %s: %v", containerID, err)
|
||||
return nil
|
||||
return err
|
||||
}
|
||||
|
||||
cidrs, ok := weaveCIDRsFromConfig(container.Config)
|
||||
@@ -39,12 +28,12 @@ func (i *startContainerInterceptor) InterceptResponse(r *http.Response) error {
|
||||
Debug.Print("No Weave CIDR, ignoring")
|
||||
return nil
|
||||
}
|
||||
Info.Printf("Container %s was started with CIDR \"%s\"", containerID, strings.Join(cidrs, " "))
|
||||
Info.Printf("Container %s was started with CIDR \"%s\"", container.ID, strings.Join(cidrs, " "))
|
||||
args := []string{"attach"}
|
||||
args = append(args, cidrs...)
|
||||
args = append(args, containerID)
|
||||
args = append(args, container.ID)
|
||||
if _, err := callWeave(args...); err != nil {
|
||||
Warning.Printf("Attaching container %s to weave failed: %v", containerID, err)
|
||||
Warning.Printf("Attaching container %s to weave failed: %v", container.ID, err)
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -14,7 +14,7 @@ docker_proxy_on $HOST1 run -e WEAVE_CIDR=$C2/24 -dt --name=c2 -h $NAME gliderlab
|
||||
docker_proxy_on $HOST1 run -e WEAVE_CIDR=$C1/24 -dt --name=c1 aanand/docker-dnsutils /bin/sh
|
||||
|
||||
docker_proxy_on $HOST1 restart c2
|
||||
assert_raises "exec_on $HOST1 c2 ip link show ethwe | grep 'state UP'"
|
||||
assert_raises "proxy_exec_on $HOST1 c2 ip link show ethwe | grep 'state \\(UP\\|UNKNOWN\\)'"
|
||||
assert_dns_record $HOST1 c1 $NAME $C2
|
||||
|
||||
end_suite
|
||||
@@ -97,6 +97,14 @@ exec_on() {
|
||||
docker -H tcp://$host:2375 exec $container "$@"
|
||||
}
|
||||
|
||||
proxy_exec_on() {
|
||||
host=$1
|
||||
container=$2
|
||||
shift 2
|
||||
docker -H tcp://$host:12375 exec $container "$@"
|
||||
}
|
||||
|
||||
|
||||
start_container() {
|
||||
host=$1
|
||||
shift 1
|
||||
|
||||
Reference in new issue
Block a user