Add docker scratch for agent and collector (#156)

* Add docker from scratch linux for agent and collector

* Fix flaky test that depended on timing
This commit is contained in:
Paulo Janotti 2018-11-01 13:19:30 -07:00 committed by GitHub
parent c409a77796
commit 57dd1cca46
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 66 additions and 49 deletions

5
.gitignore vendored
View File

@ -3,3 +3,8 @@ bin/
# Miscellaneous files # Miscellaneous files
*.sw[op] *.sw[op]
*.DS_Store *.DS_Store
# Binaries are copied (as needed) to the same location as their respective Dockerfile in
# order to simplify docker build commands. Ignore these files if proper clean up fails.
cmd/ocagent/ocagent_linux
cmd/occollector/occollector_linux

View File

@ -1,6 +1,6 @@
ALL_SRC := $(shell find . -type f -name '*.go' -not -path "./vendor/*") ALL_SRC := $(shell find . -type f -name '*.go' -not -path "./vendor/*")
GOTEST_OPT=-v -race GOTEST_OPT?=-v -race
GOTEST=go test GOTEST=go test
GOFMT=gofmt GOFMT=gofmt
GOOS=$(shell go env GOOS) GOOS=$(shell go env GOOS)
@ -14,10 +14,6 @@ BUILD_INFO=-ldflags "-X $(BUILD_INFO_IMPORT_PATH).GitHash=$(GIT_SHA)"
.PHONY: default_goal .PHONY: default_goal
default_goal: fmt test default_goal: fmt test
.PHONY: clean
clean:
rm -rf bin/
.PHONY: test .PHONY: test
test: test:
$(GOTEST) $(GOTEST_OPT) ./... $(GOTEST) $(GOTEST_OPT) ./...
@ -39,6 +35,28 @@ agent:
collector: collector:
CGO_ENABLED=0 go build -o ./bin/occollector_$(GOOS) $(BUILD_INFO) ./cmd/occollector CGO_ENABLED=0 go build -o ./bin/occollector_$(GOOS) $(BUILD_INFO) ./cmd/occollector
.PHONY: docker-component # Not intended to be used directly
docker-component: check-component
GOOS=linux $(MAKE) $(COMPONENT)
cp ./bin/oc$(COMPONENT)_linux ./cmd/oc$(COMPONENT)/
docker build -t oc$(COMPONENT) ./cmd/oc$(COMPONENT)/
rm ./cmd/oc$(COMPONENT)/oc$(COMPONENT)_linux
.PHONY: check-component
check-component:
ifndef COMPONENT
$(error COMPONENT variable was not defined)
endif
.PHONY: docker-agent
docker-agent:
COMPONENT=agent $(MAKE) docker-component
.PHONY: docker-collector
docker-collector:
COMPONENT=collector $(MAKE) docker-component
.PHONY: binaries .PHONY: binaries
binaries: agent collector binaries: agent collector

9
cmd/ocagent/Dockerfile Normal file
View File

@ -0,0 +1,9 @@
# Use a helper to create an emtpy configuration since the agent requires such file
FROM alpine:3.7 as helper
RUN touch ./config.yaml
FROM scratch
COPY ocagent_linux /
COPY --from=helper ./config.yaml config.yaml
ENTRYPOINT ["/ocagent_linux"]
EXPOSE 55678 55679

View File

@ -47,7 +47,7 @@ import (
// port: 55679 // port: 55679
const ( const (
defaultOCInterceptorAddress = "localhost:55678" defaultOCInterceptorAddress = ":55678"
defaultZPagesPort = 55679 defaultZPagesPort = 55679
) )

View File

@ -121,14 +121,15 @@ func runZPages(port int) func() error {
log.Fatalf("Failed to bind to run zPages on %q: %v", addr, err) log.Fatalf("Failed to bind to run zPages on %q: %v", addr, err)
} }
srv := http.Server{Handler: zPagesMux}
go func() { go func() {
log.Printf("Running zPages at %q", addr) log.Printf("Running zPages at %q", addr)
if err := http.Serve(ln, zPagesMux); err != nil { if err := srv.Serve(ln); err != nil && err != http.ErrServerClosed {
log.Fatalf("Failed to serve zPages: %v", err) log.Fatalf("Failed to serve zPages: %v", err)
} }
}() }()
return ln.Close return srv.Close
} }
func runOCInterceptor(addr string, sr spanreceiver.SpanReceiver) (doneFn func() error, err error) { func runOCInterceptor(addr string, sr spanreceiver.SpanReceiver) (doneFn func() error, err error) {
@ -152,13 +153,14 @@ func runOCInterceptor(addr string, sr spanreceiver.SpanReceiver) (doneFn func()
agenttracepb.RegisterTraceServiceServer(srv, oci) agenttracepb.RegisterTraceServiceServer(srv, oci)
go func() { go func() {
log.Printf("Running OpenCensus interceptor as a gRPC service at %q", addr) log.Printf("Running OpenCensus interceptor as a gRPC service at %q", addr)
if err := srv.Serve(ln); err != nil {
// Not using log.Fatalf(srv.Serve(ln)) because CTRL-C will close the listener as the user requested log.Fatalf("Failed to run OpenCensus interceptor: %v", err)
// and that log.Fatalf will produce an unrelated but misleading error: }
// "Failed to run OpenCensus interceptor: accept tcp 127.0.0.1:55678: use of closed network connection"
_ = srv.Serve(ln)
}() }()
doneFn = ln.Close doneFn = func() error {
srv.Stop()
return nil
}
return doneFn, nil return doneFn, nil
} }

View File

@ -0,0 +1,4 @@
FROM scratch
COPY occollector_linux /
ENTRYPOINT ["/occollector_linux"]
EXPOSE 55678

View File

@ -42,7 +42,7 @@ import (
) )
const ( const (
defaultOCAddress = "localhost:55678" defaultOCAddress = ":55678"
) )
func main() { func main() {
@ -103,7 +103,12 @@ func runOCServerWithInterceptor(addr string, logger *zap.Logger) (func() error,
} }
}() }()
return lis.Close, nil closeFn := func() error {
grpcSrv.Stop()
return nil
}
return closeFn, nil
} }
type fakeSpanReceiver struct { type fakeSpanReceiver struct {

View File

@ -21,9 +21,7 @@ import (
"net/http" "net/http"
"net/http/httptest" "net/http/httptest"
"strings" "strings"
"sync"
"testing" "testing"
"time"
"github.com/census-instrumentation/opencensus-service/exporter" "github.com/census-instrumentation/opencensus-service/exporter"
"github.com/census-instrumentation/opencensus-service/exporter/exporterparser" "github.com/census-instrumentation/opencensus-service/exporter/exporterparser"
@ -41,10 +39,12 @@ import (
// //
// The rest of the fields should match up exactly // The rest of the fields should match up exactly
func TestZipkinExportersFromYAML_roundtripJSON(t *testing.T) { func TestZipkinExportersFromYAML_roundtripJSON(t *testing.T) {
cb := newConcurrentBuffer() responseReady := make(chan bool)
buf := new(bytes.Buffer)
cst := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { cst := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
io.Copy(cb, r.Body) io.Copy(buf, r.Body)
r.Body.Close() r.Body.Close()
responseReady <- true
})) }))
defer cst.Close() defer cst.Close()
@ -79,9 +79,8 @@ exporters:
req, _ := http.NewRequest("POST", "https://tld.org/", strings.NewReader(zipkinSpansJSONJavaLibrary)) req, _ := http.NewRequest("POST", "https://tld.org/", strings.NewReader(zipkinSpansJSONJavaLibrary))
responseWriter := httptest.NewRecorder() responseWriter := httptest.NewRecorder()
zi.ServeHTTP(responseWriter, req) zi.ServeHTTP(responseWriter, req)
// Just for 100X longer than the Zipkin reporting period // Wait for the server to write the response.
// because -race slows things down a lot. <-responseReady
<-time.After(100 * time.Millisecond)
// We expect back the exact JSON that was intercepted // We expect back the exact JSON that was intercepted
want := testutils.GenerateNormalizedJSON(` want := testutils.GenerateNormalizedJSON(`
@ -111,38 +110,13 @@ exporters:
}]`) }]`)
// Finally we need to inspect the output // Finally we need to inspect the output
gotBytes, _ := ioutil.ReadAll(cb) gotBytes, _ := ioutil.ReadAll(buf)
got := testutils.GenerateNormalizedJSON(string(gotBytes)) got := testutils.GenerateNormalizedJSON(string(gotBytes))
if got != want { if got != want {
t.Errorf("RoundTrip result do not match:\nGot\n %s\n\nWant\n: %s\n", got, want) t.Errorf("RoundTrip result do not match:\nGot\n %s\n\nWant\n: %s\n", got, want)
} }
} }
type concurrentBuffer struct {
mu sync.Mutex
buf *bytes.Buffer
}
func newConcurrentBuffer() *concurrentBuffer {
return &concurrentBuffer{
buf: new(bytes.Buffer),
}
}
func (cb *concurrentBuffer) Write(b []byte) (int, error) {
cb.mu.Lock()
defer cb.mu.Unlock()
return cb.buf.Write(b)
}
func (cb *concurrentBuffer) Read(b []byte) (int, error) {
cb.mu.Lock()
defer cb.mu.Unlock()
return cb.buf.Read(b)
}
const zipkinSpansJSONJavaLibrary = ` const zipkinSpansJSONJavaLibrary = `
[{ [{
"traceId": "4d1e00c0db9010db86154a4ba6e91385", "traceId": "4d1e00c0db9010db86154a4ba6e91385",