Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
6878f105
Commit
6878f105
authored
Jul 14, 2014
by
Nan Deng
Committed by
Nan Monnand Deng
Jul 16, 2014
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add a client to get container info from kubelet
parent
c7d31fab
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
333 additions
and
33 deletions
+333
-33
containerinfo.go
pkg/client/containerinfo.go
+91
-0
containerinfo_test.go
pkg/client/containerinfo_test.go
+171
-0
CHANGELOG.md
third_party/src/github.com/google/cadvisor/CHANGELOG.md
+4
-0
client_test.go
...arty/src/github.com/google/cadvisor/client/client_test.go
+2
-27
handler.go
...rc/github.com/google/cadvisor/container/docker/handler.go
+16
-3
Dockerfile
.../github.com/google/cadvisor/deploy/docker-only/Dockerfile
+1
-1
Dockerfile
...ithub.com/google/cadvisor/deploy/lmctfy-docker/Dockerfile
+1
-1
container.go
third_party/src/github.com/google/cadvisor/info/container.go
+46
-0
version.go
third_party/src/github.com/google/cadvisor/info/version.go
+1
-1
No files found.
pkg/client/containerinfo.go
0 → 100644
View file @
6878f105
/*
Copyright 2014 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
client
import
(
"bytes"
"encoding/json"
"fmt"
"io"
"net"
"net/http"
"strconv"
"github.com/google/cadvisor/info"
)
type
ContainerInfoGetter
interface
{
GetContainerInfo
(
host
,
podID
,
containerID
string
,
req
*
info
.
ContainerInfoRequest
)
(
*
info
.
ContainerInfo
,
error
)
GetMachineInfo
(
host
string
,
req
*
info
.
ContainerInfoRequest
)
(
*
info
.
ContainerInfo
,
error
)
}
type
HTTPContainerInfoGetter
struct
{
Client
*
http
.
Client
Port
int
}
func
(
self
*
HTTPContainerInfoGetter
)
getContainerInfo
(
host
,
path
string
,
req
*
info
.
ContainerInfoRequest
)
(
*
info
.
ContainerInfo
,
error
)
{
var
body
io
.
Reader
if
req
!=
nil
{
content
,
err
:=
json
.
Marshal
(
req
)
if
err
!=
nil
{
return
nil
,
err
}
body
=
bytes
.
NewBuffer
(
content
)
}
request
,
err
:=
http
.
NewRequest
(
"GET"
,
fmt
.
Sprintf
(
"http://%v/stats/%v"
,
net
.
JoinHostPort
(
host
,
strconv
.
Itoa
(
self
.
Port
)),
path
,
),
body
,
)
if
err
!=
nil
{
return
nil
,
err
}
response
,
err
:=
self
.
Client
.
Do
(
request
)
if
err
!=
nil
{
return
nil
,
err
}
defer
response
.
Body
.
Close
()
if
response
.
StatusCode
!=
http
.
StatusOK
{
return
nil
,
fmt
.
Errorf
(
"trying to get info for %v from %v; received status %v"
,
path
,
host
,
response
.
Status
)
}
decoder
:=
json
.
NewDecoder
(
response
.
Body
)
var
cinfo
info
.
ContainerInfo
err
=
decoder
.
Decode
(
&
cinfo
)
if
err
!=
nil
{
return
nil
,
err
}
return
&
cinfo
,
nil
}
func
(
self
*
HTTPContainerInfoGetter
)
GetContainerInfo
(
host
,
podID
,
containerID
string
,
req
*
info
.
ContainerInfoRequest
)
(
*
info
.
ContainerInfo
,
error
)
{
return
self
.
getContainerInfo
(
host
,
fmt
.
Sprintf
(
"%v/%v"
,
podID
,
containerID
),
req
,
)
}
func
(
self
*
HTTPContainerInfoGetter
)
GetMachineInfo
(
host
string
,
req
*
info
.
ContainerInfoRequest
)
(
*
info
.
ContainerInfo
,
error
)
{
return
self
.
getContainerInfo
(
host
,
""
,
req
)
}
pkg/client/containerinfo_test.go
0 → 100644
View file @
6878f105
/*
Copyright 2014 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
client
import
(
"encoding/json"
"net/http"
"net/http/httptest"
"net/url"
"path"
"reflect"
"strconv"
"strings"
"testing"
"time"
"github.com/google/cadvisor/info"
itest
"github.com/google/cadvisor/info/test"
)
func
testHTTPContainerInfoGetter
(
req
*
info
.
ContainerInfoRequest
,
cinfo
*
info
.
ContainerInfo
,
podID
string
,
containerID
string
,
status
int
,
t
*
testing
.
T
,
)
{
expectedPath
:=
"/stats"
if
len
(
podID
)
>
0
&&
len
(
containerID
)
>
0
{
expectedPath
=
path
.
Join
(
expectedPath
,
podID
,
containerID
)
}
ts
:=
httptest
.
NewServer
(
http
.
HandlerFunc
(
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
if
status
!=
0
{
w
.
WriteHeader
(
status
)
}
if
strings
.
TrimRight
(
r
.
URL
.
Path
,
"/"
)
!=
strings
.
TrimRight
(
expectedPath
,
"/"
)
{
t
.
Fatalf
(
"Received request to an invalid path. Should be %v. got %v"
,
expectedPath
,
r
.
URL
.
Path
)
}
decoder
:=
json
.
NewDecoder
(
r
.
Body
)
var
receivedReq
info
.
ContainerInfoRequest
err
:=
decoder
.
Decode
(
&
receivedReq
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
// Note: This will not make a deep copy of req.
// So changing req after Get*Info would be a race.
expectedReq
:=
req
// Fill any empty fields with default value
expectedReq
=
expectedReq
.
FillDefaults
()
if
!
reflect
.
DeepEqual
(
expectedReq
,
&
receivedReq
)
{
t
.
Errorf
(
"received wrong request"
)
}
encoder
:=
json
.
NewEncoder
(
w
)
err
=
encoder
.
Encode
(
cinfo
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
}))
hostURL
,
err
:=
url
.
Parse
(
ts
.
URL
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
parts
:=
strings
.
Split
(
hostURL
.
Host
,
":"
)
port
,
err
:=
strconv
.
Atoi
(
parts
[
1
])
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
containerInfoGetter
:=
&
HTTPContainerInfoGetter
{
Client
:
http
.
DefaultClient
,
Port
:
port
,
}
var
receivedContainerInfo
*
info
.
ContainerInfo
if
len
(
podID
)
>
0
&&
len
(
containerID
)
>
0
{
receivedContainerInfo
,
err
=
containerInfoGetter
.
GetContainerInfo
(
parts
[
0
],
podID
,
containerID
,
req
)
}
else
{
receivedContainerInfo
,
err
=
containerInfoGetter
.
GetMachineInfo
(
parts
[
0
],
req
)
}
if
status
==
0
||
status
==
http
.
StatusOK
{
if
err
!=
nil
{
t
.
Errorf
(
"received unexpected error: %v"
,
err
)
}
if
!
receivedContainerInfo
.
Eq
(
cinfo
)
{
t
.
Error
(
"received unexpected container info"
)
}
}
else
{
if
err
==
nil
{
t
.
Error
(
"did not receive expected error."
)
}
}
}
func
TestHTTPContainerInfoGetterGetContainerInfoSuccessfully
(
t
*
testing
.
T
)
{
req
:=
&
info
.
ContainerInfoRequest
{
NumStats
:
10
,
NumSamples
:
10
,
}
req
=
req
.
FillDefaults
()
cinfo
:=
itest
.
GenerateRandomContainerInfo
(
"dockerIDWhichWillNotBeChecked"
,
// docker ID
2
,
// Number of cores
req
,
1
*
time
.
Second
,
)
testHTTPContainerInfoGetter
(
req
,
cinfo
,
"somePodID"
,
"containerNameInK8S"
,
0
,
t
)
}
func
TestHTTPContainerInfoGetterGetMachineInfoSuccessfully
(
t
*
testing
.
T
)
{
req
:=
&
info
.
ContainerInfoRequest
{
NumStats
:
10
,
NumSamples
:
10
,
}
req
=
req
.
FillDefaults
()
cinfo
:=
itest
.
GenerateRandomContainerInfo
(
"dockerIDWhichWillNotBeChecked"
,
// docker ID
2
,
// Number of cores
req
,
1
*
time
.
Second
,
)
testHTTPContainerInfoGetter
(
req
,
cinfo
,
""
,
""
,
0
,
t
)
}
func
TestHTTPContainerInfoGetterGetContainerInfoWithError
(
t
*
testing
.
T
)
{
req
:=
&
info
.
ContainerInfoRequest
{
NumStats
:
10
,
NumSamples
:
10
,
}
req
=
req
.
FillDefaults
()
cinfo
:=
itest
.
GenerateRandomContainerInfo
(
"dockerIDWhichWillNotBeChecked"
,
// docker ID
2
,
// Number of cores
req
,
1
*
time
.
Second
,
)
testHTTPContainerInfoGetter
(
req
,
cinfo
,
"somePodID"
,
"containerNameInK8S"
,
http
.
StatusNotFound
,
t
)
}
func
TestHTTPContainerInfoGetterGetMachineInfoWithError
(
t
*
testing
.
T
)
{
req
:=
&
info
.
ContainerInfoRequest
{
NumStats
:
10
,
NumSamples
:
10
,
}
req
=
req
.
FillDefaults
()
cinfo
:=
itest
.
GenerateRandomContainerInfo
(
"dockerIDWhichWillNotBeChecked"
,
// docker ID
2
,
// Number of cores
req
,
1
*
time
.
Second
,
)
testHTTPContainerInfoGetter
(
req
,
cinfo
,
""
,
""
,
http
.
StatusNotFound
,
t
)
}
third_party/src/github.com/google/cadvisor/CHANGELOG.md
View file @
6878f105
# Changelog
## 0.1.3 (2014-07-14)
-
Add support for systemd systems.
-
Fixes for UI with InfluxDB storage driver.
## 0.1.2 (2014-07-10)
-
Added Storage Driver concept (flag: storage_driver), default is the in-memory driver
-
Implemented InfluxDB storage driver
...
...
third_party/src/github.com/google/cadvisor/client/client_test.go
View file @
6878f105
...
...
@@ -110,32 +110,7 @@ func TestGetContainerInfo(t *testing.T) {
t
.
Fatal
(
err
)
}
// We cannot use DeepEqual() to compare them directly,
// because json en/decoded time may have precision issues.
if
!
reflect
.
DeepEqual
(
returned
.
ContainerReference
,
cinfo
.
ContainerReference
)
{
t
.
Errorf
(
"received unexpected container ref"
)
}
if
!
reflect
.
DeepEqual
(
returned
.
Subcontainers
,
cinfo
.
Subcontainers
)
{
t
.
Errorf
(
"received unexpected subcontainers"
)
}
if
!
reflect
.
DeepEqual
(
returned
.
Spec
,
cinfo
.
Spec
)
{
t
.
Errorf
(
"received unexpected spec"
)
}
if
!
reflect
.
DeepEqual
(
returned
.
StatsPercentiles
,
cinfo
.
StatsPercentiles
)
{
t
.
Errorf
(
"received unexpected spec"
)
}
for
i
,
expectedStats
:=
range
cinfo
.
Stats
{
returnedStats
:=
returned
.
Stats
[
i
]
if
!
expectedStats
.
Eq
(
returnedStats
)
{
t
.
Errorf
(
"received unexpected stats"
)
}
}
for
i
,
expectedSample
:=
range
cinfo
.
Samples
{
returnedSample
:=
returned
.
Samples
[
i
]
if
!
expectedSample
.
Eq
(
returnedSample
)
{
t
.
Errorf
(
"received unexpected sample"
)
}
if
!
returned
.
Eq
(
cinfo
)
{
t
.
Error
(
"received unexpected ContainerInfo"
)
}
}
third_party/src/github.com/google/cadvisor/container/docker/handler.go
View file @
6878f105
...
...
@@ -21,12 +21,14 @@ import (
"math"
"os"
"path"
"path/filepath"
"strings"
"time"
"github.com/docker/libcontainer"
"github.com/docker/libcontainer/cgroups"
"github.com/docker/libcontainer/cgroups/fs"
"github.com/docker/libcontainer/cgroups/systemd"
"github.com/fsouza/go-dockerclient"
"github.com/google/cadvisor/container"
"github.com/google/cadvisor/info"
...
...
@@ -98,8 +100,11 @@ func (self *dockerContainerHandler) splitName() (string, string, error) {
if
nestedLevels
>
0
{
// we are running inside a docker container
upperLevel
:=
strings
.
Repeat
(
"../../"
,
nestedLevels
)
//parent = strings.Join([]string{parent, upperLevel}, "/")
parent
=
fmt
.
Sprintf
(
"%v%v"
,
upperLevel
,
parent
)
parent
=
filepath
.
Join
(
upperLevel
,
parent
)
}
// Strip the last "/"
if
parent
[
len
(
parent
)
-
1
]
==
'/'
{
parent
=
parent
[
:
len
(
parent
)
-
1
]
}
return
parent
,
id
,
nil
}
...
...
@@ -237,7 +242,15 @@ func (self *dockerContainerHandler) GetStats() (stats *info.ContainerStats, err
Parent
:
parent
,
Name
:
id
,
}
s
,
err
:=
fs
.
GetStats
(
cg
)
// TODO(vmarmol): Use libcontainer's Stats() in the new API when that is ready.
// Use systemd paths if systemd is being used.
var
s
*
cgroups
.
Stats
if
systemd
.
UseSystemd
()
{
s
,
err
=
systemd
.
GetStats
(
cg
)
}
else
{
s
,
err
=
fs
.
GetStats
(
cg
)
}
if
err
!=
nil
{
return
}
...
...
third_party/src/github.com/google/cadvisor/deploy/docker-only/Dockerfile
View file @
6878f105
...
...
@@ -2,7 +2,7 @@ FROM busybox:ubuntu-14.04
MAINTAINER
kyurtsever@google.com dengnan@google.com vmarmol@google.com jason@swindle.me
# Get cAdvisor binaries.
ADD
http://storage.googleapis.com/cadvisor-bin/cadvisor /usr/bin/cadvisor
ADD
http://storage.googleapis.com/cadvisor-bin/cadvisor
-0.1.3
/usr/bin/cadvisor
RUN
chmod
+x /usr/bin/cadvisor
EXPOSE
8080
...
...
third_party/src/github.com/google/cadvisor/deploy/lmctfy-docker/Dockerfile
View file @
6878f105
...
...
@@ -7,7 +7,7 @@ RUN apt-get update && apt-get install -y -q --no-install-recommends pkg-config l
# Get the lcmtfy and cAdvisor binaries.
ADD
http://storage.googleapis.com/cadvisor-bin/lmctfy/lmctfy /usr/bin/lmctfy
ADD
http://storage.googleapis.com/cadvisor-bin/lmctfy/libre2.so.0.0.0 /usr/lib/libre2.so.0
ADD
http://storage.googleapis.com/cadvisor-bin/cadvisor-0.1.
2
/usr/bin/cadvisor
ADD
http://storage.googleapis.com/cadvisor-bin/cadvisor-0.1.
3
/usr/bin/cadvisor
RUN
chmod
+x /usr/bin/lmctfy
&&
chmod
+x /usr/bin/cadvisor
EXPOSE
8080
...
...
third_party/src/github.com/google/cadvisor/info/container.go
View file @
6878f105
...
...
@@ -110,6 +110,52 @@ type ContainerInfo struct {
StatsPercentiles
*
ContainerStatsPercentiles
`json:"stats_summary,omitempty"`
}
// ContainerInfo may be (un)marshaled by json or other en/decoder. In that
// case, the Timestamp field in each stats/sample may not be precisely
// en/decoded. This will lead to small but acceptable differences between a
// ContainerInfo and its encode-then-decode version. Eq() is used to compare
// two ContainerInfo accepting small difference (<10ms) of Time fields.
func
(
self
*
ContainerInfo
)
Eq
(
b
*
ContainerInfo
)
bool
{
// If both self and b are nil, then Eq() returns true
if
self
==
nil
{
return
b
==
nil
}
if
b
==
nil
{
return
self
==
nil
}
// For fields other than time.Time, we will compare them precisely.
// This would require that any slice should have same order.
if
!
reflect
.
DeepEqual
(
self
.
ContainerReference
,
b
.
ContainerReference
)
{
return
false
}
if
!
reflect
.
DeepEqual
(
self
.
Subcontainers
,
b
.
Subcontainers
)
{
return
false
}
if
!
reflect
.
DeepEqual
(
self
.
Spec
,
b
.
Spec
)
{
return
false
}
if
!
reflect
.
DeepEqual
(
self
.
StatsPercentiles
,
b
.
StatsPercentiles
)
{
return
false
}
for
i
,
expectedStats
:=
range
b
.
Stats
{
selfStats
:=
self
.
Stats
[
i
]
if
!
expectedStats
.
Eq
(
selfStats
)
{
return
false
}
}
for
i
,
expectedSample
:=
range
b
.
Samples
{
selfSample
:=
self
.
Samples
[
i
]
if
!
expectedSample
.
Eq
(
selfSample
)
{
return
false
}
}
return
true
}
func
(
self
*
ContainerInfo
)
StatsAfter
(
ref
time
.
Time
)
[]
*
ContainerStats
{
n
:=
len
(
self
.
Stats
)
+
1
for
i
,
s
:=
range
self
.
Stats
{
...
...
third_party/src/github.com/google/cadvisor/info/version.go
View file @
6878f105
...
...
@@ -15,4 +15,4 @@
package
info
// Version of cAdvisor.
const
VERSION
=
"0.1.
2
"
const
VERSION
=
"0.1.
3
"
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment