diff --git a/client/app/styles/contrast.scss b/client/app/styles/contrast.scss
index 2862d3842..7533c1d9d 100644
--- a/client/app/styles/contrast.scss
+++ b/client/app/styles/contrast.scss
@@ -1,3 +1,4 @@
@import "variables";
@import "contrast-overrides";
@import "base";
+@import "terminal";
diff --git a/client/package.json b/client/package.json
index 84358a277..ee9b7c574 100644
--- a/client/package.json
+++ b/client/package.json
@@ -102,7 +102,7 @@
"build-external": "EXTERNAL=true webpack --config webpack.production.config.js",
"copy-pkg-files": "cp package.json build-pkg/ && cp -R app/styles build-pkg/",
"build-pkg": "mkdir -p build-pkg && node node_modules/.bin/babel app/scripts --ignore __tests__ --out-dir build-pkg && yarn run copy-pkg-files",
- "bundle": "yarn run build-pkg && cd ./build-pkg && yarn pack --filename ../tmp/weave-scope.tgz",
+ "bundle": "mkdir -p bundle && yarn run build-pkg && cd ./build-pkg && yarn pack --filename ../bundle/weave-scope.tgz",
"start": "node server.js",
"start-production": "NODE_ENV=production node server.js",
"test": "jest",
diff --git a/docker/Dockerfile.cloud-agent b/docker/Dockerfile.cloud-agent
index 627fcfa2b..8f7434854 100644
--- a/docker/Dockerfile.cloud-agent
+++ b/docker/Dockerfile.cloud-agent
@@ -2,7 +2,6 @@ FROM alpine:3.7
WORKDIR /home/weave
RUN apk add --update bash conntrack-tools iproute2 util-linux curl && \
rm -rf /var/cache/apk/*
-ADD ./weave ./weaveutil /usr/bin/
COPY ./scope /home/weave/
ENTRYPOINT ["/home/weave/scope", "--mode=probe", "--no-app", "--probe.docker=true"]
diff --git a/docker/Dockerfile.scope b/docker/Dockerfile.scope
index 9f2dc2851..7e0af4571 100644
--- a/docker/Dockerfile.scope
+++ b/docker/Dockerfile.scope
@@ -2,6 +2,7 @@ FROM weaveworks/cloud-agent
RUN apk add --update runit && \
rm -rf /var/cache/apk/*
ADD ./demo.json /
+ADD ./weave ./weaveutil /usr/bin/
COPY ./runsvinit ./entrypoint.sh /home/weave/
COPY ./run-app /etc/service/app/run
COPY ./run-probe /etc/service/probe/run
diff --git a/examples/k8s/cluster-role.yaml b/examples/k8s/cluster-role.yaml
index 5f70075ef..391d175b5 100644
--- a/examples/k8s/cluster-role.yaml
+++ b/examples/k8s/cluster-role.yaml
@@ -51,6 +51,14 @@ rules:
verbs:
- list
- watch
+- apigroups:
+ - extensions
+ resourcenames:
+ - weave-scope
+ resources:
+ - podsecuritypolicies
+ verbs:
+ - use
- apiGroups:
- volumesnapshot.external-storage.k8s.io
resources:
@@ -58,4 +66,4 @@ rules:
- volumesnapshotdatas
verbs:
- list
- - watch
+ - watch
\ No newline at end of file
diff --git a/examples/k8s/psp.yaml b/examples/k8s/psp.yaml
new file mode 100644
index 000000000..555a7c027
--- /dev/null
+++ b/examples/k8s/psp.yaml
@@ -0,0 +1,21 @@
+apiVersion: extensions/v1beta1
+kind: PodSecurityPolicy
+metadata:
+ name: weave-scope
+spec:
+ privileged: true
+ hostPID: true
+ hostNetwork: true
+ allowedCapabilities:
+ - 'NET_ADMIN'
+ fsGroup:
+ rule: RunAsAny
+ runAsUser:
+ rule: RunAsAny
+ seLinux:
+ rule: RunAsAny
+ supplementalGroups:
+ rule: RunAsAny
+ volumes:
+ - secret
+ - hostPath
\ No newline at end of file
diff --git a/probe/cri/registry_test.go b/probe/cri/registry_test.go
new file mode 100644
index 000000000..916f06e4f
--- /dev/null
+++ b/probe/cri/registry_test.go
@@ -0,0 +1,21 @@
+package cri_test
+
+import (
+ "testing"
+
+ "github.com/bmizerany/assert"
+ "github.com/weaveworks/scope/probe/cri"
+)
+
+func TestParseHttpEndpointUrl(t *testing.T) {
+ _, err := cri.NewCRIClient("http://xyz.com")
+
+ assert.Equal(t, "protocol \"http\" not supported", err.Error())
+}
+
+func TestParseTcpEndpointUrl(t *testing.T) {
+ client, err := cri.NewCRIClient("127.0.0.1")
+
+ assert.Equal(t, nil, err)
+ assert.NotEqual(t, nil, client)
+}
diff --git a/probe/kubernetes/reporter.go b/probe/kubernetes/reporter.go
index 3bc120cd4..29493c54a 100644
--- a/probe/kubernetes/reporter.go
+++ b/probe/kubernetes/reporter.go
@@ -210,6 +210,10 @@ func (r *Reporter) Stop() {
func (Reporter) Name() string { return "K8s" }
func (r *Reporter) podEvent(e Event, pod Pod) {
+ // filter out non-local pods, if we have been given a node name to report on
+ if r.nodeName != "" && pod.NodeName() != r.nodeName {
+ return
+ }
switch e {
case ADD:
rpt := report.MakeReport()
diff --git a/probe/probe.go b/probe/probe.go
index b34f21cde..4e9bac59e 100644
--- a/probe/probe.go
+++ b/probe/probe.go
@@ -1,17 +1,20 @@
package probe
import (
+ "context"
"sync"
"time"
"github.com/armon/go-metrics"
log "github.com/sirupsen/logrus"
+ "golang.org/x/time/rate"
"github.com/weaveworks/scope/report"
)
const (
- reportBufferSize = 16
+ spiedReportBufferSize = 16
+ shortcutReportBufferSize = 1024
)
// ReportPublisher publishes reports, probably to a remote collector.
@@ -23,6 +26,7 @@ type ReportPublisher interface {
type Probe struct {
spyInterval, publishInterval time.Duration
publisher ReportPublisher
+ rateLimiter *rate.Limiter
noControls bool
tickers []Ticker
@@ -79,10 +83,11 @@ func New(
spyInterval: spyInterval,
publishInterval: publishInterval,
publisher: publisher,
+ rateLimiter: rate.NewLimiter(rate.Every(publishInterval/100), 1),
noControls: noControls,
quit: make(chan struct{}),
- spiedReports: make(chan report.Report, reportBufferSize),
- shortcutReports: make(chan report.Report, reportBufferSize),
+ spiedReports: make(chan report.Report, spiedReportBufferSize),
+ shortcutReports: make(chan report.Report, shortcutReportBufferSize),
}
return result
}
@@ -197,6 +202,7 @@ func (p *Probe) tag(r report.Report) report.Report {
}
func (p *Probe) drainAndPublish(rpt report.Report, rs chan report.Report) {
+ p.rateLimiter.Wait(context.Background())
ForLoop:
for {
select {
diff --git a/probe/process/walker_linux.go b/probe/process/walker_linux.go
index 05240bd97..b0cad69cd 100644
--- a/probe/process/walker_linux.go
+++ b/probe/process/walker_linux.go
@@ -3,6 +3,7 @@ package process
import (
"bytes"
"encoding/binary"
+ "errors"
"fmt"
"os"
"path"
@@ -31,6 +32,8 @@ var (
// key: filename in /proc. Example: "42"
// value: two strings separated by a '\0'
cmdlineCache = freecache.NewCache(1024 * 16)
+
+ errDeadProcess = errors.New("The process is dead")
)
const (
@@ -75,6 +78,7 @@ func readStats(path string) (ppid, threads int, jiffies, rss, rssLimit uint64, e
const (
// /proc/
/stat field positions, counting from zero
// see "man 5 proc"
+ procStatFieldState int = 2
procStatFieldPpid int = 3
procStatFieldUserJiffies int = 13
procStatFieldSysJiffies int = 14
@@ -94,7 +98,16 @@ func readStats(path string) (ppid, threads int, jiffies, rss, rssLimit uint64, e
// Parse the file without using expensive extra string allocations
pos := 0
- skipNSpaces(&buf, &pos, procStatFieldPpid)
+ skipNSpaces(&buf, &pos, procStatFieldState)
+
+ // Error on processes which are in zombie (defunct) or dead state, so they will be skipped
+ switch buf[pos] {
+ case 'Z', 'X', 'x':
+ err = errDeadProcess
+ return
+ }
+
+ pos += 2 // Move past state and space after state
ppid = parseIntWithSpaces(&buf, &pos)
skipNSpaces(&buf, &pos, procStatFieldUserJiffies-procStatFieldPpid)
diff --git a/site/ami.md b/site/ami.md
index 409670891..3b8993471 100644
--- a/site/ami.md
+++ b/site/ami.md
@@ -54,8 +54,8 @@ The latest Weave ECS AMIs are based on Amazon's
[ECS-Optimized Amazon Linux AMI](https://aws.amazon.com/marketplace/pp/B06XS8WHGJ),
version `2017.03.f` and also includes:
-* [Weave Net 2.0.4](https://github.com/weaveworks/weave/blob/master/CHANGELOG.md#release-204)
-* [Weave Scope 1.6.4](https://github.com/weaveworks/scope/blob/master/CHANGELOG.md#release-164)
+* [Weave Net 2.3.0](https://github.com/weaveworks/weave/blob/master/CHANGELOG.md#release-230)
+* [Weave Scope 1.9.0](https://github.com/weaveworks/scope/blob/master/CHANGELOG.md#release-190)
## Deployment Requirements
@@ -250,6 +250,12 @@ that region when invoking the script:
ONLY_REGION=us-east-1 AWS_ACCSS_KEY_ID=XXXX AWS_SECRET_ACCESS_KEY=YYYY ./build-all-amis.sh
~~~
+To make an AMI public:
+
+~~~bash
+aws ec2 modify-image-attribute --region=us-east-2 --image-id ami-6a0b350f --launch-permission "{\"Add\": [{\"Group\":\"all\"}]}"
+~~~
+
## Further Reading
Read the