Skip to content

Commit

Permalink
Merge pull request #94 from tgross/example_cleanup
Browse files Browse the repository at this point in the history
Merge examples into integration tests
  • Loading branch information
tgross committed Mar 2, 2016
2 parents f788bfa + 37de332 commit 9ce5041
Show file tree
Hide file tree
Showing 58 changed files with 530 additions and 828 deletions.
62 changes: 12 additions & 50 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -270,53 +270,15 @@ Docker will automatically deliver a `SIGTERM` with `docker stop`, not when using

Please report any issues you encounter with Containerbuddy or its documentation by [opening a Github issue](https://github.com/joyent/containerbuddy/issues). Roadmap items will be maintained as [enhancements](https://github.com/joyent/containerbuddy/issues?q=is%3Aopen+is%3Aissue+label%3Aenhancement). PRs are welcome on any issue.

### Running the example

In the `examples` directory is a simple application demonstrating how Containerbuddy works. In this application, an Nginx node acts as a reverse proxy for any number of upstream application nodes. The application nodes register themselves with Consul as they come online, and the Nginx application is configured with an `onChange` handler that uses `consul-template` to write out a new virtualhost configuration file and then fires an `nginx -s reload` signal to Nginx, which causes it to gracefully reload its configuration.

To try this example on your own:

1. [Get a Joyent account](https://my.joyent.com/landing/signup/) and [add your SSH key](https://docs.joyent.com/public-cloud/getting-started).
1. Install the [Docker Toolbox](https://docs.docker.com/installation/mac/) (including `docker` and `docker-compose`) on your laptop or other environment, as well as the [Joyent CloudAPI CLI tools](https://apidocs.joyent.com/cloudapi/#getting-started) (including the `smartdc` and `json` tools)
1. [Configure Docker and Docker Compose for use with Joyent](https://docs.joyent.com/public-cloud/api-access/docker):

```bash
curl -O https://raw.githubusercontent.com/joyent/sdc-docker/master/tools/sdc-docker-setup.sh && chmod +x sdc-docker-setup.sh
./sdc-docker-setup.sh -k us-east-1.api.joyent.com <ACCOUNT> ~/.ssh/<PRIVATE_KEY_FILE>
```

At this point you can run the example on Triton:

```bash
$ env | grep -E '(SDC_URL|DOCKER_HOST)'
SDC_URL=https://us-east-1.api.joyentcloud.com
DOCKER_HOST=tcp://us-east-1.docker.joyent.com:2376
$ cd ./examples
$ ./run.sh consul -p example

```

or in your local Docker environment:

```bash
$ env | grep DOCKER_HOST
DOCKER_HOST=tcp://192.168.99.100:2376
$ cd ./examples
$ curl -Lo containerbuddy-0.0.4.tar.gz \
https://github.com/joyent/containerbuddy/releases/download/0.0.4/containerbuddy-0.0.4.tar.gz
$ tar -xf containerbuddy-0.0.4.tar.gz
$ cp ./containerbuddy ./consul/nginx/opt/containerbuddy/
$ cp ./containerbuddy ./consul/app/opt/containerbuddy/
./run.sh consul -p example -f docker-compose-local.yml

```

Let's scale up the number of `app` nodes:

```bash
docker-compose -p example scale app=3
```

(Note that if we scale up app nodes locally we don't have an IP-per-container and this will result in port conflicts.)

As the nodes launch and register themselves with Consul, you'll see them appear in the Consul UI. The web page that the start script opens refreshes itself every 5 seconds, so once you've added new application containers you'll start seeing the "This page served by app server: <container ID>" change in a round-robin fashion.
### Examples

We've published a number of example applications demonstrating how Containerbuddy works.

- [CloudFlare DNS and CDN with dynamic origins](https://github.com/tgross/triton-cloudflare)
- [Consul, running as an HA raft](https://github.com/misterbisson/triton-consul)
- [Couchbase](https://www.joyent.com/blog/couchbase-in-docker-containers)
- [ELK stack](https://github.com/tgross/triton-elk)
- [Mesos on Joyent Triton](https://www.joyent.com/blog/mesos-by-the-pound)
- [Nginx with dynamic upstreams](https://www.joyent.com/blog/dynamic-nginx-upstreams-with-containerbuddy)
- [MySQL (Percona Server) with auto scaling and fail-over](https://www.joyent.com/blog/dbaas-simplicity-no-lock-in)
- [Node.js + Nginx + Couchbase](https://www.joyent.com/blog/how-to-dockerize-a-complete-application)
18 changes: 9 additions & 9 deletions containerbuddy/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ func TestValidConfigParse(t *testing.T) {
defer argTestCleanup(argTestSetup())

os.Setenv("TEST", "HELLO")
os.Args = []string{"this", "-config", testJSON, "/test.sh", "valid1", "--debug"}
os.Args = []string{"this", "-config", testJSON, "/testdata/test.sh", "valid1", "--debug"}
config, _ := loadConfig()
if !reflect.DeepEqual(config, getConfig()) {
t.Errorf("Global config was not written after load")
Expand All @@ -66,7 +66,7 @@ func TestValidConfigParse(t *testing.T) {
t.Errorf("Expected 2 backends and 2 services but got: %v", config)
}
args := flag.Args()
if len(args) != 3 || args[0] != "/test.sh" {
if len(args) != 3 || args[0] != "/testdata/test.sh" {
t.Errorf("Expected 3 args but got unexpected results: %v", args)
}

Expand Down Expand Up @@ -155,7 +155,7 @@ func validateParseError(t *testing.T, matchStrings []string, config *Config) {
}

func TestOnChangeCmd(t *testing.T) {
cmd1 := strToCmd("/root/examples/test/test.sh doStuff --debug")
cmd1 := strToCmd("./testdata/test.sh doStuff --debug")
backend := &BackendConfig{
onChangeCmd: cmd1,
}
Expand All @@ -169,7 +169,7 @@ func TestOnChangeCmd(t *testing.T) {
}

func TestHealthCheck(t *testing.T) {
cmd1 := strToCmd("/root/examples/test/test.sh doStuff --debug")
cmd1 := strToCmd("./testdata/test.sh doStuff --debug")
service := &ServiceConfig{
healthCheckCmd: cmd1,
}
Expand All @@ -189,15 +189,15 @@ func TestParseCommandArgs(t *testing.T) {
t.Errorf("Unexpected parse error: %s", err.Error())
}

expected := []string{"/test.sh", "arg1"}
json1 := json.RawMessage(`"/test.sh arg1"`)
expected := []string{"/testdata/test.sh", "arg1"}
json1 := json.RawMessage(`"/testdata/test.sh arg1"`)
if cmd, err := parseCommandArgs(json1); err == nil {
validateCommandParsed(t, "json1", cmd, expected)
} else {
t.Errorf("Unexpected parse error json1: %s", err.Error())
}

json2 := json.RawMessage(`["/test.sh","arg1"]`)
json2 := json.RawMessage(`["/testdata/test.sh","arg1"]`)
if cmd, err := parseCommandArgs(json2); err == nil {
validateCommandParsed(t, "json2", cmd, expected)
} else {
Expand Down Expand Up @@ -231,7 +231,7 @@ func validateCommandParsed(t *testing.T, name string, parsed *exec.Cmd, expected

func TestInvalidConfigNoConfigFlag(t *testing.T) {
defer argTestCleanup(argTestSetup())
os.Args = []string{"this", "/test.sh", "invalid1", "--debug"}
os.Args = []string{"this", "/testdata/test.sh", "invalid1", "--debug"}
if _, err := loadConfig(); err != nil && err.Error() != "-config flag is required" {
t.Errorf("Expected error but got %s", err)
}
Expand Down Expand Up @@ -290,7 +290,7 @@ func argTestCleanup(oldArgs []string) {
}

func testParseExpectError(t *testing.T, testJSON string, expected string) {
os.Args = []string{"this", "-config", testJSON, "/test.sh", "test", "--debug"}
os.Args = []string{"this", "-config", testJSON, "/testdata/test.sh", "test", "--debug"}
if _, err := loadConfig(); err != nil && !strings.Contains(err.Error(), expected) {
t.Errorf("Expected %s but got %s", expected, err)
}
Expand Down
6 changes: 3 additions & 3 deletions containerbuddy/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ func TestPoll(t *testing.T) {
}

func TestRunSuccess(t *testing.T) {
cmd1 := strToCmd("/root/examples/test/test.sh doStuff --debug")
cmd1 := strToCmd("./testdata/test.sh doStuff --debug")
if exitCode, _ := run(cmd1); exitCode != 0 {
t.Errorf("Expected exit code 0 but got %d", exitCode)
}
cmd2 := argsToCmd([]string{"/root/examples/test/test.sh", "doStuff", "--debug"})
cmd2 := argsToCmd([]string{"./testdata/test.sh", "doStuff", "--debug"})
if exitCode, _ := run(cmd2); exitCode != 0 {
t.Errorf("Expected exit code 0 but got %d", exitCode)
}
Expand All @@ -34,7 +34,7 @@ func TestRunFailed(t *testing.T) {
t.Errorf("Expected panic but did not.")
}
}()
cmd := strToCmd("/root/examples/test/test.sh failStuff --debug")
cmd := strToCmd("./testdata/test.sh failStuff --debug")
if exitCode, _ := run(cmd); exitCode != 255 {
t.Errorf("Expected exit code 255 but got %d", exitCode)
}
Expand Down
2 changes: 1 addition & 1 deletion containerbuddy/signals_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func (c *NoopDiscoveryService) Deregister(service *ServiceConfig) {}
func getSignalTestConfig() *Config {
config := &Config{
Command: argsToCmd([]string{
"/root/examples/test/test.sh",
"./testdata/test.sh",
"interruptSleep"}),
StopTimeout: 5,
Services: []*ServiceConfig{
Expand Down
File renamed without changes.
14 changes: 0 additions & 14 deletions examples/consul/app/Dockerfile

This file was deleted.

51 changes: 0 additions & 51 deletions examples/consul/docker-compose-local.yml

This file was deleted.

43 changes: 0 additions & 43 deletions examples/consul/docker-compose.yml

This file was deleted.

17 changes: 0 additions & 17 deletions examples/consul/nginx/Dockerfile

This file was deleted.

32 changes: 0 additions & 32 deletions examples/consul/nginx/default.ctmpl

This file was deleted.

13 changes: 0 additions & 13 deletions examples/consul/nginx/etc/nginx/conf.d/default.conf

This file was deleted.

20 changes: 0 additions & 20 deletions examples/consul/nginx/opt/containerbuddy/nginx.json

This file was deleted.

15 changes: 0 additions & 15 deletions examples/consul/nginx/opt/containerbuddy/reload-nginx.sh

This file was deleted.

Loading

0 comments on commit 9ce5041

Please sign in to comment.