Compare commits

...

9 Commits

Author SHA1 Message Date
Vincent Demeester
c452fd2195 Merge pull request #62 from EmileVauge/websockets-support
Websockets support
2015-10-14 23:13:07 +02:00
emile
5454299bf0 update docs 2015-10-14 13:21:40 +02:00
emile
80f4884d50 Added websocket support https://github.com/EmileVauge/traefik/issues/8 2015-10-14 10:42:27 +02:00
emile
4ea48c2d19 Removed panicing spew https://github.com/EmileVauge/traefik/issues/56 2015-10-14 10:39:26 +02:00
Vincent Demeester
37438a6395 Merge pull request #63 from EmileVauge/no-more-godep-ever
Update package management with Glide
2015-10-13 23:38:27 +02:00
emile
784dc9ea62 update docs 2015-10-13 22:57:10 +02:00
emile
6362b1da7f Update package management with Glide 2015-10-13 22:56:44 +02:00
Emile Vauge
31c7aba8c4 Merge pull request #57 from vdemeester/no-more-sleep-in-integration
Update integration setups to use libcompose events
2015-10-12 15:43:08 +02:00
Vincent Demeester
45ea23ecc1 Update integration setups to use libcompose events
Now that docker/libcompose#55 is merged, use it \o/
No more sleeps !

Signed-off-by: Vincent Demeester <vincent@sbr.pm>
2015-10-12 08:44:56 +02:00
19 changed files with 469 additions and 391 deletions

3
.gitignore vendored
View File

@@ -6,5 +6,4 @@ log
traefik
traefik.toml
Godeps/_workspace/bin
Godeps/_workspace/pkg
vendor/

302
Godeps/Godeps.json generated
View File

@@ -1,302 +0,0 @@
{
"ImportPath": "github.com/emilevauge/traefik",
"GoVersion": "go1.4.2",
"Packages": [
"./..."
],
"Deps": [{
"ImportPath": "github.com/BurntSushi/toml",
"Rev": "bd2bdf7f18f849530ef7a1c29a4290217cab32a1"
}, {
"ImportPath": "github.com/BurntSushi/ty",
"Rev": "6add9cd6ad42d389d6ead1dde60b4ad71e46fd74"
}, {
"ImportPath": "github.com/Sirupsen/logrus",
"Comment": "v0.8.7",
"Rev": "418b41d23a1bf978c06faea5313ba194650ac088"
}, {
"ImportPath": "github.com/alecthomas/template",
"Rev": "b867cc6ab45cece8143cfcc6fc9c77cf3f2c23c0"
}, {
"ImportPath": "github.com/alecthomas/units",
"Rev": "6b4e7dc5e3143b85ea77909c72caf89416fc2915"
}, {
"ImportPath": "github.com/boltdb/bolt",
"Rev": "51f99c862475898df9773747d3accd05a7ca33c1"
}, {
"ImportPath": "github.com/cenkalti/backoff",
"Rev": "4dc77674aceaabba2c7e3da25d4c823edfb73f99"
}, {
"ImportPath": "github.com/codahale/hdrhistogram",
"Rev": "954f16e8b9ef0e5d5189456aa4c1202758e04f17"
}, {
"ImportPath": "github.com/codegangsta/negroni",
"Comment": "v0.1-70-gc7477ad",
"Rev": "c7477ad8e330bef55bf1ebe300cf8aa67c492d1b"
}, {
"ImportPath": "github.com/coreos/go-etcd/etcd",
"Comment": "v2.0.0-11-gcc90c7b",
"Rev": "cc90c7b091275e606ad0ca7102a23fb2072f3f5e"
}, {
"ImportPath": "github.com/davecgh/go-spew/spew",
"Rev": "2df174808ee097f90d259e432cc04442cf60be21"
}, {
"ImportPath": "github.com/docker/libkv",
"Rev": "3732f7ff1b56057c3158f10bceb1e79133025373"
}, {
"ImportPath": "github.com/docker/distribution",
"Comment": "v2.0.0-467-g9038e48",
"Rev": "9038e48c3b982f8e82281ea486f078a73731ac4e"
}, {
"ImportPath": "github.com/docker/docker/api",
"Comment": "v1.4.1-5200-gf39987a",
"Rev": "f39987afe8d611407887b3094c03d6ba6a766a67"
}, {
"ImportPath": "github.com/docker/docker/cliconfig",
"Comment": "v1.4.1-5200-gf39987a",
"Rev": "f39987afe8d611407887b3094c03d6ba6a766a67"
}, {
"ImportPath": "github.com/docker/docker/daemon/network",
"Comment": "v1.4.1-5200-gf39987a",
"Rev": "f39987afe8d611407887b3094c03d6ba6a766a67"
}, {
"ImportPath": "github.com/docker/docker/graph/tags",
"Comment": "v1.4.1-5200-gf39987a",
"Rev": "f39987afe8d611407887b3094c03d6ba6a766a67"
}, {
"ImportPath": "github.com/docker/docker/image",
"Comment": "v1.4.1-5200-gf39987a",
"Rev": "f39987afe8d611407887b3094c03d6ba6a766a67"
}, {
"ImportPath": "github.com/docker/docker/opts",
"Comment": "v1.4.1-5200-gf39987a",
"Rev": "f39987afe8d611407887b3094c03d6ba6a766a67"
}, {
"ImportPath": "github.com/docker/docker/pkg/archive",
"Comment": "v1.4.1-5200-gf39987a",
"Rev": "f39987afe8d611407887b3094c03d6ba6a766a67"
}, {
"ImportPath": "github.com/docker/docker/pkg/fileutils",
"Comment": "v1.4.1-5200-gf39987a",
"Rev": "f39987afe8d611407887b3094c03d6ba6a766a67"
}, {
"ImportPath": "github.com/docker/docker/pkg/homedir",
"Comment": "v1.4.1-5200-gf39987a",
"Rev": "f39987afe8d611407887b3094c03d6ba6a766a67"
}, {
"ImportPath": "github.com/docker/docker/pkg/httputils",
"Comment": "v1.4.1-5200-gf39987a",
"Rev": "f39987afe8d611407887b3094c03d6ba6a766a67"
}, {
"ImportPath": "github.com/docker/docker/pkg/ioutils",
"Comment": "v1.4.1-5200-gf39987a",
"Rev": "f39987afe8d611407887b3094c03d6ba6a766a67"
}, {
"ImportPath": "github.com/docker/docker/pkg/jsonmessage",
"Comment": "v1.4.1-5200-gf39987a",
"Rev": "f39987afe8d611407887b3094c03d6ba6a766a67"
}, {
"ImportPath": "github.com/docker/docker/pkg/mflag",
"Comment": "v1.4.1-5200-gf39987a",
"Rev": "f39987afe8d611407887b3094c03d6ba6a766a67"
}, {
"ImportPath": "github.com/docker/docker/pkg/nat",
"Comment": "v1.4.1-5200-gf39987a",
"Rev": "f39987afe8d611407887b3094c03d6ba6a766a67"
}, {
"ImportPath": "github.com/docker/docker/pkg/parsers",
"Comment": "v1.4.1-5200-gf39987a",
"Rev": "f39987afe8d611407887b3094c03d6ba6a766a67"
}, {
"ImportPath": "github.com/docker/docker/pkg/pools",
"Comment": "v1.4.1-5200-gf39987a",
"Rev": "f39987afe8d611407887b3094c03d6ba6a766a67"
}, {
"ImportPath": "github.com/docker/docker/pkg/promise",
"Comment": "v1.4.1-5200-gf39987a",
"Rev": "f39987afe8d611407887b3094c03d6ba6a766a67"
}, {
"ImportPath": "github.com/docker/docker/pkg/random",
"Comment": "v1.4.1-5200-gf39987a",
"Rev": "f39987afe8d611407887b3094c03d6ba6a766a67"
}, {
"ImportPath": "github.com/docker/docker/pkg/stdcopy",
"Comment": "v1.4.1-5200-gf39987a",
"Rev": "f39987afe8d611407887b3094c03d6ba6a766a67"
}, {
"ImportPath": "github.com/docker/docker/pkg/stringid",
"Comment": "v1.4.1-5200-gf39987a",
"Rev": "f39987afe8d611407887b3094c03d6ba6a766a67"
}, {
"ImportPath": "github.com/docker/docker/pkg/symlink",
"Comment": "v1.4.1-5200-gf39987a",
"Rev": "f39987afe8d611407887b3094c03d6ba6a766a67"
}, {
"ImportPath": "github.com/docker/docker/pkg/system",
"Comment": "v1.4.1-5200-gf39987a",
"Rev": "f39987afe8d611407887b3094c03d6ba6a766a67"
}, {
"ImportPath": "github.com/docker/docker/pkg/tarsum",
"Comment": "v1.4.1-5200-gf39987a",
"Rev": "f39987afe8d611407887b3094c03d6ba6a766a67"
}, {
"ImportPath": "github.com/docker/docker/pkg/term",
"Comment": "v1.4.1-5200-gf39987a",
"Rev": "f39987afe8d611407887b3094c03d6ba6a766a67"
}, {
"ImportPath": "github.com/docker/docker/pkg/timeutils",
"Comment": "v1.4.1-5200-gf39987a",
"Rev": "f39987afe8d611407887b3094c03d6ba6a766a67"
}, {
"ImportPath": "github.com/docker/docker/pkg/tlsconfig",
"Comment": "v1.4.1-5200-gf39987a",
"Rev": "f39987afe8d611407887b3094c03d6ba6a766a67"
}, {
"ImportPath": "github.com/docker/docker/pkg/ulimit",
"Comment": "v1.4.1-5200-gf39987a",
"Rev": "f39987afe8d611407887b3094c03d6ba6a766a67"
}, {
"ImportPath": "github.com/docker/docker/pkg/units",
"Comment": "v1.4.1-5200-gf39987a",
"Rev": "f39987afe8d611407887b3094c03d6ba6a766a67"
}, {
"ImportPath": "github.com/docker/docker/pkg/urlutil",
"Comment": "v1.4.1-5200-gf39987a",
"Rev": "f39987afe8d611407887b3094c03d6ba6a766a67"
}, {
"ImportPath": "github.com/docker/docker/pkg/useragent",
"Comment": "v1.4.1-5200-gf39987a",
"Rev": "f39987afe8d611407887b3094c03d6ba6a766a67"
}, {
"ImportPath": "github.com/docker/docker/pkg/version",
"Comment": "v1.4.1-5200-gf39987a",
"Rev": "f39987afe8d611407887b3094c03d6ba6a766a67"
}, {
"ImportPath": "github.com/docker/docker/registry",
"Comment": "v1.4.1-5200-gf39987a",
"Rev": "f39987afe8d611407887b3094c03d6ba6a766a67"
}, {
"ImportPath": "github.com/docker/docker/runconfig",
"Comment": "v1.4.1-5200-gf39987a",
"Rev": "f39987afe8d611407887b3094c03d6ba6a766a67"
}, {
"ImportPath": "github.com/docker/docker/utils",
"Comment": "v1.4.1-5200-gf39987a",
"Rev": "f39987afe8d611407887b3094c03d6ba6a766a67"
}, {
"ImportPath": "github.com/docker/docker/volume",
"Comment": "v1.4.1-5200-gf39987a",
"Rev": "f39987afe8d611407887b3094c03d6ba6a766a67"
}, {
"ImportPath": "github.com/docker/libcompose/docker",
"Rev": "aad672800904307e96a2c21cad1420f3080e0f35"
}, {
"ImportPath": "github.com/docker/libcompose/logger",
"Rev": "aad672800904307e96a2c21cad1420f3080e0f35"
}, {
"ImportPath": "github.com/docker/libcompose/lookup",
"Rev": "aad672800904307e96a2c21cad1420f3080e0f35"
}, {
"ImportPath": "github.com/docker/libcompose/project",
"Rev": "aad672800904307e96a2c21cad1420f3080e0f35"
}, {
"ImportPath": "github.com/docker/libcompose/utils",
"Rev": "aad672800904307e96a2c21cad1420f3080e0f35"
}, {
"ImportPath": "github.com/docker/libtrust",
"Rev": "9cbd2a1374f46905c68a4eb3694a130610adc62a"
}, {
"ImportPath": "github.com/elazarl/go-bindata-assetfs",
"Rev": "d5cac425555ca5cf00694df246e04f05e6a55150"
}, {
"ImportPath": "github.com/flynn/go-shlex",
"Rev": "3f9db97f856818214da2e1057f8ad84803971cff"
}, {
"ImportPath": "github.com/fsouza/go-dockerclient",
"Rev": "0239034d42f665efa17fd77c39f891c2f9f32922"
}, {
"ImportPath": "github.com/gambol99/go-marathon",
"Rev": "0ba31bcb0d7633ba1888d744c42990eb15281cf1"
}, {
"ImportPath": "github.com/gorilla/context",
"Rev": "215affda49addc4c8ef7e2534915df2c8c35c6cd"
}, {
"ImportPath": "github.com/gorilla/handlers",
"Rev": "40694b40f4a928c062f56849989d3e9cd0570e5f"
}, {
"ImportPath": "github.com/gorilla/mux",
"Rev": "f15e0c49460fd49eebe2bcc8486b05d1bef68d3a"
}, {
"ImportPath": "github.com/hashicorp/consul/api",
"Comment": "v0.5.2-313-gde08067",
"Rev": "de080672fee9e6104572eeea89eccdca135bb918"
}, {
"ImportPath": "github.com/mailgun/log",
"Rev": "44874009257d4d47ba9806f1b7f72a32a015e4d8"
}, {
"ImportPath": "github.com/mailgun/manners",
"Comment": "0.3.1-30-g37136f7",
"Rev": "37136f736785d7c6aa3b9a27b4b2dd1028ca6d79"
}, {
"ImportPath": "github.com/mailgun/oxy/cbreaker",
"Rev": "547c334d658398c05b346c0b79d8f47ba2e1473b"
}, {
"ImportPath": "github.com/mailgun/oxy/forward",
"Rev": "547c334d658398c05b346c0b79d8f47ba2e1473b"
}, {
"ImportPath": "github.com/mailgun/oxy/memmetrics",
"Rev": "547c334d658398c05b346c0b79d8f47ba2e1473b"
}, {
"ImportPath": "github.com/mailgun/oxy/roundrobin",
"Rev": "547c334d658398c05b346c0b79d8f47ba2e1473b"
}, {
"ImportPath": "github.com/mailgun/oxy/utils",
"Rev": "547c334d658398c05b346c0b79d8f47ba2e1473b"
}, {
"ImportPath": "github.com/mailgun/predicate",
"Rev": "cb0bff91a7ab7cf7571e661ff883fc997bc554a3"
}, {
"ImportPath": "github.com/mailgun/timetools",
"Rev": "fd192d755b00c968d312d23f521eb0cdc6f66bd0"
}, {
"ImportPath": "github.com/samuel/go-zookeeper/zk",
"Rev": "fa6674abf3f4580b946a01bf7a1ce4ba8766205b"
}, {
"ImportPath": "github.com/opencontainers/runc/libcontainer/user",
"Comment": "v0.0.4-21-g4ab1324",
"Rev": "4ab132458fc3e9dbeea624153e0331952dc4c8d5"
}, {
"ImportPath": "github.com/samalba/dockerclient",
"Rev": "cfb489c624b635251a93e74e1e90eb0959c5367f"
}, {
"ImportPath": "github.com/thoas/stats",
"Rev": "54ed61c2b47e263ae2f01b86837b0c4bd1da28e8"
}, {
"ImportPath": "github.com/unrolled/render",
"Rev": "26b4e3aac686940fe29521545afad9966ddfc80c"
}, {
"ImportPath": "github.com/vdemeester/shakers",
"Rev": "8fe734f75f3a70b651cbfbf8a55a009da09e8dc5"
}, {
"ImportPath": "golang.org/x/net/context",
"Rev": "d9558e5c97f85372afee28cf2b6059d7d3818919"
}, {
"ImportPath": "gopkg.in/alecthomas/kingpin.v2",
"Comment": "v2.0.12",
"Rev": "639879d6110b1b0409410c7b737ef0bb18325038"
}, {
"ImportPath": "gopkg.in/check.v1",
"Rev": "11d3bc7aa68e238947792f30573146a3231fc0f1"
}, {
"ImportPath": "gopkg.in/fsnotify.v1",
"Comment": "v1.2.0",
"Rev": "96c060f6a6b7e0d6f75fddd10efeaca3e5d1bcb0"
}, {
"ImportPath": "gopkg.in/mgo.v2/bson",
"Comment": "r2015.06.03-5-g22287ba",
"Rev": "22287bab4379e1fbf6002fb4eb769888f3fb224c"
}, {
"ImportPath": "gopkg.in/yaml.v2",
"Rev": "7ad95dd0798a40da1ccdff6dff35fd177b5edf40"
}]
}

5
Godeps/Readme generated
View File

@@ -1,5 +0,0 @@
This directory tree is generated automatically by godep.
Please do not edit.
See https://github.com/tools/godep for more information.

3
Godeps/_workspace/.gitignore generated vendored
View File

@@ -1,3 +0,0 @@
/pkg
/bin
/src

View File

@@ -25,7 +25,8 @@ It supports several backends ([Docker :whale:](https://www.docker.com/), [Mesos/
- Tiny docker image included
- SSL backends support
- SSL frontend support
- WebUI
- Clean AngularJS Web UI
- Websocket support
## Demo
@@ -33,6 +34,13 @@ Here is a demo of Træfɪk using Docker backend, showing a load-balancing betwee
[![asciicast](https://asciinema.org/a/4tcyde7riou5vxulo6my3mtko.png)](https://asciinema.org/a/4tcyde7riou5vxulo6my3mtko)
## Web UI
You can access to a simple HTML frontend of Træfik.
![Web UI Providers](docs/img/web.frontend.png)
![Web UI Health](docs/img/traefik-health.png)
## Plumbing
- [Oxy](https://github.com/mailgun/oxy/): an awsome proxy library made by Mailgun guys
@@ -68,66 +76,61 @@ You can find the complete documentation [here](docs/index.md).
Refer to the [benchmarks section](docs/index.md#benchmarks) in the documentation.
## Web UI
You can access to a simple HTML frontend of Træfik.
![Web UI Providers](docs/img/web.frontend.png)
![Web UI Health](docs/img/traefik-health.png)
## Contributing
### Building
You need either [Docker](https://github.com/docker/docker) and `make`, or `go` and `godep` in order to build traefik.
You need either [Docker](https://github.com/docker/docker) and `make`, or `go` and `glide` in order to build traefik.
#### Using Docker and Makefile
#### Setting up your `go` environment
- You need `go` v1.5
- You need to set `export GO15VENDOREXPERIMENT=1` environment variable
- If you clone Træfɪk into something like `~/go/src/github.com/traefik`, your `GOPATH` variable will have to be set to `~/go`: export `GOPATH=~/go`.
#### Using `Docker` and `Makefile`
You need to run the `binary` target. This will create binaries for
linux and darwin platforms in the `dist` folder.
linux platform in the `dist` folder.
```bash
$ make binary
docker build -t "traefik-dev:your-feature-branch" -f build.Dockerfile .
# […]
docker run --rm -it -e OS_ARCH_ARG -e OS_PLATFORM_ARG -e TESTFLAGS -v "/home/vincent/src/github/vdemeester/traefik/dist:/go/src/github.com/emilevauge/traefik/dist" "traefik-dev:your-feature-branch" ./script/make.sh generate binary
docker build -t "traefik-dev:no-more-godep-ever" -f build.Dockerfile .
Sending build context to Docker daemon 295.3 MB
Step 0 : FROM golang:1.5
---> 8c6473912976
Step 1 : RUN go get github.com/Masterminds/glide
[...]
docker run --rm -v "/var/run/docker.sock:/var/run/docker.sock" -it -e OS_ARCH_ARG -e OS_PLATFORM_ARG -e TESTFLAGS -v "/home/emile/dev/go/src/github.com/emilevauge/traefik/"dist":/go/src/github.com/emilevauge/traefik/"dist"" "traefik-dev:no-more-godep-ever" ./script/make.sh generate binary
---> Making bundle: generate (in .)
removed 'gen.go'
---> Making bundle: binary (in .)
Number of parallel builds: 8
--> linux/arm: github.com/emilevauge/traefik
--> darwin/amd64: github.com/emilevauge/traefik
--> darwin/386: github.com/emilevauge/traefik
--> linux/386: github.com/emilevauge/traefik
--> linux/amd64: github.com/emilevauge/traefik
$ ls dist/
traefik* traefik_darwin-386* traefik_darwin-amd64* traefik_linux-386* traefik_linux-amd64* traefik_linux-arm*
traefik*
```
#### Using `godep`
#### Using `glide`
The idea behind `godep` is the following :
The idea behind `glide` is the following :
- when checkout(ing) a project, **run `godep restore`** to install
- when checkout(ing) a project, **run `glide up`** to install
(`go get …`) the dependencies in the `GOPATH`.
- if you need another dependency, `go get` it, import and use it in
the source, and **run `godep save ./...`** to save it in
`Godeps/Godeps.json`.
- if you need another dependency, import and use it in
the source, and **run `glide get github.com/Masterminds/cookoo`** to save it in
`vendor` and add it to your `glide.yaml`.
```bash
$ godep restore
# Generate
$ godep go generate
$ glide up --update-vendored
# generate
$ go generate
# Simple go build
$ godep go build
$ go build
# Using gox to build multiple platform
$ GOPATH=`godep path`:$GOPATH gox "linux darwin" "386 amd64 arm" \
$ gox "linux darwin" "386 amd64 arm" \
-output="dist/traefik_{{.OS}}-{{.Arch}}"
# run other commands like tests
$ godep go test ./...
$ go test ./...
ok _/home/vincent/src/github/vdemeester/traefik 0.004s
```

View File

@@ -1,12 +1,15 @@
FROM golang:1.5
RUN go get github.com/tools/godep
RUN go get github.com/Masterminds/glide
RUN go get github.com/mitchellh/gox
RUN go get github.com/tcnksm/ghr
# Which docker version to test on
ENV DOCKER_VERSION 1.6.2
# enable GO15VENDOREXPERIMENT
ENV GO15VENDOREXPERIMENT 1
# Download docker
RUN set -ex; \
curl https://get.docker.com/builds/Linux/x86_64/docker-${DOCKER_VERSION} -o /usr/local/bin/docker-${DOCKER_VERSION}; \
@@ -15,17 +18,9 @@ RUN set -ex; \
# Set the default Docker to be run
RUN ln -s /usr/local/bin/docker-${DOCKER_VERSION} /usr/local/bin/docker
ENV PATH /go/src/github.com/emilevauge/traefik/Godeps/_workspace/bin:$PATH
WORKDIR /go/src/github.com/emilevauge/traefik
# This is a hack (see libcompose#32) - will be removed when libcompose will be fixed
# (i.e go get able)
RUN mkdir -p /go/src/github.com/docker/docker/autogen/dockerversion/
COPY Godeps/_workspace/src/github.com/docker/docker/autogen/dockerversion/dockerversion.go /go/src/github.com/docker/docker/autogen/dockerversion/dockerversion.go
RUN mkdir Godeps
COPY Godeps/Godeps.json Godeps/
RUN godep restore
COPY glide.yaml glide.yaml
RUN glide up
COPY . /go/src/github.com/emilevauge/traefik

144
glide.yaml Normal file
View File

@@ -0,0 +1,144 @@
package: main
import:
- package: github.com/coreos/go-etcd
ref: cc90c7b091275e606ad0ca7102a23fb2072f3f5e
subpackages:
- etcd
- package: github.com/docker/distribution
ref: 9038e48c3b982f8e82281ea486f078a73731ac4e
- package: github.com/mailgun/log
ref: 44874009257d4d47ba9806f1b7f72a32a015e4d8
- package: github.com/mailgun/oxy
ref: 547c334d658398c05b346c0b79d8f47ba2e1473b
subpackages:
- cbreaker
- forward
- memmetrics
- roundrobin
- utils
- package: github.com/hashicorp/consul
ref: de080672fee9e6104572eeea89eccdca135bb918
subpackages:
- api
- package: github.com/samuel/go-zookeeper
ref: fa6674abf3f4580b946a01bf7a1ce4ba8766205b
subpackages:
- zk
- package: github.com/docker/libtrust
ref: 9cbd2a1374f46905c68a4eb3694a130610adc62a
- package: gopkg.in/check.v1
ref: 11d3bc7aa68e238947792f30573146a3231fc0f1
- package: golang.org/x/net
ref: d9558e5c97f85372afee28cf2b6059d7d3818919
subpackages:
- context
- package: github.com/gorilla/handlers
ref: 40694b40f4a928c062f56849989d3e9cd0570e5f
- package: github.com/docker/libkv
ref: 3732f7ff1b56057c3158f10bceb1e79133025373
- package: github.com/alecthomas/template
ref: b867cc6ab45cece8143cfcc6fc9c77cf3f2c23c0
- package: github.com/vdemeester/shakers
ref: 8fe734f75f3a70b651cbfbf8a55a009da09e8dc5
- package: github.com/alecthomas/units
ref: 6b4e7dc5e3143b85ea77909c72caf89416fc2915
- package: github.com/gambol99/go-marathon
ref: 0ba31bcb0d7633ba1888d744c42990eb15281cf1
- package: github.com/mailgun/predicate
ref: cb0bff91a7ab7cf7571e661ff883fc997bc554a3
- package: github.com/thoas/stats
ref: 54ed61c2b47e263ae2f01b86837b0c4bd1da28e8
- package: github.com/samalba/dockerclient
ref: cfb489c624b635251a93e74e1e90eb0959c5367f
- package: github.com/Sirupsen/logrus
ref: 418b41d23a1bf978c06faea5313ba194650ac088
- package: github.com/unrolled/render
ref: 26b4e3aac686940fe29521545afad9966ddfc80c
- package: github.com/flynn/go-shlex
ref: 3f9db97f856818214da2e1057f8ad84803971cff
- package: github.com/fsouza/go-dockerclient
ref: 0239034d42f665efa17fd77c39f891c2f9f32922
- package: github.com/boltdb/bolt
ref: 51f99c862475898df9773747d3accd05a7ca33c1
- package: gopkg.in/mgo.v2
ref: 22287bab4379e1fbf6002fb4eb769888f3fb224c
subpackages:
- bson
- package: github.com/docker/docker
ref: f39987afe8d611407887b3094c03d6ba6a766a67
subpackages:
- autogen
- api
- cliconfig
- daemon/network
- graph/tags
- image
- opts
- pkg/archive
- pkg/fileutils
- pkg/homedir
- pkg/httputils
- pkg/ioutils
- pkg/jsonmessage
- pkg/mflag
- pkg/nat
- pkg/parsers
- pkg/pools
- pkg/promise
- pkg/random
- pkg/stdcopy
- pkg/stringid
- pkg/symlink
- pkg/system
- pkg/tarsum
- pkg/term
- pkg/timeutils
- pkg/tlsconfig
- pkg/ulimit
- pkg/units
- pkg/urlutil
- pkg/useragent
- pkg/version
- registry
- runconfig
- utils
- volume
- package: github.com/mailgun/timetools
ref: fd192d755b00c968d312d23f521eb0cdc6f66bd0
- package: github.com/codegangsta/negroni
ref: c7477ad8e330bef55bf1ebe300cf8aa67c492d1b
- package: gopkg.in/yaml.v2
ref: 7ad95dd0798a40da1ccdff6dff35fd177b5edf40
- package: github.com/opencontainers/runc
ref: 4ab132458fc3e9dbeea624153e0331952dc4c8d5
subpackages:
- libcontainer/user
- package: github.com/gorilla/mux
ref: f15e0c49460fd49eebe2bcc8486b05d1bef68d3a
- package: github.com/BurntSushi/ty
ref: 6add9cd6ad42d389d6ead1dde60b4ad71e46fd74
- package: github.com/elazarl/go-bindata-assetfs
ref: d5cac425555ca5cf00694df246e04f05e6a55150
- package: github.com/BurntSushi/toml
ref: bd2bdf7f18f849530ef7a1c29a4290217cab32a1
- package: gopkg.in/alecthomas/kingpin.v2
ref: 639879d6110b1b0409410c7b737ef0bb18325038
- package: github.com/docker/libcompose
ref: 79ef5d150f053a5b12f16b02d8844ed7cf33611a
subpackages:
- docker
- logger
- lookup
- project
- utils
- package: github.com/cenkalti/backoff
ref: 4dc77674aceaabba2c7e3da25d4c823edfb73f99
- package: gopkg.in/fsnotify.v1
ref: 96c060f6a6b7e0d6f75fddd10efeaca3e5d1bcb0
- package: github.com/mailgun/manners
ref: 37136f736785d7c6aa3b9a27b4b2dd1028ca6d79
- package: github.com/gorilla/context
ref: 215affda49addc4c8ef7e2534915df2c8c35c6cd
- package: github.com/codahale/hdrhistogram
ref: 954f16e8b9ef0e5d5189456aa4c1202758e04f17
- package: github.com/gorilla/websocket

View File

@@ -9,3 +9,36 @@
logLevel = "DEBUG"
[file]
# rules
[backends]
[backends.backend1]
[backends.backend1.circuitbreaker]
expression = "NetworkErrorRatio() > 0.5"
[backends.backend1.servers.server1]
url = "http://172.17.0.2:80"
weight = 10
[backends.backend1.servers.server2]
url = "http://172.17.0.3:80"
weight = 1
[backends.backend2]
[backends.backend2.LoadBalancer]
method = "drr"
[backends.backend2.servers.server1]
url = "http://172.17.0.4:80"
weight = 1
[backends.backend2.servers.server2]
url = "http://172.17.0.5:80"
weight = 2
[frontends]
[frontends.frontend1]
backend = "backend2"
[frontends.frontend1.routes.test_1]
rule = "Host"
value = "test.localhost"
[frontends.frontend2]
backend = "backend1"
[frontends.frontend2.routes.test_2]
rule = "Path"
value = "/test"

View File

@@ -9,7 +9,6 @@ import (
"path/filepath"
"testing"
"text/template"
"time"
"github.com/docker/libcompose/docker"
"github.com/docker/libcompose/project"
@@ -72,7 +71,7 @@ func (s *MarathonSuite) SetUpSuite(c *check.C) {
type BaseSuite struct {
composeProject *project.Project
listenChan chan project.ProjectEvent
listenChan chan project.Event
started chan bool
stopped chan bool
deleted chan bool
@@ -82,14 +81,12 @@ func (s *BaseSuite) TearDownSuite(c *check.C) {
// shutdown and delete compose project
if s.composeProject != nil {
s.composeProject.Down()
// Waiting for libcompose#55 to be merged
// <-s.stopped
time.Sleep(2 * time.Second)
<-s.stopped
defer close(s.stopped)
s.composeProject.Delete()
// Waiting for libcompose#55 to be merged
// <-s.deleted
time.Sleep(2 * time.Second)
<-s.deleted
defer close(s.deleted)
}
}
@@ -103,32 +100,32 @@ func (s *BaseSuite) createComposeProject(c *check.C, name string) {
c.Assert(err, checker.IsNil)
s.composeProject = composeProject
s.listenChan = make(chan project.ProjectEvent)
s.started = make(chan bool)
s.stopped = make(chan bool)
s.deleted = make(chan bool)
s.listenChan = make(chan project.Event)
go s.startListening(c)
composeProject.AddListener(s.listenChan)
composeProject.Start()
// FIXME Wait for compose to start
// Waiting for libcompose#55 to be merged
// <-s.started
time.Sleep(2 * time.Second)
// Wait for compose to start
<-s.started
defer close(s.started)
}
func (s *BaseSuite) startListening(c *check.C) {
for event := range s.listenChan {
// FIXME Remove this when it's working (libcompose#55)
// fmt.Fprintf(os.Stdout, "Event: %s (%v)\n", event.Event, event)
// FIXME Add a timeout on event
if event.Event == project.PROJECT_UP_DONE {
// FIXME Add a timeout on event ?
if event.EventType == project.EventProjectStartDone {
s.started <- true
}
if event.Event == project.PROJECT_DOWN_DONE {
if event.EventType == project.EventProjectDownDone {
s.stopped <- true
}
if event.Event == project.PROJECT_DELETE_DONE {
if event.EventType == project.EventProjectDeleteDone {
s.deleted <- true
}
}

52
middlewares/websocket.go Normal file
View File

@@ -0,0 +1,52 @@
/*
Copyright
*/
package middlewares
import (
log "github.com/Sirupsen/logrus"
"github.com/mailgun/oxy/roundrobin"
"net/http"
"strings"
"time"
)
type WebsocketUpgrader struct {
rr *roundrobin.RoundRobin
}
func NewWebsocketUpgrader(rr *roundrobin.RoundRobin) *WebsocketUpgrader {
wu := WebsocketUpgrader{
rr: rr,
}
return &wu
}
func (u *WebsocketUpgrader) ServeHTTP(w http.ResponseWriter, req *http.Request) {
// If request is websocket, serve with golang websocket server to do protocol handshake
if strings.Join(req.Header["Upgrade"], "") == "websocket" {
start := time.Now().UTC()
url, err := u.rr.NextServer()
if err != nil {
log.Errorf("Can't round robin in websocket middleware")
return
}
log.Debugf("Websocket forward to %s", url.String())
NewProxy(url).ServeHTTP(w, req)
if req.TLS != nil {
log.Debugf("Round trip: %v, duration: %v tls:version: %x, tls:resume:%t, tls:csuite:%x, tls:server:%v",
req.URL, time.Now().UTC().Sub(start),
req.TLS.Version,
req.TLS.DidResume,
req.TLS.CipherSuite,
req.TLS.ServerName)
} else {
log.Debugf("Round trip: %v, duration: %v",
req.URL, time.Now().UTC().Sub(start))
}
return
}
u.rr.ServeHTTP(w, req)
}

View File

@@ -0,0 +1,170 @@
package middlewares
import (
"io"
"net"
"net/http"
"net/url"
"strings"
log "github.com/Sirupsen/logrus"
"github.com/gorilla/websocket"
)
// Original developpement made by https://github.com/koding/websocketproxy
var (
// DefaultUpgrader specifies the parameters for upgrading an HTTP
// connection to a WebSocket connection.
DefaultUpgrader = &websocket.Upgrader{
ReadBufferSize: 1024,
WriteBufferSize: 1024,
}
// DefaultDialer is a dialer with all fields set to the default zero values.
DefaultDialer = websocket.DefaultDialer
)
// WebsocketProxy is an HTTP Handler that takes an incoming WebSocket
// connection and proxies it to another server.
type WebsocketProxy struct {
// Backend returns the backend URL which the proxy uses to reverse proxy
// the incoming WebSocket connection. Request is the initial incoming and
// unmodified request.
Backend func(*http.Request) *url.URL
// Upgrader specifies the parameters for upgrading a incoming HTTP
// connection to a WebSocket connection. If nil, DefaultUpgrader is used.
Upgrader *websocket.Upgrader
// Dialer contains options for connecting to the backend WebSocket server.
// If nil, DefaultDialer is used.
Dialer *websocket.Dialer
}
// ProxyHandler returns a new http.Handler interface that reverse proxies the
// request to the given target.
func ProxyHandler(target *url.URL) http.Handler {
return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
NewProxy(target).ServeHTTP(rw, req)
})
}
// NewProxy returns a new Websocket reverse proxy that rewrites the
// URL's to the scheme, host and base path provider in target.
func NewProxy(target *url.URL) *WebsocketProxy {
backend := func(r *http.Request) *url.URL {
// Shallow copy
u := *target
u.Fragment = r.URL.Fragment
u.Path = r.URL.Path
u.RawQuery = r.URL.RawQuery
rurl := u.String()
if strings.HasPrefix(rurl, "http") {
u.Scheme = "ws"
}
if strings.HasPrefix(rurl, "https") {
u.Scheme = "wss"
}
return &u
}
return &WebsocketProxy{Backend: backend}
}
// ServeHTTP implements the http.Handler that proxies WebSocket connections.
func (w *WebsocketProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
if w.Backend == nil {
log.Println("websocketproxy: backend function is not defined")
http.Error(rw, "internal server error (code: 1)", http.StatusInternalServerError)
return
}
backendURL := w.Backend(req)
if backendURL == nil {
log.Println("websocketproxy: backend URL is nil")
http.Error(rw, "internal server error (code: 2)", http.StatusInternalServerError)
return
}
dialer := w.Dialer
if w.Dialer == nil {
dialer = DefaultDialer
}
// Pass headers from the incoming request to the dialer to forward them to
// the final destinations.
requestHeader := http.Header{}
requestHeader.Add("Origin", req.Header.Get("Origin"))
for _, prot := range req.Header[http.CanonicalHeaderKey("Sec-WebSocket-Protocol")] {
requestHeader.Add("Sec-WebSocket-Protocol", prot)
}
for _, cookie := range req.Header[http.CanonicalHeaderKey("Cookie")] {
requestHeader.Add("Cookie", cookie)
}
// Pass X-Forwarded-For headers too, code below is a part of
// httputil.ReverseProxy. See http://en.wikipedia.org/wiki/X-Forwarded-For
// for more information
// TODO: use RFC7239 http://tools.ietf.org/html/rfc7239
if clientIP, _, err := net.SplitHostPort(req.RemoteAddr); err == nil {
// If we aren't the first proxy retain prior
// X-Forwarded-For information as a comma+space
// separated list and fold multiple headers into one.
if prior, ok := req.Header["X-Forwarded-For"]; ok {
clientIP = strings.Join(prior, ", ") + ", " + clientIP
}
requestHeader.Set("X-Forwarded-For", clientIP)
}
// Set the originating protocol of the incoming HTTP request. The SSL might
// be terminated on our site and because we doing proxy adding this would
// be helpful for applications on the backend.
requestHeader.Set("X-Forwarded-Proto", "http")
if req.TLS != nil {
requestHeader.Set("X-Forwarded-Proto", "https")
}
// Connect to the backend URL, also pass the headers we get from the requst
// together with the Forwarded headers we prepared above.
// TODO: support multiplexing on the same backend connection instead of
// opening a new TCP connection time for each request. This should be
// optional:
// http://tools.ietf.org/html/draft-ietf-hybi-websocket-multiplexing-01
connBackend, resp, err := dialer.Dial(backendURL.String(), nil)
if err != nil {
log.Printf("websocketproxy: couldn't dial to remote backend url %s, %s, %+v", backendURL.String(), err, resp)
return
}
defer connBackend.Close()
upgrader := w.Upgrader
if w.Upgrader == nil {
upgrader = DefaultUpgrader
}
// Only pass those headers to the upgrader.
upgradeHeader := http.Header{}
upgradeHeader.Set("Sec-WebSocket-Protocol",
resp.Header.Get(http.CanonicalHeaderKey("Sec-WebSocket-Protocol")))
upgradeHeader.Set("Set-Cookie",
resp.Header.Get(http.CanonicalHeaderKey("Set-Cookie")))
// Now upgrade the existing incoming request to a WebSocket connection.
// Also pass the header that we gathered from the Dial handshake.
connPub, err := upgrader.Upgrade(rw, req, upgradeHeader)
if err != nil {
log.Printf("websocketproxy: couldn't upgrade %s\n", err)
return
}
defer connPub.Close()
errc := make(chan error, 2)
cp := func(dst io.Writer, src io.Reader) {
_, err := io.Copy(dst, src)
errc <- err
}
// Start our proxy now, everything is ready...
go cp(connBackend.UnderlyingConn(), connPub.UnderlyingConn())
go cp(connPub.UnderlyingConn(), connBackend.UnderlyingConn())
<-errc
}

View File

@@ -7,8 +7,7 @@ if ! test -e gen.go; then
fi
rm -f dist/traefik
rm -rf Godeps/_workspace/pkg
# Build binaries
CGO_ENABLED=0 godep go build -a -installsuffix nocgo -o dist/traefik .
CGO_ENABLED=0 go build -a -installsuffix nocgo -o dist/traefik .

View File

@@ -22,9 +22,8 @@ fi
# Get rid of existing binaries
rm -f dist/traefik_*
rm -rf Godeps/_workspace/pkg
# Build binaries
GOPATH=`godep path`:$GOPATH gox "${OS_PLATFORM_ARG[@]}" "${OS_ARCH_ARG[@]}" \
gox "${OS_PLATFORM_ARG[@]}" "${OS_ARCH_ARG[@]}" \
-output="dist/traefik_{{.OS}}-{{.Arch}}"

View File

@@ -6,5 +6,5 @@ export DEST=.
TESTFLAGS="$TESTFLAGS -test.timeout=30m -check.v"
cd integration
GOPATH=`godep path`:$GOPATH go test $TESTFLAGS
go test $TESTFLAGS

View File

@@ -17,7 +17,7 @@ find_dirs() {
find . -not \( \
\( \
-path './integration/*' \
-o -path './Godeps/*' \
-o -path './vendor/*' \
-o -path './.git/*' \
\) \
-prune \
@@ -34,7 +34,7 @@ TESTS_FAILED=()
for dir in $TESTDIRS; do
echo '+ go test' $TESTFLAGS "${dir}"
godep go test ${TESTFLAGS} ${dir}
go test ${TESTFLAGS} ${dir}
if [ $? != 0 ]; then
TESTS_FAILED+=("$dir")
echo

View File

@@ -3,7 +3,7 @@
source "$(dirname "$BASH_SOURCE")/.validate"
IFS=$'\n'
files=( $(validate_diff --diff-filter=ACMR --name-only -- '*.go' | grep -v '^Godeps' || true) )
files=( $(validate_diff --diff-filter=ACMR --name-only -- '*.go' | grep -v '^vendor' || true) )
unset IFS
badFiles=()

View File

@@ -3,7 +3,7 @@
source "$(dirname "$BASH_SOURCE")/.validate"
IFS=$'\n'
files=( $(validate_diff --diff-filter=ACMR --name-only -- '*.go' | grep -v '^Godeps/' || true) )
files=( $(validate_diff --diff-filter=ACMR --name-only -- '*.go' | grep -v '^vendor/' || true) )
unset IFS
errors=()

View File

@@ -16,7 +16,6 @@ import (
"github.com/BurntSushi/toml"
log "github.com/Sirupsen/logrus"
"github.com/codegangsta/negroni"
"github.com/davecgh/go-spew/spew"
"github.com/emilevauge/traefik/middlewares"
"github.com/gorilla/mux"
"github.com/mailgun/manners"
@@ -88,7 +87,7 @@ func main() {
} else {
log.SetFormatter(&log.TextFormatter{FullTimestamp: true, DisableSorting: true})
}
log.Debugf("Global configuration loaded %s", spew.Sdump(globalConfiguration))
log.Debugf("Global configuration loaded %+v", globalConfiguration)
configurationRouter = LoadDefaultConfig(globalConfiguration)
// listen new configurations from providers
@@ -97,7 +96,6 @@ func main() {
for {
configMsg := <-configurationChan
log.Infof("Configuration receveived from provider %s: %#v", configMsg.providerName, configMsg.configuration)
log.Debugf("Configuration %s", spew.Sdump(configMsg.configuration))
if configMsg.configuration == nil {
log.Info("Skipping empty configuration")
} else if reflect.DeepEqual(currentConfigurations[configMsg.providerName], configMsg.configuration) {
@@ -191,7 +189,6 @@ func main() {
func startServer(srv *manners.GracefulServer, globalConfiguration *GlobalConfiguration) {
log.Info("Starting server")
log.Debugf("Server %s", spew.Sdump(srv))
if len(globalConfiguration.CertFile) > 0 && len(globalConfiguration.KeyFile) > 0 {
err := srv.ListenAndServeTLS(globalConfiguration.CertFile, globalConfiguration.KeyFile)
if err != nil {
@@ -281,7 +278,7 @@ func LoadConfig(configurations configs, globalConfiguration *GlobalConfiguration
}
case wrr:
log.Infof("Creating load-balancer wrr")
lb = rr
lb = middlewares.NewWebsocketUpgrader(rr)
for serverName, server := range configuration.Backends[frontend.Backend].Servers {
url, err := url.Parse(server.URL)
if err != nil {