some refactoring and tidying

- some inlining
- compile regexps once
- consistent error messages
- always mention container id in startContainerInterceptor errors
This commit is contained in:
Matthias Radestock authored and Paul Bellamy committed 2015-05-19 10:34:46 +01:00
1 parent ca4b8e6f8e
commit 126d4f4079
4 files changed
+51 -84

No files matched your search

+2 -2
View File
@@ -33,7 +33,7 @@ func (c *client) ServeHTTP(w http.ResponseWriter, r *http.Request) {
return
}
if err != nil {
http.Error(w, "Unable to create proxied request", http.StatusInternalServerError)
http.Error(w, "Unable to intercept request", http.StatusInternalServerError)
Warning.Print("Error intercepting request: ", err)
return
}
@@ -49,7 +49,7 @@ func (c *client) ServeHTTP(w http.ResponseWriter, r *http.Request) {
resp, err := client.Do(req)
if err != nil && err != httputil.ErrPersistEOF {
http.Error(w, fmt.Sprintf("Could not make request to target: %s", err.Error()), http.StatusInternalServerError)
http.Error(w, fmt.Sprintf("Could not make request to target: %v", err), http.StatusInternalServerError)
Warning.Print("Error forwarding request: ", err)
return
}
+3 -7
View File
@@ -34,7 +34,7 @@ func (i *createContainerInterceptor) InterceptRequest(r *http.Request) (*http.Re
}
if _, ok := weaveCIDRsFromConfig(container.Config); ok {
i.addToVolumesFrom(container.HostConfig, "weaveproxy")
container.HostConfig.VolumesFrom = append(container.HostConfig.VolumesFrom, "weaveproxy")
if err := i.setWeaveWaitEntrypoint(container.Config); err != nil {
return nil, err
}
@@ -53,10 +53,6 @@ func (i *createContainerInterceptor) InterceptRequest(r *http.Request) (*http.Re
return r, nil
}
func (i *createContainerInterceptor) addToVolumesFrom(config *docker.HostConfig, mounts ...string) {
config.VolumesFrom = append(config.VolumesFrom, mounts...)
}
func (i *createContainerInterceptor) setWeaveWaitEntrypoint(container *docker.Config) error {
var image *docker.Config
if !configHasEntrypoint(container) || !configHasCmd(container) {
@@ -104,6 +100,6 @@ func (i *createContainerInterceptor) setWeaveDNS(container *createContainerReque
return nil
}
func (i *createContainerInterceptor) InterceptResponse(res *http.Response) (*http.Response, error) {
return res, nil
func (i *createContainerInterceptor) InterceptResponse(r *http.Response) (*http.Response, error) {
return r, nil
}
+25 -50
View File
@@ -11,6 +11,11 @@ import (
. "github.com/weaveworks/weave/common"
)
var (
containerCreateRegexp = regexp.MustCompile("/v[0-9\\.]*/containers/create")
containerStartRegexp = regexp.MustCompile("^/v[0-9\\.]*/containers/[^/]*/(re)?start$")
)
type Proxy struct {
Dial func() (net.Conn, error)
client *docker.Client
@@ -36,9 +41,18 @@ func NewProxy(targetURL string, withDNS bool) (*Proxy, error) {
if err != nil {
return nil, err
}
targetAddr := ""
switch u.Scheme {
case "tcp":
targetAddr = u.Host
case "unix":
targetAddr = u.Path
}
return &Proxy{
Dial: func() (net.Conn, error) {
return net.Dial(targetNetwork(u), targetAddress(u))
return net.Dial(u.Scheme, targetAddr)
},
client: client,
withDNS: withDNS,
@@ -46,60 +60,21 @@ func NewProxy(targetURL string, withDNS bool) (*Proxy, error) {
}, nil
}
func targetNetwork(u *url.URL) string {
return u.Scheme
}
func targetAddress(u *url.URL) (addr string) {
switch u.Scheme {
case "tcp":
addr = u.Host
case "unix":
addr = u.Path
}
return
}
func isWeaveStatus(r *http.Request) bool {
return strings.HasPrefix(r.URL.Path, "/weave")
}
func isCreateContainer(r *http.Request) bool {
ok, err := regexp.MatchString("/v[0-9\\.]*/containers/create", r.URL.Path)
return err == nil && ok
}
func isStartContainer(r *http.Request) bool {
ok, err := regexp.MatchString("^/v[0-9\\.]*/containers/[^/]*/(re)?start$", r.URL.Path)
return err == nil && ok
}
func (proxy *Proxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
Info.Printf("%s %s", r.Method, r.URL)
path := r.URL.Path
switch {
case isCreateContainer(r):
proxy.createContainer(w, r)
case isStartContainer(r):
proxy.startContainer(w, r)
case isWeaveStatus(r):
proxy.weaveStatus(w, r)
case containerCreateRegexp.MatchString(path):
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 strings.HasPrefix(path, "/weave"):
w.WriteHeader(http.StatusOK)
default:
proxy.proxyRequest(w, r)
proxy.serveWithInterceptor(&nullInterceptor{}, w, r)
}
}
func (proxy *Proxy) weaveStatus(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
}
func (proxy *Proxy) createContainer(w http.ResponseWriter, r *http.Request) {
newClient(proxy.Dial, &createContainerInterceptor{proxy.client, proxy.withDNS, proxy.dockerBridgeIP}).ServeHTTP(w, r)
}
func (proxy *Proxy) startContainer(w http.ResponseWriter, r *http.Request) {
newClient(proxy.Dial, &startContainerInterceptor{proxy.client, proxy.withDNS}).ServeHTTP(w, r)
}
func (proxy *Proxy) proxyRequest(w http.ResponseWriter, r *http.Request) {
newClient(proxy.Dial, &nullInterceptor{}).ServeHTTP(w, r)
func (proxy *Proxy) serveWithInterceptor(i interceptor, w http.ResponseWriter, r *http.Request) {
newClient(proxy.Dial, i).ServeHTTP(w, r)
}
+21 -25
View File
@@ -9,6 +9,8 @@ import (
. "github.com/weaveworks/weave/common"
)
var containerIDRegexp = regexp.MustCompile("^/v[0-9\\.]*/containers/([^/]*)/.*")
type startContainerInterceptor struct {
client *docker.Client
withDNS bool
@@ -18,39 +20,33 @@ func (i *startContainerInterceptor) InterceptRequest(r *http.Request) (*http.Req
return r, nil
}
func (i *startContainerInterceptor) InterceptResponse(res *http.Response) (*http.Response, error) {
containerID := containerFromPath(res.Request.URL.Path)
func (i *startContainerInterceptor) InterceptResponse(r *http.Response) (*http.Response, error) {
containerID := ""
if subs := containerIDRegexp.FindStringSubmatch(r.Request.URL.Path); subs == nil {
Warning.Printf("No container id found in request with path %s", r.Request.URL.Path)
return r, nil
} else {
containerID = subs[1]
}
container, err := i.client.InspectContainer(containerID)
if err != nil {
Warning.Print("Error Inspecting Container: ", err)
return res, nil
Warning.Printf("Error inspecting container %s: %v", containerID, err)
return r, nil
}
if cidrs, ok := weaveCIDRsFromConfig(container.Config); ok {
Info.Printf("Container %s was started with CIDR \"%s\"", containerID, strings.Join(cidrs, " "))
if err := i.attachContainerToWeave(containerID, cidrs); err != nil {
Warning.Print("Attaching container to weave failed: ", err)
return res, nil
}
} else {
cidrs, ok := weaveCIDRsFromConfig(container.Config)
if !ok {
Debug.Print("No Weave CIDR, ignoring")
return r, nil
}
return res, nil
}
func containerFromPath(path string) string {
if subs := regexp.MustCompile("^/v[0-9\\.]*/containers/([^/]*)/.*").FindStringSubmatch(path); subs != nil {
return subs[1]
}
return ""
}
func (i *startContainerInterceptor) attachContainerToWeave(containerID string, cidrs []string) error {
Info.Printf("Container %s was started with CIDR \"%s\"", containerID, strings.Join(cidrs, " "))
args := []string{"attach"}
args = append(args, cidrs...)
args = append(args, containerID)
_, err := callWeave(args...)
return err
if _, err := callWeave(args...); err != nil {
Warning.Printf("Attaching container %s to weave failed: %v", containerID, err)
return r, nil
}
return r, nil
}