Skip to content

Commit 1280daf

Browse files
author
Matthew Fisher
committed
feat(controller): introduce deis/logspout
1 parent dbd50a8 commit 1280daf

9 files changed

Lines changed: 120 additions & 64 deletions

File tree

Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44

55
include includes.mk
66

7-
COMPONENTS=builder cache controller database logger publisher registry router
8-
START_ORDER=publisher logger database cache registry controller builder router
7+
COMPONENTS=builder cache controller database logger logspout publisher registry router
8+
START_ORDER=publisher logger logspout database cache registry controller builder router
99
CLIENTS=client deisctl
1010

1111
all: build run

controller/scheduler/coreos.py

Lines changed: 4 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import cStringIO
22
import base64
33
import copy
4-
import functools
54
import json
65
import httplib
76
import paramiko
@@ -105,7 +104,6 @@ def create(self, name, image, command='', template=None, **kwargs):
105104
"""Create a container"""
106105
self._create_container(name, image, command,
107106
template or copy.deepcopy(CONTAINER_TEMPLATE), **kwargs)
108-
self._create_log(name, image, command, copy.deepcopy(LOG_TEMPLATE))
109107

110108
def _create_container(self, name, image, command, unit, **kwargs):
111109
l = locals().copy()
@@ -138,15 +136,6 @@ def _create_container(self, name, image, command, unit, **kwargs):
138136
# post unit to fleet
139137
self._put_unit(name, {"desiredState": "launched", "options": unit})
140138

141-
def _create_log(self, name, image, command, unit):
142-
l = locals().copy()
143-
l.update(re.match(MATCH, name).groupdict())
144-
# construct unit from template
145-
for f in unit:
146-
f['value'] = f['value'].format(**l)
147-
# post unit to fleet
148-
self._put_unit(name+'-log', {"desiredState": "launched", "options": unit})
149-
150139
def start(self, name):
151140
"""Start a container"""
152141
self._wait_for_container(name)
@@ -181,23 +170,16 @@ def stop(self, name):
181170

182171
def destroy(self, name):
183172
"""Destroy a container"""
184-
funcs = []
185-
funcs.append(functools.partial(self._destroy_container, name))
186-
funcs.append(functools.partial(self._destroy_log, name))
187173
# call all destroy functions, ignoring any errors
188-
for f in funcs:
189-
try:
190-
f()
191-
except:
192-
pass
174+
try:
175+
self._destroy_container(name)
176+
except:
177+
pass
193178
self._wait_for_destroy(name)
194179

195180
def _destroy_container(self, name):
196181
return self._delete_unit(name)
197182

198-
def _destroy_log(self, name):
199-
return self._delete_unit(name+'-log')
200-
201183
def run(self, name, image, entrypoint, command): # noqa
202184
"""Run a one-off command"""
203185
self._create_container(name, image, command, copy.deepcopy(RUN_TEMPLATE),
@@ -307,16 +289,6 @@ def attach(self, name):
307289
]
308290

309291

