diff --git a/CHANGELOG.md b/CHANGELOG.md index 49686a90..bb1894eb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +### 0.24.1 (2016-10-10) + +- Fix issue with running cAdvisor in a container on some distributions. + ### 0.24.0 (2016-09-19) - Added host-level inode stats (total & available) diff --git a/Makefile b/Makefile index d6b9b6b4..de9c56d2 100644 --- a/Makefile +++ b/Makefile @@ -23,6 +23,9 @@ test: test-integration: @./build/integration.sh +test-runner: + @$(GO) build github.com/google/cadvisor/integration/runner + format: @echo ">> formatting code" @$(GO) fmt $(pkgs) diff --git a/build/jenkins_e2e.sh b/build/jenkins_e2e.sh index 614041e8..1f5b25c0 100755 --- a/build/jenkins_e2e.sh +++ b/build/jenkins_e2e.sh @@ -31,8 +31,11 @@ if [[ ! -z "$(git diff --name-only pages)" ]]; then exit 1 fi -make -go build -tags test github.com/google/cadvisor/integration/runner +# Build & test with go 1.7 +docker run --rm \ + -w "/go/src/github.com/google/cadvisor" \ + -v "${GOPATH}/src/github.com/google/cadvisor:/go/src/github.com/google/cadvisor" \ + golang:1.7.1 make all test-runner # Nodes that are currently stable. When tests fail on a specific node, and the failure is not remedied within a week, that node will be removed from this list. golden_nodes=( diff --git a/fs/fs.go b/fs/fs.go index 46756d4e..a879e59f 100644 --- a/fs/fs.go +++ b/fs/fs.go @@ -346,7 +346,7 @@ func (self *RealFsInfo) GetFsInfoForPath(mountSet map[string]struct{}) ([]Fs, er return filesystems, nil } -var partitionRegex = regexp.MustCompile(`^(?:(?:s|xv)d[a-z]+\d*|dm-\d+)$`) +var partitionRegex = regexp.MustCompile(`^(?:(?:s|v|xv)d[a-z]+\d*|dm-\d+)$`) func getDiskStatsMap(diskStatsFile string) (map[string]DiskStats, error) { diskStatsMap := make(map[string]DiskStats) diff --git a/info/v2/conversion.go b/info/v2/conversion.go index 03dfe096..dc24c9fe 100644 --- a/info/v2/conversion.go +++ b/info/v2/conversion.go @@ -119,6 +119,8 @@ func ContainerStatsFromV1(spec *v1.ContainerSpec, stats []*v1.ContainerStats) [] if spec.HasNetwork { // TODO: Handle TcpStats stat.Network = &NetworkStats{ + Tcp: TcpStat(val.Network.Tcp), + Tcp6: TcpStat(val.Network.Tcp6), Interfaces: val.Network.Interfaces, } } diff --git a/utils/tail/tail.go b/utils/tail/tail.go index 2d04f3fc..beccee36 100644 --- a/utils/tail/tail.go +++ b/utils/tail/tail.go @@ -45,6 +45,16 @@ const ( // NewTail starts opens the given file and watches it for deletion/rotation func NewTail(filename string) (*Tail, error) { + t, err := newTail(filename) + if err != nil { + return nil, err + } + go t.watchLoop() + return t, nil +} + +// newTail creates a Tail object. +func newTail(filename string) (*Tail, error) { t := &Tail{ filename: filename, } @@ -54,7 +64,9 @@ func NewTail(filename string) (*Tail, error) { if err != nil { return nil, fmt.Errorf("inotify init failed on %s: %v", t.filename, err) } - go t.watchLoop() + // Initialize readerErr as io.EOF, so that the reader can work properly + // during initialization. + t.readerErr = io.EOF return t, nil } @@ -62,23 +74,23 @@ func NewTail(filename string) (*Tail, error) { func (t *Tail) Read(p []byte) (int, error) { t.readerLock.RLock() defer t.readerLock.RUnlock() - if t.reader == nil || t.readerErr != nil { + if t.readerErr != nil { return 0, t.readerErr } return t.reader.Read(p) } -var _ io.Reader = &Tail{} +var _ io.ReadCloser = &Tail{} // Close stops watching and closes the file -func (t *Tail) Close() { +func (t *Tail) Close() error { close(t.stop) + return nil } func (t *Tail) attemptOpen() error { t.readerLock.Lock() defer t.readerLock.Unlock() - t.reader = nil t.readerErr = nil attempt := 0 for interval := defaultRetryInterval; ; interval *= 2 { diff --git a/utils/tail/tail_test.go b/utils/tail/tail_test.go new file mode 100644 index 00000000..f47405af --- /dev/null +++ b/utils/tail/tail_test.go @@ -0,0 +1,34 @@ +// Copyright 2016 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package tail + +import ( + "io" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestReadNewTail(t *testing.T) { + // Read should return (0, io.EOF) before first + // attemptOpen. + tail, err := newTail("test/nonexist/file") + assert.NoError(t, err) + buf := make([]byte, 0, 100) + n, err := tail.Read(buf) + assert.Equal(t, n, 0) + assert.Equal(t, len(buf), 0) + assert.EqualError(t, err, io.EOF.Error()) +}