From 0d2e2cda8fc45044c084fe1e15be2809dc255503 Mon Sep 17 00:00:00 2001 From: Tom Wilkie Date: Mon, 25 Apr 2016 14:00:02 +0100 Subject: [PATCH 1/2] Detect if sudo is required by running 'docker info' --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index a91dec0379..a61f352526 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ .PHONY: all deps static clean client-lint client-test client-sync backend frontend shell lint # If you can use Docker without being root, you can `make SUDO= ` -SUDO=$(shell (echo "$$DOCKER_HOST" | grep "tcp://" >/dev/null) || echo "sudo -E") +SUDO=$(shell docker info >/dev/null 2>&1 || echo "sudo -E") DOCKERHUB_USER=weaveworks SCOPE_EXE=prog/scope SCOPE_IMAGE=$(DOCKERHUB_USER)/scope From b05ef7455296840820fc1c473cad63417590bedc Mon Sep 17 00:00:00 2001 From: Tom Wilkie Date: Mon, 25 Apr 2016 14:11:04 +0100 Subject: [PATCH 2/2] Report hostname and version in probe struct, and version in host node. --- app/api_report.go | 23 ++++++++++++++++--- probe/host/reporter.go | 32 ++++++++++++++++++--------- probe/host/reporter_test.go | 3 +-- probe/probe.go | 12 ++++------ probe/probe_internal_test.go | 9 ++------ prog/probe.go | 4 ++-- report/probes.go | 43 ------------------------------------ report/report.go | 6 ----- 8 files changed, 50 insertions(+), 82 deletions(-) delete mode 100644 report/probes.go diff --git a/app/api_report.go b/app/api_report.go index bf17046351..380c30387e 100644 --- a/app/api_report.go +++ b/app/api_report.go @@ -2,9 +2,11 @@ package app import ( "net/http" + "time" "golang.org/x/net/context" + "github.com/weaveworks/scope/probe/host" "github.com/weaveworks/scope/report" ) @@ -20,6 +22,13 @@ func makeRawReportHandler(rep Reporter) CtxHandlerFunc { } } +type probeDesc struct { + ID string `json:"id"` + Hostname string `json:"hostname"` + Version string `json:"version"` + LastSeen time.Time `json:"lastSeen"` +} + // Probe handler func makeProbeHandler(rep Reporter) CtxHandlerFunc { return func(ctx context.Context, w http.ResponseWriter, r *http.Request) { @@ -28,9 +37,17 @@ func makeProbeHandler(rep Reporter) CtxHandlerFunc { respondWith(w, http.StatusInternalServerError, err.Error()) return } - result := []report.Probe{} - for _, p := range rpt.Probes { - result = append(result, p) + result := []probeDesc{} + for _, n := range rpt.Host.Nodes { + id, _ := n.Latest.Lookup(report.ControlProbeID) + hostname, _ := n.Latest.Lookup(host.HostName) + version, dt, _ := n.Latest.LookupEntry(host.ScopeVersion) + result = append(result, probeDesc{ + ID: id, + Hostname: hostname, + Version: version, + LastSeen: dt, + }) } respondWith(w, http.StatusOK, result) } diff --git a/probe/host/reporter.go b/probe/host/reporter.go index d1a2074b83..e93538b5e7 100644 --- a/probe/host/reporter.go +++ b/probe/host/reporter.go @@ -21,6 +21,7 @@ const ( Load1 = "load1" CPUUsage = "host_cpu_usage_percent" MemoryUsage = "host_mem_usage_bytes" + ScopeVersion = "host_scope_version" ) // Exposed for testing. @@ -39,6 +40,7 @@ var ( HostName: {ID: HostName, Label: "Hostname", From: report.FromLatest, Priority: 11}, OS: {ID: OS, Label: "OS", From: report.FromLatest, Priority: 12}, LocalNetworks: {ID: LocalNetworks, Label: "Local Networks", From: report.FromSets, Priority: 13}, + ScopeVersion: {ID: ScopeVersion, Label: "Scope Version", From: report.FromLatest, Priority: 14}, } MetricTemplates = report.MetricTemplates{ @@ -53,18 +55,20 @@ type Reporter struct { hostID string hostName string probeID string + version string pipes controls.PipeClient hostShellCmd []string } // NewReporter returns a Reporter which produces a report containing host // topology for this host. -func NewReporter(hostID, hostName, probeID string, pipes controls.PipeClient) *Reporter { +func NewReporter(hostID, hostName, probeID, version string, pipes controls.PipeClient) *Reporter { r := &Reporter{ hostID: hostID, hostName: hostName, probeID: probeID, pipes: pipes, + version: version, hostShellCmd: getHostShellCmd(), } r.registerControls() @@ -125,16 +129,22 @@ func (r *Reporter) Report() (report.Report, error) { memoryUsage, max := GetMemoryUsageBytes() metrics[MemoryUsage] = report.MakeMetric().Add(now, memoryUsage).WithMax(max) - metadata := map[string]string{report.ControlProbeID: r.probeID} - rep.Host.AddNode(report.MakeNodeWith(report.MakeHostNodeID(r.hostID), map[string]string{ - Timestamp: mtime.Now().UTC().Format(time.RFC3339Nano), - HostName: r.hostName, - OS: runtime.GOOS, - KernelVersion: kernel, - Uptime: uptime.String(), - }).WithSets(report.EmptySets. - Add(LocalNetworks, report.MakeStringSet(localCIDRs...)), - ).WithMetrics(metrics).WithControls(ExecHost).WithLatests(metadata)) + rep.Host.AddNode( + report.MakeNodeWith(report.MakeHostNodeID(r.hostID), map[string]string{ + report.ControlProbeID: r.probeID, + Timestamp: mtime.Now().UTC().Format(time.RFC3339Nano), + HostName: r.hostName, + OS: runtime.GOOS, + KernelVersion: kernel, + Uptime: uptime.String(), + ScopeVersion: r.version, + }). + WithSets(report.EmptySets. + Add(LocalNetworks, report.MakeStringSet(localCIDRs...)), + ). + WithMetrics(metrics). + WithControls(ExecHost), + ) rep.Host.Controls.AddControl(report.Control{ ID: ExecHost, diff --git a/probe/host/reporter_test.go b/probe/host/reporter_test.go index 5ddccf0c99..08cf2ffed1 100644 --- a/probe/host/reporter_test.go +++ b/probe/host/reporter_test.go @@ -18,7 +18,6 @@ func TestReporter(t *testing.T) { network = "192.168.0.0/16" hostID = "hostid" hostname = "hostname" - probeID = "abcdeadbeef" timestamp = time.Now() metrics = report.Metrics{ host.Load1: report.MakeMetric().Add(timestamp, 1.0), @@ -56,7 +55,7 @@ func TestReporter(t *testing.T) { host.GetMemoryUsageBytes = func() (float64, float64) { return 60.0, 100.0 } host.GetLocalNetworks = func() ([]*net.IPNet, error) { return []*net.IPNet{ipnet}, nil } - rpt, err := host.NewReporter(hostID, hostname, probeID, nil).Report() + rpt, err := host.NewReporter(hostID, hostname, "", "", nil).Report() if err != nil { t.Fatal(err) } diff --git a/probe/probe.go b/probe/probe.go index 729f61064b..0c5697be28 100644 --- a/probe/probe.go +++ b/probe/probe.go @@ -7,7 +7,6 @@ import ( log "github.com/Sirupsen/logrus" "github.com/armon/go-metrics" - "github.com/weaveworks/scope/common/mtime" "github.com/weaveworks/scope/probe/appclient" "github.com/weaveworks/scope/report" ) @@ -18,7 +17,6 @@ const ( // Probe sits there, generating and publishing reports. type Probe struct { - id string spyInterval, publishInterval time.Duration publisher *appclient.ReportPublisher @@ -67,9 +65,11 @@ type Ticker interface { } // New makes a new Probe. -func New(id string, spyInterval, publishInterval time.Duration, publisher appclient.Publisher) *Probe { +func New( + spyInterval, publishInterval time.Duration, + publisher appclient.Publisher, +) *Probe { result := &Probe{ - id: id, spyInterval: spyInterval, publishInterval: publishInterval, publisher: appclient.NewReportPublisher(publisher), @@ -166,10 +166,6 @@ func (p *Probe) report() report.Report { for i := 0; i < cap(reports); i++ { result = result.Merge(<-reports) } - result.Probes[p.id] = report.Probe{ - ID: p.id, - LastSeen: mtime.Now(), - } return result } diff --git a/probe/probe_internal_test.go b/probe/probe_internal_test.go index f9ac1522c5..81ab7e0487 100644 --- a/probe/probe_internal_test.go +++ b/probe/probe_internal_test.go @@ -19,7 +19,7 @@ func TestApply(t *testing.T) { endpointNode = report.MakeNodeWith(endpointNodeID, map[string]string{"5": "6"}) ) - p := New("", 0, 0, nil) + p := New(0, 0, nil) p.AddTagger(NewTopologyTagger()) r := report.MakeReport() @@ -89,16 +89,11 @@ func TestProbe(t *testing.T) { want.Service.Controls = nil want.Host.Controls = nil want.Overlay.Controls = nil - want.Endpoint.AddNode(node) - want.Probes[probeID] = report.Probe{ - ID: probeID, - LastSeen: now, - } pub := mockPublisher{make(chan report.Report, 10)} - p := New(probeID, 10*time.Millisecond, 100*time.Millisecond, pub) + p := New(10*time.Millisecond, 100*time.Millisecond, pub) p.AddReporter(mockReporter{want}) p.Start() defer p.Stop() diff --git a/prog/probe.go b/prog/probe.go index dc43ba12f4..e572a29755 100644 --- a/prog/probe.go +++ b/prog/probe.go @@ -117,9 +117,9 @@ func probeMain(flags probeFlags) { endpointReporter := endpoint.NewReporter(hostID, hostName, flags.spyProcs, flags.useConntrack, scanner) defer endpointReporter.Stop() - p := probe.New(probeID, flags.spyInterval, flags.publishInterval, clients) + p := probe.New(flags.spyInterval, flags.publishInterval, clients) p.AddTicker(processCache) - hostReporter := host.NewReporter(hostID, hostName, probeID, clients) + hostReporter := host.NewReporter(hostID, hostName, probeID, version, clients) defer hostReporter.Stop() p.AddReporter( endpointReporter, diff --git a/report/probes.go b/report/probes.go deleted file mode 100644 index 3d320bf639..0000000000 --- a/report/probes.go +++ /dev/null @@ -1,43 +0,0 @@ -package report - -import ( - "time" -) - -// Probes contains details of the probe(s) which generated a report. -type Probes map[string]Probe - -// Copy produces a copy of the Probes -func (ps Probes) Copy() Probes { - result := Probes{} - for id, probe := range ps { - result[id] = probe.Copy() - } - return result -} - -// Merge two sets of Probes, keeping the records with the latest LastSeen -func (ps Probes) Merge(other Probes) Probes { - result := ps.Copy() - for id, probe := range other { - o, ok := result[id] - if !ok || o.LastSeen.Before(probe.LastSeen) { - result[id] = probe - } - } - return result -} - -// Probe is the details for a single probe that generated a report. -type Probe struct { - ID string `json:"id"` - LastSeen time.Time `json:"lastSeen"` -} - -// Copy produces a copy of the Probe -func (p Probe) Copy() Probe { - return Probe{ - ID: p.ID, - LastSeen: p.LastSeen, - } -} diff --git a/report/report.go b/report/report.go index 7488f60877..493dcb55e1 100644 --- a/report/report.go +++ b/report/report.go @@ -95,9 +95,6 @@ type Report struct { // must be equal, but we don't require that equal reports have // the same id. ID string `deepequal:"skip"` - - // Probes is the details of the probes who reported this report - Probes Probes } // MakeReport makes a clean report, ready to Merge() other reports into. @@ -135,7 +132,6 @@ func MakeReport() Report { Window: 0, Plugins: xfer.MakePluginSpecs(), ID: fmt.Sprintf("%d", rand.Int63()), - Probes: Probes{}, } } @@ -154,7 +150,6 @@ func (r Report) Copy() Report { Window: r.Window, Plugins: r.Plugins.Copy(), ID: fmt.Sprintf("%d", rand.Int63()), - Probes: r.Probes.Copy(), } } @@ -171,7 +166,6 @@ func (r Report) Merge(other Report) Report { cp.Service = r.Service.Merge(other.Service) cp.Overlay = r.Overlay.Merge(other.Overlay) cp.Sampling = r.Sampling.Merge(other.Sampling) - cp.Probes = r.Probes.Merge(other.Probes) cp.Window += other.Window cp.Plugins = r.Plugins.Merge(other.Plugins) return cp