diff --git a/prog/probe.go b/prog/probe.go index e572a2975..f18768d55 100644 --- a/prog/probe.go +++ b/prog/probe.go @@ -42,7 +42,7 @@ const ( var pluginAPIVersion = "1" -func check() { +func check(flags map[string]string) { handleResponse := func(r *checkpoint.CheckResponse, err error) { if err != nil { log.Errorf("Error checking version: %v", err) @@ -56,6 +56,7 @@ func check() { params := checkpoint.CheckParams{ Product: "scope-probe", Version: version, + Flags: flags, } resp, err := checkpoint.Check(¶ms) handleResponse(resp, err) @@ -87,7 +88,11 @@ func probeMain(flags probeFlags) { ) log.Infof("probe starting, version %s, ID %s", version, probeID) log.Infof("command line: %v", os.Args) - go check() + checkpointFlags := map[string]string{} + if flags.kubernetesEnabled { + checkpointFlags["kubernetes_enabled"] = "true" + } + go check(checkpointFlags) var targets = []string{fmt.Sprintf("localhost:%d", xfer.AppPort)} if len(flag.Args()) > 0 { diff --git a/vendor/github.com/weaveworks/go-checkpoint/Makefile b/vendor/github.com/weaveworks/go-checkpoint/Makefile index 129dad6e7..294727626 100644 --- a/vendor/github.com/weaveworks/go-checkpoint/Makefile +++ b/vendor/github.com/weaveworks/go-checkpoint/Makefile @@ -1,24 +1,36 @@ +.PHONY: all build test lint + BUILD_IN_CONTAINER ?= true RM=--rm -BUILD_IMAGE=golang:1.5.3 +BUILD_UPTODATE=backend/.image.uptodate +BUILD_IMAGE=checkpoint_build + +all: build + +$(BUILD_UPTODATE): backend/* + docker build -t $(BUILD_IMAGE) backend + touch $@ ifeq ($(BUILD_IN_CONTAINER),true) -all test: +build test lint: $(BUILD_UPTODATE) $(SUDO) docker run $(RM) -ti \ -v $(shell pwd):/go/src/github.com/weaveworks/go-checkpoint \ -e GOARCH -e GOOS -e BUILD_IN_CONTAINER=false \ - $(BUILD_IMAGE) make -C /go/src/github.com/weaveworks/go-checkpoint $@ + $(BUILD_IMAGE) $@ else -all: +build: go get . go build . test: - go get . + go get -t . go test +lint: + ./tools/lint -notestpackage . + endif diff --git a/vendor/github.com/weaveworks/go-checkpoint/README.md b/vendor/github.com/weaveworks/go-checkpoint/README.md index ab8ebc0d3..f82a37095 100644 --- a/vendor/github.com/weaveworks/go-checkpoint/README.md +++ b/vendor/github.com/weaveworks/go-checkpoint/README.md @@ -1,22 +1,29 @@ # Go Checkpoint Client -[Checkpoint](http://checkpoint.hashicorp.com) is an internal service at -Hashicorp that we use to check version information, broadcoast security -bulletins, etc. +[![Circle CI](https://circleci.com/gh/weaveworks/go-checkpoint/tree/master.svg?style=shield)](https://circleci.com/gh/weaveworks/go-checkpoint/tree/master) -We understand that software making remote calls over the internet -for any reason can be undesirable. Because of this, Checkpoint can be -disabled in all of our software that includes it. You can view the source -of this client to see that we're not sending any private information. +Checkpoint is an internal service at +[Weaveworks](https://www.weave.works/) to check version information, +broadcast security bulletins, etc. This repository contains the client +code for accessing that service. It is a fork of +[Hashicorp's Go Checkpoint Client](https://github.com/hashicorp/go-checkpoint) +and is embedded in several +[Weaveworks open source projects](https://github.com/weaveworks/) and +proprietary software. + +We understand that software making remote calls over the internet for +any reason can be undesirable. Because of this, Checkpoint can be +disabled in all of Weavework's software that includes it. You can view +the source of this client to see that it is not sending any private +information. + +To disable checkpoint calls, set the `CHECKPOINT_DISABLE` environment +variable, e.g. -Each Hashicorp application has it's specific configuration option -to disable chekpoint calls, but the `CHECKPOINT_DISABLE` makes -the underlying checkpoint component itself disabled. For example -in the case of packer: ``` -CHECKPOINT_DISABLE=1 packer build +export CHECKPOINT_DISABLE=1 ``` -**Note:** This repository is probably useless outside of internal HashiCorp -use. It is open source for disclosure and because our open source projects -must be able to link to it. +**Note:** This repository is probably useless outside of internal +Weaveworks use. It is open source for disclosure and because +Weaveworks open source projects must be able to link to it. diff --git a/vendor/github.com/weaveworks/go-checkpoint/backend/Dockerfile b/vendor/github.com/weaveworks/go-checkpoint/backend/Dockerfile new file mode 100644 index 000000000..f3a5a7fc7 --- /dev/null +++ b/vendor/github.com/weaveworks/go-checkpoint/backend/Dockerfile @@ -0,0 +1,12 @@ +FROM golang:1.6.2 +RUN apt-get update && \ + apt-get install -y python-requests time file sudo && \ + rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* +RUN go get -tags netgo \ + github.com/fzipp/gocyclo \ + github.com/golang/lint/golint \ + github.com/kisielk/errcheck \ + github.com/client9/misspell/cmd/misspell && \ + rm -rf /go/pkg/ /go/src/ +COPY build.sh / +ENTRYPOINT ["/build.sh"] diff --git a/vendor/github.com/weaveworks/go-checkpoint/backend/build.sh b/vendor/github.com/weaveworks/go-checkpoint/backend/build.sh new file mode 100644 index 000000000..7a6864086 --- /dev/null +++ b/vendor/github.com/weaveworks/go-checkpoint/backend/build.sh @@ -0,0 +1,23 @@ +#!/bin/sh + +set -eu + +SRC=$GOPATH/src/github.com/weaveworks/go-checkpoint + +# Mount the checkpoint repo: +# -v $(pwd):/go/src/github.com/weaveworks/checkpoint + +# If we run make directly, any files created on the bind mount +# will have awkward ownership. So we switch to a user with the +# same user and group IDs as source directory. We have to set a +# few things up so that sudo works without complaining later on. +uid=$(stat --format="%u" $SRC) +gid=$(stat --format="%g" $SRC) +echo "weave:x:$uid:$gid::$SRC:/bin/sh" >>/etc/passwd +echo "weave:*:::::::" >>/etc/shadow +echo "weave ALL=(ALL) NOPASSWD: ALL" >>/etc/sudoers + +chmod o+rw $GOPATH/src +chmod o+rw $GOPATH/src/github.com + +su weave -c "PATH=$PATH make -C $SRC BUILD_IN_CONTAINER=false $*" diff --git a/vendor/github.com/weaveworks/go-checkpoint/checkpoint.go b/vendor/github.com/weaveworks/go-checkpoint/checkpoint.go index dbff7d20f..423640c6d 100644 --- a/vendor/github.com/weaveworks/go-checkpoint/checkpoint.go +++ b/vendor/github.com/weaveworks/go-checkpoint/checkpoint.go @@ -1,5 +1,5 @@ -// checkpoint is a package for checking version information and alerts -// for a HashiCorp product. +// Package checkpoint is a package for checking version information and alerts +// for a Weaveworks product. package checkpoint import ( @@ -19,12 +19,13 @@ import ( "reflect" "runtime" "strings" + "sync" "time" "github.com/hashicorp/go-cleanhttp" ) -var magicBytes [4]byte = [4]byte{0x35, 0x77, 0x69, 0xFB} +var magicBytes = [4]byte{0x35, 0x77, 0x69, 0xFB} // CheckParams are the parameters for configuring a check request. type CheckParams struct { @@ -34,6 +35,9 @@ type CheckParams struct { Product string Version string + // Generic product flags + Flags map[string]string + // Arch and OS are used to filter alerts potentially only to things // affecting a specific os/arch combination. If these aren't specified, // they'll be automatically filled in. @@ -95,9 +99,16 @@ type CheckAlert struct { Level string } +// Checker is a state of a checker. +type Checker struct { + doneCh chan struct{} + nextCheckAt time.Time + nextCheckAtLock sync.RWMutex +} + // Check checks for alerts and new version information. func Check(p *CheckParams) (*CheckResponse, error) { - if disabled := os.Getenv("CHECKPOINT_DISABLE"); disabled != "" && !p.Force { + if IsCheckDisabled() && !p.Force { return &CheckResponse{}, nil } @@ -138,6 +149,9 @@ func Check(p *CheckParams) (*CheckResponse, error) { v.Set("arch", p.Arch) v.Set("os", p.OS) v.Set("signature", signature) + for flag, value := range p.Flags { + v.Set("flag_"+flag, value) + } u.Scheme = "https" u.Host = "checkpoint-api.weave.works" @@ -193,27 +207,56 @@ func Check(p *CheckParams) (*CheckResponse, error) { // CheckInterval is used to check for a response on a given interval duration. // The interval is not exact, and checks are randomized to prevent a thundering // herd. However, it is expected that on average one check is performed per -// interval. The returned channel may be closed to stop background checks. -func CheckInterval(p *CheckParams, interval time.Duration, cb func(*CheckResponse, error)) chan struct{} { - doneCh := make(chan struct{}) +// interval. +// The first check happens immediately after a goroutine which is responsible for +// making checks has been started. +func CheckInterval(p *CheckParams, interval time.Duration, + cb func(*CheckResponse, error)) *Checker { - if disabled := os.Getenv("CHECKPOINT_DISABLE"); disabled != "" { - return doneCh + state := &Checker{ + doneCh: make(chan struct{}), + } + + if IsCheckDisabled() { + return state } go func() { + cb(Check(p)) + for { + after := randomStagger(interval) + state.nextCheckAtLock.Lock() + state.nextCheckAt = time.Now().Add(after) + state.nextCheckAtLock.Unlock() + select { - case <-time.After(randomStagger(interval)): - resp, err := Check(p) - cb(resp, err) - case <-doneCh: + case <-time.After(after): + cb(Check(p)) + case <-state.doneCh: return } } }() - return doneCh + return state +} + +// NextCheckAt returns at what time next check will happen. +func (c *Checker) NextCheckAt() time.Time { + c.nextCheckAtLock.RLock() + defer c.nextCheckAtLock.RUnlock() + return c.nextCheckAt +} + +// Stop stops the checker. +func (c *Checker) Stop() { + close(c.doneCh) +} + +// IsCheckDisabled returns true if checks are disabled. +func IsCheckDisabled() bool { + return os.Getenv("CHECKPOINT_DISABLE") != "" } // randomStagger returns an interval that is between 3/4 and 5/4 of @@ -369,7 +412,7 @@ func writeCacheHeader(f io.Writer, v string) error { } // Write out our current version length - var length uint32 = uint32(len(v)) + var length = uint32(len(v)) if err := binary.Write(f, binary.LittleEndian, length); err != nil { return err } diff --git a/vendor/github.com/weaveworks/go-checkpoint/checkpoint_test.go b/vendor/github.com/weaveworks/go-checkpoint/checkpoint_test.go index 6d0a5addc..b81855556 100644 --- a/vendor/github.com/weaveworks/go-checkpoint/checkpoint_test.go +++ b/vendor/github.com/weaveworks/go-checkpoint/checkpoint_test.go @@ -11,19 +11,47 @@ import ( func TestCheck(t *testing.T) { expected := &CheckResponse{ - Product: "test", - CurrentVersion: "1.0", - CurrentReleaseDate: 0, - CurrentDownloadURL: "http://www.hashicorp.com", - CurrentChangelogURL: "http://www.hashicorp.com", - ProjectWebsite: "http://www.hashicorp.com", + CurrentVersion: "1.0.0", + CurrentReleaseDate: 1460459932, // 2016-04-12 11:18:52 + CurrentDownloadURL: "https://test-app.used-for-testing", + CurrentChangelogURL: "https://test-app.used-for-testing", + ProjectWebsite: "https://test-app.used-for-testing", Outdated: false, - Alerts: []*CheckAlert{}, + Alerts: nil, } actual, err := Check(&CheckParams{ - Product: "test", - Version: "1.0", + Product: "test-app", + Version: "1.0.0", + }) + + if err != nil { + t.Fatalf("err: %s", err) + } + + if !reflect.DeepEqual(actual, expected) { + t.Fatalf("bad: %#v", actual) + } +} + +func TestCheck_flags(t *testing.T) { + expected := &CheckResponse{ + CurrentVersion: "1.0.0", + CurrentReleaseDate: 1460459932, // 2016-04-12 11:18:52 + CurrentDownloadURL: "https://test-app.used-for-testing", + CurrentChangelogURL: "https://test-app.used-for-testing", + ProjectWebsite: "https://test-app.used-for-testing", + Outdated: false, + Alerts: nil, + } + + actual, err := Check(&CheckParams{ + Product: "test-app", + Version: "1.0.0", + Flags: map[string]string{ + "flag1": "value1", + "flag2": "value2", + }, }) if err != nil { @@ -42,8 +70,8 @@ func TestCheck_disabled(t *testing.T) { expected := &CheckResponse{} actual, err := Check(&CheckParams{ - Product: "test", - Version: "1.0", + Product: "test-app", + Version: "1.0.0", }) if err != nil { @@ -62,22 +90,21 @@ func TestCheck_cache(t *testing.T) { } expected := &CheckResponse{ - Product: "test", - CurrentVersion: "1.0", - CurrentReleaseDate: 0, - CurrentDownloadURL: "http://www.hashicorp.com", - CurrentChangelogURL: "http://www.hashicorp.com", - ProjectWebsite: "http://www.hashicorp.com", + CurrentVersion: "1.0.0", + CurrentReleaseDate: 1460459932, // 2016-04-12 11:18:52 + CurrentDownloadURL: "https://test-app.used-for-testing", + CurrentChangelogURL: "https://test-app.used-for-testing", + ProjectWebsite: "https://test-app.used-for-testing", Outdated: false, - Alerts: []*CheckAlert{}, + Alerts: nil, } var actual *CheckResponse for i := 0; i < 5; i++ { var err error actual, err = Check(&CheckParams{ - Product: "test", - Version: "1.0", + Product: "test-app", + Version: "1.0.0", CacheFile: filepath.Join(dir, "cache"), }) if err != nil { @@ -86,7 +113,7 @@ func TestCheck_cache(t *testing.T) { } if !reflect.DeepEqual(actual, expected) { - t.Fatalf("bad: %#v", actual) + t.Fatalf("bad: %#v %#v", actual, expected) } } @@ -97,22 +124,21 @@ func TestCheck_cacheNested(t *testing.T) { } expected := &CheckResponse{ - Product: "test", - CurrentVersion: "1.0", - CurrentReleaseDate: 0, - CurrentDownloadURL: "http://www.hashicorp.com", - CurrentChangelogURL: "http://www.hashicorp.com", - ProjectWebsite: "http://www.hashicorp.com", + CurrentVersion: "1.0.0", + CurrentReleaseDate: 1460459932, // 2016-04-12 11:18:52 + CurrentDownloadURL: "https://test-app.used-for-testing", + CurrentChangelogURL: "https://test-app.used-for-testing", + ProjectWebsite: "https://test-app.used-for-testing", Outdated: false, - Alerts: []*CheckAlert{}, + Alerts: nil, } var actual *CheckResponse for i := 0; i < 5; i++ { var err error actual, err = Check(&CheckParams{ - Product: "test", - Version: "1.0", + Product: "test-app", + Version: "1.0.0", CacheFile: filepath.Join(dir, "nested", "cache"), }) if err != nil { @@ -127,19 +153,18 @@ func TestCheck_cacheNested(t *testing.T) { func TestCheckInterval(t *testing.T) { expected := &CheckResponse{ - Product: "test", - CurrentVersion: "1.0", - CurrentReleaseDate: 0, - CurrentDownloadURL: "http://www.hashicorp.com", - CurrentChangelogURL: "http://www.hashicorp.com", - ProjectWebsite: "http://www.hashicorp.com", + CurrentVersion: "1.0.0", + CurrentReleaseDate: 1460459932, // 2016-04-12 11:18:52 + CurrentDownloadURL: "https://test-app.used-for-testing", + CurrentChangelogURL: "https://test-app.used-for-testing", + ProjectWebsite: "https://test-app.used-for-testing", Outdated: false, - Alerts: []*CheckAlert{}, + Alerts: nil, } params := &CheckParams{ - Product: "test", - Version: "1.0", + Product: "test-app", + Version: "1.0.0", } calledCh := make(chan struct{}) @@ -154,8 +179,8 @@ func TestCheckInterval(t *testing.T) { } } - doneCh := CheckInterval(params, 500*time.Millisecond, checkFn) - defer close(doneCh) + st := CheckInterval(params, 500*time.Millisecond, checkFn) + defer st.Stop() select { case <-calledCh: @@ -169,8 +194,8 @@ func TestCheckInterval_disabled(t *testing.T) { defer os.Setenv("CHECKPOINT_DISABLE", "") params := &CheckParams{ - Product: "test", - Version: "1.0", + Product: "test-app", + Version: "1.0.0", } calledCh := make(chan struct{}) @@ -178,8 +203,8 @@ func TestCheckInterval_disabled(t *testing.T) { defer close(calledCh) } - doneCh := CheckInterval(params, 500*time.Millisecond, checkFn) - defer close(doneCh) + st := CheckInterval(params, 500*time.Millisecond, checkFn) + defer st.Stop() select { case <-calledCh: @@ -188,6 +213,44 @@ func TestCheckInterval_disabled(t *testing.T) { } } +func TestCheckInterval_immediate(t *testing.T) { + expected := &CheckResponse{ + CurrentVersion: "1.0.0", + CurrentReleaseDate: 1460459932, // 2016-04-12 11:18:52 + CurrentDownloadURL: "https://test-app.used-for-testing", + CurrentChangelogURL: "https://test-app.used-for-testing", + ProjectWebsite: "https://test-app.used-for-testing", + Outdated: false, + Alerts: nil, + } + + params := &CheckParams{ + Product: "test-app", + Version: "1.0.0", + } + + calledCh := make(chan struct{}) + checkFn := func(actual *CheckResponse, err error) { + defer close(calledCh) + if err != nil { + t.Fatalf("err: %s", err) + } + + if !reflect.DeepEqual(actual, expected) { + t.Fatalf("bad: %#v", actual) + } + } + + st := CheckInterval(params, 500*time.Second, checkFn) + defer st.Stop() + + select { + case <-calledCh: + case <-time.After(time.Second): + t.Fatalf("timeout") + } +} + func TestRandomStagger(t *testing.T) { intv := 24 * time.Hour min := 18 * time.Hour diff --git a/vendor/github.com/weaveworks/go-checkpoint/circle.yml b/vendor/github.com/weaveworks/go-checkpoint/circle.yml new file mode 100644 index 000000000..497e52eb2 --- /dev/null +++ b/vendor/github.com/weaveworks/go-checkpoint/circle.yml @@ -0,0 +1,13 @@ +machine: + services: + - docker + +dependencies: + override: + - git submodule update --init --recursive + +test: + override: + - make RM= lint + - make + - make test diff --git a/vendor/manifest b/vendor/manifest index fce63bbec..fb5ce2097 100644 --- a/vendor/manifest +++ b/vendor/manifest @@ -872,7 +872,7 @@ { "importpath": "github.com/weaveworks/go-checkpoint", "repository": "https://github.com/weaveworks/go-checkpoint", - "revision": "d99cc14f13e7845b370a7dc81d47cafb29cdc97f", + "revision": "62324982ab514860761ec81e618664580513ffad", "branch": "master" }, {