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:
parent
c409a77796
commit
57dd1cca46
|
@ -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
|
||||||
|
|
28
Makefile
28
Makefile
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
|
@ -47,7 +47,7 @@ import (
|
||||||
// port: 55679
|
// port: 55679
|
||||||
|
|
||||||
const (
|
const (
|
||||||
defaultOCInterceptorAddress = "localhost:55678"
|
defaultOCInterceptorAddress = ":55678"
|
||||||
defaultZPagesPort = 55679
|
defaultZPagesPort = 55679
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
FROM scratch
|
||||||
|
COPY occollector_linux /
|
||||||
|
ENTRYPOINT ["/occollector_linux"]
|
||||||
|
EXPOSE 55678
|
|
@ -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 {
|
||||||
|
|
|
@ -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",
|
||||||
|
|
Loading…
Reference in New Issue