310-
LOG_TEMPLATE = [
311-
{"section": "Unit", "name": "Description", "value": "{name} log"},
312-
{"section": "Unit", "name": "BindsTo", "value": "{name}.service"},
313-
{"section": "Service", "name": "ExecStartPre", "value": '''/bin/sh -c "until docker inspect {name} >/dev/null 2>&1; do sleep 1; done"'''}, # noqa
314-
{"section": "Service", "name": "ExecStart", "value": '''/bin/sh -c "docker logs -f {name} 2>&1 | logger -p local0.info -t {app}[{c_type}.{c_num}] --udp --server $(etcdctl get /deis/logs/host) --port $(etcdctl get /deis/logs/port)"'''}, # noqa
315-
{"section": "Service", "name": "TimeoutStartSec", "value": "20m"},
316-
{"section": "X-Fleet", "name": "MachineOf", "value": "{name}.service"},
317-
]
318-
319-
320292
RUN_TEMPLATE = [
321293
{"section": "Unit", "name": "Description", "value": "{name} admin command"},
322294
{"section": "Service", "name": "ExecStartPre", "value": '''/bin/sh -c "IMAGE=$(etcdctl get /deis/registry/host 2>&1):$(etcdctl get /deis/registry/port 2>&1)/{image}; docker pull $IMAGE"'''}, # noqa

deisctl/cmd/cmd.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ func startDefaultServices(b backend.Backend) error {
9292
if err := Start(b, []string{"logger@1"}); err != nil {
9393
return err
9494
}
95-
if err := Start(b, []string{"publisher", "cache@1", "router@1", "database@1", "controller@1", "registry@1", "builder@1"}); err != nil {
95+
if err := Start(b, []string{"publisher", "logspout", "cache@1", "router@1", "database@1", "controller@1", "registry@1", "builder@1"}); err != nil {
9696
return err
9797
}
9898
fmt.Println("Service containers launched.")
@@ -118,7 +118,7 @@ func StopPlatform(b backend.Backend) error {
118118

119119
func stopDefaultServices(b backend.Backend) error {
120120
fmt.Println("Stopping service containers...")
121-
if err := Stop(b, []string{"publisher", "builder@1", "registry@1", "controller@1", "database@1", "cache@1", "router@1", "logger@1"}); err != nil {
121+
if err := Stop(b, []string{"publisher", "logspout", "builder@1", "registry@1", "controller@1", "database@1", "cache@1", "router@1", "logger@1"}); err != nil {
122122
return err
123123
}
124124
fmt.Println("Service containers stopped.")
@@ -196,7 +196,7 @@ func installDefaultServices(b backend.Backend) error {
196196
if err := Scale(b, targets); err != nil {
197197
return err
198198
}
199-
if err := b.Create([]string{"publisher"}); err != nil {
199+
if err := b.Create([]string{"publisher", "logspout"}); err != nil {
200200
return err
201201
}
202202
fmt.Println("Service containers scheduled.")
@@ -226,7 +226,7 @@ func uninstallAllServices(b backend.Backend) error {
226226
if err := Scale(b, targets); err != nil {
227227
return err
228228
}
229-
if err := b.Destroy([]string{"publisher"}); err != nil {
229+
if err := b.Destroy([]string{"publisher", "logspout"}); err != nil {
230230
return err
231231
}
232232
fmt.Println("Service containers destroyed.")
@@ -309,6 +309,7 @@ Options:
309309
"deis-database-data.service",
310310
"deis-logger.service",
311311
"deis-logger-data.service",
312+
"deis-logspout.service",
312313
"deis-publisher.service",
313314
"deis-registry.service",
314315
"deis-registry-data.service",
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
[Unit]
2+
Description=deis-logspout
3+
Requires=docker.socket etcd.service
4+
After=docker.socket etcd.service
5+
6+
[Service]
7+
EnvironmentFile=/etc/environment
8+
ExecStartPre=/bin/sh -c "IMAGE=`/run/deis/bin/get_image /deis/logspout`; docker history $IMAGE >/dev/null || docker pull $IMAGE"
9+
ExecStartPre=/bin/sh -c "docker inspect deis-logspout >/dev/null && docker rm -f deis-logspout || true"
10+
ExecStart=/bin/sh -c "IMAGE=`/run/deis/bin/get_image /deis/logspout` && docker run --name deis-logspout --rm -v /var/run/docker.sock:/tmp/docker.sock -e ETCD_HOST=$COREOS_PRIVATE_IPV4 -e HOST=$COREOS_PRIVATE_IPV4 $IMAGE"
11+
ExecStopPost=/usr/bin/docker stop deis-logspout
12+
13+
[Install]
14+
WantedBy=multi-user.target
15+
16+
[X-Fleet]
17+
Global=true

logspout/Dockerfile

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,6 @@
1-
FROM flynn/busybox
2-
MAINTAINER Jeff Lindsay <progrium@gmail.com>
1+
FROM deis/go:latest
2+
MAINTAINER OpDemand <info@opdemand.com>
33

4-
ADD ./stage/logspout /bin/logspout
5-
6-
ENV DOCKER_HOST unix:///tmp/docker.sock
7-
ENV ROUTESPATH /mnt/routes
8-
VOLUME /mnt/routes
9-
10-
EXPOSE 8000
11-
12-
ENTRYPOINT ["/bin/logspout"]
13-
CMD []
4+
WORKDIR /go/src/github.com/deis/deis/logspout
5+
ADD . /go/src/github.com/deis/deis/logspout
6+
RUN go get .

logspout/Makefile

Lines changed: 62 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,67 @@
1-
build/container: stage/logspout Dockerfile
2-
docker build --no-cache -t logspout .
3-
touch build/container
1+
include ../includes.mk
42

5-
build/logspout: *.go
6-
GOOS=linux GOARCH=amd64 go build -o build/logspout
3+
COMPONENT := logspout
4+
DOCKER_IMAGE := deis/$(COMPONENT)
5+
BUILD_IMAGE := $(DOCKER_IMAGE)-build
6+
RELEASE_IMAGE := $(DOCKER_IMAGE):$(BUILD_TAG)
7+
DEV_DOCKER_IMAGE := $(DEV_REGISTRY)/$(RELEASE_IMAGE)
78

8-
stage/logspout: build/logspout
9-
mkdir -p stage
10-
cp build/logspout stage/logspout
9+
build: check-docker
10+
docker build -t $(BUILD_IMAGE) .
11+
docker cp `docker run -d $(BUILD_IMAGE)`:/go/bin/logspout image/
12+
docker build -t $(RELEASE_IMAGE) image
13+
rm -rf image/logspout
14+
15+
clean: check-docker check-registry
16+
docker rmi $(RELEASE_IMAGE) $(BUILD_IMAGE)
17+
18+
full-clean: check-docker check-registry
19+
docker images -q $(DOCKER_IMAGE) | xargs docker rmi -f
20+
docker images -q $(BUILD_IMAGE) | xargs docker rmi -f
21+
docker images -q $(DEV_DOCKER_IMAGE) | xargs docker rmi -f
22+
23+
install: check-deisctl
24+
deisctl install $(COMPONENT)
25+
26+
uninstall: check-deisctl
27+
deisctl uninstall $(COMPONENT)
28+
29+
start: check-deisctl
30+
deisctl start $(COMPONENT)
31+
32+
stop: check-deisctl
33+
deisctl stop $(COMPONENT)
34+
35+
restart: stop start
36+
37+
run: install start
38+
39+
dev-release: check-registry check-deisctl
40+
docker tag $(RELEASE_IMAGE) $(DEV_DOCKER_IMAGE)
41+
docker push $(DEV_DOCKER_IMAGE)
42+
deisctl config $(COMPONENT) set image=$(DEV_DOCKER_IMAGE)
1143

1244
release:
13-
docker tag logspout progrium/logspout
14-
docker push progrium/logspout
45+
docker push $(RELEASE_IMAGE)
46+
47+
deploy: build dev-release restart
48+
49+
test: test-unit test-functional
50+
51+
setup-root-gotools:
52+
sudo GOPATH=/tmp/tmpGOPATH go get -u -v code.google.com/p/go.tools/cmd/cover
53+
sudo GOPATH=/tmp/tmpGOPATH go get -u -v code.google.com/p/go.tools/cmd/vet
54+
sudo rm -rf /tmp/tmpGOPATH
55+
56+
setup-gotools:
57+
go get -v github.com/golang/lint/golint
58+
59+
test-style:
60+
go vet -x ./...
61+
-golint .
62+
63+
test-unit: test-style
64+
@echo no tests
1565

16-
.PHONY: clean
17-
clean:
18-
rm -rf build
66+
test-functional:
67+
@echo no functional tests

logspout/attacher.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ func (m *AttachManager) attach(id string) {
8080
m.Unlock()
8181
success <- struct{}{}
8282
m.send(&AttachEvent{ID: id, Name: name, Type: "attach"})
83-
debug("attach:", id, "success")
83+
debug("attach:", id, name, "success")
8484
return
8585
}
8686
debug("attach:", id, "failure:", <-failure)

logspout/image/Dockerfile

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
FROM flynn/busybox
2+
MAINTAINER OpDemand <info@opdemand.com>
3+
4+
ENV DOCKER_HOST unix:///tmp/docker.sock
5+
ENV ROUTESPATH /tmp
6+
CMD ["/bin/logspout"]
7+
8+
ADD logspout /bin/logspout

logspout/logspout.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"strings"
1313

1414
"code.google.com/p/go.net/websocket"
15+
"github.com/coreos/go-etcd/etcd"
1516
"github.com/fsouza/go-dockerclient"
1617
"github.com/go-martini/martini"
1718
)
@@ -136,6 +137,21 @@ func main() {
136137
attacher := NewAttachManager(client)
137138
router := NewRouteManager(attacher)
138139

140+
// HACK: if we are connecting to etcd, get the logger's connection
141+
// details from there
142+
if etcdHost := os.Getenv("ETCD_HOST"); etcdHost != "" {
143+
connectionString := []string{"http://" + etcdHost + ":4001"}
144+
debug("etcd:", connectionString[0])
145+
etcd := etcd.NewClient(connectionString)
146+
hostResp, err := etcd.Get("/deis/logs/host", false, false)
147+
assert(err, "url")
148+
portResp, err := etcd.Get("/deis/logs/port", false, false)
149+
assert(err, "url")
150+
host := fmt.Sprintf("%s:%s", hostResp.Node.Value, portResp.Node.Value)
151+
log.Println("routing all to " + host)
152+
router.Add(&Route{Target: Target{Type: "syslog", Addr: host}})
153+
}
154+
139155
if len(os.Args) > 1 {
140156
u, err := url.Parse(os.Args[1])
141157
assert(err, "url")

0 commit comments

Comments
 (0)