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
*.sw[op]
*.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/*")
GOTEST_OPT=-v -race
GOTEST_OPT?=-v -race
GOTEST=go test
GOFMT=gofmt
GOOS=$(shell go env GOOS)
@ -14,10 +14,6 @@ BUILD_INFO=-ldflags "-X $(BUILD_INFO_IMPORT_PATH).GitHash=$(GIT_SHA)"
.PHONY: default_goal
default_goal: fmt test
.PHONY: clean
clean:
rm -rf bin/
.PHONY: test
test:
$(GOTEST) $(GOTEST_OPT) ./...
@ -39,6 +35,28 @@ agent:
collector:
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
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
const (
defaultOCInterceptorAddress = "localhost:55678"
defaultOCInterceptorAddress = ":55678"
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)
}
srv := http.Server{Handler: zPagesMux}
go func() {
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)
}
}()
return ln.Close
return srv.Close
}
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)
go func() {
log.Printf("Running OpenCensus interceptor as a gRPC service at %q", addr)
// Not using log.Fatalf(srv.Serve(ln)) because CTRL-C will close the listener as the user requested
// 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)
if err := srv.Serve(ln); err != nil {
log.Fatalf("Failed to run OpenCensus interceptor: %v", err)
}
}()
doneFn = ln.Close
doneFn = func() error {
srv.Stop()
return 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 (
defaultOCAddress = "localhost:55678"
defaultOCAddress = ":55678"
)
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 {

View File

@ -21,9 +21,7 @@ import (
"net/http"
"net/http/httptest"
"strings"
"sync"
"testing"
"time"
"github.com/census-instrumentation/opencensus-service/exporter"
"github.com/census-instrumentation/opencensus-service/exporter/exporterparser"
@ -41,10 +39,12 @@ import (
//
// The rest of the fields should match up exactly
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) {
io.Copy(cb, r.Body)
io.Copy(buf, r.Body)
r.Body.Close()
responseReady <- true
}))
defer cst.Close()
@ -79,9 +79,8 @@ exporters:
req, _ := http.NewRequest("POST", "https://tld.org/", strings.NewReader(zipkinSpansJSONJavaLibrary))
responseWriter := httptest.NewRecorder()
zi.ServeHTTP(responseWriter, req)
// Just for 100X longer than the Zipkin reporting period
// because -race slows things down a lot.
<-time.After(100 * time.Millisecond)
// Wait for the server to write the response.
<-responseReady
// We expect back the exact JSON that was intercepted
want := testutils.GenerateNormalizedJSON(`
@ -111,38 +110,13 @@ exporters:
}]`)
// Finally we need to inspect the output
gotBytes, _ := ioutil.ReadAll(cb)
gotBytes, _ := ioutil.ReadAll(buf)
got := testutils.GenerateNormalizedJSON(string(gotBytes))
if 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 = `
[{
"traceId": "4d1e00c0db9010db86154a4ba6e91385",