Merge pull request #68431 from dashpole/cadvisor_godep_update

Update cAdvisor godeps to v0.31.0
pull/8/head
k8s-ci-robot 2018-09-12 15:04:53 -07:00 committed by GitHub
commit 37ef6eeb6d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
118 changed files with 190025 additions and 318 deletions

393
Godeps/Godeps.json generated
View File

@ -26,12 +26,12 @@
},
{
"ImportPath": "cloud.google.com/go/compute/metadata",
"Comment": "v0.1.0-115-g3b1ae45",
"Comment": "v0.1.0-115-g3b1ae453",
"Rev": "3b1ae45394a234c385be014e9a488f2bb6eef821"
},
{
"ImportPath": "cloud.google.com/go/internal",
"Comment": "v0.1.0-115-g3b1ae45",
"Comment": "v0.1.0-115-g3b1ae453",
"Rev": "3b1ae45394a234c385be014e9a488f2bb6eef821"
},
{
@ -150,6 +150,26 @@
"ImportPath": "github.com/PuerkitoBio/urlesc",
"Rev": "5bd2802263f21d8788851d5305584c82a5c75d7e"
},
{
"ImportPath": "github.com/Rican7/retry",
"Comment": "v0.1.0-9-g272ad12",
"Rev": "272ad122d6e5ce1be757544007cf8bcd1c9c9ab0"
},
{
"ImportPath": "github.com/Rican7/retry/backoff",
"Comment": "v0.1.0-9-g272ad12",
"Rev": "272ad122d6e5ce1be757544007cf8bcd1c9c9ab0"
},
{
"ImportPath": "github.com/Rican7/retry/jitter",
"Comment": "v0.1.0-9-g272ad12",
"Rev": "272ad122d6e5ce1be757544007cf8bcd1c9c9ab0"
},
{
"ImportPath": "github.com/Rican7/retry/strategy",
"Comment": "v0.1.0-9-g272ad12",
"Rev": "272ad122d6e5ce1be757544007cf8bcd1c9c9ab0"
},
{
"ImportPath": "github.com/armon/circbuf",
"Rev": "bbbad097214e2918d8543d5201d12bfd7bca254d"
@ -1320,142 +1340,142 @@
},
{
"ImportPath": "github.com/docker/distribution/digestset",
"Comment": "v2.6.0-rc.1-209-gedc3ab2",
"Comment": "v2.6.0-rc.1-209-gedc3ab29",
"Rev": "edc3ab29cdff8694dd6feb85cfeb4b5f1b38ed9c"
},
{
"ImportPath": "github.com/docker/distribution/reference",
"Comment": "v2.6.0-rc.1-209-gedc3ab2",
"Comment": "v2.6.0-rc.1-209-gedc3ab29",
"Rev": "edc3ab29cdff8694dd6feb85cfeb4b5f1b38ed9c"
},
{
"ImportPath": "github.com/docker/docker/api",
"Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc",
"Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8d",
"Rev": "a9fbbdc8dd8794b20af358382ab780559bca589d"
},
{
"ImportPath": "github.com/docker/docker/api/types",
"Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc",
"Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8d",
"Rev": "a9fbbdc8dd8794b20af358382ab780559bca589d"
},
{
"ImportPath": "github.com/docker/docker/api/types/blkiodev",
"Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc",
"Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8d",
"Rev": "a9fbbdc8dd8794b20af358382ab780559bca589d"
},
{
"ImportPath": "github.com/docker/docker/api/types/container",
"Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc",
"Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8d",
"Rev": "a9fbbdc8dd8794b20af358382ab780559bca589d"
},
{
"ImportPath": "github.com/docker/docker/api/types/events",
"Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc",
"Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8d",
"Rev": "a9fbbdc8dd8794b20af358382ab780559bca589d"
},
{
"ImportPath": "github.com/docker/docker/api/types/filters",
"Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc",
"Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8d",
"Rev": "a9fbbdc8dd8794b20af358382ab780559bca589d"
},
{
"ImportPath": "github.com/docker/docker/api/types/image",
"Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc",
"Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8d",
"Rev": "a9fbbdc8dd8794b20af358382ab780559bca589d"
},
{
"ImportPath": "github.com/docker/docker/api/types/mount",
"Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc",
"Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8d",
"Rev": "a9fbbdc8dd8794b20af358382ab780559bca589d"
},
{
"ImportPath": "github.com/docker/docker/api/types/network",
"Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc",
"Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8d",
"Rev": "a9fbbdc8dd8794b20af358382ab780559bca589d"
},
{
"ImportPath": "github.com/docker/docker/api/types/registry",
"Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc",
"Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8d",
"Rev": "a9fbbdc8dd8794b20af358382ab780559bca589d"
},
{
"ImportPath": "github.com/docker/docker/api/types/strslice",
"Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc",
"Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8d",
"Rev": "a9fbbdc8dd8794b20af358382ab780559bca589d"
},
{
"ImportPath": "github.com/docker/docker/api/types/swarm",
"Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc",
"Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8d",
"Rev": "a9fbbdc8dd8794b20af358382ab780559bca589d"
},
{
"ImportPath": "github.com/docker/docker/api/types/swarm/runtime",
"Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc",
"Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8d",
"Rev": "a9fbbdc8dd8794b20af358382ab780559bca589d"
},
{
"ImportPath": "github.com/docker/docker/api/types/time",
"Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc",
"Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8d",
"Rev": "a9fbbdc8dd8794b20af358382ab780559bca589d"
},
{
"ImportPath": "github.com/docker/docker/api/types/versions",
"Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc",
"Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8d",
"Rev": "a9fbbdc8dd8794b20af358382ab780559bca589d"
},
{
"ImportPath": "github.com/docker/docker/api/types/volume",
"Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc",
"Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8d",
"Rev": "a9fbbdc8dd8794b20af358382ab780559bca589d"
},
{
"ImportPath": "github.com/docker/docker/client",
"Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc",
"Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8d",
"Rev": "a9fbbdc8dd8794b20af358382ab780559bca589d"
},
{
"ImportPath": "github.com/docker/docker/daemon/logger/jsonfilelog/jsonlog",
"Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc",
"Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8d",
"Rev": "a9fbbdc8dd8794b20af358382ab780559bca589d"
},
{
"ImportPath": "github.com/docker/docker/pkg/jsonmessage",
"Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc",
"Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8d",
"Rev": "a9fbbdc8dd8794b20af358382ab780559bca589d"
},
{
"ImportPath": "github.com/docker/docker/pkg/mount",
"Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc",
"Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8d",
"Rev": "a9fbbdc8dd8794b20af358382ab780559bca589d"
},
{
"ImportPath": "github.com/docker/docker/pkg/parsers",
"Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc",
"Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8d",
"Rev": "a9fbbdc8dd8794b20af358382ab780559bca589d"
},
{
"ImportPath": "github.com/docker/docker/pkg/parsers/operatingsystem",
"Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc",
"Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8d",
"Rev": "a9fbbdc8dd8794b20af358382ab780559bca589d"
},
{
"ImportPath": "github.com/docker/docker/pkg/stdcopy",
"Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc",
"Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8d",
"Rev": "a9fbbdc8dd8794b20af358382ab780559bca589d"
},
{
"ImportPath": "github.com/docker/docker/pkg/sysinfo",
"Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc",
"Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8d",
"Rev": "a9fbbdc8dd8794b20af358382ab780559bca589d"
},
{
"ImportPath": "github.com/docker/docker/pkg/term",
"Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc",
"Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8d",
"Rev": "a9fbbdc8dd8794b20af358382ab780559bca589d"
},
{
"ImportPath": "github.com/docker/docker/pkg/term/windows",
"Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc",
"Comment": "docs-v1.12.0-rc4-2016-07-15-9510-ga9fbbdc8d",
"Rev": "a9fbbdc8dd8794b20af358382ab780559bca589d"
},
{
@ -1480,7 +1500,7 @@
},
{
"ImportPath": "github.com/docker/libnetwork/ipvs",
"Comment": "v0.8.0-dev.2-910-gba46b92",
"Comment": "v0.8.0-dev.2-910-gba46b928",
"Rev": "ba46b928444931e6865d8618dc03622cac79aa6f"
},
{
@ -1599,132 +1619,132 @@
},
{
"ImportPath": "github.com/gogo/protobuf/gogoproto",
"Comment": "v0.4-3-gc0656ed",
"Comment": "v0.4-3-gc0656edd",
"Rev": "c0656edd0d9eab7c66d1eb0c568f9039345796f7"
},
{
"ImportPath": "github.com/gogo/protobuf/plugin/compare",
"Comment": "v0.4-3-gc0656ed",
"Comment": "v0.4-3-gc0656edd",
"Rev": "c0656edd0d9eab7c66d1eb0c568f9039345796f7"
},
{
"ImportPath": "github.com/gogo/protobuf/plugin/defaultcheck",
"Comment": "v0.4-3-gc0656ed",
"Comment": "v0.4-3-gc0656edd",
"Rev": "c0656edd0d9eab7c66d1eb0c568f9039345796f7"
},
{
"ImportPath": "github.com/gogo/protobuf/plugin/description",
"Comment": "v0.4-3-gc0656ed",
"Comment": "v0.4-3-gc0656edd",
"Rev": "c0656edd0d9eab7c66d1eb0c568f9039345796f7"
},
{
"ImportPath": "github.com/gogo/protobuf/plugin/embedcheck",
"Comment": "v0.4-3-gc0656ed",
"Comment": "v0.4-3-gc0656edd",
"Rev": "c0656edd0d9eab7c66d1eb0c568f9039345796f7"
},
{
"ImportPath": "github.com/gogo/protobuf/plugin/enumstringer",
"Comment": "v0.4-3-gc0656ed",
"Comment": "v0.4-3-gc0656edd",
"Rev": "c0656edd0d9eab7c66d1eb0c568f9039345796f7"
},
{
"ImportPath": "github.com/gogo/protobuf/plugin/equal",
"Comment": "v0.4-3-gc0656ed",
"Comment": "v0.4-3-gc0656edd",
"Rev": "c0656edd0d9eab7c66d1eb0c568f9039345796f7"
},
{
"ImportPath": "github.com/gogo/protobuf/plugin/face",
"Comment": "v0.4-3-gc0656ed",
"Comment": "v0.4-3-gc0656edd",
"Rev": "c0656edd0d9eab7c66d1eb0c568f9039345796f7"
},
{
"ImportPath": "github.com/gogo/protobuf/plugin/gostring",
"Comment": "v0.4-3-gc0656ed",
"Comment": "v0.4-3-gc0656edd",
"Rev": "c0656edd0d9eab7c66d1eb0c568f9039345796f7"
},
{
"ImportPath": "github.com/gogo/protobuf/plugin/marshalto",
"Comment": "v0.4-3-gc0656ed",
"Comment": "v0.4-3-gc0656edd",
"Rev": "c0656edd0d9eab7c66d1eb0c568f9039345796f7"
},
{
"ImportPath": "github.com/gogo/protobuf/plugin/oneofcheck",
"Comment": "v0.4-3-gc0656ed",
"Comment": "v0.4-3-gc0656edd",
"Rev": "c0656edd0d9eab7c66d1eb0c568f9039345796f7"
},
{
"ImportPath": "github.com/gogo/protobuf/plugin/populate",
"Comment": "v0.4-3-gc0656ed",
"Comment": "v0.4-3-gc0656edd",
"Rev": "c0656edd0d9eab7c66d1eb0c568f9039345796f7"
},
{
"ImportPath": "github.com/gogo/protobuf/plugin/size",
"Comment": "v0.4-3-gc0656ed",
"Comment": "v0.4-3-gc0656edd",
"Rev": "c0656edd0d9eab7c66d1eb0c568f9039345796f7"
},
{
"ImportPath": "github.com/gogo/protobuf/plugin/stringer",
"Comment": "v0.4-3-gc0656ed",
"Comment": "v0.4-3-gc0656edd",
"Rev": "c0656edd0d9eab7c66d1eb0c568f9039345796f7"
},
{
"ImportPath": "github.com/gogo/protobuf/plugin/testgen",
"Comment": "v0.4-3-gc0656ed",
"Comment": "v0.4-3-gc0656edd",
"Rev": "c0656edd0d9eab7c66d1eb0c568f9039345796f7"
},
{
"ImportPath": "github.com/gogo/protobuf/plugin/union",
"Comment": "v0.4-3-gc0656ed",
"Comment": "v0.4-3-gc0656edd",
"Rev": "c0656edd0d9eab7c66d1eb0c568f9039345796f7"
},
{
"ImportPath": "github.com/gogo/protobuf/plugin/unmarshal",
"Comment": "v0.4-3-gc0656ed",
"Comment": "v0.4-3-gc0656edd",
"Rev": "c0656edd0d9eab7c66d1eb0c568f9039345796f7"
},
{
"ImportPath": "github.com/gogo/protobuf/proto",
"Comment": "v0.4-3-gc0656ed",
"Comment": "v0.4-3-gc0656edd",
"Rev": "c0656edd0d9eab7c66d1eb0c568f9039345796f7"
},
{
"ImportPath": "github.com/gogo/protobuf/protoc-gen-gogo/descriptor",
"Comment": "v0.4-3-gc0656ed",
"Comment": "v0.4-3-gc0656edd",
"Rev": "c0656edd0d9eab7c66d1eb0c568f9039345796f7"
},
{
"ImportPath": "github.com/gogo/protobuf/protoc-gen-gogo/generator",
"Comment": "v0.4-3-gc0656ed",
"Comment": "v0.4-3-gc0656edd",
"Rev": "c0656edd0d9eab7c66d1eb0c568f9039345796f7"
},
{
"ImportPath": "github.com/gogo/protobuf/protoc-gen-gogo/grpc",
"Comment": "v0.4-3-gc0656ed",
"Comment": "v0.4-3-gc0656edd",
"Rev": "c0656edd0d9eab7c66d1eb0c568f9039345796f7"
},
{
"ImportPath": "github.com/gogo/protobuf/protoc-gen-gogo/plugin",
"Comment": "v0.4-3-gc0656ed",
"Comment": "v0.4-3-gc0656edd",
"Rev": "c0656edd0d9eab7c66d1eb0c568f9039345796f7"
},
{
"ImportPath": "github.com/gogo/protobuf/sortkeys",
"Comment": "v0.4-3-gc0656ed",
"Comment": "v0.4-3-gc0656edd",
"Rev": "c0656edd0d9eab7c66d1eb0c568f9039345796f7"
},
{
"ImportPath": "github.com/gogo/protobuf/types",
"Comment": "v0.4-3-gc0656ed",
"Comment": "v0.4-3-gc0656edd",
"Rev": "c0656edd0d9eab7c66d1eb0c568f9039345796f7"
},
{
"ImportPath": "github.com/gogo/protobuf/vanity",
"Comment": "v0.4-3-gc0656ed",
"Comment": "v0.4-3-gc0656edd",
"Rev": "c0656edd0d9eab7c66d1eb0c568f9039345796f7"
},
{
"ImportPath": "github.com/gogo/protobuf/vanity/command",
"Comment": "v0.4-3-gc0656ed",
"Comment": "v0.4-3-gc0656edd",
"Rev": "c0656edd0d9eab7c66d1eb0c568f9039345796f7"
},
{
@ -1790,183 +1810,188 @@
},
{
"ImportPath": "github.com/google/cadvisor/accelerators",
"Comment": "v0.30.0-12-gf834c0f",
"Rev": "f834c0f4c100ae524db33139dce953e0003f23ad"
"Comment": "v0.31.0",
"Rev": "fc17731afdcf184832482e324913c8f1a91b54ee"
},
{
"ImportPath": "github.com/google/cadvisor/cache/memory",
"Comment": "v0.30.0-12-gf834c0f",
"Rev": "f834c0f4c100ae524db33139dce953e0003f23ad"
"Comment": "v0.31.0",
"Rev": "fc17731afdcf184832482e324913c8f1a91b54ee"
},
{
"ImportPath": "github.com/google/cadvisor/client/v2",
"Comment": "v0.30.0-12-gf834c0f",
"Rev": "f834c0f4c100ae524db33139dce953e0003f23ad"
"Comment": "v0.31.0",
"Rev": "fc17731afdcf184832482e324913c8f1a91b54ee"
},
{
"ImportPath": "github.com/google/cadvisor/collector",
"Comment": "v0.30.0-12-gf834c0f",
"Rev": "f834c0f4c100ae524db33139dce953e0003f23ad"
"Comment": "v0.31.0",
"Rev": "fc17731afdcf184832482e324913c8f1a91b54ee"
},
{
"ImportPath": "github.com/google/cadvisor/container",
"Comment": "v0.30.0-12-gf834c0f",
"Rev": "f834c0f4c100ae524db33139dce953e0003f23ad"
"Comment": "v0.31.0",
"Rev": "fc17731afdcf184832482e324913c8f1a91b54ee"
},
{
"ImportPath": "github.com/google/cadvisor/container/common",
"Comment": "v0.30.0-12-gf834c0f",
"Rev": "f834c0f4c100ae524db33139dce953e0003f23ad"
"Comment": "v0.31.0",
"Rev": "fc17731afdcf184832482e324913c8f1a91b54ee"
},
{
"ImportPath": "github.com/google/cadvisor/container/containerd",
"Comment": "v0.30.0-12-gf834c0f",
"Rev": "f834c0f4c100ae524db33139dce953e0003f23ad"
"Comment": "v0.31.0",
"Rev": "fc17731afdcf184832482e324913c8f1a91b54ee"
},
{
"ImportPath": "github.com/google/cadvisor/container/crio",
"Comment": "v0.30.0-12-gf834c0f",
"Rev": "f834c0f4c100ae524db33139dce953e0003f23ad"
"Comment": "v0.31.0",
"Rev": "fc17731afdcf184832482e324913c8f1a91b54ee"
},
{
"ImportPath": "github.com/google/cadvisor/container/docker",
"Comment": "v0.30.0-12-gf834c0f",
"Rev": "f834c0f4c100ae524db33139dce953e0003f23ad"
"Comment": "v0.31.0",
"Rev": "fc17731afdcf184832482e324913c8f1a91b54ee"
},
{
"ImportPath": "github.com/google/cadvisor/container/libcontainer",
"Comment": "v0.30.0-12-gf834c0f",
"Rev": "f834c0f4c100ae524db33139dce953e0003f23ad"
"Comment": "v0.31.0",
"Rev": "fc17731afdcf184832482e324913c8f1a91b54ee"
},
{
"ImportPath": "github.com/google/cadvisor/container/mesos",
"Comment": "v0.31.0",
"Rev": "fc17731afdcf184832482e324913c8f1a91b54ee"
},
{
"ImportPath": "github.com/google/cadvisor/container/raw",
"Comment": "v0.30.0-12-gf834c0f",
"Rev": "f834c0f4c100ae524db33139dce953e0003f23ad"
"Comment": "v0.31.0",
"Rev": "fc17731afdcf184832482e324913c8f1a91b54ee"
},
{
"ImportPath": "github.com/google/cadvisor/container/rkt",
"Comment": "v0.30.0-12-gf834c0f",
"Rev": "f834c0f4c100ae524db33139dce953e0003f23ad"
"Comment": "v0.31.0",
"Rev": "fc17731afdcf184832482e324913c8f1a91b54ee"
},
{
"ImportPath": "github.com/google/cadvisor/container/systemd",
"Comment": "v0.30.0-12-gf834c0f",
"Rev": "f834c0f4c100ae524db33139dce953e0003f23ad"
"Comment": "v0.31.0",
"Rev": "fc17731afdcf184832482e324913c8f1a91b54ee"
},
{
"ImportPath": "github.com/google/cadvisor/devicemapper",
"Comment": "v0.30.0-12-gf834c0f",
"Rev": "f834c0f4c100ae524db33139dce953e0003f23ad"
"Comment": "v0.31.0",
"Rev": "fc17731afdcf184832482e324913c8f1a91b54ee"
},
{
"ImportPath": "github.com/google/cadvisor/events",
"Comment": "v0.30.0-12-gf834c0f",
"Rev": "f834c0f4c100ae524db33139dce953e0003f23ad"
"Comment": "v0.31.0",
"Rev": "fc17731afdcf184832482e324913c8f1a91b54ee"
},
{
"ImportPath": "github.com/google/cadvisor/fs",
"Comment": "v0.30.0-12-gf834c0f",
"Rev": "f834c0f4c100ae524db33139dce953e0003f23ad"
"Comment": "v0.31.0",
"Rev": "fc17731afdcf184832482e324913c8f1a91b54ee"
},
{
"ImportPath": "github.com/google/cadvisor/info/v1",
"Comment": "v0.30.0-12-gf834c0f",
"Rev": "f834c0f4c100ae524db33139dce953e0003f23ad"
"Comment": "v0.31.0",
"Rev": "fc17731afdcf184832482e324913c8f1a91b54ee"
},
{
"ImportPath": "github.com/google/cadvisor/info/v2",
"Comment": "v0.30.0-12-gf834c0f",
"Rev": "f834c0f4c100ae524db33139dce953e0003f23ad"
"Comment": "v0.31.0",
"Rev": "fc17731afdcf184832482e324913c8f1a91b54ee"
},
{
"ImportPath": "github.com/google/cadvisor/machine",
"Comment": "v0.30.0-12-gf834c0f",
"Rev": "f834c0f4c100ae524db33139dce953e0003f23ad"
"Comment": "v0.31.0",
"Rev": "fc17731afdcf184832482e324913c8f1a91b54ee"
},
{
"ImportPath": "github.com/google/cadvisor/manager",
"Comment": "v0.30.0-12-gf834c0f",
"Rev": "f834c0f4c100ae524db33139dce953e0003f23ad"
"Comment": "v0.31.0",
"Rev": "fc17731afdcf184832482e324913c8f1a91b54ee"
},
{
"ImportPath": "github.com/google/cadvisor/manager/watcher",
"Comment": "v0.30.0-12-gf834c0f",
"Rev": "f834c0f4c100ae524db33139dce953e0003f23ad"
"Comment": "v0.31.0",
"Rev": "fc17731afdcf184832482e324913c8f1a91b54ee"
},
{
"ImportPath": "github.com/google/cadvisor/manager/watcher/raw",
"Comment": "v0.30.0-12-gf834c0f",
"Rev": "f834c0f4c100ae524db33139dce953e0003f23ad"
"Comment": "v0.31.0",
"Rev": "fc17731afdcf184832482e324913c8f1a91b54ee"
},
{
"ImportPath": "github.com/google/cadvisor/manager/watcher/rkt",
"Comment": "v0.30.0-12-gf834c0f",
"Rev": "f834c0f4c100ae524db33139dce953e0003f23ad"
"Comment": "v0.31.0",
"Rev": "fc17731afdcf184832482e324913c8f1a91b54ee"
},
{
"ImportPath": "github.com/google/cadvisor/metrics",
"Comment": "v0.30.0-12-gf834c0f",
"Rev": "f834c0f4c100ae524db33139dce953e0003f23ad"
"Comment": "v0.31.0",
"Rev": "fc17731afdcf184832482e324913c8f1a91b54ee"
},
{
"ImportPath": "github.com/google/cadvisor/storage",
"Comment": "v0.30.0-12-gf834c0f",
"Rev": "f834c0f4c100ae524db33139dce953e0003f23ad"
"Comment": "v0.31.0",
"Rev": "fc17731afdcf184832482e324913c8f1a91b54ee"
},
{
"ImportPath": "github.com/google/cadvisor/summary",
"Comment": "v0.30.0-12-gf834c0f",
"Rev": "f834c0f4c100ae524db33139dce953e0003f23ad"
"Comment": "v0.31.0",
"Rev": "fc17731afdcf184832482e324913c8f1a91b54ee"
},
{
"ImportPath": "github.com/google/cadvisor/utils",
"Comment": "v0.30.0-12-gf834c0f",
"Rev": "f834c0f4c100ae524db33139dce953e0003f23ad"
"Comment": "v0.31.0",
"Rev": "fc17731afdcf184832482e324913c8f1a91b54ee"
},
{
"ImportPath": "github.com/google/cadvisor/utils/cloudinfo",
"Comment": "v0.30.0-12-gf834c0f",
"Rev": "f834c0f4c100ae524db33139dce953e0003f23ad"
"Comment": "v0.31.0",
"Rev": "fc17731afdcf184832482e324913c8f1a91b54ee"
},
{
"ImportPath": "github.com/google/cadvisor/utils/cpuload",
"Comment": "v0.30.0-12-gf834c0f",
"Rev": "f834c0f4c100ae524db33139dce953e0003f23ad"
"Comment": "v0.31.0",
"Rev": "fc17731afdcf184832482e324913c8f1a91b54ee"
},
{
"ImportPath": "github.com/google/cadvisor/utils/cpuload/netlink",
"Comment": "v0.30.0-12-gf834c0f",
"Rev": "f834c0f4c100ae524db33139dce953e0003f23ad"
"Comment": "v0.31.0",
"Rev": "fc17731afdcf184832482e324913c8f1a91b54ee"
},
{
"ImportPath": "github.com/google/cadvisor/utils/docker",
"Comment": "v0.30.0-12-gf834c0f",
"Rev": "f834c0f4c100ae524db33139dce953e0003f23ad"
"Comment": "v0.31.0",
"Rev": "fc17731afdcf184832482e324913c8f1a91b54ee"
},
{
"ImportPath": "github.com/google/cadvisor/utils/oomparser",
"Comment": "v0.30.0-12-gf834c0f",
"Rev": "f834c0f4c100ae524db33139dce953e0003f23ad"
"Comment": "v0.31.0",
"Rev": "fc17731afdcf184832482e324913c8f1a91b54ee"
},
{
"ImportPath": "github.com/google/cadvisor/utils/sysfs",
"Comment": "v0.30.0-12-gf834c0f",
"Rev": "f834c0f4c100ae524db33139dce953e0003f23ad"
"Comment": "v0.31.0",
"Rev": "fc17731afdcf184832482e324913c8f1a91b54ee"
},
{
"ImportPath": "github.com/google/cadvisor/utils/sysinfo",
"Comment": "v0.30.0-12-gf834c0f",
"Rev": "f834c0f4c100ae524db33139dce953e0003f23ad"
"Comment": "v0.31.0",
"Rev": "fc17731afdcf184832482e324913c8f1a91b54ee"
},
{
"ImportPath": "github.com/google/cadvisor/version",
"Comment": "v0.30.0-12-gf834c0f",
"Rev": "f834c0f4c100ae524db33139dce953e0003f23ad"
"Comment": "v0.31.0",
"Rev": "fc17731afdcf184832482e324913c8f1a91b54ee"
},
{
"ImportPath": "github.com/google/cadvisor/zfs",
"Comment": "v0.30.0-12-gf834c0f",
"Rev": "f834c0f4c100ae524db33139dce953e0003f23ad"
"Comment": "v0.31.0",
"Rev": "fc17731afdcf184832482e324913c8f1a91b54ee"
},
{
"ImportPath": "github.com/google/certificate-transparency-go",
@ -2392,6 +2417,76 @@
"Comment": "v1.0.1",
"Rev": "c12348ce28de40eed0136aa2b644d0ee0650e56c"
},
{
"ImportPath": "github.com/mesos/mesos-go/api/v1/lib",
"Comment": "mesos-1.6.x-12-gff8175b",
"Rev": "ff8175bfda54b1eb1f1954c8102a9dc612aa2312"
},
{
"ImportPath": "github.com/mesos/mesos-go/api/v1/lib/agent",
"Comment": "mesos-1.6.x-12-gff8175b",
"Rev": "ff8175bfda54b1eb1f1954c8102a9dc612aa2312"
},
{
"ImportPath": "github.com/mesos/mesos-go/api/v1/lib/agent/calls",
"Comment": "mesos-1.6.x-12-gff8175b",
"Rev": "ff8175bfda54b1eb1f1954c8102a9dc612aa2312"
},
{
"ImportPath": "github.com/mesos/mesos-go/api/v1/lib/client",
"Comment": "mesos-1.6.x-12-gff8175b",
"Rev": "ff8175bfda54b1eb1f1954c8102a9dc612aa2312"
},
{
"ImportPath": "github.com/mesos/mesos-go/api/v1/lib/debug",
"Comment": "mesos-1.6.x-12-gff8175b",
"Rev": "ff8175bfda54b1eb1f1954c8102a9dc612aa2312"
},
{
"ImportPath": "github.com/mesos/mesos-go/api/v1/lib/encoding",
"Comment": "mesos-1.6.x-12-gff8175b",
"Rev": "ff8175bfda54b1eb1f1954c8102a9dc612aa2312"
},
{
"ImportPath": "github.com/mesos/mesos-go/api/v1/lib/encoding/codecs",
"Comment": "mesos-1.6.x-12-gff8175b",
"Rev": "ff8175bfda54b1eb1f1954c8102a9dc612aa2312"
},
{
"ImportPath": "github.com/mesos/mesos-go/api/v1/lib/encoding/framing",
"Comment": "mesos-1.6.x-12-gff8175b",
"Rev": "ff8175bfda54b1eb1f1954c8102a9dc612aa2312"
},
{
"ImportPath": "github.com/mesos/mesos-go/api/v1/lib/encoding/json",
"Comment": "mesos-1.6.x-12-gff8175b",
"Rev": "ff8175bfda54b1eb1f1954c8102a9dc612aa2312"
},
{
"ImportPath": "github.com/mesos/mesos-go/api/v1/lib/encoding/proto",
"Comment": "mesos-1.6.x-12-gff8175b",
"Rev": "ff8175bfda54b1eb1f1954c8102a9dc612aa2312"
},
{
"ImportPath": "github.com/mesos/mesos-go/api/v1/lib/httpcli",
"Comment": "mesos-1.6.x-12-gff8175b",
"Rev": "ff8175bfda54b1eb1f1954c8102a9dc612aa2312"
},
{
"ImportPath": "github.com/mesos/mesos-go/api/v1/lib/httpcli/apierrors",
"Comment": "mesos-1.6.x-12-gff8175b",
"Rev": "ff8175bfda54b1eb1f1954c8102a9dc612aa2312"
},
{
"ImportPath": "github.com/mesos/mesos-go/api/v1/lib/recordio",
"Comment": "mesos-1.6.x-12-gff8175b",
"Rev": "ff8175bfda54b1eb1f1954c8102a9dc612aa2312"
},
{
"ImportPath": "github.com/mesos/mesos-go/api/v1/lib/roles",
"Comment": "mesos-1.6.x-12-gff8175b",
"Rev": "ff8175bfda54b1eb1f1954c8102a9dc612aa2312"
},
{
"ImportPath": "github.com/mholt/caddy/caddyfile",
"Comment": "v0.10.10-57-g2de4950",
@ -2656,82 +2751,82 @@
},
{
"ImportPath": "github.com/opencontainers/runc/libcontainer",
"Comment": "v1.0.0-rc5-46-g871ba2e",
"Comment": "v1.0.0-rc5-46-g871ba2e5",
"Rev": "871ba2e58e24314d1fab4517a80410191ba5ad01"
},
{
"ImportPath": "github.com/opencontainers/runc/libcontainer/apparmor",
"Comment": "v1.0.0-rc5-46-g871ba2e",
"Comment": "v1.0.0-rc5-46-g871ba2e5",
"Rev": "871ba2e58e24314d1fab4517a80410191ba5ad01"
},
{
"ImportPath": "github.com/opencontainers/runc/libcontainer/cgroups",
"Comment": "v1.0.0-rc5-46-g871ba2e",
"Comment": "v1.0.0-rc5-46-g871ba2e5",
"Rev": "871ba2e58e24314d1fab4517a80410191ba5ad01"
},
{
"ImportPath": "github.com/opencontainers/runc/libcontainer/cgroups/fs",
"Comment": "v1.0.0-rc5-46-g871ba2e",
"Comment": "v1.0.0-rc5-46-g871ba2e5",
"Rev": "871ba2e58e24314d1fab4517a80410191ba5ad01"
},
{
"ImportPath": "github.com/opencontainers/runc/libcontainer/cgroups/systemd",
"Comment": "v1.0.0-rc5-46-g871ba2e",
"Comment": "v1.0.0-rc5-46-g871ba2e5",
"Rev": "871ba2e58e24314d1fab4517a80410191ba5ad01"
},
{
"ImportPath": "github.com/opencontainers/runc/libcontainer/configs",
"Comment": "v1.0.0-rc5-46-g871ba2e",
"Comment": "v1.0.0-rc5-46-g871ba2e5",
"Rev": "871ba2e58e24314d1fab4517a80410191ba5ad01"
},
{
"ImportPath": "github.com/opencontainers/runc/libcontainer/configs/validate",
"Comment": "v1.0.0-rc5-46-g871ba2e",
"Comment": "v1.0.0-rc5-46-g871ba2e5",
"Rev": "871ba2e58e24314d1fab4517a80410191ba5ad01"
},
{
"ImportPath": "github.com/opencontainers/runc/libcontainer/criurpc",
"Comment": "v1.0.0-rc5-46-g871ba2e",
"Comment": "v1.0.0-rc5-46-g871ba2e5",
"Rev": "871ba2e58e24314d1fab4517a80410191ba5ad01"
},
{
"ImportPath": "github.com/opencontainers/runc/libcontainer/intelrdt",
"Comment": "v1.0.0-rc5-46-g871ba2e",
"Comment": "v1.0.0-rc5-46-g871ba2e5",
"Rev": "871ba2e58e24314d1fab4517a80410191ba5ad01"
},
{
"ImportPath": "github.com/opencontainers/runc/libcontainer/keys",
"Comment": "v1.0.0-rc5-46-g871ba2e",
"Comment": "v1.0.0-rc5-46-g871ba2e5",
"Rev": "871ba2e58e24314d1fab4517a80410191ba5ad01"
},
{
"ImportPath": "github.com/opencontainers/runc/libcontainer/mount",
"Comment": "v1.0.0-rc5-46-g871ba2e",
"Comment": "v1.0.0-rc5-46-g871ba2e5",
"Rev": "871ba2e58e24314d1fab4517a80410191ba5ad01"
},
{
"ImportPath": "github.com/opencontainers/runc/libcontainer/seccomp",
"Comment": "v1.0.0-rc5-46-g871ba2e",
"Comment": "v1.0.0-rc5-46-g871ba2e5",
"Rev": "871ba2e58e24314d1fab4517a80410191ba5ad01"
},
{
"ImportPath": "github.com/opencontainers/runc/libcontainer/stacktrace",
"Comment": "v1.0.0-rc5-46-g871ba2e",
"Comment": "v1.0.0-rc5-46-g871ba2e5",
"Rev": "871ba2e58e24314d1fab4517a80410191ba5ad01"
},
{
"ImportPath": "github.com/opencontainers/runc/libcontainer/system",
"Comment": "v1.0.0-rc5-46-g871ba2e",
"Comment": "v1.0.0-rc5-46-g871ba2e5",
"Rev": "871ba2e58e24314d1fab4517a80410191ba5ad01"
},
{
"ImportPath": "github.com/opencontainers/runc/libcontainer/user",
"Comment": "v1.0.0-rc5-46-g871ba2e",
"Comment": "v1.0.0-rc5-46-g871ba2e5",
"Rev": "871ba2e58e24314d1fab4517a80410191ba5ad01"
},
{
"ImportPath": "github.com/opencontainers/runc/libcontainer/utils",
"Comment": "v1.0.0-rc5-46-g871ba2e",
"Comment": "v1.0.0-rc5-46-g871ba2e5",
"Rev": "871ba2e58e24314d1fab4517a80410191ba5ad01"
},
{
@ -2784,6 +2879,14 @@
"ImportPath": "github.com/pquerna/cachecontrol/cacheobject",
"Rev": "0dec1b30a0215bb68605dfc568e8855066c9202d"
},
{
"ImportPath": "github.com/pquerna/ffjson/fflib/v1",
"Rev": "af8b230fcd2007c7095168ca8ab94c68b60840c6"
},
{
"ImportPath": "github.com/pquerna/ffjson/fflib/v1/internal",
"Rev": "af8b230fcd2007c7095168ca8ab94c68b60840c6"
},
{
"ImportPath": "github.com/prometheus/client_golang/prometheus",
"Comment": "v0.8.0-83-ge7e9030",

3638
Godeps/LICENSES generated

File diff suppressed because it is too large Load Diff

View File

@ -104,18 +104,23 @@ func containerLabels(c *cadvisorapi.ContainerInfo) map[string]string {
func New(imageFsInfoProvider ImageFsInfoProvider, rootPath string, usingLegacyStats bool) (Interface, error) {
sysFs := sysfs.NewRealSysFs()
ignoreMetrics := cadvisormetrics.MetricSet{
cadvisormetrics.NetworkTcpUsageMetrics: struct{}{},
cadvisormetrics.NetworkUdpUsageMetrics: struct{}{},
cadvisormetrics.PerCpuUsageMetrics: struct{}{},
cadvisormetrics.ProcessSchedulerMetrics: struct{}{},
includedMetrics := cadvisormetrics.MetricSet{
cadvisormetrics.CpuUsageMetrics: struct{}{},
cadvisormetrics.MemoryUsageMetrics: struct{}{},
cadvisormetrics.CpuLoadMetrics: struct{}{},
cadvisormetrics.DiskIOMetrics: struct{}{},
cadvisormetrics.NetworkUsageMetrics: struct{}{},
cadvisormetrics.AcceleratorUsageMetrics: struct{}{},
cadvisormetrics.AppMetrics: struct{}{},
}
if !usingLegacyStats {
ignoreMetrics[cadvisormetrics.DiskUsageMetrics] = struct{}{}
if usingLegacyStats {
includedMetrics[cadvisormetrics.DiskUsageMetrics] = struct{}{}
}
// collect metrics for all cgroups
rawContainerCgroupPathPrefixWhiteList := []string{"/"}
// Create and start the cAdvisor container manager.
m, err := manager.New(memory.New(statsCacheDuration, nil), sysFs, maxHousekeepingInterval, allowDynamicHousekeeping, ignoreMetrics, http.DefaultClient)
m, err := manager.New(memory.New(statsCacheDuration, nil), sysFs, maxHousekeepingInterval, allowDynamicHousekeeping, includedMetrics, http.DefaultClient, rawContainerCgroupPathPrefixWhiteList)
if err != nil {
return nil, err
}

View File

@ -43,6 +43,7 @@ go_library(
"//staging/src/k8s.io/apiserver/pkg/util/logs:go_default_library",
"//vendor/github.com/emicklei/go-restful:go_default_library",
"//vendor/github.com/golang/glog:go_default_library",
"//vendor/github.com/google/cadvisor/container:go_default_library",
"//vendor/github.com/google/cadvisor/info/v1:go_default_library",
"//vendor/github.com/google/cadvisor/metrics:go_default_library",
"//vendor/github.com/prometheus/client_golang/prometheus:go_default_library",

View File

@ -33,6 +33,7 @@ import (
restful "github.com/emicklei/go-restful"
"github.com/golang/glog"
cadvisormetrics "github.com/google/cadvisor/container"
cadvisorapi "github.com/google/cadvisor/info/v1"
"github.com/google/cadvisor/metrics"
"github.com/prometheus/client_golang/prometheus"
@ -276,7 +277,18 @@ func (s *Server) InstallDefaultHandlers() {
// cAdvisor metrics are exposed under the secured handler as well
r := prometheus.NewRegistry()
r.MustRegister(metrics.NewPrometheusCollector(prometheusHostAdapter{s.host}, containerPrometheusLabelsFunc(s.host)))
includedMetrics := cadvisormetrics.MetricSet{
cadvisormetrics.CpuUsageMetrics: struct{}{},
cadvisormetrics.MemoryUsageMetrics: struct{}{},
cadvisormetrics.CpuLoadMetrics: struct{}{},
cadvisormetrics.DiskIOMetrics: struct{}{},
cadvisormetrics.DiskUsageMetrics: struct{}{},
cadvisormetrics.NetworkUsageMetrics: struct{}{},
cadvisormetrics.AcceleratorUsageMetrics: struct{}{},
cadvisormetrics.AppMetrics: struct{}{},
}
r.MustRegister(metrics.NewPrometheusCollector(prometheusHostAdapter{s.host}, containerPrometheusLabelsFunc(s.host), includedMetrics))
s.restfulCont.Handle(cadvisorMetricsPath,
promhttp.HandlerFor(r, promhttp.HandlerOpts{ErrorHandling: promhttp.ContinueOnError}),
)

3
vendor/BUILD vendored
View File

@ -33,6 +33,7 @@ filegroup(
"//vendor/github.com/Nvveen/Gotty:all-srcs",
"//vendor/github.com/PuerkitoBio/purell:all-srcs",
"//vendor/github.com/PuerkitoBio/urlesc:all-srcs",
"//vendor/github.com/Rican7/retry:all-srcs",
"//vendor/github.com/armon/circbuf:all-srcs",
"//vendor/github.com/asaskevich/govalidator:all-srcs",
"//vendor/github.com/aws/aws-sdk-go/aws:all-srcs",
@ -302,6 +303,7 @@ filegroup(
"//vendor/github.com/mattn/go-shellwords:all-srcs",
"//vendor/github.com/mattn/go-sqlite3:all-srcs",
"//vendor/github.com/matttproud/golang_protobuf_extensions/pbutil:all-srcs",
"//vendor/github.com/mesos/mesos-go/api/v1/lib:all-srcs",
"//vendor/github.com/mholt/caddy/caddyfile:all-srcs",
"//vendor/github.com/miekg/dns:all-srcs",
"//vendor/github.com/mindprince/gonvml:all-srcs",
@ -328,6 +330,7 @@ filegroup(
"//vendor/github.com/pkg/sftp:all-srcs",
"//vendor/github.com/pmezard/go-difflib/difflib:all-srcs",
"//vendor/github.com/pquerna/cachecontrol:all-srcs",
"//vendor/github.com/pquerna/ffjson/fflib/v1:all-srcs",
"//vendor/github.com/prometheus/client_golang/prometheus:all-srcs",
"//vendor/github.com/prometheus/client_model/go:all-srcs",
"//vendor/github.com/prometheus/common/expfmt:all-srcs",

39
vendor/github.com/Rican7/retry/.travis.yml generated vendored Normal file
View File

@ -0,0 +1,39 @@
language: go
go:
- 1.6
- tip
sudo: false
before_install:
# Install tools necessary to report code-coverage to Coveralls.io
- go get github.com/mattn/goveralls
# Export some environment variables
- export GO_TEST_COVERAGE_FILE_NAME='coverage.out'
install:
# Get all imported packages
- make install-deps install-deps-dev
# Basic build errors
- make build
script:
# Lint
- make format-lint
- make import-lint
- make copyright-lint
# Run tests
- make test-with-coverage-profile
after_success:
# Report our code-coverage to Coveralls.io
- goveralls -service=travis-ci -coverprofile="${GO_TEST_COVERAGE_FILE_NAME}"
matrix:
allow_failures:
- go: tip
fast_finish: true

29
vendor/github.com/Rican7/retry/BUILD generated vendored Normal file
View File

@ -0,0 +1,29 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = ["retry.go"],
importmap = "k8s.io/kubernetes/vendor/github.com/Rican7/retry",
importpath = "github.com/Rican7/retry",
visibility = ["//visibility:public"],
deps = ["//vendor/github.com/Rican7/retry/strategy:go_default_library"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//vendor/github.com/Rican7/retry/backoff:all-srcs",
"//vendor/github.com/Rican7/retry/jitter:all-srcs",
"//vendor/github.com/Rican7/retry/strategy:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

19
vendor/github.com/Rican7/retry/LICENSE generated vendored Normal file
View File

@ -0,0 +1,19 @@
Copyright (C) 2016 Trevor N. Suarez (Rican7)
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

83
vendor/github.com/Rican7/retry/Makefile generated vendored Normal file
View File

@ -0,0 +1,83 @@
# Define some VCS context
PARENT_BRANCH ?= master
# Set the mode for code-coverage
GO_TEST_COVERAGE_MODE ?= count
GO_TEST_COVERAGE_FILE_NAME ?= coverage.out
# Set flags for `gofmt`
GOFMT_FLAGS ?= -s
# Set a default `min_confidence` value for `golint`
GOLINT_MIN_CONFIDENCE ?= 0.3
all: install-deps build install
clean:
go clean -i -x ./...
build:
go build -v ./...
install:
go install ./...
install-deps:
go get -d -t ./...
install-deps-dev: install-deps
go get github.com/golang/lint/golint
go get golang.org/x/tools/cmd/goimports
update-deps:
go get -d -t -u ./...
update-deps-dev: update-deps
go get -u github.com/golang/lint/golint
go get -u golang.org/x/tools/cmd/goimports
test:
go test -v ./...
test-with-coverage:
go test -cover ./...
test-with-coverage-formatted:
go test -cover ./... | column -t | sort -r
test-with-coverage-profile:
echo "mode: ${GO_TEST_COVERAGE_MODE}" > ${GO_TEST_COVERAGE_FILE_NAME}
for package in $$(go list ./...); do \
go test -covermode ${GO_TEST_COVERAGE_MODE} -coverprofile "coverage_$${package##*/}.out" "$${package}"; \
sed '1d' "coverage_$${package##*/}.out" >> ${GO_TEST_COVERAGE_FILE_NAME}; \
done
format-lint:
errors=$$(gofmt -l ${GOFMT_FLAGS} .); if [ "$${errors}" != "" ]; then echo "$${errors}"; exit 1; fi
import-lint:
errors=$$(goimports -l .); if [ "$${errors}" != "" ]; then echo "$${errors}"; exit 1; fi
style-lint:
errors=$$(golint -min_confidence=${GOLINT_MIN_CONFIDENCE} ./...); if [ "$${errors}" != "" ]; then echo "$${errors}"; exit 1; fi
copyright-lint:
@old_dates=$$(git diff --diff-filter=ACMRTUXB --name-only "${PARENT_BRANCH}" | xargs grep -E '[Cc]opyright(\s+)[©Cc]?(\s+)[0-9]{4}' | grep -E -v "[Cc]opyright(\s+)[©Cc]?(\s+)$$(date '+%Y')"); if [ "$${old_dates}" != "" ]; then printf "The following files contain outdated copyrights:\n$${old_dates}\n\nThis can be fixed with 'make copyright-fix'\n"; exit 1; fi
lint: install-deps-dev format-lint import-lint style-lint copyright-lint
format-fix:
gofmt -w ${GOFMT_FLAGS} .
import-fix:
goimports -w .
copyright-fix:
@git diff --diff-filter=ACMRTUXB --name-only "${PARENT_BRANCH}" | xargs -I '_FILENAME' -- sh -c 'sed -i.bak "s/\([Cc]opyright\([[:space:]][©Cc]\{0,1\}[[:space:]]*\)\)[0-9]\{4\}/\1"$$(date '+%Y')"/g" _FILENAME && rm _FILENAME.bak'
vet:
go vet ./...
.PHONY: all clean build install install-deps install-deps-dev update-deps update-deps-dev test test-with-coverage test-with-coverage-formatted test-with-coverage-profile format-lint import-lint style-lint copyright-lint lint format-fix import-fix copyright-fix vet

101
vendor/github.com/Rican7/retry/README.md generated vendored Normal file
View File

@ -0,0 +1,101 @@
# retry
[![Build Status](https://travis-ci.org/Rican7/retry.svg?branch=master)](https://travis-ci.org/Rican7/retry)
[![Coverage Status](https://coveralls.io/repos/github/Rican7/retry/badge.svg)](https://coveralls.io/github/Rican7/retry)
[![Go Report Card](https://goreportcard.com/badge/Rican7/retry)](http://goreportcard.com/report/Rican7/retry)
[![GoDoc](https://godoc.org/github.com/Rican7/retry?status.png)](https://godoc.org/github.com/Rican7/retry)
[![Latest Stable Version](https://img.shields.io/github/release/Rican7/retry.svg?style=flat)](https://github.com/Rican7/retry/releases)
A simple, stateless, functional mechanism to perform actions repetitively until successful.
## Project Status
This project is currently in "pre-release". While the code is heavily tested, the API may change.
Vendor (commit or lock) this dependency if you plan on using it.
## Install
`go get github.com/Rican7/retry`
## Examples
### Basic
```go
retry.Retry(func(attempt uint) error {
return nil // Do something that may or may not cause an error
})
```
### File Open
```go
const logFilePath = "/var/log/myapp.log"
var logFile *os.File
err := retry.Retry(func(attempt uint) error {
var err error
logFile, err = os.Open(logFilePath)
return err
})
if nil != err {
log.Fatalf("Unable to open file %q with error %q", logFilePath, err)
}
logFile.Chdir() // Do something with the file
```
### HTTP request with strategies and backoff
```go
var response *http.Response
action := func(attempt uint) error {
var err error
response, err = http.Get("https://api.github.com/repos/Rican7/retry")
if nil == err && nil != response && response.StatusCode > 200 {
err = fmt.Errorf("failed to fetch (attempt #%d) with status code: %d", attempt, response.StatusCode)
}
return err
}
err := retry.Retry(
action,
strategy.Limit(5),
strategy.Backoff(backoff.Fibonacci(10*time.Millisecond)),
)
if nil != err {
log.Fatalf("Failed to fetch repository with error %q", err)
}
```
### Retry with backoff jitter
```go
action := func(attempt uint) error {
return errors.New("something happened")
}
seed := time.Now().UnixNano()
random := rand.New(rand.NewSource(seed))
retry.Retry(
action,
strategy.Limit(5),
strategy.BackoffWithJitter(
backoff.BinaryExponential(10*time.Millisecond),
jitter.Deviation(random, 0.5),
),
)
```

23
vendor/github.com/Rican7/retry/backoff/BUILD generated vendored Normal file
View File

@ -0,0 +1,23 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = ["backoff.go"],
importmap = "k8s.io/kubernetes/vendor/github.com/Rican7/retry/backoff",
importpath = "github.com/Rican7/retry/backoff",
visibility = ["//visibility:public"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

67
vendor/github.com/Rican7/retry/backoff/backoff.go generated vendored Normal file
View File

@ -0,0 +1,67 @@
// Package backoff provides stateless methods of calculating durations based on
// a number of attempts made.
//
// Copyright © 2016 Trevor N. Suarez (Rican7)
package backoff
import (
"math"
"time"
)
// Algorithm defines a function that calculates a time.Duration based on
// the given retry attempt number.
type Algorithm func(attempt uint) time.Duration
// Incremental creates a Algorithm that increments the initial duration
// by the given increment for each attempt.
func Incremental(initial, increment time.Duration) Algorithm {
return func(attempt uint) time.Duration {
return initial + (increment * time.Duration(attempt))
}
}
// Linear creates a Algorithm that linearly multiplies the factor
// duration by the attempt number for each attempt.
func Linear(factor time.Duration) Algorithm {
return func(attempt uint) time.Duration {
return (factor * time.Duration(attempt))
}
}
// Exponential creates a Algorithm that multiplies the factor duration by
// an exponentially increasing factor for each attempt, where the factor is
// calculated as the given base raised to the attempt number.
func Exponential(factor time.Duration, base float64) Algorithm {
return func(attempt uint) time.Duration {
return (factor * time.Duration(math.Pow(base, float64(attempt))))
}
}
// BinaryExponential creates a Algorithm that multiplies the factor
// duration by an exponentially increasing factor for each attempt, where the
// factor is calculated as `2` raised to the attempt number (2^attempt).
func BinaryExponential(factor time.Duration) Algorithm {
return Exponential(factor, 2)
}
// Fibonacci creates a Algorithm that multiplies the factor duration by
// an increasing factor for each attempt, where the factor is the Nth number in
// the Fibonacci sequence.
func Fibonacci(factor time.Duration) Algorithm {
return func(attempt uint) time.Duration {
return (factor * time.Duration(fibonacciNumber(attempt)))
}
}
// fibonacciNumber calculates the Fibonacci sequence number for the given
// sequence position.
func fibonacciNumber(n uint) uint {
if 0 == n {
return 0
} else if 1 == n {
return 1
} else {
return fibonacciNumber(n-1) + fibonacciNumber(n-2)
}
}

23
vendor/github.com/Rican7/retry/jitter/BUILD generated vendored Normal file
View File

@ -0,0 +1,23 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = ["jitter.go"],
importmap = "k8s.io/kubernetes/vendor/github.com/Rican7/retry/jitter",
importpath = "github.com/Rican7/retry/jitter",
visibility = ["//visibility:public"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

89
vendor/github.com/Rican7/retry/jitter/jitter.go generated vendored Normal file
View File

@ -0,0 +1,89 @@
// Package jitter provides methods of transforming durations.
//
// Copyright © 2016 Trevor N. Suarez (Rican7)
package jitter
import (
"math"
"math/rand"
"time"
)
// Transformation defines a function that calculates a time.Duration based on
// the given duration.
type Transformation func(duration time.Duration) time.Duration
// Full creates a Transformation that transforms a duration into a result
// duration in [0, n) randomly, where n is the given duration.
//
// The given generator is what is used to determine the random transformation.
// If a nil generator is passed, a default one will be provided.
//
// Inspired by https://www.awsarchitectureblog.com/2015/03/backoff.html
func Full(generator *rand.Rand) Transformation {
random := fallbackNewRandom(generator)
return func(duration time.Duration) time.Duration {
return time.Duration(random.Int63n(int64(duration)))
}
}
// Equal creates a Transformation that transforms a duration into a result
// duration in [n/2, n) randomly, where n is the given duration.
//
// The given generator is what is used to determine the random transformation.
// If a nil generator is passed, a default one will be provided.
//
// Inspired by https://www.awsarchitectureblog.com/2015/03/backoff.html
func Equal(generator *rand.Rand) Transformation {
random := fallbackNewRandom(generator)
return func(duration time.Duration) time.Duration {
return (duration / 2) + time.Duration(random.Int63n(int64(duration))/2)
}
}
// Deviation creates a Transformation that transforms a duration into a result
// duration that deviates from the input randomly by a given factor.
//
// The given generator is what is used to determine the random transformation.
// If a nil generator is passed, a default one will be provided.
//
// Inspired by https://developers.google.com/api-client-library/java/google-http-java-client/backoff
func Deviation(generator *rand.Rand, factor float64) Transformation {
random := fallbackNewRandom(generator)
return func(duration time.Duration) time.Duration {
min := int64(math.Floor(float64(duration) * (1 - factor)))
max := int64(math.Ceil(float64(duration) * (1 + factor)))
return time.Duration(random.Int63n(max-min) + min)
}
}
// NormalDistribution creates a Transformation that transforms a duration into a
// result duration based on a normal distribution of the input and the given
// standard deviation.
//
// The given generator is what is used to determine the random transformation.
// If a nil generator is passed, a default one will be provided.
func NormalDistribution(generator *rand.Rand, standardDeviation float64) Transformation {
random := fallbackNewRandom(generator)
return func(duration time.Duration) time.Duration {
return time.Duration(random.NormFloat64()*standardDeviation + float64(duration))
}
}
// fallbackNewRandom returns the passed in random instance if it's not nil,
// and otherwise returns a new random instance seeded with the current time.
func fallbackNewRandom(random *rand.Rand) *rand.Rand {
// Return the passed in value if it's already not null
if nil != random {
return random
}
seed := time.Now().UnixNano()
return rand.New(rand.NewSource(seed))
}

36
vendor/github.com/Rican7/retry/retry.go generated vendored Normal file
View File

@ -0,0 +1,36 @@
// Package retry provides a simple, stateless, functional mechanism to perform
// actions repetitively until successful.
//
// Copyright © 2016 Trevor N. Suarez (Rican7)
package retry
import "github.com/Rican7/retry/strategy"
// Action defines a callable function that package retry can handle.
type Action func(attempt uint) error
// Retry takes an action and performs it, repetitively, until successful.
//
// Optionally, strategies may be passed that assess whether or not an attempt
// should be made.
func Retry(action Action, strategies ...strategy.Strategy) error {
var err error
for attempt := uint(0); (0 == attempt || nil != err) && shouldAttempt(attempt, strategies...); attempt++ {
err = action(attempt)
}
return err
}
// shouldAttempt evaluates the provided strategies with the given attempt to
// determine if the Retry loop should make another attempt.
func shouldAttempt(attempt uint, strategies ...strategy.Strategy) bool {
shouldAttempt := true
for i := 0; shouldAttempt && i < len(strategies); i++ {
shouldAttempt = shouldAttempt && strategies[i](attempt)
}
return shouldAttempt
}

27
vendor/github.com/Rican7/retry/strategy/BUILD generated vendored Normal file
View File

@ -0,0 +1,27 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = ["strategy.go"],
importmap = "k8s.io/kubernetes/vendor/github.com/Rican7/retry/strategy",
importpath = "github.com/Rican7/retry/strategy",
visibility = ["//visibility:public"],
deps = [
"//vendor/github.com/Rican7/retry/backoff:go_default_library",
"//vendor/github.com/Rican7/retry/jitter:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

85
vendor/github.com/Rican7/retry/strategy/strategy.go generated vendored Normal file
View File

@ -0,0 +1,85 @@
// Package strategy provides a way to change the way that retry is performed.
//
// Copyright © 2016 Trevor N. Suarez (Rican7)
package strategy
import (
"time"
"github.com/Rican7/retry/backoff"
"github.com/Rican7/retry/jitter"
)
// Strategy defines a function that Retry calls before every successive attempt
// to determine whether it should make the next attempt or not. Returning `true`
// allows for the next attempt to be made. Returning `false` halts the retrying
// process and returns the last error returned by the called Action.
//
// The strategy will be passed an "attempt" number on each successive retry
// iteration, starting with a `0` value before the first attempt is actually
// made. This allows for a pre-action delay, etc.
type Strategy func(attempt uint) bool
// Limit creates a Strategy that limits the number of attempts that Retry will
// make.
func Limit(attemptLimit uint) Strategy {
return func(attempt uint) bool {
return (attempt <= attemptLimit)
}
}
// Delay creates a Strategy that waits the given duration before the first
// attempt is made.
func Delay(duration time.Duration) Strategy {
return func(attempt uint) bool {
if 0 == attempt {
time.Sleep(duration)
}
return true
}
}
// Wait creates a Strategy that waits the given durations for each attempt after
// the first. If the number of attempts is greater than the number of durations
// provided, then the strategy uses the last duration provided.
func Wait(durations ...time.Duration) Strategy {
return func(attempt uint) bool {
if 0 < attempt && 0 < len(durations) {
durationIndex := int(attempt - 1)
if len(durations) <= durationIndex {
durationIndex = len(durations) - 1
}
time.Sleep(durations[durationIndex])
}
return true
}
}
// Backoff creates a Strategy that waits before each attempt, with a duration as
// defined by the given backoff.Algorithm.
func Backoff(algorithm backoff.Algorithm) Strategy {
return BackoffWithJitter(algorithm, noJitter())
}
// BackoffWithJitter creates a Strategy that waits before each attempt, with a
// duration as defined by the given backoff.Algorithm and jitter.Transformation.
func BackoffWithJitter(algorithm backoff.Algorithm, transformation jitter.Transformation) Strategy {
return func(attempt uint) bool {
if 0 < attempt {
time.Sleep(transformation(algorithm(attempt)))
}
return true
}
}
// noJitter creates a jitter.Transformation that simply returns the input.
func noJitter() jitter.Transformation {
return func(duration time.Duration) time.Duration {
return duration
}
}

View File

@ -31,7 +31,10 @@ import (
)
type NvidiaManager struct {
sync.RWMutex
sync.Mutex
// true if there are NVIDIA devices present on the node
devicesPresent bool
// true if the NVML library (libnvidia-ml.so.1) was loaded successfully
nvmlInitialized bool
@ -51,20 +54,9 @@ func (nm *NvidiaManager) Setup() {
return
}
nm.initializeNVML()
if nm.nvmlInitialized {
return
}
go func() {
glog.V(2).Info("Starting goroutine to initialize NVML")
// TODO: use globalHousekeepingInterval
for range time.Tick(time.Minute) {
nm.initializeNVML()
if nm.nvmlInitialized {
return
}
}
}()
nm.devicesPresent = true
initializeNVML(nm)
}
// detectDevices returns true if a device with given pci id is present on the node.
@ -91,20 +83,18 @@ func detectDevices(vendorId string) bool {
}
// initializeNVML initializes the NVML library and sets up the nvmlDevices map.
func (nm *NvidiaManager) initializeNVML() {
// This is defined as a variable to help in testing.
var initializeNVML = func(nm *NvidiaManager) {
if err := gonvml.Initialize(); err != nil {
// This is under a logging level because otherwise we may cause
// log spam if the drivers/nvml is not installed on the system.
glog.V(4).Infof("Could not initialize NVML: %v", err)
return
}
nm.nvmlInitialized = true
numDevices, err := gonvml.DeviceCount()
if err != nil {
glog.Warningf("GPU metrics would not be available. Failed to get the number of nvidia devices: %v", err)
nm.Lock()
// Even though we won't have GPU metrics, the library was initialized and should be shutdown when exiting.
nm.nvmlInitialized = true
nm.Unlock()
return
}
glog.V(1).Infof("NVML initialized. Number of nvidia devices: %v", numDevices)
@ -122,10 +112,6 @@ func (nm *NvidiaManager) initializeNVML() {
}
nm.nvidiaDevices[int(minorNumber)] = device
}
nm.Lock()
// Doing this at the end to avoid race in accessing nvidiaDevices in GetCollector.
nm.nvmlInitialized = true
nm.Unlock()
}
// Destroy shuts down NVML.
@ -139,12 +125,21 @@ func (nm *NvidiaManager) Destroy() {
// present in the devices.list file in the given devicesCgroupPath.
func (nm *NvidiaManager) GetCollector(devicesCgroupPath string) (AcceleratorCollector, error) {
nc := &NvidiaCollector{}
nm.RLock()
if !nm.nvmlInitialized || len(nm.nvidiaDevices) == 0 {
nm.RUnlock()
if !nm.devicesPresent {
return nc, nil
}
nm.RUnlock()
// Makes sure that we don't call initializeNVML() concurrently and
// that we only call initializeNVML() when it's not initialized.
nm.Lock()
if !nm.nvmlInitialized {
initializeNVML(nm)
}
if !nm.nvmlInitialized || len(nm.nvidiaDevices) == 0 {
nm.Unlock()
return nc, nil
}
nm.Unlock()
nvidiaMinorNumbers, err := parseDevicesCgroup(devicesCgroupPath)
if err != nil {
return nc, err

View File

@ -15,7 +15,7 @@
package memory
import (
"fmt"
"errors"
"sync"
"time"
@ -26,6 +26,9 @@ import (
"github.com/golang/glog"
)
// ErrDataNotFound is the error resulting if failed to find a container in memory cache.
var ErrDataNotFound = errors.New("unable to find data in memory cache")
// TODO(vmarmol): See about refactoring this class, we have an unecessary redirection of containerCache and InMemoryCache.
// containerCache is used to store per-container information
type containerCache struct {
@ -101,7 +104,7 @@ func (self *InMemoryCache) RecentStats(name string, start, end time.Time, maxSta
self.lock.RLock()
defer self.lock.RUnlock()
if cstore, ok = self.containerCacheMap[name]; !ok {
return fmt.Errorf("unable to find data for container %v", name)
return ErrDataNotFound
}
return nil
}()

View File

@ -32,6 +32,7 @@ filegroup(
"//vendor/github.com/google/cadvisor/container/crio:all-srcs",
"//vendor/github.com/google/cadvisor/container/docker:all-srcs",
"//vendor/github.com/google/cadvisor/container/libcontainer:all-srcs",
"//vendor/github.com/google/cadvisor/container/mesos:all-srcs",
"//vendor/github.com/google/cadvisor/container/raw:all-srcs",
"//vendor/github.com/google/cadvisor/container/rkt:all-srcs",
"//vendor/github.com/google/cadvisor/container/systemd:all-srcs",

View File

@ -36,6 +36,7 @@ const (
ContainerTypeSystemd
ContainerTypeCrio
ContainerTypeContainerd
ContainerTypeMesos
)
// Interface for container operation handlers.

View File

@ -47,8 +47,8 @@ type containerdFactory struct {
// Information about the mounted cgroup subsystems.
cgroupSubsystems libcontainer.CgroupSubsystems
// Information about mounted filesystems.
fsInfo fs.FsInfo
ignoreMetrics container.MetricSet
fsInfo fs.FsInfo
includedMetrics container.MetricSet
}
func (self *containerdFactory) String() string {
@ -70,7 +70,7 @@ func (self *containerdFactory) NewContainerHandler(name string, inHostNamespace
&self.cgroupSubsystems,
inHostNamespace,
metadataEnvs,
self.ignoreMetrics,
self.includedMetrics,
)
}
@ -117,7 +117,7 @@ func (self *containerdFactory) DebugInfo() map[string][]string {
}
// Register root container before running this function!
func Register(factory info.MachineInfoFactory, fsInfo fs.FsInfo, ignoreMetrics container.MetricSet) error {
func Register(factory info.MachineInfoFactory, fsInfo fs.FsInfo, includedMetrics container.MetricSet) error {
client, err := Client()
if err != nil {
return fmt.Errorf("unable to create containerd client: %v", err)
@ -140,7 +140,7 @@ func Register(factory info.MachineInfoFactory, fsInfo fs.FsInfo, ignoreMetrics c
fsInfo: fsInfo,
machineInfoFactory: factory,
version: containerdVersion,
ignoreMetrics: ignoreMetrics,
includedMetrics: includedMetrics,
}
container.RegisterContainerHandlerFactory(f, []watcher.ContainerWatchSource{watcher.Raw})

View File

@ -48,7 +48,7 @@ type containerdContainerHandler struct {
// Image name used for this container.
image string
// Filesystem handler.
ignoreMetrics container.MetricSet
includedMetrics container.MetricSet
libcontainerHandler *containerlibcontainer.Handler
}
@ -64,7 +64,7 @@ func newContainerdContainerHandler(
cgroupSubsystems *containerlibcontainer.CgroupSubsystems,
inHostNamespace bool,
metadataEnvs []string,
ignoreMetrics container.MetricSet,
includedMetrics container.MetricSet,
) (container.ContainerHandler, error) {
// Create the cgroup paths.
cgroupPaths := make(map[string]string, len(cgroupSubsystems.MountPoints))
@ -127,7 +127,7 @@ func newContainerdContainerHandler(
Aliases: []string{id, name},
}
libcontainerHandler := containerlibcontainer.NewHandler(cgroupManager, rootfs, int(taskPid), ignoreMetrics)
libcontainerHandler := containerlibcontainer.NewHandler(cgroupManager, rootfs, int(taskPid), includedMetrics)
handler := &containerdContainerHandler{
machineInfoFactory: machineInfoFactory,
@ -135,7 +135,7 @@ func newContainerdContainerHandler(
fsInfo: fsInfo,
envs: make(map[string]string),
labels: cntr.Labels,
ignoreMetrics: ignoreMetrics,
includedMetrics: includedMetrics,
reference: containerReference,
libcontainerHandler: libcontainerHandler,
}
@ -159,9 +159,9 @@ func (self *containerdContainerHandler) ContainerReference() (info.ContainerRefe
func (self *containerdContainerHandler) needNet() bool {
// Since containerd does not handle networking ideally we need to return based
// on ignoreMetrics list. Here the assumption is the presence of cri-containerd
// on includedMetrics list. Here the assumption is the presence of cri-containerd
// label
if !self.ignoreMetrics.Has(container.NetworkUsageMetrics) {
if self.includedMetrics.Has(container.NetworkUsageMetrics) {
//TODO change it to exported cri-containerd constants
return self.labels["io.cri-containerd.kind"] == "sandbox"
}
@ -186,7 +186,7 @@ func (self *containerdContainerHandler) getFsStats(stats *info.ContainerStats) e
return err
}
if !self.ignoreMetrics.Has(container.DiskIOMetrics) {
if self.includedMetrics.Has(container.DiskIOMetrics) {
common.AssignDeviceNamesToDiskStats((*common.MachineInfoNamer)(mi), &stats.DiskIo)
}
return nil

View File

@ -55,7 +55,7 @@ type crioFactory struct {
// Information about mounted filesystems.
fsInfo fs.FsInfo
ignoreMetrics container.MetricSet
includedMetrics container.MetricSet
client crioClient
}
@ -81,7 +81,7 @@ func (self *crioFactory) NewContainerHandler(name string, inHostNamespace bool)
&self.cgroupSubsystems,
inHostNamespace,
metadataEnvs,
self.ignoreMetrics,
self.includedMetrics,
)
return
}
@ -136,7 +136,7 @@ var (
)
// Register root container before running this function!
func Register(factory info.MachineInfoFactory, fsInfo fs.FsInfo, ignoreMetrics container.MetricSet) error {
func Register(factory info.MachineInfoFactory, fsInfo fs.FsInfo, includedMetrics container.MetricSet) error {
client, err := Client()
if err != nil {
return err
@ -162,7 +162,7 @@ func Register(factory info.MachineInfoFactory, fsInfo fs.FsInfo, ignoreMetrics c
machineInfoFactory: factory,
storageDriver: storageDriver(info.StorageDriver),
storageDir: info.StorageRoot,
ignoreMetrics: ignoreMetrics,
includedMetrics: includedMetrics,
}
container.RegisterContainerHandlerFactory(f, []watcher.ContainerWatchSource{watcher.Raw})

View File

@ -63,7 +63,7 @@ type crioContainerHandler struct {
// The IP address of the container
ipAddress string
ignoreMetrics container.MetricSet
includedMetrics container.MetricSet
reference info.ContainerReference
@ -83,7 +83,7 @@ func newCrioContainerHandler(
cgroupSubsystems *containerlibcontainer.CgroupSubsystems,
inHostNamespace bool,
metadataEnvs []string,
ignoreMetrics container.MetricSet,
includedMetrics container.MetricSet,
) (container.ContainerHandler, error) {
// Create the cgroup paths.
cgroupPaths := make(map[string]string, len(cgroupSubsystems.MountPoints))
@ -141,7 +141,7 @@ func newCrioContainerHandler(
Namespace: CrioNamespace,
}
libcontainerHandler := containerlibcontainer.NewHandler(cgroupManager, rootFs, cInfo.Pid, ignoreMetrics)
libcontainerHandler := containerlibcontainer.NewHandler(cgroupManager, rootFs, cInfo.Pid, includedMetrics)
// TODO: extract object mother method
handler := &crioContainerHandler{
@ -152,7 +152,7 @@ func newCrioContainerHandler(
rootfsStorageDir: rootfsStorageDir,
envs: make(map[string]string),
labels: cInfo.Labels,
ignoreMetrics: ignoreMetrics,
includedMetrics: includedMetrics,
reference: containerReference,
libcontainerHandler: libcontainerHandler,
}
@ -171,7 +171,7 @@ func newCrioContainerHandler(
handler.ipAddress = cInfo.IP
// we optionally collect disk usage metrics
if !ignoreMetrics.Has(container.DiskUsageMetrics) {
if includedMetrics.Has(container.DiskUsageMetrics) {
handler.fsHandler = common.NewFsHandler(common.DefaultPeriod, rootfsStorageDir, storageLogDir, fsInfo)
}
// TODO for env vars we wanted to show from container.Config.Env from whitelist
@ -199,14 +199,14 @@ func (self *crioContainerHandler) ContainerReference() (info.ContainerReference,
}
func (self *crioContainerHandler) needNet() bool {
if !self.ignoreMetrics.Has(container.NetworkUsageMetrics) {
if self.includedMetrics.Has(container.NetworkUsageMetrics) {
return self.labels["io.kubernetes.container.name"] == "POD"
}
return false
}
func (self *crioContainerHandler) GetSpec() (info.ContainerSpec, error) {
hasFilesystem := !self.ignoreMetrics.Has(container.DiskUsageMetrics)
hasFilesystem := self.includedMetrics.Has(container.DiskUsageMetrics)
spec, err := common.GetSpec(self.cgroupPaths, self.machineInfoFactory, self.needNet(), hasFilesystem)
spec.Labels = self.labels
@ -222,11 +222,11 @@ func (self *crioContainerHandler) getFsStats(stats *info.ContainerStats) error {
return err
}
if !self.ignoreMetrics.Has(container.DiskIOMetrics) {
if self.includedMetrics.Has(container.DiskIOMetrics) {
common.AssignDeviceNamesToDiskStats((*common.MachineInfoNamer)(mi), &stats.DiskIo)
}
if self.ignoreMetrics.Has(container.DiskUsageMetrics) {
if !self.includedMetrics.Has(container.DiskUsageMetrics) {
return nil
}
var device string

View File

@ -110,7 +110,7 @@ type dockerFactory struct {
dockerAPIVersion []int
ignoreMetrics container.MetricSet
includedMetrics container.MetricSet
thinPoolName string
thinPoolWatcher *devicemapper.ThinPoolWatcher
@ -141,7 +141,7 @@ func (self *dockerFactory) NewContainerHandler(name string, inHostNamespace bool
inHostNamespace,
metadataEnvs,
self.dockerVersion,
self.ignoreMetrics,
self.includedMetrics,
self.thinPoolName,
self.thinPoolWatcher,
self.zfsWatcher,
@ -309,7 +309,7 @@ func ensureThinLsKernelVersion(kernelVersion string) error {
}
// Register root container before running this function!
func Register(factory info.MachineInfoFactory, fsInfo fs.FsInfo, ignoreMetrics container.MetricSet) error {
func Register(factory info.MachineInfoFactory, fsInfo fs.FsInfo, includedMetrics container.MetricSet) error {
client, err := Client()
if err != nil {
return fmt.Errorf("unable to communicate with docker daemon: %v", err)
@ -363,7 +363,7 @@ func Register(factory info.MachineInfoFactory, fsInfo fs.FsInfo, ignoreMetrics c
machineInfoFactory: factory,
storageDriver: storageDriver(dockerInfo.Driver),
storageDir: RootDir(),
ignoreMetrics: ignoreMetrics,
includedMetrics: includedMetrics,
thinPoolName: thinPoolName,
thinPoolWatcher: thinPoolWatcher,
zfsWatcher: zfsWatcher,

View File

@ -83,7 +83,7 @@ type dockerContainerHandler struct {
// The IP address of the container
ipAddress string
ignoreMetrics container.MetricSet
includedMetrics container.MetricSet
// the devicemapper poolname
poolName string
@ -128,7 +128,7 @@ func newDockerContainerHandler(
inHostNamespace bool,
metadataEnvs []string,
dockerVersion []int,
ignoreMetrics container.MetricSet,
includedMetrics container.MetricSet,
thinPoolName string,
thinPoolWatcher *devicemapper.ThinPoolWatcher,
zfsWatcher *zfs.ZfsWatcher,
@ -203,7 +203,7 @@ func newDockerContainerHandler(
rootfsStorageDir: rootfsStorageDir,
envs: make(map[string]string),
labels: ctnr.Config.Labels,
ignoreMetrics: ignoreMetrics,
includedMetrics: includedMetrics,
zfsParent: zfsParent,
}
// Timestamp returned by Docker is in time.RFC3339Nano format.
@ -212,7 +212,7 @@ func newDockerContainerHandler(
// This should not happen, report the error just in case
return nil, fmt.Errorf("failed to parse the create timestamp %q for container %q: %v", ctnr.Created, id, err)
}
handler.libcontainerHandler = containerlibcontainer.NewHandler(cgroupManager, rootFs, ctnr.State.Pid, ignoreMetrics)
handler.libcontainerHandler = containerlibcontainer.NewHandler(cgroupManager, rootFs, ctnr.State.Pid, includedMetrics)
// Add the name and bare ID as aliases of the container.
handler.reference = info.ContainerReference{
@ -244,7 +244,7 @@ func newDockerContainerHandler(
handler.ipAddress = ipAddress
if !ignoreMetrics.Has(container.DiskUsageMetrics) {
if includedMetrics.Has(container.DiskUsageMetrics) {
handler.fsHandler = &dockerFsHandler{
fsHandler: common.NewFsHandler(common.DefaultPeriod, rootfsStorageDir, otherStorageDir, fsInfo),
thinPoolWatcher: thinPoolWatcher,
@ -345,14 +345,14 @@ func (self *dockerContainerHandler) ContainerReference() (info.ContainerReferenc
}
func (self *dockerContainerHandler) needNet() bool {
if !self.ignoreMetrics.Has(container.NetworkUsageMetrics) {
if self.includedMetrics.Has(container.NetworkUsageMetrics) {
return !self.networkMode.IsContainer()
}
return false
}
func (self *dockerContainerHandler) GetSpec() (info.ContainerSpec, error) {
hasFilesystem := !self.ignoreMetrics.Has(container.DiskUsageMetrics)
hasFilesystem := self.includedMetrics.Has(container.DiskUsageMetrics)
spec, err := common.GetSpec(self.cgroupPaths, self.machineInfoFactory, self.needNet(), hasFilesystem)
spec.Labels = self.labels
@ -369,11 +369,11 @@ func (self *dockerContainerHandler) getFsStats(stats *info.ContainerStats) error
return err
}
if !self.ignoreMetrics.Has(container.DiskIOMetrics) {
if self.includedMetrics.Has(container.DiskIOMetrics) {
common.AssignDeviceNamesToDiskStats((*common.MachineInfoNamer)(mi), &stats.DiskIo)
}
if self.ignoreMetrics.Has(container.DiskUsageMetrics) {
if !self.includedMetrics.Has(container.DiskUsageMetrics) {
return nil
}
var device string

View File

@ -51,6 +51,7 @@ const (
NetworkUsageMetrics MetricKind = "network"
NetworkTcpUsageMetrics MetricKind = "tcp"
NetworkUdpUsageMetrics MetricKind = "udp"
AcceleratorUsageMetrics MetricKind = "accelerator"
AppMetrics MetricKind = "app"
)

View File

@ -43,16 +43,16 @@ type Handler struct {
cgroupManager cgroups.Manager
rootFs string
pid int
ignoreMetrics container.MetricSet
includedMetrics container.MetricSet
pidMetricsCache map[int]*info.CpuSchedstat
}
func NewHandler(cgroupManager cgroups.Manager, rootFs string, pid int, ignoreMetrics container.MetricSet) *Handler {
func NewHandler(cgroupManager cgroups.Manager, rootFs string, pid int, includedMetrics container.MetricSet) *Handler {
return &Handler{
cgroupManager: cgroupManager,
rootFs: rootFs,
pid: pid,
ignoreMetrics: ignoreMetrics,
includedMetrics: includedMetrics,
pidMetricsCache: make(map[int]*info.CpuSchedstat),
}
}
@ -66,10 +66,10 @@ func (h *Handler) GetStats() (*info.ContainerStats, error) {
libcontainerStats := &libcontainer.Stats{
CgroupStats: cgroupStats,
}
withPerCPU := !h.ignoreMetrics.Has(container.PerCpuUsageMetrics)
withPerCPU := h.includedMetrics.Has(container.PerCpuUsageMetrics)
stats := newContainerStats(libcontainerStats, withPerCPU)
if !h.ignoreMetrics.Has(container.ProcessSchedulerMetrics) {
if h.includedMetrics.Has(container.ProcessSchedulerMetrics) {
pids, err := h.cgroupManager.GetAllPids()
if err != nil {
glog.V(4).Infof("Could not get PIDs for container %d: %v", h.pid, err)
@ -85,7 +85,7 @@ func (h *Handler) GetStats() (*info.ContainerStats, error) {
if h.pid == 0 {
return stats, nil
}
if !h.ignoreMetrics.Has(container.NetworkUsageMetrics) {
if h.includedMetrics.Has(container.NetworkUsageMetrics) {
netStats, err := networkStatsFromProc(h.rootFs, h.pid)
if err != nil {
glog.V(4).Infof("Unable to get network stats from pid %d: %v", h.pid, err)
@ -93,7 +93,7 @@ func (h *Handler) GetStats() (*info.ContainerStats, error) {
stats.Network.Interfaces = append(stats.Network.Interfaces, netStats...)
}
}
if !h.ignoreMetrics.Has(container.NetworkTcpUsageMetrics) {
if h.includedMetrics.Has(container.NetworkTcpUsageMetrics) {
t, err := tcpStatsFromProc(h.rootFs, h.pid, "net/tcp")
if err != nil {
glog.V(4).Infof("Unable to get tcp stats from pid %d: %v", h.pid, err)
@ -108,7 +108,7 @@ func (h *Handler) GetStats() (*info.ContainerStats, error) {
stats.Network.Tcp6 = t6
}
}
if !h.ignoreMetrics.Has(container.NetworkUdpUsageMetrics) {
if h.includedMetrics.Has(container.NetworkUdpUsageMetrics) {
u, err := udpStatsFromProc(h.rootFs, h.pid, "net/udp")
if err != nil {
glog.V(4).Infof("Unable to get udp stats from pid %d: %v", h.pid, err)
@ -498,14 +498,17 @@ func setMemoryStats(s *cgroups.Stats, ret *info.ContainerStats) {
ret.Memory.Usage = s.MemoryStats.Usage.Usage
ret.Memory.MaxUsage = s.MemoryStats.Usage.MaxUsage
ret.Memory.Failcnt = s.MemoryStats.Usage.Failcnt
ret.Memory.Cache = s.MemoryStats.Stats["cache"]
if s.MemoryStats.UseHierarchy {
ret.Memory.Cache = s.MemoryStats.Stats["total_cache"]
ret.Memory.RSS = s.MemoryStats.Stats["total_rss"]
ret.Memory.Swap = s.MemoryStats.Stats["total_swap"]
ret.Memory.MappedFile = s.MemoryStats.Stats["total_mapped_file"]
} else {
ret.Memory.Cache = s.MemoryStats.Stats["cache"]
ret.Memory.RSS = s.MemoryStats.Stats["rss"]
ret.Memory.Swap = s.MemoryStats.Stats["swap"]
ret.Memory.MappedFile = s.MemoryStats.Stats["mapped_file"]
}
if v, ok := s.MemoryStats.Stats["pgfault"]; ok {
ret.Memory.ContainerData.Pgfault = v

View File

@ -0,0 +1,47 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"client.go",
"factory.go",
"handler.go",
"mesos_agent.go",
],
importmap = "k8s.io/kubernetes/vendor/github.com/google/cadvisor/container/mesos",
importpath = "github.com/google/cadvisor/container/mesos",
visibility = ["//visibility:public"],
deps = [
"//vendor/github.com/Rican7/retry:go_default_library",
"//vendor/github.com/Rican7/retry/strategy:go_default_library",
"//vendor/github.com/golang/glog:go_default_library",
"//vendor/github.com/google/cadvisor/container:go_default_library",
"//vendor/github.com/google/cadvisor/container/common:go_default_library",
"//vendor/github.com/google/cadvisor/container/libcontainer:go_default_library",
"//vendor/github.com/google/cadvisor/fs:go_default_library",
"//vendor/github.com/google/cadvisor/info/v1:go_default_library",
"//vendor/github.com/google/cadvisor/manager/watcher:go_default_library",
"//vendor/github.com/mesos/mesos-go/api/v1/lib:go_default_library",
"//vendor/github.com/mesos/mesos-go/api/v1/lib/agent:go_default_library",
"//vendor/github.com/mesos/mesos-go/api/v1/lib/agent/calls:go_default_library",
"//vendor/github.com/mesos/mesos-go/api/v1/lib/client:go_default_library",
"//vendor/github.com/mesos/mesos-go/api/v1/lib/encoding/codecs:go_default_library",
"//vendor/github.com/mesos/mesos-go/api/v1/lib/httpcli:go_default_library",
"//vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs:go_default_library",
"//vendor/github.com/opencontainers/runc/libcontainer/configs:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@ -0,0 +1,190 @@
// Copyright 2018 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 mesos
import (
"fmt"
"github.com/Rican7/retry"
"github.com/Rican7/retry/strategy"
"github.com/mesos/mesos-go/api/v1/lib"
"github.com/mesos/mesos-go/api/v1/lib/agent"
"github.com/mesos/mesos-go/api/v1/lib/agent/calls"
mclient "github.com/mesos/mesos-go/api/v1/lib/client"
"github.com/mesos/mesos-go/api/v1/lib/encoding/codecs"
"github.com/mesos/mesos-go/api/v1/lib/httpcli"
"net/url"
"sync"
)
const (
maxRetryAttempts = 3
invalidPID = -1
)
var (
mesosClientOnce sync.Once
mesosClient *client
)
type client struct {
hc *httpcli.Client
}
type mesosAgentClient interface {
ContainerInfo(id string) (*containerInfo, error)
ContainerPid(id string) (int, error)
}
type containerInfo struct {
cntr *mContainer
labels map[string]string
}
// Client is an interface to query mesos agent http endpoints
func Client() (mesosAgentClient, error) {
mesosClientOnce.Do(func() {
// Start Client
apiURL := url.URL{
Scheme: "http",
Host: *MesosAgentAddress,
Path: "/api/v1",
}
mesosClient = &client{
hc: httpcli.New(
httpcli.Endpoint(apiURL.String()),
httpcli.Codec(codecs.ByMediaType[codecs.MediaTypeProtobuf]),
httpcli.Do(httpcli.With(httpcli.Timeout(*MesosAgentTimeout))),
),
}
})
return mesosClient, nil
}
// ContainerInfo returns the container information of the given container id
func (self *client) ContainerInfo(id string) (*containerInfo, error) {
c, err := self.getContainer(id)
if err != nil {
return nil, err
}
// Get labels of the container
l, err := self.getLabels(c)
if err != nil {
return nil, err
}
return &containerInfo{
cntr: c,
labels: l,
}, nil
}
// Get the Pid of the container
func (self *client) ContainerPid(id string) (int, error) {
var pid int
var err error
err = retry.Retry(
func(attempt uint) error {
c, err := self.ContainerInfo(id)
if err != nil {
return err
}
if c.cntr.ContainerStatus != nil {
pid = int(*c.cntr.ContainerStatus.ExecutorPID)
} else {
err = fmt.Errorf("error fetching Pid")
}
return err
},
strategy.Limit(maxRetryAttempts),
)
if err != nil {
return invalidPID, fmt.Errorf("failed to fetch pid")
}
return pid, err
}
func (self *client) getContainer(id string) (*mContainer, error) {
// Get all containers
cntrs, err := self.getContainers()
if err != nil {
return nil, err
}
// Check if there is a container with given id and return the container
for _, c := range cntrs.Containers {
if c.ContainerID.Value == id {
return &c, nil
}
}
return nil, fmt.Errorf("can't locate container %s", id)
}
func (self *client) getContainers() (mContainers, error) {
req := calls.NonStreaming(calls.GetContainers())
result, err := self.fetchAndDecode(req)
if err != nil {
return nil, fmt.Errorf("failed to get mesos containers: %v", err)
}
cntrs := result.GetContainers
return cntrs, nil
}
func (self *client) getLabels(c *mContainer) (map[string]string, error) {
// Get mesos agent state which contains all containers labels
var s state
req := calls.NonStreaming(calls.GetState())
result, err := self.fetchAndDecode(req)
if err != nil {
return map[string]string{}, fmt.Errorf("failed to get mesos agent state: %v", err)
}
s.st = result.GetState
// Fetch labels from state object
labels, err := s.FetchLabels(c.FrameworkID.Value, c.ExecutorID.Value)
if err != nil {
return labels, fmt.Errorf("error while fetching labels from executor: %v", err)
}
return labels, nil
}
func (self *client) fetchAndDecode(req calls.RequestFunc) (*agent.Response, error) {
var res mesos.Response
var err error
// Send request
err = retry.Retry(
func(attempt uint) error {
res, err = mesosClient.hc.Send(req, mclient.ResponseClassSingleton, nil)
return err
},
strategy.Limit(maxRetryAttempts),
)
if err != nil {
return nil, fmt.Errorf("error fetching %s: %s", req.Call(), err)
}
// Decode the result
var target agent.Response
err = res.Decode(&target)
if err != nil {
return nil, fmt.Errorf("error while decoding response body from %s: %s", res, err)
}
return &target, nil
}

View File

@ -0,0 +1,148 @@
// Copyright 2018 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 mesos
import (
"flag"
"fmt"
"path"
"regexp"
"strings"
"time"
"github.com/golang/glog"
"github.com/google/cadvisor/container"
"github.com/google/cadvisor/container/libcontainer"
"github.com/google/cadvisor/fs"
info "github.com/google/cadvisor/info/v1"
"github.com/google/cadvisor/manager/watcher"
)
var MesosAgentAddress = flag.String("mesos_agent", "127.0.0.1:5051", "Mesos agent address")
var MesosAgentTimeout = flag.Duration("mesos_agent_timeout", 10*time.Second, "Mesos agent timeout")
// The namespace under which mesos aliases are unique.
const MesosNamespace = "mesos"
// Regexp that identifies mesos cgroups, containers started with
// --cgroup-parent have another prefix than 'mesos'
var mesosCgroupRegexp = regexp.MustCompile(`([a-z-0-9]{36})`)
// mesosFactory implements the interface ContainerHandlerFactory
type mesosFactory struct {
machineInfoFactory info.MachineInfoFactory
// Information about the cgroup subsystems.
cgroupSubsystems libcontainer.CgroupSubsystems
// Information about mounted filesystems.
fsInfo fs.FsInfo
includedMetrics map[container.MetricKind]struct{}
client mesosAgentClient
}
func (self *mesosFactory) String() string {
return MesosNamespace
}
func (self *mesosFactory) NewContainerHandler(name string, inHostNamespace bool) (container.ContainerHandler, error) {
client, err := Client()
if err != nil {
return nil, err
}
return newMesosContainerHandler(
name,
&self.cgroupSubsystems,
self.machineInfoFactory,
self.fsInfo,
self.includedMetrics,
inHostNamespace,
client,
)
}
// ContainerNameToMesosId returns the Mesos ID from the full container name.
func ContainerNameToMesosId(name string) string {
id := path.Base(name)
if matches := mesosCgroupRegexp.FindStringSubmatch(id); matches != nil {
return matches[1]
}
return id
}
// isContainerName returns true if the cgroup with associated name
// corresponds to a mesos container.
func isContainerName(name string) bool {
// always ignore .mount cgroup even if associated with mesos and delegate to systemd
if strings.HasSuffix(name, ".mount") {
return false
}
return mesosCgroupRegexp.MatchString(path.Base(name))
}
// The mesos factory can handle any container.
func (self *mesosFactory) CanHandleAndAccept(name string) (handle bool, accept bool, err error) {
// if the container is not associated with mesos, we can't handle it or accept it.
if !isContainerName(name) {
return false, false, nil
}
// Check if the container is known to mesos and it is active.
id := ContainerNameToMesosId(name)
_, err = self.client.ContainerInfo(id)
if err != nil {
return false, true, fmt.Errorf("error getting running container: %v", err)
}
return true, true, nil
}
func (self *mesosFactory) DebugInfo() map[string][]string {
return map[string][]string{}
}
func Register(
machineInfoFactory info.MachineInfoFactory,
fsInfo fs.FsInfo,
includedMetrics container.MetricSet,
) error {
client, err := Client()
if err != nil {
return fmt.Errorf("unable to create mesos agent client: %v", err)
}
cgroupSubsystems, err := libcontainer.GetCgroupSubsystems()
if err != nil {
return fmt.Errorf("failed to get cgroup subsystems: %v", err)
}
glog.V(1).Infof("Registering mesos factory")
factory := &mesosFactory{
machineInfoFactory: machineInfoFactory,
cgroupSubsystems: cgroupSubsystems,
fsInfo: fsInfo,
includedMetrics: includedMetrics,
client: client,
}
container.RegisterContainerHandlerFactory(factory, []watcher.ContainerWatchSource{watcher.Raw})
return nil
}

View File

@ -0,0 +1,213 @@
// Copyright 2018 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.
// Handler for "mesos" containers.
package mesos
import (
"fmt"
"path"
"github.com/google/cadvisor/container"
"github.com/google/cadvisor/container/common"
containerlibcontainer "github.com/google/cadvisor/container/libcontainer"
"github.com/google/cadvisor/fs"
info "github.com/google/cadvisor/info/v1"
cgroupfs "github.com/opencontainers/runc/libcontainer/cgroups/fs"
libcontainerconfigs "github.com/opencontainers/runc/libcontainer/configs"
)
type mesosContainerHandler struct {
// Name of the container for this handler.
name string
// machineInfoFactory provides info.MachineInfo
machineInfoFactory info.MachineInfoFactory
// Absolute path to the cgroup hierarchies of this container.
// (e.g.: "cpu" -> "/sys/fs/cgroup/cpu/test")
cgroupPaths map[string]string
// File System Info
fsInfo fs.FsInfo
// Metrics to be included.
includedMetrics container.MetricSet
labels map[string]string
// Reference to the container
reference info.ContainerReference
libcontainerHandler *containerlibcontainer.Handler
}
func isRootCgroup(name string) bool {
return name == "/"
}
func newMesosContainerHandler(
name string,
cgroupSubsystems *containerlibcontainer.CgroupSubsystems,
machineInfoFactory info.MachineInfoFactory,
fsInfo fs.FsInfo,
includedMetrics container.MetricSet,
inHostNamespace bool,
client mesosAgentClient,
) (container.ContainerHandler, error) {
cgroupPaths := common.MakeCgroupPaths(cgroupSubsystems.MountPoints, name)
for key, val := range cgroupSubsystems.MountPoints {
cgroupPaths[key] = path.Join(val, name)
}
// Generate the equivalent cgroup manager for this container.
cgroupManager := &cgroupfs.Manager{
Cgroups: &libcontainerconfigs.Cgroup{
Name: name,
},
Paths: cgroupPaths,
}
rootFs := "/"
if !inHostNamespace {
rootFs = "/rootfs"
}
id := ContainerNameToMesosId(name)
cinfo, err := client.ContainerInfo(id)
if err != nil {
return nil, err
}
labels := cinfo.labels
pid, err := client.ContainerPid(id)
if err != nil {
return nil, err
}
libcontainerHandler := containerlibcontainer.NewHandler(cgroupManager, rootFs, pid, includedMetrics)
reference := info.ContainerReference{
Id: id,
Name: name,
Namespace: MesosNamespace,
Aliases: []string{id, name},
}
handler := &mesosContainerHandler{
name: name,
machineInfoFactory: machineInfoFactory,
cgroupPaths: cgroupPaths,
fsInfo: fsInfo,
includedMetrics: includedMetrics,
labels: labels,
reference: reference,
libcontainerHandler: libcontainerHandler,
}
return handler, nil
}
func (self *mesosContainerHandler) ContainerReference() (info.ContainerReference, error) {
// We only know the container by its one name.
return self.reference, nil
}
// Nothing to start up.
func (self *mesosContainerHandler) Start() {}
// Nothing to clean up.
func (self *mesosContainerHandler) Cleanup() {}
func (self *mesosContainerHandler) GetSpec() (info.ContainerSpec, error) {
// TODO: Since we dont collect disk usage and network stats for mesos containers, we set
// hasFilesystem and hasNetwork to false. Revisit when we support disk usage, network
// stats for mesos containers.
hasNetwork := false
hasFilesystem := false
spec, err := common.GetSpec(self.cgroupPaths, self.machineInfoFactory, hasNetwork, hasFilesystem)
if err != nil {
return spec, err
}
spec.Labels = self.labels
return spec, nil
}
func (self *mesosContainerHandler) getFsStats(stats *info.ContainerStats) error {
mi, err := self.machineInfoFactory.GetMachineInfo()
if err != nil {
return err
}
if self.includedMetrics.Has(container.DiskIOMetrics) {
common.AssignDeviceNamesToDiskStats((*common.MachineInfoNamer)(mi), &stats.DiskIo)
}
return nil
}
func (self *mesosContainerHandler) GetStats() (*info.ContainerStats, error) {
stats, err := self.libcontainerHandler.GetStats()
if err != nil {
return stats, err
}
// Get filesystem stats.
err = self.getFsStats(stats)
if err != nil {
return stats, err
}
return stats, nil
}
func (self *mesosContainerHandler) GetCgroupPath(resource string) (string, error) {
path, ok := self.cgroupPaths[resource]
if !ok {
return "", fmt.Errorf("could not find path for resource %q for container %q\n", resource, self.name)
}
return path, nil
}
func (self *mesosContainerHandler) GetContainerLabels() map[string]string {
return self.labels
}
func (self *mesosContainerHandler) GetContainerIPAddress() string {
// the IP address for the mesos container corresponds to the system ip address.
return "127.0.0.1"
}
func (self *mesosContainerHandler) ListContainers(listType container.ListType) ([]info.ContainerReference, error) {
return common.ListContainers(self.name, self.cgroupPaths, listType)
}
func (self *mesosContainerHandler) ListProcesses(listType container.ListType) ([]int, error) {
return self.libcontainerHandler.GetProcesses()
}
func (self *mesosContainerHandler) Exists() bool {
return common.CgroupExists(self.cgroupPaths)
}
func (self *mesosContainerHandler) Type() container.ContainerType {
return container.ContainerTypeMesos
}

View File

@ -0,0 +1,147 @@
// Copyright 2018 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 mesos
import (
"fmt"
"github.com/mesos/mesos-go/api/v1/lib"
"github.com/mesos/mesos-go/api/v1/lib/agent"
)
const (
cpus = "cpus"
schedulerSLA = "scheduler_sla"
framework = "framework"
source = "source"
revocable = "revocable"
nonRevocable = "non_revocable"
)
type mContainers *agent.Response_GetContainers
type mContainer = agent.Response_GetContainers_Container
type (
state struct {
st *agent.Response_GetState
}
)
// GetFramework finds a framework with the given id and returns nil if not found. Note that
// this is different from the framework name.
func (s *state) GetFramework(id string) (*mesos.FrameworkInfo, error) {
for _, fw := range s.st.GetFrameworks.Frameworks {
if fw.FrameworkInfo.ID.Value == id {
return &fw.FrameworkInfo, nil
}
}
return nil, fmt.Errorf("unable to find framework id %s", id)
}
// GetExecutor finds an executor with the given ID and returns nil if not found. Note that
// this is different from the executor name.
func (s *state) GetExecutor(id string) (*mesos.ExecutorInfo, error) {
for _, exec := range s.st.GetExecutors.Executors {
if exec.ExecutorInfo.ExecutorID.Value == id {
return &exec.ExecutorInfo, nil
}
}
return nil, fmt.Errorf("unable to find executor with id %s", id)
}
// GetTask returns a task launched by given executor.
func (s *state) GetTask(exID string) (*mesos.Task, error) {
// Check if task is in Launched Tasks list
for _, t := range s.st.GetTasks.LaunchedTasks {
if s.isMatchingTask(&t, exID) {
return &t, nil
}
}
// Check if task is in Queued Tasks list
for _, t := range s.st.GetTasks.QueuedTasks {
if s.isMatchingTask(&t, exID) {
return &t, nil
}
}
return nil, fmt.Errorf("unable to find task matching executor id %s", exID)
}
func (s *state) isMatchingTask(t *mesos.Task, exID string) bool {
// MESOS-9111: For tasks launched through mesos command/default executor, the
// executorID(which is same as the taskID) field is not filled in the TaskInfo object.
// The workaround is compare with taskID field if executorID is empty
if t.ExecutorID != nil {
if t.ExecutorID.Value == exID {
return true
}
} else {
if t.TaskID.Value == exID {
return true
}
}
return false
}
func (s *state) fetchLabelsFromTask(exID string, labels map[string]string) error {
t, err := s.GetTask(exID)
if err != nil {
return err
}
// Identify revocability. Can be removed once we have a proper label
for _, resource := range t.Resources {
if resource.Name == cpus {
if resource.Revocable != nil {
labels[schedulerSLA] = revocable
} else {
labels[schedulerSLA] = nonRevocable
}
break
}
}
for _, l := range t.Labels.Labels {
labels[l.Key] = *l.Value
}
return nil
}
func (s *state) FetchLabels(fwID string, exID string) (map[string]string, error) {
labels := make(map[string]string)
// Look for the framework which launched the container.
fw, err := s.GetFramework(fwID)
if err != nil {
return labels, fmt.Errorf("framework ID %q not found: %v", fwID, err)
}
labels[framework] = fw.Name
// Get the executor info of the container which contains all the task info.
exec, err := s.GetExecutor(exID)
if err != nil {
return labels, fmt.Errorf("executor ID %q not found: %v", exID, err)
}
labels[source] = *exec.Source
err = s.fetchLabelsFromTask(exID, labels)
if err != nil {
return labels, fmt.Errorf("failed to fetch labels from task with executor ID %s", exID)
}
return labels, nil
}

View File

@ -17,6 +17,7 @@ package raw
import (
"flag"
"fmt"
"strings"
"github.com/google/cadvisor/container"
"github.com/google/cadvisor/container/common"
@ -43,8 +44,11 @@ type rawFactory struct {
// Watcher for inotify events.
watcher *common.InotifyWatcher
// List of metrics to be ignored.
ignoreMetrics map[container.MetricKind]struct{}
// List of metrics to be included.
includedMetrics map[container.MetricKind]struct{}
// List of raw container cgroup path prefix whitelist.
rawPrefixWhiteList []string
}
func (self *rawFactory) String() string {
@ -56,12 +60,19 @@ func (self *rawFactory) NewContainerHandler(name string, inHostNamespace bool) (
if !inHostNamespace {
rootFs = "/rootfs"
}
return newRawContainerHandler(name, self.cgroupSubsystems, self.machineInfoFactory, self.fsInfo, self.watcher, rootFs, self.ignoreMetrics)
return newRawContainerHandler(name, self.cgroupSubsystems, self.machineInfoFactory, self.fsInfo, self.watcher, rootFs, self.includedMetrics)
}
// The raw factory can handle any container. If --docker_only is set to false, non-docker containers are ignored.
func (self *rawFactory) CanHandleAndAccept(name string) (bool, bool, error) {
accept := name == "/" || !*dockerOnly
for _, prefix := range self.rawPrefixWhiteList {
if strings.HasPrefix(name, prefix) {
accept = true
break
}
}
return true, accept, nil
}
@ -69,7 +80,7 @@ func (self *rawFactory) DebugInfo() map[string][]string {
return common.DebugInfo(self.watcher.GetWatches())
}
func Register(machineInfoFactory info.MachineInfoFactory, fsInfo fs.FsInfo, ignoreMetrics map[container.MetricKind]struct{}) error {
func Register(machineInfoFactory info.MachineInfoFactory, fsInfo fs.FsInfo, includedMetrics map[container.MetricKind]struct{}, rawPrefixWhiteList []string) error {
cgroupSubsystems, err := libcontainer.GetCgroupSubsystems()
if err != nil {
return fmt.Errorf("failed to get cgroup subsystems: %v", err)
@ -89,7 +100,8 @@ func Register(machineInfoFactory info.MachineInfoFactory, fsInfo fs.FsInfo, igno
fsInfo: fsInfo,
cgroupSubsystems: &cgroupSubsystems,
watcher: watcher,
ignoreMetrics: ignoreMetrics,
includedMetrics: includedMetrics,
rawPrefixWhiteList: rawPrefixWhiteList,
}
container.RegisterContainerHandlerFactory(factory, []watch.ContainerWatchSource{watch.Raw})
return nil

View File

@ -49,7 +49,7 @@ func isRootCgroup(name string) bool {
return name == "/"
}
func newRawContainerHandler(name string, cgroupSubsystems *libcontainer.CgroupSubsystems, machineInfoFactory info.MachineInfoFactory, fsInfo fs.FsInfo, watcher *common.InotifyWatcher, rootFs string, ignoreMetrics container.MetricSet) (container.ContainerHandler, error) {
func newRawContainerHandler(name string, cgroupSubsystems *libcontainer.CgroupSubsystems, machineInfoFactory info.MachineInfoFactory, fsInfo fs.FsInfo, watcher *common.InotifyWatcher, rootFs string, includedMetrics container.MetricSet) (container.ContainerHandler, error) {
cgroupPaths := common.MakeCgroupPaths(cgroupSubsystems.MountPoints, name)
cHints, err := common.GetContainerHintsFromFile(*common.ArgContainerHints)
@ -78,7 +78,7 @@ func newRawContainerHandler(name string, cgroupSubsystems *libcontainer.CgroupSu
pid = 1
}
handler := libcontainer.NewHandler(cgroupManager, rootFs, pid, ignoreMetrics)
handler := libcontainer.NewHandler(cgroupManager, rootFs, pid, includedMetrics)
return &rawContainerHandler{
name: name,

View File

@ -35,7 +35,7 @@ type rktFactory struct {
fsInfo fs.FsInfo
ignoreMetrics container.MetricSet
includedMetrics container.MetricSet
rktPath string
}
@ -54,7 +54,7 @@ func (self *rktFactory) NewContainerHandler(name string, inHostNamespace bool) (
if !inHostNamespace {
rootFs = "/rootfs"
}
return newRktContainerHandler(name, client, self.rktPath, self.cgroupSubsystems, self.machineInfoFactory, self.fsInfo, rootFs, self.ignoreMetrics)
return newRktContainerHandler(name, client, self.rktPath, self.cgroupSubsystems, self.machineInfoFactory, self.fsInfo, rootFs, self.includedMetrics)
}
func (self *rktFactory) CanHandleAndAccept(name string) (bool, bool, error) {
@ -67,7 +67,7 @@ func (self *rktFactory) DebugInfo() map[string][]string {
return map[string][]string{}
}
func Register(machineInfoFactory info.MachineInfoFactory, fsInfo fs.FsInfo, ignoreMetrics container.MetricSet) error {
func Register(machineInfoFactory info.MachineInfoFactory, fsInfo fs.FsInfo, includedMetrics container.MetricSet) error {
_, err := Client()
if err != nil {
return fmt.Errorf("unable to communicate with Rkt api service: %v", err)
@ -91,7 +91,7 @@ func Register(machineInfoFactory info.MachineInfoFactory, fsInfo fs.FsInfo, igno
machineInfoFactory: machineInfoFactory,
fsInfo: fsInfo,
cgroupSubsystems: &cgroupSubsystems,
ignoreMetrics: ignoreMetrics,
includedMetrics: includedMetrics,
rktPath: rktPath,
}
container.RegisterContainerHandlerFactory(factory, []watcher.ContainerWatchSource{watcher.Rkt})

View File

@ -48,7 +48,7 @@ type rktContainerHandler struct {
// Filesystem handler.
fsHandler common.FsHandler
ignoreMetrics container.MetricSet
includedMetrics container.MetricSet
apiPod *rktapi.Pod
@ -59,7 +59,7 @@ type rktContainerHandler struct {
libcontainerHandler *libcontainer.Handler
}
func newRktContainerHandler(name string, rktClient rktapi.PublicAPIClient, rktPath string, cgroupSubsystems *libcontainer.CgroupSubsystems, machineInfoFactory info.MachineInfoFactory, fsInfo fs.FsInfo, rootFs string, ignoreMetrics container.MetricSet) (container.ContainerHandler, error) {
func newRktContainerHandler(name string, rktClient rktapi.PublicAPIClient, rktPath string, cgroupSubsystems *libcontainer.CgroupSubsystems, machineInfoFactory info.MachineInfoFactory, fsInfo fs.FsInfo, rootFs string, includedMetrics container.MetricSet) (container.ContainerHandler, error) {
aliases := make([]string, 1)
isPod := false
@ -109,7 +109,7 @@ func newRktContainerHandler(name string, rktClient rktapi.PublicAPIClient, rktPa
Paths: cgroupPaths,
}
libcontainerHandler := libcontainer.NewHandler(cgroupManager, rootFs, pid, ignoreMetrics)
libcontainerHandler := libcontainer.NewHandler(cgroupManager, rootFs, pid, includedMetrics)
rootfsStorageDir := getRootFs(rktPath, parsed)
@ -125,14 +125,14 @@ func newRktContainerHandler(name string, rktClient rktapi.PublicAPIClient, rktPa
fsInfo: fsInfo,
isPod: isPod,
rootfsStorageDir: rootfsStorageDir,
ignoreMetrics: ignoreMetrics,
includedMetrics: includedMetrics,
apiPod: apiPod,
labels: labels,
reference: containerReference,
libcontainerHandler: libcontainerHandler,
}
if !ignoreMetrics.Has(container.DiskUsageMetrics) {
if includedMetrics.Has(container.DiskUsageMetrics) {
handler.fsHandler = common.NewFsHandler(common.DefaultPeriod, rootfsStorageDir, "", fsInfo)
}
@ -170,8 +170,8 @@ func (handler *rktContainerHandler) Cleanup() {
}
func (handler *rktContainerHandler) GetSpec() (info.ContainerSpec, error) {
hasNetwork := handler.isPod && !handler.ignoreMetrics.Has(container.NetworkUsageMetrics)
hasFilesystem := !handler.ignoreMetrics.Has(container.DiskUsageMetrics)
hasNetwork := handler.isPod && handler.includedMetrics.Has(container.NetworkUsageMetrics)
hasFilesystem := handler.includedMetrics.Has(container.DiskUsageMetrics)
spec, err := common.GetSpec(handler.cgroupPaths, handler.machineInfoFactory, hasNetwork, hasFilesystem)
@ -186,11 +186,11 @@ func (handler *rktContainerHandler) getFsStats(stats *info.ContainerStats) error
return err
}
if !handler.ignoreMetrics.Has(container.DiskIOMetrics) {
if handler.includedMetrics.Has(container.DiskIOMetrics) {
common.AssignDeviceNamesToDiskStats((*common.MachineInfoNamer)(mi), &stats.DiskIo)
}
if handler.ignoreMetrics.Has(container.DiskUsageMetrics) {
if !handler.includedMetrics.Has(container.DiskUsageMetrics) {
return nil
}

View File

@ -50,7 +50,7 @@ func (f *systemdFactory) DebugInfo() map[string][]string {
}
// Register registers the systemd container factory.
func Register(machineInfoFactory info.MachineInfoFactory, fsInfo fs.FsInfo, ignoreMetrics container.MetricSet) error {
func Register(machineInfoFactory info.MachineInfoFactory, fsInfo fs.FsInfo, includedMetrics container.MetricSet) error {
glog.V(1).Infof("Registering systemd factory")
factory := &systemdFactory{}
container.RegisterContainerHandlerFactory(factory, []watcher.ContainerWatchSource{watcher.Raw})

View File

@ -422,7 +422,7 @@ func (self *RealFsInfo) GetFsInfoForPath(mountSet map[string]struct{}) ([]Fs, er
}
}
if err != nil {
glog.Errorf("Stat fs failed. Error: %v", err)
glog.V(4).Infof("Stat fs failed. Error: %v", err)
} else {
deviceSet[device] = struct{}{}
fs.DeviceInfo = DeviceInfo{
@ -533,6 +533,21 @@ func (self *RealFsInfo) GetDirFsDevice(dir string) (*DeviceInfo, error) {
}
mount, found := self.mounts[dir]
// try the parent dir if not found until we reach the root dir
// this is an issue on btrfs systems where the directory is not
// the subvolume
for !found {
pathdir, _ := filepath.Split(dir)
// break when we reach root
if pathdir == "/" {
break
}
// trim "/" from the new parent path otherwise the next possible
// filepath.Split in the loop will not split the string any further
dir = strings.TrimSuffix(pathdir, "/")
mount, found = self.mounts[dir]
}
if found && mount.Fstype == "btrfs" && mount.Major == 0 && strings.HasPrefix(mount.Source, "/dev/") {
major, minor, err := getBtrfsMajorMinorIds(mount)
if err != nil {

View File

@ -358,6 +358,9 @@ type MemoryStats struct {
// Units: Bytes.
Swap uint64 `json:"swap"`
// The amount of memory used for mapped files (includes tmpfs/shmem)
MappedFile uint64 `json:"mapped_file"`
// The amount of working set memory, this includes recently accessed memory,
// dirty memory, and kernel memory. Working set is <= "usage".
// Units: Bytes.

View File

@ -19,6 +19,7 @@ go_library(
"//vendor/github.com/google/cadvisor/container/containerd:go_default_library",
"//vendor/github.com/google/cadvisor/container/crio:go_default_library",
"//vendor/github.com/google/cadvisor/container/docker:go_default_library",
"//vendor/github.com/google/cadvisor/container/mesos:go_default_library",
"//vendor/github.com/google/cadvisor/container/raw:go_default_library",
"//vendor/github.com/google/cadvisor/container/rkt:go_default_library",
"//vendor/github.com/google/cadvisor/container/systemd:go_default_library",

View File

@ -33,6 +33,7 @@ import (
"github.com/google/cadvisor/container/containerd"
"github.com/google/cadvisor/container/crio"
"github.com/google/cadvisor/container/docker"
"github.com/google/cadvisor/container/mesos"
"github.com/google/cadvisor/container/raw"
"github.com/google/cadvisor/container/rkt"
"github.com/google/cadvisor/container/systemd"
@ -141,7 +142,7 @@ type Manager interface {
}
// New takes a memory storage and returns a new manager.
func New(memoryCache *memory.InMemoryCache, sysfs sysfs.SysFs, maxHousekeepingInterval time.Duration, allowDynamicHousekeeping bool, ignoreMetricsSet container.MetricSet, collectorHttpClient *http.Client) (Manager, error) {
func New(memoryCache *memory.InMemoryCache, sysfs sysfs.SysFs, maxHousekeepingInterval time.Duration, allowDynamicHousekeeping bool, includedMetricsSet container.MetricSet, collectorHttpClient *http.Client, rawContainerCgroupPathPrefixWhiteList []string) (Manager, error) {
if memoryCache == nil {
return nil, fmt.Errorf("manager requires memory storage")
}
@ -203,20 +204,21 @@ func New(memoryCache *memory.InMemoryCache, sysfs sysfs.SysFs, maxHousekeepingIn
eventsChannel := make(chan watcher.ContainerEvent, 16)
newManager := &manager{
containers: make(map[namespacedContainerName]*containerData),
quitChannels: make([]chan error, 0, 2),
memoryCache: memoryCache,
fsInfo: fsInfo,
cadvisorContainer: selfContainer,
inHostNamespace: inHostNamespace,
startupTime: time.Now(),
maxHousekeepingInterval: maxHousekeepingInterval,
allowDynamicHousekeeping: allowDynamicHousekeeping,
ignoreMetrics: ignoreMetricsSet,
containerWatchers: []watcher.ContainerWatcher{},
eventsChannel: eventsChannel,
collectorHttpClient: collectorHttpClient,
nvidiaManager: &accelerators.NvidiaManager{},
containers: make(map[namespacedContainerName]*containerData),
quitChannels: make([]chan error, 0, 2),
memoryCache: memoryCache,
fsInfo: fsInfo,
cadvisorContainer: selfContainer,
inHostNamespace: inHostNamespace,
startupTime: time.Now(),
maxHousekeepingInterval: maxHousekeepingInterval,
allowDynamicHousekeeping: allowDynamicHousekeeping,
includedMetrics: includedMetricsSet,
containerWatchers: []watcher.ContainerWatcher{},
eventsChannel: eventsChannel,
collectorHttpClient: collectorHttpClient,
nvidiaManager: &accelerators.NvidiaManager{},
rawContainerCgroupPathPrefixWhiteList: rawContainerCgroupPathPrefixWhiteList,
}
machineInfo, err := machine.Info(sysfs, fsInfo, inHostNamespace)
@ -283,21 +285,23 @@ type manager struct {
startupTime time.Time
maxHousekeepingInterval time.Duration
allowDynamicHousekeeping bool
ignoreMetrics container.MetricSet
includedMetrics container.MetricSet
containerWatchers []watcher.ContainerWatcher
eventsChannel chan watcher.ContainerEvent
collectorHttpClient *http.Client
nvidiaManager accelerators.AcceleratorManager
// List of raw container cgroup path prefix whitelist.
rawContainerCgroupPathPrefixWhiteList []string
}
// Start the container manager.
func (self *manager) Start() error {
err := docker.Register(self, self.fsInfo, self.ignoreMetrics)
err := docker.Register(self, self.fsInfo, self.includedMetrics)
if err != nil {
glog.V(5).Infof("Registration of the Docker container factory failed: %v.", err)
}
err = rkt.Register(self, self.fsInfo, self.ignoreMetrics)
err = rkt.Register(self, self.fsInfo, self.includedMetrics)
if err != nil {
glog.V(5).Infof("Registration of the rkt container factory failed: %v", err)
} else {
@ -308,22 +312,27 @@ func (self *manager) Start() error {
self.containerWatchers = append(self.containerWatchers, watcher)
}
err = containerd.Register(self, self.fsInfo, self.ignoreMetrics)
err = containerd.Register(self, self.fsInfo, self.includedMetrics)
if err != nil {
glog.V(5).Infof("Registration of the containerd container factory failed: %v", err)
}
err = crio.Register(self, self.fsInfo, self.ignoreMetrics)
err = crio.Register(self, self.fsInfo, self.includedMetrics)
if err != nil {
glog.V(5).Infof("Registration of the crio container factory failed: %v", err)
}
err = systemd.Register(self, self.fsInfo, self.ignoreMetrics)
err = mesos.Register(self, self.fsInfo, self.includedMetrics)
if err != nil {
glog.V(5).Infof("Registration of the mesos container factory failed: %v", err)
}
err = systemd.Register(self, self.fsInfo, self.includedMetrics)
if err != nil {
glog.V(5).Infof("Registration of the systemd container factory failed: %v", err)
}
err = raw.Register(self, self.fsInfo, self.ignoreMetrics)
err = raw.Register(self, self.fsInfo, self.includedMetrics, self.rawContainerCgroupPathPrefixWhiteList)
if err != nil {
glog.Errorf("Registration of the raw container factory failed: %v", err)
}
@ -619,6 +628,11 @@ func (self *manager) AllDockerContainers(query *info.ContainerInfoRequest) (map[
for name, cont := range containers {
inf, err := self.containerDataToContainerInfo(cont, query)
if err != nil {
// Ignore the error because of race condition and return best-effort result.
if err == memory.ErrDataNotFound {
glog.Warningf("Error getting data for container %s because of race condition", name)
continue
}
return nil, err
}
output[name] = *inf
@ -1072,22 +1086,25 @@ func (m *manager) destroyContainerLocked(containerName string) error {
// Detect all containers that have been added or deleted from the specified container.
func (m *manager) getContainersDiff(containerName string) (added []info.ContainerReference, removed []info.ContainerReference, err error) {
m.containersLock.RLock()
defer m.containersLock.RUnlock()
// Get all subcontainers recursively.
m.containersLock.RLock()
cont, ok := m.containers[namespacedContainerName{
Name: containerName,
}]
m.containersLock.RUnlock()
if !ok {
return nil, nil, fmt.Errorf("failed to find container %q while checking for new containers", containerName)
}
allContainers, err := cont.handler.ListContainers(container.ListRecursive)
if err != nil {
return nil, nil, err
}
allContainers = append(allContainers, info.ContainerReference{Name: containerName})
m.containersLock.RLock()
defer m.containersLock.RUnlock()
// Determine which were added and which were removed.
allContainersSet := make(map[string]*containerData)
for name, d := range m.containers {

View File

@ -8,6 +8,7 @@ go_library(
visibility = ["//visibility:public"],
deps = [
"//vendor/github.com/golang/glog:go_default_library",
"//vendor/github.com/google/cadvisor/container:go_default_library",
"//vendor/github.com/google/cadvisor/info/v1:go_default_library",
"//vendor/github.com/prometheus/client_golang/prometheus:go_default_library",
],

View File

@ -19,6 +19,7 @@ import (
"regexp"
"time"
"github.com/google/cadvisor/container"
info "github.com/google/cadvisor/info/v1"
"github.com/golang/glog"
@ -114,7 +115,7 @@ type PrometheusCollector struct {
// ContainerLabelsFunc specifies which base labels will be attached to all
// exported metrics. If left to nil, the DefaultContainerLabels function
// will be used instead.
func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc) *PrometheusCollector {
func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc, includedMetrics container.MetricSet) *PrometheusCollector {
if f == nil {
f = DefaultContainerLabels
}
@ -134,7 +135,12 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc) *PrometheusCo
getValues: func(s *info.ContainerStats) metricValues {
return metricValues{{value: float64(time.Now().Unix())}}
},
}, {
},
},
}
if includedMetrics.Has(container.CpuUsageMetrics) {
c.containerMetrics = append(c.containerMetrics, []containerMetric{
{
name: "container_cpu_user_seconds_total",
help: "Cumulative user cpu time consumed in seconds.",
valueType: prometheus.CounterValue,
@ -197,7 +203,12 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc) *PrometheusCo
getValues: func(s *info.ContainerStats) metricValues {
return metricValues{{value: float64(s.Cpu.CFS.ThrottledTime) / float64(time.Second)}}
},
}, {
},
}...)
}
if includedMetrics.Has(container.ProcessSchedulerMetrics) {
c.containerMetrics = append(c.containerMetrics, []containerMetric{
{
name: "container_cpu_schedstat_run_seconds_total",
help: "Time duration the processes of the container have run on the CPU.",
valueType: prometheus.CounterValue,
@ -218,7 +229,12 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc) *PrometheusCo
getValues: func(s *info.ContainerStats) metricValues {
return metricValues{{value: float64(s.Cpu.Schedstat.RunPeriods)}}
},
}, {
},
}...)
}
if includedMetrics.Has(container.CpuLoadMetrics) {
c.containerMetrics = append(c.containerMetrics, []containerMetric{
{
name: "container_cpu_load_average_10s",
help: "Value of container cpu load average over the last 10 seconds.",
valueType: prometheus.GaugeValue,
@ -226,6 +242,40 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc) *PrometheusCo
return metricValues{{value: float64(s.Cpu.LoadAverage)}}
},
}, {
name: "container_tasks_state",
help: "Number of tasks in given state",
extraLabels: []string{"state"},
valueType: prometheus.GaugeValue,
getValues: func(s *info.ContainerStats) metricValues {
return metricValues{
{
value: float64(s.TaskStats.NrSleeping),
labels: []string{"sleeping"},
},
{
value: float64(s.TaskStats.NrRunning),
labels: []string{"running"},
},
{
value: float64(s.TaskStats.NrStopped),
labels: []string{"stopped"},
},
{
value: float64(s.TaskStats.NrUninterruptible),
labels: []string{"uninterruptible"},
},
{
value: float64(s.TaskStats.NrIoWait),
labels: []string{"iowaiting"},
},
}
},
},
}...)
}
if includedMetrics.Has(container.MemoryUsageMetrics) {
c.containerMetrics = append(c.containerMetrics, []containerMetric{
{
name: "container_memory_cache",
help: "Number of bytes of page cache memory.",
valueType: prometheus.GaugeValue,
@ -239,6 +289,13 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc) *PrometheusCo
getValues: func(s *info.ContainerStats) metricValues {
return metricValues{{value: float64(s.Memory.RSS)}}
},
}, {
name: "container_memory_mapped_file",
help: "Size of memory mapped files in bytes.",
valueType: prometheus.GaugeValue,
getValues: func(s *info.ContainerStats) metricValues {
return metricValues{{value: float64(s.Memory.MappedFile)}}
},
}, {
name: "container_memory_swap",
help: "Container swap usage in bytes.",
@ -300,7 +357,12 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc) *PrometheusCo
},
}
},
}, {
},
}...)
}
if includedMetrics.Has(container.AcceleratorUsageMetrics) {
c.containerMetrics = append(c.containerMetrics, []containerMetric{
{
name: "container_accelerator_memory_total_bytes",
help: "Total accelerator memory.",
valueType: prometheus.GaugeValue,
@ -345,7 +407,12 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc) *PrometheusCo
}
return values
},
}, {
},
}...)
}
if includedMetrics.Has(container.DiskUsageMetrics) {
c.containerMetrics = append(c.containerMetrics, []containerMetric{
{
name: "container_fs_inodes_free",
help: "Number of available Inodes",
valueType: prometheus.GaugeValue,
@ -385,7 +452,12 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc) *PrometheusCo
return float64(fs.Usage)
})
},
}, {
},
}...)
}
if includedMetrics.Has(container.DiskIOMetrics) {
c.containerMetrics = append(c.containerMetrics, []containerMetric{
{
name: "container_fs_reads_bytes_total",
help: "Cumulative count of bytes read",
valueType: prometheus.CounterValue,
@ -547,7 +619,12 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc) *PrometheusCo
return float64(fs.WeightedIoTime) / float64(time.Second)
})
},
}, {
},
}...)
}
if includedMetrics.Has(container.NetworkUsageMetrics) {
c.containerMetrics = append(c.containerMetrics, []containerMetric{
{
name: "container_network_receive_bytes_total",
help: "Cumulative count of bytes received",
valueType: prometheus.CounterValue,
@ -667,7 +744,12 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc) *PrometheusCo
}
return values
},
}, {
},
}...)
}
if includedMetrics.Has(container.NetworkTcpUsageMetrics) {
c.containerMetrics = append(c.containerMetrics, []containerMetric{
{
name: "container_network_tcp_usage_total",
help: "tcp connection usage statistic for container",
valueType: prometheus.GaugeValue,
@ -720,7 +802,12 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc) *PrometheusCo
},
}
},
}, {
},
}...)
}
if includedMetrics.Has(container.NetworkUdpUsageMetrics) {
c.containerMetrics = append(c.containerMetrics, []containerMetric{
{
name: "container_network_udp_usage_total",
help: "udp connection usage statistic for container",
valueType: prometheus.GaugeValue,
@ -745,37 +832,8 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc) *PrometheusCo
},
}
},
}, {
name: "container_tasks_state",
help: "Number of tasks in given state",
extraLabels: []string{"state"},
valueType: prometheus.GaugeValue,
getValues: func(s *info.ContainerStats) metricValues {
return metricValues{
{
value: float64(s.TaskStats.NrSleeping),
labels: []string{"sleeping"},
},
{
value: float64(s.TaskStats.NrRunning),
labels: []string{"running"},
},
{
value: float64(s.TaskStats.NrStopped),
labels: []string{"stopped"},
},
{
value: float64(s.TaskStats.NrUninterruptible),
labels: []string{"uninterruptible"},
},
{
value: float64(s.TaskStats.NrIoWait),
labels: []string{"iowaiting"},
},
}
},
},
},
}...)
}
return c
@ -842,6 +900,19 @@ func DefaultContainerLabels(container *info.ContainerInfo) map[string]string {
return set
}
// BaseContainerLabels implements ContainerLabelsFunc. It only exports the
// container name, first alias, and image name.
func BaseContainerLabels(container *info.ContainerInfo) map[string]string {
set := map[string]string{LabelID: container.Name}
if len(container.Aliases) > 0 {
set[LabelName] = container.Aliases[0]
}
if image := container.Spec.Image; len(image) > 0 {
set[LabelImage] = image
}
return set
}
func (c *PrometheusCollector) collectContainersInfo(ch chan<- prometheus.Metric) {
containers, err := c.infoProvider.SubcontainersInfo("/", &info.ContainerInfoRequest{NumStats: 1})
if err != nil {
@ -889,6 +960,9 @@ func (c *PrometheusCollector) collectContainersInfo(ch chan<- prometheus.Metric)
}
// Now for the actual metrics
if len(container.Stats) == 0 {
continue
}
stats := container.Stats[0]
for _, cm := range c.containerMetrics {
if cm.condition != nil && !cm.condition(container.Spec) {

201
vendor/github.com/mesos/mesos-go/LICENSE generated vendored Normal file
View File

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright {yyyy} {name of copyright owner}
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.

13
vendor/github.com/mesos/mesos-go/NOTICE generated vendored Normal file
View File

@ -0,0 +1,13 @@
Copyright 2013-2015, Mesosphere, Inc.
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.

50
vendor/github.com/mesos/mesos-go/api/v1/lib/BUILD generated vendored Normal file
View File

@ -0,0 +1,50 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"client.go",
"doc.go",
"filters.go",
"fixedpoint.go",
"labels.go",
"mesos.pb.go",
"mesos.pb_ffjson.go",
"ranges.go",
"resources.go",
"values.go",
],
importmap = "k8s.io/kubernetes/vendor/github.com/mesos/mesos-go/api/v1/lib",
importpath = "github.com/mesos/mesos-go/api/v1/lib",
visibility = ["//visibility:public"],
deps = [
"//vendor/github.com/gogo/protobuf/gogoproto:go_default_library",
"//vendor/github.com/gogo/protobuf/proto:go_default_library",
"//vendor/github.com/mesos/mesos-go/api/v1/lib/encoding:go_default_library",
"//vendor/github.com/mesos/mesos-go/api/v1/lib/roles:go_default_library",
"//vendor/github.com/pquerna/ffjson/fflib/v1:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//vendor/github.com/mesos/mesos-go/api/v1/lib/agent:all-srcs",
"//vendor/github.com/mesos/mesos-go/api/v1/lib/client:all-srcs",
"//vendor/github.com/mesos/mesos-go/api/v1/lib/debug:all-srcs",
"//vendor/github.com/mesos/mesos-go/api/v1/lib/encoding:all-srcs",
"//vendor/github.com/mesos/mesos-go/api/v1/lib/httpcli:all-srcs",
"//vendor/github.com/mesos/mesos-go/api/v1/lib/recordio:all-srcs",
"//vendor/github.com/mesos/mesos-go/api/v1/lib/roles:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@ -0,0 +1,35 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"agent.pb.go",
"agent.pb_ffjson.go",
],
importmap = "k8s.io/kubernetes/vendor/github.com/mesos/mesos-go/api/v1/lib/agent",
importpath = "github.com/mesos/mesos-go/api/v1/lib/agent",
visibility = ["//visibility:public"],
deps = [
"//vendor/github.com/gogo/protobuf/gogoproto:go_default_library",
"//vendor/github.com/gogo/protobuf/proto:go_default_library",
"//vendor/github.com/mesos/mesos-go/api/v1/lib:go_default_library",
"//vendor/github.com/pquerna/ffjson/fflib/v1:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//vendor/github.com/mesos/mesos-go/api/v1/lib/agent/calls:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,706 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you 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.
syntax = "proto2";
package mesos.agent;
import "github.com/mesos/mesos-go/api/v1/lib/mesos.proto";
import "github.com/gogo/protobuf/gogoproto/gogo.proto";
option go_package = "agent";
option (gogoproto.benchgen_all) = true;
option (gogoproto.enum_stringer_all) = true;
option (gogoproto.equal_all) = true;
option (gogoproto.goproto_enum_prefix_all) = false;
option (gogoproto.goproto_enum_stringer_all) = false;
option (gogoproto.goproto_stringer_all) = false;
option (gogoproto.goproto_unrecognized_all) = false;
option (gogoproto.gostring_all) = true;
option (gogoproto.marshaler_all) = true;
option (gogoproto.populate_all) = true;
option (gogoproto.protosizer_all) = true;
option (gogoproto.stringer_all) = true;
option (gogoproto.testgen_all) = true;
option (gogoproto.unmarshaler_all) = true;
option (gogoproto.verbose_equal_all) = true;
/**
* Calls that can be sent to the v1 agent API.
*
* A call is described using the standard protocol buffer "union"
* trick, see
* https://developers.google.com/protocol-buffers/docs/techniques#union.
*/
message Call {
// If a call of type `Call::FOO` requires additional parameters they can be
// included in the corresponding `Call::Foo` message. Similarly, if a call
// receives a synchronous response it will be returned as a `Response`
// message of type `Response::FOO`; see `Call::LaunchNestedContainerSession`
// and `Call::AttachContainerOutput` for exceptions.
enum Type {
UNKNOWN = 0;
GET_HEALTH = 1; // Retrieves the agent's health status.
GET_FLAGS = 2; // Retrieves the agent's flag configuration.
GET_VERSION = 3; // Retrieves the agent's version information.
GET_METRICS = 4; // See 'GetMetrics' below.
GET_LOGGING_LEVEL = 5; // Retrieves the agent's logging level.
SET_LOGGING_LEVEL = 6; // See 'SetLoggingLevel' below.
LIST_FILES = 7;
READ_FILE = 8; // See 'ReadFile' below.
GET_STATE = 9;
GET_CONTAINERS = 10;
// Retrieves the information about known frameworks.
GET_FRAMEWORKS = 11;
// Retrieves the information about known executors.
GET_EXECUTORS = 12;
// Retrieves the information about known operations.
GET_OPERATIONS = 31;
// Retrieves the information about known tasks.
GET_TASKS = 13;
// Retrieves the agent information.
GET_AGENT = 20;
// Retrieves the information about known resource providers.
GET_RESOURCE_PROVIDERS = 26;
// Calls for managing nested containers underneath an executor's container.
// Some of these calls are deprecated in favor of the calls
// for both standalone or nested containers further below.
LAUNCH_NESTED_CONTAINER = 14 [deprecated = true];
WAIT_NESTED_CONTAINER = 15 [deprecated = true];
KILL_NESTED_CONTAINER = 16 [deprecated = true];
REMOVE_NESTED_CONTAINER = 21 [deprecated = true];
// See 'LaunchNestedContainerSession' below.
LAUNCH_NESTED_CONTAINER_SESSION = 17;
ATTACH_CONTAINER_INPUT = 18; // See 'AttachContainerInput' below.
ATTACH_CONTAINER_OUTPUT = 19; // see 'AttachContainerOutput' below.
// Calls for managing standalone containers
// or containers nested underneath another container.
LAUNCH_CONTAINER = 22; // See 'LaunchContainer' below.
WAIT_CONTAINER = 23; // See 'WaitContainer' below.
KILL_CONTAINER = 24; // See 'KillContainer' below.
REMOVE_CONTAINER = 25; // See 'RemoveContainer' below.
ADD_RESOURCE_PROVIDER_CONFIG = 27; // See 'AddResourceProviderConfig' below. // NOLINT
UPDATE_RESOURCE_PROVIDER_CONFIG = 28; // See 'UpdateResourceProviderConfig' below. // NOLINT
REMOVE_RESOURCE_PROVIDER_CONFIG = 29; // See 'RemoveResourceProviderConfig' below. // NOLINT
// Prune unused container images.
PRUNE_IMAGES = 30;
option (gogoproto.goproto_enum_prefix) = true;
}
// Provides a snapshot of the current metrics tracked by the agent.
message GetMetrics {
// If set, `timeout` would be used to determines the maximum amount of time
// the API will take to respond. If the timeout is exceeded, some metrics
// may not be included in the response.
optional DurationInfo timeout = 1;
}
// Sets the logging verbosity level for a specified duration. Mesos uses
// [glog](https://github.com/google/glog) for logging. The library only uses
// verbose logging which means nothing will be output unless the verbosity
// level is set (by default it's 0, libprocess uses levels 1, 2, and 3).
message SetLoggingLevel {
// The verbosity level.
required uint32 level = 1 [(gogoproto.nullable) = false];
// The duration to keep verbosity level toggled. After this duration, the
// verbosity level of log would revert to the original level.
required DurationInfo duration = 2 [(gogoproto.nullable) = false];
}
// Provides the file listing for a directory.
message ListFiles {
required string path = 1 [(gogoproto.nullable) = false];
}
// Reads data from a file.
message ReadFile {
// The path of file.
required string path = 1 [(gogoproto.nullable) = false];
// Initial offset in file to start reading from.
required uint64 offset = 2 [(gogoproto.nullable) = false];
// The maximum number of bytes to read. The read length is capped at 16
// memory pages.
optional uint64 length = 3;
}
// Lists active containers on the agent.
message GetContainers {
optional bool show_nested = 1;
optional bool show_standalone = 2;
}
// Deprecated in favor of `LaunchContainer`.
message LaunchNestedContainer {
required ContainerID container_id = 1 [(gogoproto.customname) = "ContainerID", (gogoproto.nullable) = false];
optional CommandInfo command = 2;
optional ContainerInfo container = 3;
}
// Deprecated in favor of `WaitContainer`.
message WaitNestedContainer {
required ContainerID container_id = 1 [(gogoproto.customname) = "ContainerID", (gogoproto.nullable) = false];
}
// Deprecated in favor of `KillContainer`.
message KillNestedContainer {
required ContainerID container_id = 1 [(gogoproto.customname) = "ContainerID", (gogoproto.nullable) = false];
optional int32 signal = 2;
}
// Deprecated in favor of `RemoveContainer`.
message RemoveNestedContainer {
required ContainerID container_id = 1 [(gogoproto.customname) = "ContainerID", (gogoproto.nullable) = false];
}
// Launches a nested container within an executor's tree of containers.
// The differences between this call and `LaunchNestedContainer` are:
// 1) The container's life-cycle is tied to the lifetime of the
// connection used to make this call, i.e., if the connection ever
// breaks, the container will be destroyed.
// 2) The nested container shares the same namespaces and cgroups as
// its parent container.
// 3) Results in a streaming response of type `ProcessIO`. So the call
// needs to be made on a persistent connection.
message LaunchNestedContainerSession {
required ContainerID container_id = 1 [(gogoproto.customname) = "ContainerID", (gogoproto.nullable) = false];
optional CommandInfo command = 2;
optional ContainerInfo container = 3;
}
// Attaches the caller to the STDIN of the entry point of the container.
// Clients can use this to stream input data to a container.
// Note that this call needs to be made on a persistent connection by
// streaming a CONTAINER_ID message followed by one or more PROCESS_IO
// messages.
message AttachContainerInput {
enum Type {
UNKNOWN = 0;
CONTAINER_ID = 1;
PROCESS_IO = 2;
option (gogoproto.goproto_enum_prefix) = true;
}
optional Type type = 1 [(gogoproto.nullable) = false];
optional ContainerID container_id = 2 [(gogoproto.customname) = "ContainerID"];
optional ProcessIO process_io = 3 [(gogoproto.customname) = "ProcessIO"];
}
// Attaches the caller to the STDOUT and STDERR of the entrypoint of
// the container. Clients can use this to stream output/error from the
// container. This call will result in a streaming response of `ProcessIO`;
// so this call needs to be made on a persistent connection.
message AttachContainerOutput {
required ContainerID container_id = 1 [(gogoproto.customname) = "ContainerID", (gogoproto.nullable) = false];
}
// Launches a either a "standalone" container on this agent
// or a nested container within another tree of containers.
//
// A standalone container is launched by specifying a ContainerID
// with no parent. Standalone containers bypass the normal offer cycle
// between the master and agent. Unlike other containers, a standalone
// container does not have an executor or any tasks. This means the
// standalone container does not report back to Mesos or any framework
// and must be supervised separately.
//
// A nested container is launched by specifying a ContainerID with
// another existing container (including standalone containers)
// as the parent.
//
// Returns 200 OK if the new container launch succeeds.
// Returns 202 Accepted if the requested ContainerID is already in use
// by a standalone or nested container.
// Returns 400 Bad Request if the container launch fails.
message LaunchContainer {
// NOTE: Some characters cannot be used in the ID. All characters
// must be valid filesystem path characters. In addition, '/' and '.'
// are reserved.
required ContainerID container_id = 1 [(gogoproto.nullable) = false, (gogoproto.customname) = "ContainerID"];
optional CommandInfo command = 2;
// NOTE: Nested containers may not specify resources and instead
// share resources with its parent container.
//
// TODO(josephw): These resources are purely used for isolation
// and are not accounted for by the Mesos master (if connected).
// It is the caller's responsibility to ensure that resources are
// not overcommitted (e.g. CPU and memory) or conflicting (e.g. ports
// and volumes). Once there is support for preempting tasks and a
// way to update the resources advertised by the agent, these standalone
// container resources should be accounted for by the master.
repeated Resource resources = 3 [(gogoproto.nullable) = false];
optional ContainerInfo container = 4;
}
// Waits for the standalone or nested container to terminate
// and returns the exit status.
//
// Returns 200 OK if and when the container exits.
// Returns 404 Not Found if the container does not exist.
message WaitContainer {
required ContainerID container_id = 1 [(gogoproto.nullable) = false, (gogoproto.customname) = "ContainerID"];
}
// Kills the standalone or nested container. The signal to be sent
// to the container can be specified in the 'signal' field.
//
// Returns 200 OK if the signal is sent successfully.
// Returns 404 Not Found if the container does not exist.
message KillContainer {
required ContainerID container_id = 1 [(gogoproto.nullable) = false, (gogoproto.customname) = "ContainerID"];
// Defaults to SIGKILL.
optional int32 signal = 2;
}
// Removes a container's artifacts (runtime and sandbox directories).
//
// For nested containers, it is important to use this call if multiple
// nested containers are launched under the same parent container, because
// garbage collection only takes place at the parent container. Artifacts
// belonging to nested containers will not be garbage collected while
// the parent container is running.
//
// TODO(josephw): A standalone container's runtime directory is currently
// garbage collected as soon as the container exits. To allow the user to
// retrieve the exit status reliably, the runtime directory cannot be
// garbage collected immediately. Instead, the user will eventually be
// required to make this call after the standalone container has exited.
// Also, a standalone container's sandbox directory is currently not
// garbage collected and is only deleted via this call.
//
// Returns 200 OK if the removal is successful or if the parent container
// (for nested containers) does not exist.
// Returns 500 Internal Server Error if anything goes wrong, including
// if the container is still running or does not exist.
//
// TODO(josephw): Consider returning a 400 Bad Request instead of 500
// Internal Server Error when the user tries to remove a running or
// nonexistent nested container.
message RemoveContainer {
required ContainerID container_id = 1 [(gogoproto.nullable) = false, (gogoproto.customname) = "ContainerID"];
}
// Adds a new resource provider config file.
//
// The content of the `info` field will be written into a new config file in
// the resource provider config directory, and a new resource provider will be
// launched asynchronously based on the config. Callers must not set the
// `info.id` field. This call is idempotent, so if a config file identical to
// the content of the `info` field already exists, this call will return
// without launching a resource provider. Note that if a config file is
// placed into the resource provider config directory out-of-band after the
// agent starts up, it will not be checked against this call.
//
// Returns 200 OK if a new config file is created, or an identical config file
// exists.
// Returns 400 Bad Request if `info` is not well-formed.
// Returns 403 Forbidden if the call is not authorized.
// Returns 409 Conflict if another config file that describes a
// resource provider of the same type and name exists, but the content is
// not identical.
// Returns 500 Internal Server Error if anything goes wrong.
message AddResourceProviderConfig {
required ResourceProviderInfo info = 1 [(gogoproto.nullable) = false];
}
// Updates an existing resource provider config file.
//
// The content of the `info` field will be written into an existing config
// file that describes a resource provider of the specified type and name in
// the resource provider config directory, and the corresponding resource
// provider will be relaunched asynchronously to reflect the changes in the
// config. Callers must not set the `info.id` field. This call is idempotent,
// so if there is no change in the config, this call will return without
// relaunching the resource provider. Note that if a config file is placed
// into the resource provider config directory out-of-band after the agent
// starts up, it will not be checked against this call.
//
// Returns 200 OK if an existing config file is updated, or there is no change
// in the config file.
// Returns 400 Bad Request if `info` is not well-formed.
// Returns 403 Forbidden if the call is not authorized.
// Returns 404 Not Found if no config file describes a resource
// provider of the same type and name exists.
// Returns 500 Internal Server Error if anything goes wrong.
message UpdateResourceProviderConfig {
required ResourceProviderInfo info = 1 [(gogoproto.nullable) = false];
}
// Removes a config file from the resource provider config directory.
//
// The config file that describes the resource provider of the specified type
// and name will be removed, and the corresponding resource provider will be
// terminated asynchronously. This call is idempotent, so if no matching
// config file exists, this call will return without terminating any resource
// provider. Note that if a config file is placed into the resource provider
// config directory out-of-band after the agent starts up, it will not be
// checked against this call.
//
// Returns 200 OK if the config file is removed, or no matching config file
// exists.
// Returns 403 Forbidden if the call is not authorized.
// Returns 500 Internal Server Error if anything goes wrong.
message RemoveResourceProviderConfig {
required string type = 1 [(gogoproto.nullable) = false];
required string name = 2 [(gogoproto.nullable) = false];
}
// Prune unused container images from image store.
//
// Images and layers referenced by active containers as well as
// image references specified in `excluded_images` will not be pruned.
message PruneImages {
repeated Image excluded_images = 1 [(gogoproto.nullable) = false];
}
optional Type type = 1 [(gogoproto.nullable) = false];
optional GetMetrics get_metrics = 2;
optional SetLoggingLevel set_logging_level = 3;
optional ListFiles list_files = 4;
optional ReadFile read_file = 5;
optional GetContainers get_containers = 20;
optional LaunchNestedContainer launch_nested_container = 6
[deprecated = true];
optional WaitNestedContainer wait_nested_container = 7 [deprecated = true];
optional KillNestedContainer kill_nested_container = 8 [deprecated = true];
optional RemoveNestedContainer remove_nested_container = 12
[deprecated = true];
optional LaunchNestedContainerSession launch_nested_container_session = 9;
optional AttachContainerInput attach_container_input = 10;
optional AttachContainerOutput attach_container_output = 11;
optional LaunchContainer launch_container = 13;
optional WaitContainer wait_container = 14;
optional KillContainer kill_container = 15;
optional RemoveContainer remove_container = 16;
optional AddResourceProviderConfig add_resource_provider_config = 17;
optional UpdateResourceProviderConfig update_resource_provider_config = 18;
optional RemoveResourceProviderConfig remove_resource_provider_config = 19;
optional PruneImages prune_images = 21;
}
/**
* Synchronous responses for all calls made to the v1 agent API.
*/
message Response {
// Each of the responses of type `FOO` corresponds to `Foo` message below.
enum Type {
UNKNOWN = 0;
GET_HEALTH = 1; // See 'GetHealth' below.
GET_FLAGS = 2; // See 'GetFlags' below.
GET_VERSION = 3; // See 'GetVersion' below.
GET_METRICS = 4; // See 'GetMetrics' below.
GET_LOGGING_LEVEL = 5; // See 'GetLoggingLevel' below.
LIST_FILES = 6;
READ_FILE = 7; // See 'ReadFile' below.
GET_STATE = 8;
GET_CONTAINERS = 9;
GET_FRAMEWORKS = 10; // See 'GetFrameworks' below.
GET_EXECUTORS = 11; // See 'GetExecutors' below.
GET_OPERATIONS = 17; // See 'GetOperations' below.
GET_TASKS = 12; // See 'GetTasks' below.
GET_AGENT = 14; // See 'GetAgent' below.
GET_RESOURCE_PROVIDERS = 16; // See 'GetResourceProviders' below.
WAIT_NESTED_CONTAINER = 13 [deprecated = true];
WAIT_CONTAINER = 15; // See 'WaitContainer' below.
option (gogoproto.goproto_enum_prefix) = true;
}
// `healthy` would be true if the agent is healthy. Delayed responses are also
// indicative of the poor health of the agent.
message GetHealth {
required bool healthy = 1 [(gogoproto.nullable) = false];
}
// Contains the flag configuration of the agent.
message GetFlags {
repeated Flag flags = 1 [(gogoproto.nullable) = false];
}
// Contains the version information of the agent.
message GetVersion {
required VersionInfo version_info = 1 [(gogoproto.nullable) = false];
}
// Contains a snapshot of the current metrics.
message GetMetrics {
repeated Metric metrics = 1 [(gogoproto.nullable) = false];
}
// Contains the logging level of the agent.
message GetLoggingLevel {
required uint32 level = 1 [(gogoproto.nullable) = false];
}
// Contains the file listing(similar to `ls -l`) for a directory.
message ListFiles {
repeated FileInfo file_infos = 1 [(gogoproto.nullable) = false];
}
// Contains the file data.
message ReadFile {
// The size of file (in bytes).
required uint64 size = 1 [(gogoproto.nullable) = false];
required bytes data = 2;
}
// Contains full state of the agent i.e. information about the tasks,
// frameworks and executors running in the cluster.
message GetState {
optional GetTasks get_tasks = 1;
optional GetExecutors get_executors = 2;
optional GetFrameworks get_frameworks = 3;
}
// Information about containers running on this agent. It contains
// ContainerStatus and ResourceStatistics along with some metadata
// of the containers.
message GetContainers {
message Container {
optional FrameworkID framework_id = 1 [(gogoproto.customname) = "FrameworkID"];
optional ExecutorID executor_id = 2 [(gogoproto.customname) = "ExecutorID"];
optional string executor_name = 3;
required ContainerID container_id = 4 [(gogoproto.customname) = "ContainerID", (gogoproto.nullable) = false];
optional ContainerStatus container_status = 5;
optional ResourceStatistics resource_statistics = 6;
}
repeated Container containers = 1 [(gogoproto.nullable) = false];
}
// Information about all the frameworks known to the agent at the current
// time.
message GetFrameworks {
message Framework {
required FrameworkInfo framework_info = 1 [(gogoproto.nullable) = false];
}
repeated Framework frameworks = 1 [(gogoproto.nullable) = false];
repeated Framework completed_frameworks = 2 [(gogoproto.nullable) = false];
}
// Lists information about all the executors known to the agent at the
// current time.
message GetExecutors {
message Executor {
required ExecutorInfo executor_info = 1 [(gogoproto.nullable) = false];
}
repeated Executor executors = 1 [(gogoproto.nullable) = false];
repeated Executor completed_executors = 2 [(gogoproto.nullable) = false];
}
// Lists information about all operations known to the agent at the
// current time.
message GetOperations {
repeated Operation operations = 1 [(gogoproto.nullable) = false];
}
// Lists information about all the tasks known to the agent at the current
// time.
message GetTasks {
// Tasks that are pending in the agent's queue before an executor is
// launched.
repeated Task pending_tasks = 1 [(gogoproto.nullable) = false];
// Tasks that are enqueued for a launched executor that has not yet
// registered.
repeated Task queued_tasks = 2 [(gogoproto.nullable) = false];
// Tasks that are running.
repeated Task launched_tasks = 3 [(gogoproto.nullable) = false];
// Tasks that are terminated but pending updates.
repeated Task terminated_tasks = 4 [(gogoproto.nullable) = false];
// Tasks that are terminated and updates acked.
repeated Task completed_tasks = 5 [(gogoproto.nullable) = false];
}
// Contains the agent's information.
message GetAgent {
optional AgentInfo agent_info = 1;
}
// Lists information about all resource providers known to the agent
// at the current time.
message GetResourceProviders {
message ResourceProvider {
required ResourceProviderInfo resource_provider_info = 1 [(gogoproto.nullable) = false];
repeated Resource total_resources = 2 [(gogoproto.nullable) = false];
}
repeated ResourceProvider resource_providers = 1 [(gogoproto.nullable) = false];
}
// Returns termination information about the nested container.
message WaitNestedContainer {
// Wait status of the lead process in the container. Note that this
// is the return value of `wait(2)`, so callers must use the `wait(2)`
// family of macros to extract whether the process exited cleanly and
// what the exit code was.
optional int32 exit_status = 1;
// The `state` and `reason` fields may be populated if the Mesos agent
// terminates the container. In the absence of any special knowledge,
// executors should propagate this information via the `status` field
// of an `Update` call for the corresponding TaskID.
optional TaskState state = 2;
optional TaskStatus.Reason reason = 3;
// This field will be populated if the task was terminated due to
// a resource limitation.
optional TaskResourceLimitation limitation = 4;
optional string message = 5;
}
// Returns termination information about the standalone or nested container.
message WaitContainer {
// Wait status of the lead process in the container. Note that this
// is the return value of `wait(2)`, so callers must use the `wait(2)`
// family of macros to extract whether the process exited cleanly and
// what the exit code was.
optional int32 exit_status = 1;
// The `state` and `reason` fields may be populated if the Mesos agent
// terminates the container. In the absence of any special knowledge,
// executors should propagate this information via the `status` field
// of an `Update` call for the corresponding TaskID.
optional TaskState state = 2;
optional TaskStatus.Reason reason = 3;
// This field will be populated if the task was terminated due to
// a resource limitation.
optional TaskResourceLimitation limitation = 4;
optional string message = 5;
}
optional Type type = 1 [(gogoproto.nullable) = false];
optional GetHealth get_health = 2;
optional GetFlags get_flags = 3;
optional GetVersion get_version = 4;
optional GetMetrics get_metrics = 5;
optional GetLoggingLevel get_logging_level = 6;
optional ListFiles list_files = 7;
optional ReadFile read_file = 8;
optional GetState get_state = 9;
optional GetContainers get_containers = 10;
optional GetFrameworks get_frameworks = 11;
optional GetExecutors get_executors = 12;
optional GetOperations get_operations = 18;
optional GetTasks get_tasks = 13;
optional GetAgent get_agent = 15;
optional GetResourceProviders get_resource_providers = 17;
optional WaitNestedContainer wait_nested_container = 14;
optional WaitContainer wait_container = 16;
}
/**
* Streaming response to `Call::LAUNCH_NESTED_CONTAINER_SESSION` and
* `Call::ATTACH_CONTAINER_OUTPUT`.
*
* This message is also used to stream request data for
* `Call::ATTACH_CONTAINER_INPUT`.
*/
message ProcessIO {
enum Type {
UNKNOWN = 0;
DATA = 1;
CONTROL = 2;
option (gogoproto.goproto_enum_prefix) = true;
}
message Data {
enum Type {
UNKNOWN = 0;
STDIN = 1;
STDOUT = 2;
STDERR = 3;
option (gogoproto.goproto_enum_prefix) = true;
}
optional Type type = 1 [(gogoproto.nullable) = false];
optional bytes data = 2;
}
message Control {
enum Type {
UNKNOWN = 0;
TTY_INFO = 1;
HEARTBEAT = 2;
option (gogoproto.goproto_enum_prefix) = true;
}
message Heartbeat {
optional DurationInfo interval = 1;
}
optional Type type = 1 [(gogoproto.nullable) = false];
optional TTYInfo tty_info = 2 [(gogoproto.customname) = "TTYInfo"];
optional Heartbeat heartbeat = 3;
}
optional Type type = 1 [(gogoproto.nullable) = false];
optional Data data = 2;
optional Control control = 3;
}

View File

@ -0,0 +1,32 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"calls.go",
"calls_generated.go",
"gen.go",
],
importmap = "k8s.io/kubernetes/vendor/github.com/mesos/mesos-go/api/v1/lib/agent/calls",
importpath = "github.com/mesos/mesos-go/api/v1/lib/agent/calls",
visibility = ["//visibility:public"],
deps = [
"//vendor/github.com/mesos/mesos-go/api/v1/lib:go_default_library",
"//vendor/github.com/mesos/mesos-go/api/v1/lib/agent:go_default_library",
"//vendor/github.com/mesos/mesos-go/api/v1/lib/encoding:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@ -0,0 +1,258 @@
package calls
import (
"time"
"github.com/mesos/mesos-go/api/v1/lib"
"github.com/mesos/mesos-go/api/v1/lib/agent"
)
func GetHealth() *agent.Call { return &agent.Call{Type: agent.Call_GET_HEALTH} }
func GetFlags() *agent.Call { return &agent.Call{Type: agent.Call_GET_FLAGS} }
func GetVersion() *agent.Call { return &agent.Call{Type: agent.Call_GET_VERSION} }
func GetMetrics(d *time.Duration) (call *agent.Call) {
call = &agent.Call{
Type: agent.Call_GET_METRICS,
GetMetrics: &agent.Call_GetMetrics{},
}
if d != nil {
call.GetMetrics.Timeout = &mesos.DurationInfo{
Nanoseconds: d.Nanoseconds(),
}
}
return
}
func GetLoggingLevel() *agent.Call { return &agent.Call{Type: agent.Call_GET_LOGGING_LEVEL} }
func SetLoggingLevel(level uint32, d time.Duration) *agent.Call {
return &agent.Call{
Type: agent.Call_SET_LOGGING_LEVEL,
SetLoggingLevel: &agent.Call_SetLoggingLevel{
Duration: mesos.DurationInfo{Nanoseconds: d.Nanoseconds()},
Level: level,
},
}
}
func ListFiles(path string) *agent.Call {
return &agent.Call{
Type: agent.Call_LIST_FILES,
ListFiles: &agent.Call_ListFiles{
Path: path,
},
}
}
func ReadFile(path string, offset uint64) *agent.Call {
return &agent.Call{
Type: agent.Call_READ_FILE,
ReadFile: &agent.Call_ReadFile{
Path: path,
Offset: offset,
},
}
}
func ReadFileWithLength(path string, offset, length uint64) (call *agent.Call) {
call = ReadFile(path, offset)
call.ReadFile.Length = &length
return
}
func GetState() *agent.Call { return &agent.Call{Type: agent.Call_GET_STATE} }
func GetContainers() *agent.Call { return &agent.Call{Type: agent.Call_GET_CONTAINERS} }
func GetFrameworks() *agent.Call { return &agent.Call{Type: agent.Call_GET_FRAMEWORKS} }
func GetExecutors() *agent.Call { return &agent.Call{Type: agent.Call_GET_EXECUTORS} }
func GetOperations() *agent.Call { return &agent.Call{Type: agent.Call_GET_OPERATIONS} }
func GetTasks() *agent.Call { return &agent.Call{Type: agent.Call_GET_TASKS} }
func GetAgent() *agent.Call { return &agent.Call{Type: agent.Call_GET_AGENT} }
func GetResourceProviders() *agent.Call { return &agent.Call{Type: agent.Call_GET_RESOURCE_PROVIDERS} }
func LaunchNestedContainer(cid mesos.ContainerID, cmd *mesos.CommandInfo, ci *mesos.ContainerInfo) *agent.Call {
return &agent.Call{
Type: agent.Call_LAUNCH_NESTED_CONTAINER,
LaunchNestedContainer: &agent.Call_LaunchNestedContainer{
ContainerID: cid,
Command: cmd,
Container: ci,
},
}
}
func LaunchContainer(cid mesos.ContainerID, cmd *mesos.CommandInfo, ci *mesos.ContainerInfo, r []mesos.Resource) *agent.Call {
return &agent.Call{
Type: agent.Call_LAUNCH_CONTAINER,
LaunchContainer: &agent.Call_LaunchContainer{
ContainerID: cid,
Command: cmd,
Container: ci,
Resources: r,
},
}
}
func WaitNestedContainer(cid mesos.ContainerID) *agent.Call {
return &agent.Call{
Type: agent.Call_WAIT_NESTED_CONTAINER,
WaitNestedContainer: &agent.Call_WaitNestedContainer{
ContainerID: cid,
},
}
}
func WaitContainer(cid mesos.ContainerID) *agent.Call {
return &agent.Call{
Type: agent.Call_WAIT_CONTAINER,
WaitContainer: &agent.Call_WaitContainer{
ContainerID: cid,
},
}
}
func KillNestedContainer(cid mesos.ContainerID) *agent.Call {
return &agent.Call{
Type: agent.Call_KILL_NESTED_CONTAINER,
KillNestedContainer: &agent.Call_KillNestedContainer{
ContainerID: cid,
},
}
}
func KillContainer(cid mesos.ContainerID) *agent.Call {
return &agent.Call{
Type: agent.Call_KILL_CONTAINER,
KillContainer: &agent.Call_KillContainer{
ContainerID: cid,
},
}
}
func RemoveNestedContainer(cid mesos.ContainerID) *agent.Call {
return &agent.Call{
Type: agent.Call_REMOVE_NESTED_CONTAINER,
RemoveNestedContainer: &agent.Call_RemoveNestedContainer{
ContainerID: cid,
},
}
}
func RemoveContainer(cid mesos.ContainerID) *agent.Call {
return &agent.Call{
Type: agent.Call_REMOVE_CONTAINER,
RemoveContainer: &agent.Call_RemoveContainer{
ContainerID: cid,
},
}
}
func LaunchNestedContainerSession(cid mesos.ContainerID, cmd *mesos.CommandInfo, ci *mesos.ContainerInfo) *agent.Call {
return &agent.Call{
Type: agent.Call_LAUNCH_NESTED_CONTAINER_SESSION,
LaunchNestedContainerSession: &agent.Call_LaunchNestedContainerSession{
ContainerID: cid,
Command: cmd,
Container: ci,
},
}
}
func AttachContainerOutput(cid mesos.ContainerID) *agent.Call {
return &agent.Call{
Type: agent.Call_ATTACH_CONTAINER_OUTPUT,
AttachContainerOutput: &agent.Call_AttachContainerOutput{
ContainerID: cid,
},
}
}
// AttachContainerInput returns a Call that is used to initiate attachment to a container's stdin.
// Callers should first send this Call followed by one or more AttachContainerInputXxx calls.
func AttachContainerInput(cid mesos.ContainerID) *agent.Call {
return &agent.Call{
Type: agent.Call_ATTACH_CONTAINER_INPUT,
AttachContainerInput: &agent.Call_AttachContainerInput{
Type: agent.Call_AttachContainerInput_CONTAINER_ID,
ContainerID: &cid,
},
}
}
func AttachContainerInputData(data []byte) *agent.Call {
return &agent.Call{
Type: agent.Call_ATTACH_CONTAINER_INPUT,
AttachContainerInput: &agent.Call_AttachContainerInput{
Type: agent.Call_AttachContainerInput_PROCESS_IO,
ProcessIO: &agent.ProcessIO{
Type: agent.ProcessIO_DATA,
Data: &agent.ProcessIO_Data{
Type: agent.ProcessIO_Data_STDIN,
Data: data,
},
},
},
}
}
func AttachContainerInputTTY(t *mesos.TTYInfo) *agent.Call {
return &agent.Call{
Type: agent.Call_ATTACH_CONTAINER_INPUT,
AttachContainerInput: &agent.Call_AttachContainerInput{
Type: agent.Call_AttachContainerInput_PROCESS_IO,
ProcessIO: &agent.ProcessIO{
Type: agent.ProcessIO_CONTROL,
Control: &agent.ProcessIO_Control{
Type: agent.ProcessIO_Control_TTY_INFO,
TTYInfo: t,
},
},
},
}
}
func AddResourceProviderConfig(rpi mesos.ResourceProviderInfo) *agent.Call {
return &agent.Call{
Type: agent.Call_ADD_RESOURCE_PROVIDER_CONFIG,
AddResourceProviderConfig: &agent.Call_AddResourceProviderConfig{
Info: rpi,
},
}
}
func UpdateResourceProviderConfig(rpi mesos.ResourceProviderInfo) *agent.Call {
return &agent.Call{
Type: agent.Call_UPDATE_RESOURCE_PROVIDER_CONFIG,
UpdateResourceProviderConfig: &agent.Call_UpdateResourceProviderConfig{
Info: rpi,
},
}
}
func RemoveResourceProviderConfig(typ, name string) *agent.Call {
return &agent.Call{
Type: agent.Call_REMOVE_RESOURCE_PROVIDER_CONFIG,
RemoveResourceProviderConfig: &agent.Call_RemoveResourceProviderConfig{
Type: typ,
Name: name,
},
}
}
func PruneImages(excluded []mesos.Image) *agent.Call {
return &agent.Call{
Type: agent.Call_PRUNE_IMAGES,
PruneImages: &agent.Call_PruneImages{
ExcludedImages: excluded,
},
}
}

View File

@ -0,0 +1,129 @@
package calls
// go generate -import github.com/mesos/mesos-go/api/v1/lib/agent -type C:agent.Call
// GENERATED CODE FOLLOWS; DO NOT EDIT.
import (
"context"
"github.com/mesos/mesos-go/api/v1/lib"
"github.com/mesos/mesos-go/api/v1/lib/encoding"
"github.com/mesos/mesos-go/api/v1/lib/agent"
)
type (
// Request generates a Call that's sent to a Mesos agent. Subsequent invocations are expected to
// yield equivalent calls. Intended for use w/ non-streaming requests to an agent.
Request interface {
Call() *agent.Call
}
// RequestFunc is the functional adaptation of Request.
RequestFunc func() *agent.Call
// RequestStreaming generates a Call that's send to a Mesos agent. Subsequent invocations MAY generate
// different Call objects. No more Call objects are expected once a nil is returned to signal the end of
// of the request stream.
RequestStreaming interface {
Request
IsStreaming()
}
// RequestStreamingFunc is the functional adaptation of RequestStreaming.
RequestStreamingFunc func() *agent.Call
// Send issues a Request to a Mesos agent and properly manages Call-specific mechanics.
Sender interface {
Send(context.Context, Request) (mesos.Response, error)
}
// SenderFunc is the functional adaptation of the Sender interface
SenderFunc func(context.Context, Request) (mesos.Response, error)
)
func (f RequestFunc) Call() *agent.Call { return f() }
func (f RequestFunc) Marshaler() encoding.Marshaler {
// avoid returning (*agent.Call)(nil) for interface type
if call := f(); call != nil {
return call
}
return nil
}
func (f RequestStreamingFunc) Push(c ...*agent.Call) RequestStreamingFunc { return Push(f, c...) }
func (f RequestStreamingFunc) Marshaler() encoding.Marshaler {
// avoid returning (*agent.Call)(nil) for interface type
if call := f(); call != nil {
return call
}
return nil
}
func (f RequestStreamingFunc) IsStreaming() {}
func (f RequestStreamingFunc) Call() *agent.Call { return f() }
// Push prepends one or more calls onto a request stream. If no calls are given then the original stream is returned.
func Push(r RequestStreaming, c ...*agent.Call) RequestStreamingFunc {
return func() *agent.Call {
if len(c) == 0 {
return r.Call()
}
head := c[0]
c = c[1:]
return head
}
}
// Empty generates a stream that always returns nil.
func Empty() RequestStreamingFunc { return func() *agent.Call { return nil } }
var (
_ = Request(RequestFunc(nil))
_ = RequestStreaming(RequestStreamingFunc(nil))
_ = Sender(SenderFunc(nil))
)
// NonStreaming returns a RequestFunc that always generates the same Call.
func NonStreaming(c *agent.Call) RequestFunc { return func() *agent.Call { return c } }
// FromChan returns a streaming request that fetches calls from the given channel until it closes.
// If a nil chan is specified then the returned func will always generate nil.
func FromChan(ch <-chan *agent.Call) RequestStreamingFunc {
if ch == nil {
// avoid blocking forever if we're handed a nil chan
return func() *agent.Call { return nil }
}
return func() *agent.Call {
if m, ok := <-ch; ok {
return m
}
return nil
}
}
// Send implements the Sender interface for SenderFunc
func (f SenderFunc) Send(ctx context.Context, r Request) (mesos.Response, error) {
return f(ctx, r)
}
// IgnoreResponse generates a sender that closes any non-nil response received by Mesos.
func IgnoreResponse(s Sender) SenderFunc {
return func(ctx context.Context, r Request) (mesos.Response, error) {
resp, err := s.Send(ctx, r)
if resp != nil {
resp.Close()
}
return nil, err
}
}
// SendNoData is a convenience func that executes the given Call using the provided Sender
// and always drops the response data.
func SendNoData(ctx context.Context, sender Sender, r Request) (err error) {
_, err = IgnoreResponse(sender).Send(ctx, r)
return
}

View File

@ -0,0 +1,3 @@
package calls
//go:generate go run ../../extras/gen/sender.go ../../extras/gen/gen.go -import github.com/mesos/mesos-go/api/v1/lib/agent -type C:agent.Call

71
vendor/github.com/mesos/mesos-go/api/v1/lib/client.go generated vendored Normal file
View File

@ -0,0 +1,71 @@
package mesos
// DEPRECATED in favor of github.com/mesos/mesos-go/api/v1/lib/client
import (
"io"
"github.com/mesos/mesos-go/api/v1/lib/encoding"
)
// A Client represents a Mesos API client which can send Calls and return
// a streaming Decoder from which callers can read Events from, an io.Closer to
// close the event stream on graceful termination and an error in case of failure.
type Client interface {
Do(encoding.Marshaler) (Response, error)
}
// ClientFunc is a functional adapter of the Client interface
type ClientFunc func(encoding.Marshaler) (Response, error)
// Do implements Client
func (cf ClientFunc) Do(m encoding.Marshaler) (Response, error) { return cf(m) }
// Response captures the output of a Mesos API operation. Callers are responsible for invoking
// Close when they're finished processing the response otherwise there may be connection leaks.
type Response interface {
io.Closer
encoding.Decoder
}
// ResponseDecorator optionally modifies the behavior of a Response
type ResponseDecorator interface {
Decorate(Response) Response
}
// ResponseDecoratorFunc is the functional adapter for ResponseDecorator
type ResponseDecoratorFunc func(Response) Response
func (f ResponseDecoratorFunc) Decorate(r Response) Response { return f(r) }
// CloseFunc is the functional adapter for io.Closer
type CloseFunc func() error
// Close implements io.Closer
func (f CloseFunc) Close() error { return f() }
// ResponseWrapper delegates to optional overrides for invocations of Response methods.
type ResponseWrapper struct {
Response Response
Closer io.Closer
Decoder encoding.Decoder
}
func (wrapper *ResponseWrapper) Close() error {
if wrapper.Closer != nil {
return wrapper.Closer.Close()
}
if wrapper.Response != nil {
return wrapper.Response.Close()
}
return nil
}
func (wrapper *ResponseWrapper) Decode(u encoding.Unmarshaler) error {
if wrapper.Decoder != nil {
return wrapper.Decoder.Decode(u)
}
return wrapper.Response.Decode(u)
}
var _ = Response(&ResponseWrapper{})

View File

@ -0,0 +1,24 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = ["client.go"],
importmap = "k8s.io/kubernetes/vendor/github.com/mesos/mesos-go/api/v1/lib/client",
importpath = "github.com/mesos/mesos-go/api/v1/lib/client",
visibility = ["//visibility:public"],
deps = ["//vendor/github.com/mesos/mesos-go/api/v1/lib/encoding:go_default_library"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@ -0,0 +1,54 @@
package client
import (
"github.com/mesos/mesos-go/api/v1/lib/encoding"
)
type (
// ResponseClass indicates the kind of response that a caller is expecting from Mesos.
ResponseClass int
// Request is a non-streaming request from the client to the server.
// Marshaler always returns the same object; the object is sent once to the server and then
// a response is expected.
Request interface {
Marshaler() encoding.Marshaler
}
// RequestStreaming is a streaming request from the client to the server.
// Marshaler returns a new object for upon each invocation, nil when there are no more objects to send.
// Client implementations are expected to differentiate between Request and RequestStreaming either by
// type-switching or by attempting interface conversion.
RequestStreaming interface {
Request
IsStreaming()
}
RequestFunc func() encoding.Marshaler
RequestStreamingFunc func() encoding.Marshaler
)
var (
_ = Request(RequestFunc(nil))
_ = RequestStreaming(RequestStreamingFunc(nil))
)
func (f RequestFunc) Marshaler() encoding.Marshaler { return f() }
func (f RequestStreamingFunc) Marshaler() encoding.Marshaler { return f() }
func (f RequestStreamingFunc) IsStreaming() {}
// RequestSingleton generates a non-streaming Request that always returns the same marshaler
func RequestSingleton(m encoding.Marshaler) Request {
return RequestFunc(func() encoding.Marshaler { return m })
}
const (
ResponseClassSingleton ResponseClass = iota
ResponseClassStreaming
ResponseClassNoData
// ResponseClassAuto should be used with versions of Mesos prior to 1.2.x.
// Otherwise, this type is deprecated and callers should use ResponseClassSingleton
// or ResponseClassStreaming instead.
ResponseClassAuto
)

View File

@ -0,0 +1,23 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = ["logger.go"],
importmap = "k8s.io/kubernetes/vendor/github.com/mesos/mesos-go/api/v1/lib/debug",
importpath = "github.com/mesos/mesos-go/api/v1/lib/debug",
visibility = ["//visibility:public"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@ -0,0 +1,17 @@
package debug
import "log"
type Logger bool
func (d Logger) Log(v ...interface{}) {
if d {
log.Print(v...)
}
}
func (d Logger) Logf(s string, v ...interface{}) {
if d {
log.Printf(s, v...)
}
}

3
vendor/github.com/mesos/mesos-go/api/v1/lib/doc.go generated vendored Normal file
View File

@ -0,0 +1,3 @@
// Package mesos presents common v1 HTTP API message types in addition to extension APIs that
// aim to simplify use of the machine-generated code.
package mesos

View File

@ -0,0 +1,33 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = ["types.go"],
importmap = "k8s.io/kubernetes/vendor/github.com/mesos/mesos-go/api/v1/lib/encoding",
importpath = "github.com/mesos/mesos-go/api/v1/lib/encoding",
visibility = ["//visibility:public"],
deps = [
"//vendor/github.com/gogo/protobuf/proto:go_default_library",
"//vendor/github.com/mesos/mesos-go/api/v1/lib/encoding/framing:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//vendor/github.com/mesos/mesos-go/api/v1/lib/encoding/codecs:all-srcs",
"//vendor/github.com/mesos/mesos-go/api/v1/lib/encoding/framing:all-srcs",
"//vendor/github.com/mesos/mesos-go/api/v1/lib/encoding/json:all-srcs",
"//vendor/github.com/mesos/mesos-go/api/v1/lib/encoding/proto:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@ -0,0 +1,28 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = ["codecs.go"],
importmap = "k8s.io/kubernetes/vendor/github.com/mesos/mesos-go/api/v1/lib/encoding/codecs",
importpath = "github.com/mesos/mesos-go/api/v1/lib/encoding/codecs",
visibility = ["//visibility:public"],
deps = [
"//vendor/github.com/mesos/mesos-go/api/v1/lib/encoding:go_default_library",
"//vendor/github.com/mesos/mesos-go/api/v1/lib/encoding/json:go_default_library",
"//vendor/github.com/mesos/mesos-go/api/v1/lib/encoding/proto:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@ -0,0 +1,33 @@
package codecs
import (
"github.com/mesos/mesos-go/api/v1/lib/encoding"
"github.com/mesos/mesos-go/api/v1/lib/encoding/json"
"github.com/mesos/mesos-go/api/v1/lib/encoding/proto"
)
const (
// MediaTypeProtobuf is the Protobuf serialization format media type.
MediaTypeProtobuf = encoding.MediaType("application/x-protobuf")
// MediaTypeJSON is the JSON serialiation format media type.
MediaTypeJSON = encoding.MediaType("application/json")
NameProtobuf = "protobuf"
NameJSON = "json"
)
// ByMediaType are pre-configured default Codecs, ready to use OOTB
var ByMediaType = map[encoding.MediaType]encoding.Codec{
MediaTypeProtobuf: encoding.Codec{
Name: NameProtobuf,
Type: MediaTypeProtobuf,
NewEncoder: proto.NewEncoder,
NewDecoder: proto.NewDecoder,
},
MediaTypeJSON: encoding.Codec{
Name: NameJSON,
Type: MediaTypeJSON,
NewEncoder: json.NewEncoder,
NewDecoder: json.NewDecoder,
},
}

View File

@ -0,0 +1,26 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"decoder.go",
"framing.go",
],
importmap = "k8s.io/kubernetes/vendor/github.com/mesos/mesos-go/api/v1/lib/encoding/framing",
importpath = "github.com/mesos/mesos-go/api/v1/lib/encoding/framing",
visibility = ["//visibility:public"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@ -0,0 +1,34 @@
package framing
type (
// UnmarshalFunc translates bytes to objects
UnmarshalFunc func([]byte, interface{}) error
// Decoder reads and decodes Protobuf messages from an io.Reader.
Decoder interface {
// Decode reads the next encoded message from its input and stores it
// in the value pointed to by m. If m isn't a proto.Message, Decode will panic.
Decode(interface{}) error
}
// DecoderFunc is the functional adaptation of Decoder
DecoderFunc func(interface{}) error
)
func (f DecoderFunc) Decode(m interface{}) error { return f(m) }
var _ = Decoder(DecoderFunc(nil))
// NewDecoder returns a new Decoder that reads from the given frame Reader.
func NewDecoder(r Reader, uf UnmarshalFunc) DecoderFunc {
return func(m interface{}) error {
// Note: the buf returned by ReadFrame will change over time, it can't be sub-sliced
// and then those sub-slices retained. Examination of generated proto code seems to indicate
// that byte buffers are copied vs. referenced by sub-slice (gogo protoc).
frame, err := r.ReadFrame()
if err != nil {
return err
}
return uf(frame, m)
}
}

View File

@ -0,0 +1,70 @@
package framing
import (
"io"
"io/ioutil"
)
type Error string
func (err Error) Error() string { return string(err) }
const (
ErrorUnderrun = Error("frame underrun, unexpected EOF")
ErrorBadSize = Error("bad frame size")
ErrorOversizedFrame = Error("oversized frame, max size exceeded")
)
type (
// Reader generates data frames from some source, returning io.EOF when the end of the input stream is
// detected.
Reader interface {
ReadFrame() (frame []byte, err error)
}
// ReaderFunc is the functional adaptation of Reader.
ReaderFunc func() ([]byte, error)
// Writer sends whole frames to some endpoint; returns io.ErrShortWrite if the frame is only partially written.
Writer interface {
WriteFrame(frame []byte) error
}
// WriterFunc is the functional adaptation of Writer.
WriterFunc func([]byte) error
)
func (f ReaderFunc) ReadFrame() ([]byte, error) { return f() }
func (f WriterFunc) WriteFrame(b []byte) error { return f(b) }
var _ = Reader(ReaderFunc(nil))
var _ = Writer(WriterFunc(nil))
// EOFReaderFunc always returns nil, io.EOF; it implements the ReaderFunc API.
func EOFReaderFunc() ([]byte, error) { return nil, io.EOF }
var _ = ReaderFunc(EOFReaderFunc) // sanity check
// ReadAll returns a reader func that returns the complete contents of `r` in a single frame.
// A zero length frame is treated as an "end of stream" condition, returning io.EOF.
func ReadAll(r io.Reader) ReaderFunc {
return func() (b []byte, err error) {
b, err = ioutil.ReadAll(r)
if len(b) == 0 && err == nil {
err = io.EOF
}
return
}
}
// WriterFor adapts an io.Writer to the Writer interface. All buffers are written to `w` without decoration or
// modification.
func WriterFor(w io.Writer) WriterFunc {
return func(b []byte) error {
n, err := w.Write(b)
if err == nil && n != len(b) {
return io.ErrShortWrite
}
return err
}
}

View File

@ -0,0 +1,27 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = ["json.go"],
importmap = "k8s.io/kubernetes/vendor/github.com/mesos/mesos-go/api/v1/lib/encoding/json",
importpath = "github.com/mesos/mesos-go/api/v1/lib/encoding/json",
visibility = ["//visibility:public"],
deps = [
"//vendor/github.com/mesos/mesos-go/api/v1/lib/encoding:go_default_library",
"//vendor/github.com/mesos/mesos-go/api/v1/lib/encoding/framing:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@ -0,0 +1,28 @@
package json
import (
"encoding/json"
"github.com/mesos/mesos-go/api/v1/lib/encoding"
"github.com/mesos/mesos-go/api/v1/lib/encoding/framing"
)
// NewEncoder returns a new Encoder of Calls to JSON messages written to
// the given io.Writer.
func NewEncoder(s encoding.Sink) encoding.Encoder {
w := s()
return encoding.EncoderFunc(func(m encoding.Marshaler) error {
b, err := json.Marshal(m)
if err != nil {
return err
}
return w.WriteFrame(b)
})
}
// NewDecoder returns a new Decoder of JSON messages read from the given source.
func NewDecoder(s encoding.Source) encoding.Decoder {
r := s()
dec := framing.NewDecoder(r, json.Unmarshal)
return encoding.DecoderFunc(func(u encoding.Unmarshaler) error { return dec.Decode(u) })
}

View File

@ -0,0 +1,31 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"doc.go",
"encoding.go",
],
importmap = "k8s.io/kubernetes/vendor/github.com/mesos/mesos-go/api/v1/lib/encoding/proto",
importpath = "github.com/mesos/mesos-go/api/v1/lib/encoding/proto",
visibility = ["//visibility:public"],
deps = [
"//vendor/github.com/gogo/protobuf/proto:go_default_library",
"//vendor/github.com/mesos/mesos-go/api/v1/lib/encoding:go_default_library",
"//vendor/github.com/mesos/mesos-go/api/v1/lib/encoding/framing:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@ -0,0 +1,4 @@
// Package proto implements protobuf utilities such as functional options to
// construct complex structs and encoders and decoders composable with
// io.ReadWriters.
package proto

View File

@ -0,0 +1,30 @@
package proto
import (
"github.com/gogo/protobuf/proto"
"github.com/mesos/mesos-go/api/v1/lib/encoding"
"github.com/mesos/mesos-go/api/v1/lib/encoding/framing"
)
// NewEncoder returns a new Encoder of Calls to Protobuf messages written to
// the given io.Writer.
func NewEncoder(s encoding.Sink) encoding.Encoder {
w := s()
return encoding.EncoderFunc(func(m encoding.Marshaler) error {
b, err := proto.Marshal(m.(proto.Message))
if err != nil {
return err
}
return w.WriteFrame(b)
})
}
// NewDecoder returns a new Decoder of Protobuf messages read from the given Source.
func NewDecoder(s encoding.Source) encoding.Decoder {
r := s()
var (
uf = func(b []byte, m interface{}) error { return proto.Unmarshal(b, m.(proto.Message)) }
dec = framing.NewDecoder(r, uf)
)
return encoding.DecoderFunc(func(u encoding.Unmarshaler) error { return dec.Decode(u) })
}

View File

@ -0,0 +1,111 @@
package encoding
import (
"encoding/json"
"io"
pb "github.com/gogo/protobuf/proto"
"github.com/mesos/mesos-go/api/v1/lib/encoding/framing"
)
type MediaType string
// ContentType returns the HTTP Content-Type associated with the MediaType
func (m MediaType) ContentType() string { return string(m) }
type (
Source func() framing.Reader
Sink func() framing.Writer
// A Codec composes encoding and decoding of a serialization format.
Codec struct {
Name string
Type MediaType
NewEncoder func(Sink) Encoder
NewDecoder func(Source) Decoder
}
SourceFactory interface {
NewSource(r io.Reader) Source
}
SourceFactoryFunc func(r io.Reader) Source
SinkFactory interface {
NewSink(w io.Writer) Sink
}
SinkFactoryFunc func(w io.Writer) Sink
)
func (f SourceFactoryFunc) NewSource(r io.Reader) Source { return f(r) }
func (f SinkFactoryFunc) NewSink(w io.Writer) Sink { return f(w) }
var (
_ = SourceFactory(SourceFactoryFunc(nil))
_ = SinkFactory(SinkFactoryFunc(nil))
)
// SourceReader returns a Source that buffers all input from the given io.Reader
// and returns the contents in a single frame.
func SourceReader(r io.Reader) Source {
ch := make(chan framing.ReaderFunc, 1)
ch <- framing.ReadAll(r)
return func() framing.Reader {
select {
case f := <-ch:
return f
default:
return framing.ReaderFunc(framing.EOFReaderFunc)
}
}
}
// SinkWriter returns a Sink that sends a frame to an io.Writer with no decoration.
func SinkWriter(w io.Writer) Sink { return func() framing.Writer { return framing.WriterFor(w) } }
// String implements the fmt.Stringer interface.
func (c *Codec) String() string {
if c == nil {
return ""
}
return c.Name
}
type (
// Marshaler composes the supported marshaling formats.
Marshaler interface {
pb.Marshaler
json.Marshaler
}
// Unmarshaler composes the supporter unmarshaling formats.
Unmarshaler interface {
pb.Unmarshaler
json.Unmarshaler
}
// An Encoder encodes a given Marshaler or returns an error in case of failure.
Encoder interface {
Encode(Marshaler) error
}
// EncoderFunc is the functional adapter for Encoder
EncoderFunc func(Marshaler) error
// A Decoder decodes a given Unmarshaler or returns an error in case of failure.
Decoder interface {
Decode(Unmarshaler) error
}
// DecoderFunc is the functional adapter for Decoder
DecoderFunc func(Unmarshaler) error
)
// Decode implements the Decoder interface
func (f DecoderFunc) Decode(u Unmarshaler) error { return f(u) }
// Encode implements the Encoder interface
func (f EncoderFunc) Encode(m Marshaler) error { return f(m) }
var (
_ = Encoder(EncoderFunc(nil))
_ = Decoder(DecoderFunc(nil))
)

26
vendor/github.com/mesos/mesos-go/api/v1/lib/filters.go generated vendored Normal file
View File

@ -0,0 +1,26 @@
package mesos
import "time"
type FilterOpt func(*Filters)
func (f *Filters) With(opts ...FilterOpt) *Filters {
for _, o := range opts {
o(f)
}
return f
}
func RefuseSeconds(d time.Duration) FilterOpt {
return func(f *Filters) {
s := d.Seconds()
f.RefuseSeconds = &s
}
}
func OptionalFilters(fo ...FilterOpt) *Filters {
if len(fo) == 0 {
return nil
}
return (&Filters{}).With(fo...)
}

View File

@ -0,0 +1,35 @@
package mesos
// fixed point scalar math from mesos:src/common/values.cpp
// --
// We manipulate scalar values by converting them from floating point to a
// fixed point representation, doing a calculation, and then converting
// the result back to floating point. We deliberately only preserve three
// decimal digits of precision in the fixed point representation. This
// ensures that client applications see predictable numerical behavior, at
// the expense of sacrificing some precision.
import "math"
func convertToFloat64(f int64) float64 {
// NOTE: We do the conversion from fixed point via integer division
// and then modulus, rather than a single floating point division.
// This ensures that we only apply floating point division to inputs
// in the range [0,999], which is easier to check for correctness.
var (
quotient = float64(f / 1000)
remainder = float64(f%1000) / 1000.0
)
return quotient + remainder
}
func convertToFixed64(f float64) int64 {
return round64(f * 1000)
}
func round64(f float64) int64 {
if math.Abs(f) < 0.5 {
return 0
}
return int64(f + math.Copysign(0.5, f))
}

View File

@ -0,0 +1,40 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"auth_basic.go",
"http.go",
"opts.go",
],
importmap = "k8s.io/kubernetes/vendor/github.com/mesos/mesos-go/api/v1/lib/httpcli",
importpath = "github.com/mesos/mesos-go/api/v1/lib/httpcli",
visibility = ["//visibility:public"],
deps = [
"//vendor/github.com/mesos/mesos-go/api/v1/lib:go_default_library",
"//vendor/github.com/mesos/mesos-go/api/v1/lib/client:go_default_library",
"//vendor/github.com/mesos/mesos-go/api/v1/lib/debug:go_default_library",
"//vendor/github.com/mesos/mesos-go/api/v1/lib/encoding:go_default_library",
"//vendor/github.com/mesos/mesos-go/api/v1/lib/encoding/codecs:go_default_library",
"//vendor/github.com/mesos/mesos-go/api/v1/lib/encoding/framing:go_default_library",
"//vendor/github.com/mesos/mesos-go/api/v1/lib/httpcli/apierrors:go_default_library",
"//vendor/github.com/mesos/mesos-go/api/v1/lib/recordio:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//vendor/github.com/mesos/mesos-go/api/v1/lib/httpcli/apierrors:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@ -0,0 +1,23 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = ["apierrors.go"],
importmap = "k8s.io/kubernetes/vendor/github.com/mesos/mesos-go/api/v1/lib/httpcli/apierrors",
importpath = "github.com/mesos/mesos-go/api/v1/lib/httpcli/apierrors",
visibility = ["//visibility:public"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@ -0,0 +1,161 @@
package apierrors
import (
"io"
"io/ioutil"
"net/http"
)
// Code is a Mesos HTTP v1 API response status code
type Code int
const (
// MsgNotLeader is returned by Do calls that are sent to a non leading Mesos master.
MsgNotLeader = "call sent to a non-leading master"
// MsgAuth is returned by Do calls that are not successfully authenticated.
MsgAuth = "call not authenticated"
// MsgUnsubscribed is returned by Do calls that are sent before a subscription is established.
MsgUnsubscribed = "no subscription established"
// MsgVersion is returned by Do calls that are sent to an incompatible API version.
MsgVersion = "incompatible API version"
// MsgMalformed is returned by Do calls that are malformed.
MsgMalformed = "malformed request"
// MsgMediaType is returned by Do calls that are sent with an unsupported media type.
MsgMediaType = "unsupported media type"
// MsgRateLimit is returned by Do calls that are rate limited. This is a temporary condition
// that should clear.
MsgRateLimit = "rate limited"
// MsgUnavailable is returned by Do calls that are sent to a master or agent that's in recovery, or
// does not yet realize that it's the leader. This is a temporary condition that should clear.
MsgUnavailable = "mesos server unavailable"
// MsgNotFound could happen if the master or agent libprocess has not yet set up http routes.
MsgNotFound = "mesos http endpoint not found"
CodeNotLeader = Code(http.StatusTemporaryRedirect)
CodeNotAuthenticated = Code(http.StatusUnauthorized)
CodeUnsubscribed = Code(http.StatusForbidden)
CodeIncompatibleVersion = Code(http.StatusConflict)
CodeMalformedRequest = Code(http.StatusBadRequest)
CodeUnsupportedMediaType = Code(http.StatusNotAcceptable)
CodeRateLimitExceeded = Code(http.StatusTooManyRequests)
CodeMesosUnavailable = Code(http.StatusServiceUnavailable)
CodeNotFound = Code(http.StatusNotFound)
MaxSizeDetails = 4 * 1024 // MaxSizeDetails limits the length of the details message read from a response body
)
var (
// ErrorTable maps HTTP response codes to their respective Mesos v1 API error messages.
ErrorTable = map[Code]string{
CodeNotLeader: MsgNotLeader,
CodeMalformedRequest: MsgMalformed,
CodeIncompatibleVersion: MsgVersion,
CodeUnsubscribed: MsgUnsubscribed,
CodeNotAuthenticated: MsgAuth,
CodeUnsupportedMediaType: MsgMediaType,
CodeNotFound: MsgNotFound,
CodeMesosUnavailable: MsgUnavailable,
CodeRateLimitExceeded: MsgRateLimit,
}
)
// Error captures HTTP v1 API error codes and messages generated by Mesos.
type Error struct {
code Code // code is the HTTP response status code generated by Mesos
message string // message briefly summarizes the nature of the error, possibly includes details from Mesos
}
// IsError returns true for all HTTP status codes that are not considered informational or successful.
func (code Code) IsError() bool {
return code >= 300
}
// FromResponse returns an `*Error` for a response containing a status code that indicates an error condition.
// The response body (if any) is captured in the Error.Details field.
// Returns nil for nil responses and responses with non-error status codes.
// See IsErrorCode.
func FromResponse(res *http.Response) error {
if res == nil {
return nil
}
code := Code(res.StatusCode)
if !code.IsError() {
// non-error HTTP response codes don't generate errors
return nil
}
var details string
if res.Body != nil {
defer res.Body.Close()
buf, _ := ioutil.ReadAll(io.LimitReader(res.Body, MaxSizeDetails))
details = string(buf)
}
return code.Error(details)
}
// Error generates an error from the given status code and detail string.
func (code Code) Error(details string) error {
if !code.IsError() {
return nil
}
err := &Error{
code: code,
message: ErrorTable[code],
}
if details != "" {
err.message = err.message + ": " + details
}
return err
}
// Error implements error interface
func (e *Error) Error() string { return e.message }
// Temporary returns true if the error is a temporary condition that should eventually clear.
func (e *Error) Temporary() bool {
switch e.code {
// TODO(jdef): NotFound **could** be a temporary error because there's a race at mesos startup in which the
// HTTP server responds before the internal listeners have been initialized. But it could also be reported
// because the client is accessing an invalid endpoint; as of right now, a client cannot distinguish between
// these cases.
// https://issues.apache.org/jira/browse/MESOS-7697
case CodeRateLimitExceeded, CodeMesosUnavailable:
return true
default:
return false
}
}
// CodesIndicatingSubscriptionLoss is a set of apierror.Code entries which each indicate that
// the event subscription stream has been severed between the scheduler and mesos. It's respresented
// as a public map variable so that clients can program additional error codes (if such are discovered)
// without hacking the code of the mesos-go library directly.
var CodesIndicatingSubscriptionLoss = func(codes ...Code) map[Code]struct{} {
result := make(map[Code]struct{}, len(codes))
for _, code := range codes {
result[code] = struct{}{}
}
return result
}(
// expand this list as we discover other errors that guarantee we've lost our event subscription.
CodeUnsubscribed,
)
// SubscriptionLoss returns true if the error indicates that the event subscription stream has been severed
// between mesos and a mesos client.
func (e *Error) SubscriptionLoss() (result bool) {
_, result = CodesIndicatingSubscriptionLoss[e.code]
return
}
// Matches returns true if the given error is an API error with a matching error code
func (code Code) Matches(err error) bool {
if err == nil {
return !code.IsError()
}
apiErr, ok := err.(*Error)
return ok && apiErr.code == code
}

View File

@ -0,0 +1,33 @@
package httpcli
import (
"net/http"
)
// roundTripperFunc is the functional adaptation of http.RoundTripper
type roundTripperFunc func(*http.Request) (*http.Response, error)
// RoundTrip implements RoundTripper for roundTripperFunc
func (f roundTripperFunc) RoundTrip(req *http.Request) (*http.Response, error) { return f(req) }
// BasicAuth generates a functional config option that sets HTTP Basic authentication for a Client
func BasicAuth(username, passwd string) ConfigOpt {
// TODO(jdef) this could be more efficient. according to the stdlib we're not supposed to
// mutate the original Request, so we copy here (including headers). another approach would
// be to generate a functional RequestOpt that adds the right header.
return WrapRoundTripper(func(rt http.RoundTripper) http.RoundTripper {
return roundTripperFunc(func(req *http.Request) (*http.Response, error) {
var h http.Header
if req.Header != nil {
h = make(http.Header, len(req.Header))
for k, v := range req.Header {
h[k] = append(make([]string, 0, len(v)), v...)
}
}
clonedReq := *req
clonedReq.Header = h
clonedReq.SetBasicAuth(username, passwd)
return rt.RoundTrip(&clonedReq)
})
})
}

View File

@ -0,0 +1,614 @@
package httpcli
import (
"bytes"
"context"
"crypto/tls"
"fmt"
"io"
"io/ioutil"
"net"
"net/http"
"sync"
"time"
"github.com/mesos/mesos-go/api/v1/lib"
"github.com/mesos/mesos-go/api/v1/lib/client"
logger "github.com/mesos/mesos-go/api/v1/lib/debug"
"github.com/mesos/mesos-go/api/v1/lib/encoding"
"github.com/mesos/mesos-go/api/v1/lib/encoding/codecs"
"github.com/mesos/mesos-go/api/v1/lib/encoding/framing"
"github.com/mesos/mesos-go/api/v1/lib/httpcli/apierrors"
"github.com/mesos/mesos-go/api/v1/lib/recordio"
)
func noRedirect(req *http.Request, via []*http.Request) error { return http.ErrUseLastResponse }
// ProtocolError is returned when we receive a response from Mesos that is outside of the HTTP API specification.
// Receipt of the following will yield protocol errors:
// - any unexpected non-error HTTP response codes (e.g. 199)
// - any unexpected Content-Type
type ProtocolError string
// Error implements error interface
func (pe ProtocolError) Error() string { return string(pe) }
const (
debug = logger.Logger(false)
mediaTypeRecordIO = encoding.MediaType("application/recordio")
)
// DoFunc sends an HTTP request and returns an HTTP response.
//
// An error is returned if caused by client policy (such as
// http.Client.CheckRedirect), or if there was an HTTP protocol error. A
// non-2xx response doesn't cause an error.
//
// When err is nil, resp always contains a non-nil resp.Body.
//
// Callers should close resp.Body when done reading from it. If resp.Body is
// not closed, an underlying RoundTripper (typically Transport) may not be able
// to re-use a persistent TCP connection to the server for a subsequent
// "keep-alive" request.
//
// The request Body, if non-nil, will be closed by an underlying Transport,
// even on errors.
type DoFunc func(*http.Request) (*http.Response, error)
// Response captures the output of a Mesos HTTP API operation. Callers are responsible for invoking
// Close when they're finished processing the response otherwise there may be connection leaks.
type Response struct {
io.Closer
encoding.Decoder
Header http.Header
}
// ErrorMapperFunc generates an error for the given response.
type ErrorMapperFunc func(*http.Response) error
// ResponseHandler is invoked to process an HTTP response. Callers SHALL invoke Close for
// a non-nil Response, even when errors are returned.
type ResponseHandler func(*http.Response, client.ResponseClass, error) (mesos.Response, error)
// A Client is a Mesos HTTP APIs client.
type Client struct {
url string
do DoFunc
header http.Header
codec encoding.Codec
errorMapper ErrorMapperFunc
requestOpts []RequestOpt
buildRequestFunc func(client.Request, client.ResponseClass, ...RequestOpt) (*http.Request, error)
handleResponse ResponseHandler
}
var (
DefaultCodec = codecs.ByMediaType[codecs.MediaTypeProtobuf]
DefaultHeaders = http.Header{}
// DefaultConfigOpt represents the default client config options.
DefaultConfigOpt = []ConfigOpt{
Transport(func(t *http.Transport) {
// all calls should be ack'd by the server within this interval.
t.ResponseHeaderTimeout = 15 * time.Second
t.MaxIdleConnsPerHost = 2 // don't depend on go's default
}),
}
DefaultErrorMapper = ErrorMapperFunc(apierrors.FromResponse)
)
// New returns a new Client with the given Opts applied.
// Callers are expected to configure the URL, Do, and Codec options prior to
// invoking Do.
func New(opts ...Opt) *Client {
c := &Client{
codec: DefaultCodec,
do: With(DefaultConfigOpt...),
header: cloneHeaders(DefaultHeaders),
errorMapper: DefaultErrorMapper,
}
c.buildRequestFunc = c.buildRequest
c.handleResponse = c.HandleResponse
c.With(opts...)
return c
}
func cloneHeaders(hs http.Header) http.Header {
result := make(http.Header)
for k, v := range hs {
cloned := make([]string, len(v))
copy(cloned, v)
result[k] = cloned
}
return result
}
// Endpoint returns the current Mesos API endpoint URL that the caller is set to invoke
func (c *Client) Endpoint() string {
return c.url
}
// RequestOpt defines a functional option for an http.Request.
type RequestOpt func(*http.Request)
// RequestOpts is a convenience type
type RequestOpts []RequestOpt
// Apply this set of request options to the given HTTP request.
func (opts RequestOpts) Apply(req *http.Request) {
// apply per-request options
for _, o := range opts {
if o != nil {
o(req)
}
}
}
// With applies the given Opts to a Client and returns itself.
func (c *Client) With(opts ...Opt) Opt {
return Opts(opts).Merged().Apply(c)
}
// WithTemporary configures the Client with the temporary option and returns the results of
// invoking f(). Changes made to the Client by the temporary option are reverted before this
// func returns.
func (c *Client) WithTemporary(opt Opt, f func() error) error {
if opt != nil {
undo := c.With(opt)
defer c.With(undo)
}
return f()
}
// Mesos returns a mesos.Client variant backed by this implementation.
// Deprecated.
func (c *Client) Mesos(opts ...RequestOpt) mesos.Client {
return mesos.ClientFunc(func(m encoding.Marshaler) (mesos.Response, error) {
return c.Do(m, opts...)
})
}
func prepareForResponse(rc client.ResponseClass, codec encoding.Codec) (RequestOpts, error) {
// We need to tell Mesos both the content-type and message-content-type that we're expecting, otherwise
// the server may give us validation problems, or else send back a vague content-type (w/o a
// message-content-type). In order to communicate these things we need to understand the desired response
// type from the perspective of the caller --> client.ResponseClass.
var accept RequestOpts
switch rc {
case client.ResponseClassSingleton, client.ResponseClassAuto, client.ResponseClassNoData:
accept = append(accept, Header("Accept", codec.Type.ContentType()))
case client.ResponseClassStreaming:
accept = append(accept, Header("Accept", mediaTypeRecordIO.ContentType()))
accept = append(accept, Header("Message-Accept", codec.Type.ContentType()))
default:
return nil, ProtocolError(fmt.Sprintf("illegal response class requested: %v", rc))
}
return accept, nil
}
// buildRequest is a factory func that generates and returns an http.Request for the
// given marshaler and request options.
func (c *Client) buildRequest(cr client.Request, rc client.ResponseClass, opt ...RequestOpt) (*http.Request, error) {
if crs, ok := cr.(client.RequestStreaming); ok {
return c.buildRequestStream(crs.Marshaler, rc, opt...)
}
accept, err := prepareForResponse(rc, c.codec)
if err != nil {
return nil, err
}
//TODO(jdef): use a pool to allocate these (and reduce garbage)?
// .. or else, use a pipe (like streaming does) to avoid the intermediate buffer?
var body bytes.Buffer
if err := c.codec.NewEncoder(encoding.SinkWriter(&body)).Encode(cr.Marshaler()); err != nil {
return nil, err
}
req, err := http.NewRequest("POST", c.url, &body)
if err != nil {
return nil, err
}
helper := HTTPRequestHelper{req}
return helper.
withOptions(c.requestOpts, opt).
withHeaders(c.header).
withHeader("Content-Type", c.codec.Type.ContentType()).
withHeader("Accept", c.codec.Type.ContentType()).
withOptions(accept).
Request, nil
}
func (c *Client) buildRequestStream(f func() encoding.Marshaler, rc client.ResponseClass, opt ...RequestOpt) (*http.Request, error) {
accept, err := prepareForResponse(rc, c.codec)
if err != nil {
return nil, err
}
var (
pr, pw = io.Pipe()
enc = c.codec.NewEncoder(func() framing.Writer { return recordio.NewWriter(pw) })
)
req, err := http.NewRequest("POST", c.url, pr)
if err != nil {
pw.Close() // ignore error
return nil, err
}
go func() {
var closeOnce sync.Once
defer closeOnce.Do(func() {
pw.Close()
})
for {
m := f()
if m == nil {
// no more messages to send; end of the stream
break
}
err := enc.Encode(m)
if err != nil {
closeOnce.Do(func() {
pw.CloseWithError(err)
})
break
}
}
}()
helper := HTTPRequestHelper{req}
return helper.
withOptions(c.requestOpts, opt).
withHeaders(c.header).
withHeader("Content-Type", mediaTypeRecordIO.ContentType()).
withHeader("Message-Content-Type", c.codec.Type.ContentType()).
withOptions(accept).
Request, nil
}
func validateSuccessfulResponse(codec encoding.Codec, res *http.Response, rc client.ResponseClass) error {
switch res.StatusCode {
case http.StatusOK:
ct := res.Header.Get("Content-Type")
switch rc {
case client.ResponseClassNoData:
if ct != "" {
return ProtocolError(fmt.Sprintf("unexpected content type: %q", ct))
}
case client.ResponseClassSingleton, client.ResponseClassAuto:
if ct != codec.Type.ContentType() {
return ProtocolError(fmt.Sprintf("unexpected content type: %q", ct))
}
case client.ResponseClassStreaming:
if ct != mediaTypeRecordIO.ContentType() {
return ProtocolError(fmt.Sprintf("unexpected content type: %q", ct))
}
ct = res.Header.Get("Message-Content-Type")
if ct != codec.Type.ContentType() {
return ProtocolError(fmt.Sprintf("unexpected message content type: %q", ct))
}
default:
return ProtocolError(fmt.Sprintf("unsupported response-class: %q", rc))
}
case http.StatusAccepted:
// nothing to validate, we're not expecting any response entity in this case.
// TODO(jdef) perhaps check Content-Length == 0 here?
}
return nil
}
func newSourceFactory(rc client.ResponseClass) encoding.SourceFactoryFunc {
switch rc {
case client.ResponseClassNoData:
return nil
case client.ResponseClassSingleton:
return encoding.SourceReader
case client.ResponseClassStreaming, client.ResponseClassAuto:
return recordIOSourceFactory
default:
panic(fmt.Sprintf("unsupported response-class: %q", rc))
}
}
func recordIOSourceFactory(r io.Reader) encoding.Source {
return func() framing.Reader { return recordio.NewReader(r) }
}
// HandleResponse parses an HTTP response from a Mesos service endpoint, transforming the
// raw HTTP response into a mesos.Response.
func (c *Client) HandleResponse(res *http.Response, rc client.ResponseClass, err error) (mesos.Response, error) {
if err != nil {
if res != nil && res.Body != nil {
res.Body.Close()
}
return nil, err
}
result := &Response{
Closer: res.Body,
Header: res.Header,
}
if err = c.errorMapper(res); err != nil {
return result, err
}
err = validateSuccessfulResponse(c.codec, res, rc)
if err != nil {
res.Body.Close()
return nil, err
}
switch res.StatusCode {
case http.StatusOK:
debug.Log("request OK, decoding response")
sf := newSourceFactory(rc)
if sf == nil {
if rc != client.ResponseClassNoData {
panic("nil Source for response that expected data")
}
// we don't expect any data. drain the response body and close it (compliant with golang's expectations
// for http/1.1 keepalive support.
defer res.Body.Close()
_, err = io.Copy(ioutil.Discard, res.Body)
return nil, err
}
result.Decoder = c.codec.NewDecoder(sf.NewSource(res.Body))
case http.StatusAccepted:
debug.Log("request Accepted")
// noop; no decoder for these types of calls
defer res.Body.Close()
_, err = io.Copy(ioutil.Discard, res.Body)
return nil, err
default:
debug.Log("unexpected HTTP status", res.StatusCode)
defer res.Body.Close()
io.Copy(ioutil.Discard, res.Body) // intentionally discard any error here
return nil, ProtocolError(fmt.Sprintf("unexpected mesos HTTP response code: %d", res.StatusCode))
}
return result, nil
}
// Do is deprecated in favor of Send.
func (c *Client) Do(m encoding.Marshaler, opt ...RequestOpt) (res mesos.Response, err error) {
return c.Send(client.RequestSingleton(m), client.ResponseClassAuto, opt...)
}
// Send sends a Call and returns (a) a Response (should be closed when finished) that
// contains a either a streaming or non-streaming Decoder from which callers can read
// objects from, and; (b) an error in case of failure. Callers are expected to *always*
// close a non-nil Response if one is returned. For operations which are successful but
// also for which there are no expected result objects the embedded Decoder will be nil.
// The provided ResponseClass determines whether the client implementation will attempt
// to decode a result as a single obeject or as an object stream. When working with
// versions of Mesos prior to v1.2.x callers MUST use ResponseClassAuto.
func (c *Client) Send(cr client.Request, rc client.ResponseClass, opt ...RequestOpt) (res mesos.Response, err error) {
var (
hreq *http.Request
hres *http.Response
)
hreq, err = c.buildRequestFunc(cr, rc, opt...)
if err == nil {
hres, err = c.do(hreq)
res, err = c.handleResponse(hres, rc, err)
}
return
}
// ErrorMapper returns am Opt that overrides the existing error mapping behavior of the client.
func ErrorMapper(em ErrorMapperFunc) Opt {
return func(c *Client) Opt {
old := c.errorMapper
c.errorMapper = em
return ErrorMapper(old)
}
}
// Endpoint returns an Opt that sets a Client's URL.
func Endpoint(rawurl string) Opt {
return func(c *Client) Opt {
old := c.url
c.url = rawurl
return Endpoint(old)
}
}
// WrapDoer returns an Opt that decorates a Client's DoFunc
func WrapDoer(f func(DoFunc) DoFunc) Opt {
return func(c *Client) Opt {
old := c.do
c.do = f(c.do)
return Do(old)
}
}
// Do returns an Opt that sets a Client's DoFunc
func Do(do DoFunc) Opt {
return func(c *Client) Opt {
old := c.do
c.do = do
return Do(old)
}
}
// Codec returns an Opt that sets a Client's Codec.
func Codec(codec encoding.Codec) Opt {
return func(c *Client) Opt {
old := c.codec
c.codec = codec
return Codec(old)
}
}
// DefaultHeader returns an Opt that adds a header to an Client's headers.
func DefaultHeader(k, v string) Opt {
return func(c *Client) Opt {
old, found := c.header[k]
old = append([]string{}, old...) // clone
c.header.Add(k, v)
return func(c *Client) Opt {
if found {
c.header[k] = old
} else {
c.header.Del(k)
}
return DefaultHeader(k, v)
}
}
}
// HandleResponse returns a functional config option to set the HTTP response handler of the client.
func HandleResponse(f ResponseHandler) Opt {
return func(c *Client) Opt {
old := c.handleResponse
c.handleResponse = f
return HandleResponse(old)
}
}
// RequestOptions returns an Opt that applies the given set of options to every Client request.
func RequestOptions(opts ...RequestOpt) Opt {
if len(opts) == 0 {
return nil
}
return func(c *Client) Opt {
old := append([]RequestOpt{}, c.requestOpts...)
c.requestOpts = opts
return RequestOptions(old...)
}
}
// Header returns an RequestOpt that adds a header value to an HTTP requests's header.
func Header(k, v string) RequestOpt { return func(r *http.Request) { r.Header.Add(k, v) } }
// Close returns a RequestOpt that determines whether to close the underlying connection after sending the request.
func Close(b bool) RequestOpt { return func(r *http.Request) { r.Close = b } }
// Context returns a RequestOpt that sets the request's Context (ctx must be non-nil)
func Context(ctx context.Context) RequestOpt {
return func(r *http.Request) {
r2 := r.WithContext(ctx)
*r = *r2
}
}
type Config struct {
client *http.Client
dialer *net.Dialer
transport *http.Transport
}
type ConfigOpt func(*Config)
// With returns a DoFunc that executes HTTP round-trips.
// The default implementation provides reasonable defaults for timeouts:
// keep-alive, connection, request/response read/write, and TLS handshake.
// Callers can customize configuration by specifying one or more ConfigOpt's.
func With(opt ...ConfigOpt) DoFunc {
var (
dialer = &net.Dialer{
LocalAddr: &net.TCPAddr{IP: net.IPv4zero},
KeepAlive: 30 * time.Second,
Timeout: 5 * time.Second,
}
transport = &http.Transport{
Proxy: http.ProxyFromEnvironment,
Dial: dialer.Dial,
ResponseHeaderTimeout: 5 * time.Second,
TLSClientConfig: &tls.Config{InsecureSkipVerify: false},
TLSHandshakeTimeout: 5 * time.Second,
}
config = &Config{
dialer: dialer,
transport: transport,
client: &http.Client{
Transport: transport,
CheckRedirect: noRedirect, // so we can actually see the 307 redirects
},
}
)
for _, o := range opt {
if o != nil {
o(config)
}
}
return config.client.Do
}
// Timeout returns an ConfigOpt that sets a Config's response header timeout, tls handshake timeout,
// and dialer timeout.
func Timeout(d time.Duration) ConfigOpt {
return func(c *Config) {
c.transport.ResponseHeaderTimeout = d
c.transport.TLSHandshakeTimeout = d
c.dialer.Timeout = d
}
}
// RoundTripper returns a ConfigOpt that sets a Config's round-tripper.
func RoundTripper(rt http.RoundTripper) ConfigOpt {
return func(c *Config) {
c.client.Transport = rt
}
}
// TLSConfig returns a ConfigOpt that sets a Config's TLS configuration.
func TLSConfig(tc *tls.Config) ConfigOpt {
return func(c *Config) {
c.transport.TLSClientConfig = tc
}
}
// Transport returns a ConfigOpt that allows tweaks of the default Config's http.Transport
func Transport(modifyTransport func(*http.Transport)) ConfigOpt {
return func(c *Config) {
if modifyTransport != nil {
modifyTransport(c.transport)
}
}
}
// WrapRoundTripper allows a caller to customize a configuration's HTTP exchanger. Useful
// for authentication protocols that operate over stock HTTP.
func WrapRoundTripper(f func(http.RoundTripper) http.RoundTripper) ConfigOpt {
return func(c *Config) {
if f != nil {
if rt := f(c.client.Transport); rt != nil {
c.client.Transport = rt
}
}
}
}
// HTTPRequestHelper wraps an http.Request and provides utility funcs to simplify code elsewhere
type HTTPRequestHelper struct {
*http.Request
}
func (r *HTTPRequestHelper) withOptions(optsets ...RequestOpts) *HTTPRequestHelper {
for _, opts := range optsets {
opts.Apply(r.Request)
}
return r
}
func (r *HTTPRequestHelper) withHeaders(hh http.Header) *HTTPRequestHelper {
for k, v := range hh {
r.Header[k] = v
debug.Log("request header " + k + ": " + v[0])
}
return r
}
func (r *HTTPRequestHelper) withHeader(key, value string) *HTTPRequestHelper {
r.Header.Set(key, value)
return r
}

View File

@ -0,0 +1,53 @@
package httpcli
type (
// Opt defines a functional option for the HTTP client type. A functional option
// must return an Opt that acts as an "undo" if applied to the same Client.
Opt func(*Client) Opt
// Opts represents a series of functional options
Opts []Opt
)
// Apply is a nil-safe application of an Opt: if the receiver is nil then this func
// simply returns nil, otherwise it returns the result invoking the receiving Opt
// with the given Client.
func (o Opt) Apply(c *Client) (result Opt) {
if o != nil {
result = o(c)
}
return
}
// Merged generates a single Opt that applies all the functional options, in-order
func (opts Opts) Merged() Opt {
if len(opts) == 0 {
return nil
}
return func(c *Client) Opt {
var (
size = len(opts)
undo = make(Opts, size)
)
size-- // make this a zero-based offset
for i, opt := range opts {
if opt != nil {
undo[size-i] = opt(c)
}
}
return undo.Merged()
}
}
// And combines two functional options into a single Opt
func (o Opt) And(other Opt) Opt {
if o == nil {
if other == nil {
return nil
}
return other
}
if other == nil {
return o
}
return Opts{o, other}.Merged()
}

95
vendor/github.com/mesos/mesos-go/api/v1/lib/labels.go generated vendored Normal file
View File

@ -0,0 +1,95 @@
package mesos
import (
"bytes"
"io"
)
type labelList []Label // convenience type, for working with unwrapped Label slices
// Equivalent returns true if left and right have the same labels. Order is not important.
func (left *Labels) Equivalent(right *Labels) bool {
return labelList(left.GetLabels()).Equivalent(labelList(right.GetLabels()))
}
// Equivalent returns true if left and right have the same labels. Order is not important.
func (left labelList) Equivalent(right labelList) bool {
if len(left) != len(right) {
return false
} else {
for i := range left {
found := false
for j := range right {
if left[i].Equivalent(right[j]) {
found = true
break
}
}
if !found {
return false
}
}
return true
}
}
// Equivalent returns true if left and right represent the same Label.
func (left Label) Equivalent(right Label) bool {
if left.Key != right.Key {
return false
}
if left.Value == nil {
return right.Value == nil
} else {
return right.Value != nil && *left.Value == *right.Value
}
}
func (left Label) writeTo(w io.Writer) (n int64, err error) {
write := func(s string) {
if err != nil {
return
}
var n2 int
n2, err = io.WriteString(w, s)
n += int64(n2)
}
write(left.Key)
if s := left.GetValue(); s != "" {
write("=")
write(s)
}
return
}
func (left *Labels) writeTo(w io.Writer) (n int64, err error) {
var (
lab = left.GetLabels()
n2 int
n3 int64
)
for i := range lab {
if i > 0 {
n2, err = io.WriteString(w, ",")
n += int64(n2)
if err != nil {
break
}
}
n3, err = lab[i].writeTo(w)
n += n3
if err != nil {
break
}
}
return
}
func (left *Labels) Format() string {
if left == nil {
return ""
}
var b bytes.Buffer
left.writeTo(&b)
return b.String()
}

72498
vendor/github.com/mesos/mesos-go/api/v1/lib/mesos.pb.go generated vendored Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

3600
vendor/github.com/mesos/mesos-go/api/v1/lib/mesos.proto generated vendored Normal file

File diff suppressed because it is too large Load Diff

253
vendor/github.com/mesos/mesos-go/api/v1/lib/ranges.go generated vendored Normal file
View File

@ -0,0 +1,253 @@
package mesos
import (
"sort"
)
// Ranges represents a list of Ranges.
type Ranges []Value_Range
// NewRanges returns squashed Ranges from the given numbers.
func NewRanges(ns ...uint64) Ranges {
xs := append(uint64s{}, ns...)
sort.Sort(xs)
rs := make(Ranges, len(xs))
for i := range xs {
rs[i].Begin, rs[i].End = xs[i], xs[i]
}
return rs.Squash()
}
// NewPortRanges returns Ranges from the "ports" resource in the
// given *Offer. If that resource isn't provided, nil will be returned.
//
// The returned Ranges are sorted and have all overlapping ranges merged from
// left to right. e.g. [[0, 5], [4, 3], [10, 7]] -> [[0, 5], [7, 10]]
func NewPortRanges(o *Offer) Ranges {
if o == nil {
return Ranges{}
}
var (
r Resource
found bool
)
for i := range o.Resources {
if o.Resources[i].GetName() == "ports" {
r = o.Resources[i]
found = true
break
}
}
if !found {
return Ranges{}
}
offered := r.GetRanges().GetRange()
rs := make(Ranges, len(offered))
for i, r := range offered {
if lo, hi := r.GetBegin(), r.GetEnd(); lo <= hi {
rs[i].Begin, rs[i].End = lo, hi
} else {
rs[i].Begin, rs[i].End = hi, lo
}
}
return rs.Sort().Squash()
}
// These three methods implement sort.Interface
func (rs Ranges) Len() int { return len(rs) }
func (rs Ranges) Swap(i, j int) { rs[i], rs[j] = rs[j], rs[i] }
func (rs Ranges) Less(i, j int) bool {
return rs[i].Begin < rs[j].Begin || (rs[i].Begin == rs[j].Begin && rs[i].End < rs[j].End)
}
// Size returns the sum of the Size of all Ranges.
func (rs Ranges) Size() uint64 {
var sz uint64
for i := range rs {
sz += 1 + (rs[i].End - rs[i].Begin)
}
return sz
}
// Sort sorts the receiving Ranges and returns the result; convenience
func (rs Ranges) Sort() Ranges {
sort.Sort(rs)
return rs
}
// Squash merges overlapping and continuous Ranges. It assumes they're pre-sorted.
func (rs Ranges) Squash() Ranges {
if len(rs) < 2 {
return rs
}
squashed := Ranges{rs[0]}
for i := 1; i < len(rs); i++ {
switch max := squashed[len(squashed)-1].End; {
case 1+max < rs[i].Begin: // no overlap nor continuity: push
squashed = append(squashed, rs[i])
case max <= rs[i].End: // overlap or continuity: squash
squashed[len(squashed)-1].End = rs[i].End
}
}
return squashed
}
// Search performs a binary search for n returning the index of the Range it was
// found at or -1 if not found.
func (rs Ranges) Search(n uint64) int {
for lo, hi := 0, len(rs)-1; lo <= hi; {
switch m := lo + (hi-lo)/2; {
case n < rs[m].Begin:
hi = m - 1
case n > rs[m].End:
lo = m + 1
default:
return m
}
}
return -1
}
// Partition partitions Ranges around n. It returns the partitioned Ranges
// and a boolean indicating if n was found.
func (rs Ranges) Partition(n uint64) (Ranges, bool) {
i := rs.Search(n)
if i < 0 {
return rs, false
}
pn := make(Ranges, 0, len(rs)+1)
switch pn = append(pn, rs[:i]...); {
case rs[i].Begin == rs[i].End: // delete
case rs[i].Begin == n: // increment lower bound
pn = append(pn, Value_Range{rs[i].Begin + 1, rs[i].End})
case rs[i].End == n: // decrement upper bound
pn = append(pn, Value_Range{rs[i].Begin, rs[i].End - 1})
default: // split
pn = append(pn, Value_Range{rs[i].Begin, n - 1}, Value_Range{n + 1, rs[i].End})
}
return append(pn, rs[i+1:]...), true
}
// Remove removes a range from already coalesced ranges.
// The algorithms constructs a new vector of ranges which is then
// Squash'ed into a Ranges instance.
func (rs Ranges) Remove(removal Value_Range) Ranges {
ranges := make([]Value_Range, 0, len(rs))
for _, r := range rs {
// skip if the entire range is subsumed by removal
if r.Begin >= removal.Begin && r.End <= removal.End {
continue
}
// divide if the range subsumes the removal
if r.Begin < removal.Begin && r.End > removal.End {
ranges = append(ranges,
Value_Range{r.Begin, removal.Begin - 1},
Value_Range{removal.End + 1, r.End},
)
continue
}
// add the full range if there's no intersection
if r.End < removal.Begin || r.Begin > removal.End {
ranges = append(ranges, r)
continue
}
// trim if the range does intersect
if r.End > removal.End {
ranges = append(ranges, Value_Range{removal.End + 1, r.End})
} else {
if r.Begin >= removal.Begin {
// should never happen
panic("r.Begin >= removal.Begin")
}
ranges = append(ranges, Value_Range{r.Begin, removal.Begin - 1})
}
}
return Ranges(ranges).Squash()
}
// Compare assumes that both Ranges are already in sort-order.
// Returns 0 if rs and right are equivalent, -1 if rs is a subset of right, or else 1
func (rs Ranges) Compare(right Ranges) int {
x, y, result := rs.equiv(right)
if result {
return 0
}
for _, a := range x {
// make sure that this range is a subset of a range in y
matched := false
for _, b := range y {
if a.Begin >= b.Begin && a.End <= b.End {
matched = true
break
}
}
if !matched {
return 1
}
}
return -1
}
// Equivalent assumes that both Ranges are already in sort-order.
func (rs Ranges) Equivalent(right Ranges) (result bool) {
_, _, result = rs.equiv(right)
return
}
// Equivalent assumes that both Ranges are already in sort-order.
func (rs Ranges) equiv(right Ranges) (_, _ Ranges, _ bool) {
// we need to squash rs and right but don't want to change the originals
switch len(rs) {
case 0:
case 1:
rs = Ranges{rs[0]}
default:
rs = Ranges(append([]Value_Range{rs[0], rs[1]}, rs[2:]...)).Sort().Squash()
}
switch len(right) {
case 0:
case 1:
right = Ranges{right[0]}
default:
right = Ranges(append([]Value_Range{right[0], right[1]}, right[2:]...)).Sort().Squash()
}
return rs, right, (&Value_Ranges{Range: rs}).Equal(&Value_Ranges{Range: right})
}
func (rs Ranges) Clone() Ranges {
if len(rs) == 0 {
return nil
}
x := make(Ranges, len(rs))
copy(x, rs)
return x
}
// Min returns the minimum number in Ranges. It will panic on empty Ranges.
func (rs Ranges) Min() uint64 { return rs[0].Begin }
// Max returns the maximum number in Ranges. It will panic on empty Ranges.
func (rs Ranges) Max() uint64 { return rs[len(rs)-1].End }
// resource returns a *Resource with the given name and Ranges.
func (rs Ranges) resource(name string) Resource {
vr := make([]Value_Range, len(rs))
copy(vr, rs)
return Resource{
Name: name,
Type: RANGES.Enum(),
Ranges: &Value_Ranges{Range: vr},
}
}
// uint64s is an utility used to sort a slice of uint64s
type uint64s []uint64
// These three methods implement sort.Interface
func (ns uint64s) Len() int { return len(ns) }
func (ns uint64s) Less(i, j int) bool { return ns[i] < ns[j] }
func (ns uint64s) Swap(i, j int) { ns[i], ns[j] = ns[j], ns[i] }

View File

@ -0,0 +1,32 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"doc.go",
"reader.go",
"strconv.go",
"writer.go",
],
importmap = "k8s.io/kubernetes/vendor/github.com/mesos/mesos-go/api/v1/lib/recordio",
importpath = "github.com/mesos/mesos-go/api/v1/lib/recordio",
visibility = ["//visibility:public"],
deps = [
"//vendor/github.com/mesos/mesos-go/api/v1/lib/debug:go_default_library",
"//vendor/github.com/mesos/mesos-go/api/v1/lib/encoding/framing:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@ -0,0 +1,5 @@
// Package recordio implements the Mesos variant of RecordIO framing, whereby
// each record is prefixed by a line that indicates the length of the record in
// decimal ASCII. The bytes of the record immediately follow the length-line.
// Zero-length records are allowed.
package recordio

View File

@ -0,0 +1,145 @@
package recordio
import (
"bufio"
"bytes"
"io"
logger "github.com/mesos/mesos-go/api/v1/lib/debug"
"github.com/mesos/mesos-go/api/v1/lib/encoding/framing"
)
const debug = logger.Logger(false)
type (
Opt func(*reader)
reader struct {
*bufio.Scanner
pend int
splitf func(data []byte, atEOF bool) (int, []byte, error)
maxf int // max frame size
}
)
// NewReader returns a reader that parses frames from a recordio stream.
func NewReader(read io.Reader, opt ...Opt) framing.Reader {
debug.Log("new frame reader")
r := &reader{Scanner: bufio.NewScanner(read)}
r.Split(func(data []byte, atEOF bool) (int, []byte, error) {
// Scanner panics if we invoke Split after scanning has started,
// use this proxy func as a work-around.
return r.splitf(data, atEOF)
})
buf := make([]byte, 16*1024)
r.Buffer(buf, 1<<22) // 1<<22 == max protobuf size
r.splitf = r.splitSize
// apply options
for _, f := range opt {
if f != nil {
f(r)
}
}
return r
}
// MaxMessageSize returns a functional option that configures the internal Scanner's buffer and max token (message)
// length, in bytes.
func MaxMessageSize(max int) Opt {
return func(r *reader) {
buf := make([]byte, max>>1)
r.Buffer(buf, max)
r.maxf = max
}
}
func (r *reader) splitSize(data []byte, atEOF bool) (int, []byte, error) {
const maxTokenLength = 20 // textual length of largest uint64 number
if atEOF {
x := len(data)
switch {
case x == 0:
debug.Log("EOF and empty frame, returning io.EOF")
return 0, nil, io.EOF
case x < 2: // min frame size
debug.Log("remaining data less than min total frame length")
return 0, nil, framing.ErrorUnderrun
}
// otherwise, we may have a valid frame...
}
debug.Log("len(data)=", len(data))
adv := 0
for {
i := 0
for ; i < maxTokenLength && i < len(data) && data[i] != '\n'; i++ {
}
debug.Log("i=", i)
if i == len(data) {
debug.Log("need more input")
return 0, nil, nil // need more input
}
if i == maxTokenLength && data[i] != '\n' {
debug.Log("frame size: max token length exceeded")
return 0, nil, framing.ErrorBadSize
}
n, err := ParseUintBytes(bytes.TrimSpace(data[:i]), 10, 64)
if err != nil {
debug.Log("failed to parse frame size field:", err)
return 0, nil, framing.ErrorBadSize
}
if r.maxf != 0 && int(n) > r.maxf {
debug.Log("frame size max length exceeded:", n)
return 0, nil, framing.ErrorOversizedFrame
}
if n == 0 {
// special case... don't invoke splitData, just parse the next size header
adv += i + 1
data = data[i+1:]
continue
}
r.pend = int(n)
r.splitf = r.splitFrame
debug.Logf("split next frame: %d, %d", n, adv+i+1)
return adv + i + 1, data[:0], nil // returning a nil token screws up the Scanner, so return empty
}
}
func (r *reader) splitFrame(data []byte, atEOF bool) (advance int, token []byte, err error) {
x := len(data)
debug.Log("splitFrame:x=", x, ",eof=", atEOF)
if atEOF {
if x < r.pend {
return 0, nil, framing.ErrorUnderrun
}
}
if r.pend == 0 {
panic("asked to read frame data, but no data left in frame")
}
if x < int(r.pend) {
// need more data
return 0, nil, nil
}
r.splitf = r.splitSize
adv := int(r.pend)
r.pend = 0
return adv, data[:adv], nil
}
// ReadFrame implements framing.Reader
func (r *reader) ReadFrame() (tok []byte, err error) {
for r.Scan() {
b := r.Bytes()
if len(b) == 0 {
continue
}
tok = b
debug.Log("len(tok)", len(tok))
break
}
// either scan failed, or it succeeded and we have a token...
err = r.Err()
if err == nil && len(tok) == 0 {
err = io.EOF
}
return
}

View File

@ -0,0 +1,117 @@
/*
Copyright 2013 The Camlistore Authors
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 recordio
import (
"errors"
"strconv"
)
// ParseUintBytes is like strconv.ParseUint, but using a []byte.
func ParseUintBytes(s []byte, base int, bitSize int) (n uint64, err error) {
var cutoff, maxVal uint64
if bitSize == 0 {
bitSize = int(strconv.IntSize)
}
s0 := s
switch {
case len(s) < 1:
err = strconv.ErrSyntax
goto Error
case 2 <= base && base <= 36:
// valid base; nothing to do
case base == 0:
// Look for octal, hex prefix.
switch {
case s[0] == '0' && len(s) > 1 && (s[1] == 'x' || s[1] == 'X'):
base = 16
s = s[2:]
if len(s) < 1 {
err = strconv.ErrSyntax
goto Error
}
case s[0] == '0':
base = 8
default:
base = 10
}
default:
err = errors.New("invalid base " + strconv.Itoa(base))
goto Error
}
n = 0
cutoff = cutoff64(base)
maxVal = 1<<uint(bitSize) - 1
for i := 0; i < len(s); i++ {
var v byte
d := s[i]
switch {
case '0' <= d && d <= '9':
v = d - '0'
case 'a' <= d && d <= 'z':
v = d - 'a' + 10
case 'A' <= d && d <= 'Z':
v = d - 'A' + 10
default:
n = 0
err = strconv.ErrSyntax
goto Error
}
if int(v) >= base {
n = 0
err = strconv.ErrSyntax
goto Error
}
if n >= cutoff {
// n*base overflows
n = 1<<64 - 1
err = strconv.ErrRange
goto Error
}
n *= uint64(base)
n1 := n + uint64(v)
if n1 < n || n1 > maxVal {
// n+v overflows
n = 1<<64 - 1
err = strconv.ErrRange
goto Error
}
n = n1
}
return n, nil
Error:
return n, &strconv.NumError{Func: "ParseUint", Num: string(s0), Err: err}
}
// Return the first number n such that n*base >= 1<<64.
func cutoff64(base int) uint64 {
if base < 2 {
return 0
}
return (1<<64-1)/uint64(base) + 1
}

View File

@ -0,0 +1,34 @@
package recordio
import (
"io"
"strconv"
)
var lf = []byte{'\n'}
type Writer struct {
out io.Writer
}
func NewWriter(out io.Writer) *Writer {
return &Writer{out}
}
func (w *Writer) writeBuffer(b []byte, err error) error {
if err != nil {
return err
}
n, err := w.out.Write(b)
if err == nil && n != len(b) {
return io.ErrShortWrite
}
return err
}
func (w *Writer) WriteFrame(b []byte) (err error) {
err = w.writeBuffer(([]byte)(strconv.Itoa(len(b))), err)
err = w.writeBuffer(lf, err)
err = w.writeBuffer(b, err)
return
}

1145
vendor/github.com/mesos/mesos-go/api/v1/lib/resources.go generated vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,23 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = ["role.go"],
importmap = "k8s.io/kubernetes/vendor/github.com/mesos/mesos-go/api/v1/lib/roles",
importpath = "github.com/mesos/mesos-go/api/v1/lib/roles",
visibility = ["//visibility:public"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@ -0,0 +1,82 @@
package roles
import (
"fmt"
"strings"
"unicode"
)
// Role is a deprecated type.
type Role string
const defaultRole = Role("*")
func (r Role) IsDefault() bool {
return r == defaultRole
}
func (r Role) Assign() func(interface{}) {
return func(v interface{}) {
type roler interface {
WithRole(string)
}
if ri, ok := v.(roler); ok {
ri.WithRole(string(r))
}
}
}
func (r Role) Proto() *string {
s := string(r)
return &s
}
// IsStrictSubroleOf returns true if left is a strict subrole of right.
func IsStrictSubroleOf(left, right string) bool {
return len(left) > len(right) && left[len(right)] == '/' && strings.HasPrefix(left, right)
}
var illegalComponents = map[string]struct{}{
".": struct{}{},
"..": struct{}{},
"*": struct{}{},
}
func Parse(s string) (string, error) {
if s == string(defaultRole) {
return s, nil
}
if strings.HasPrefix(s, "/") {
return "", fmt.Errorf("role %q cannot start with a slash", s)
}
if strings.HasSuffix(s, "/") {
return "", fmt.Errorf("role %q cannot end with a slash", s)
}
// validate each component in the role path
for _, part := range strings.Split(s, "/") {
if part == "" {
return "", fmt.Errorf("role %q cannot contain two adjacent slashes", s)
}
if bad, found := illegalComponents[part]; found {
return "", fmt.Errorf("role %q cannot contain %q as a component", s, bad)
}
if strings.HasPrefix(part, "-") {
return "", fmt.Errorf("role component %q is invalid because it begins with a dash", part)
}
if strings.IndexFunc(part, func(r rune) bool { return unicode.IsSpace(r) || unicode.IsControl(r) }) > -1 {
return "", fmt.Errorf("role component %q is invalid because it contains backspace or whitespace", part)
}
}
return s, nil
}
func Validate(roles ...string) error {
for i := range roles {
_, err := Parse(roles[i])
if err != nil {
return err
}
}
return nil
}

142
vendor/github.com/mesos/mesos-go/api/v1/lib/values.go generated vendored Normal file
View File

@ -0,0 +1,142 @@
package mesos
func (left *Value_Scalar) Compare(right *Value_Scalar) int {
var (
a = convertToFixed64(left.GetValue())
b = convertToFixed64(right.GetValue())
)
if a < b {
return -1
}
if a > b {
return 1
}
return 0
}
func (left *Value_Ranges) Compare(right *Value_Ranges) int {
return Ranges(left.GetRange()).Compare(right.GetRange())
}
func (left *Value_Set) Compare(right *Value_Set) int {
i, j := left.GetItem(), right.GetItem()
if len(i) <= len(j) {
b := make(map[string]struct{}, len(j))
for _, x := range j {
b[x] = struct{}{}
}
// make sure that each item on the left exists on the right,
// otherwise left is not a subset of right.
a := make(map[string]struct{}, len(i))
for _, x := range i {
if _, ok := b[x]; !ok {
return 1
}
a[x] = struct{}{}
}
// if every item on the right also exists on the left, then
// the sets are equal, otherwise left < right
for x := range b {
if _, ok := a[x]; !ok {
return -1
}
}
return 0
}
return 1
}
func (left *Value_Set) Add(right *Value_Set) *Value_Set {
lefty := left.GetItem()
righty := right.GetItem()
c := len(lefty) + len(righty)
if c == 0 {
return nil
}
m := make(map[string]struct{}, c)
for _, v := range lefty {
m[v] = struct{}{}
}
for _, v := range righty {
m[v] = struct{}{}
}
x := make([]string, 0, len(m))
for v := range m {
x = append(x, v)
}
return &Value_Set{Item: x}
}
func (left *Value_Set) Subtract(right *Value_Set) *Value_Set {
// for each item in right, remove it from left
lefty := left.GetItem()
righty := right.GetItem()
if c := len(lefty); c == 0 {
return nil
} else if len(righty) == 0 {
x := make([]string, c)
copy(x, lefty)
return &Value_Set{Item: x}
}
a := make(map[string]struct{}, len(lefty))
for _, x := range lefty {
a[x] = struct{}{}
}
for _, x := range righty {
delete(a, x)
}
if len(a) == 0 {
return nil
}
i := 0
for k := range a {
lefty[i] = k
i++
}
return &Value_Set{Item: lefty[:len(a)]}
}
func (left *Value_Ranges) Add(right *Value_Ranges) *Value_Ranges {
a, b := Ranges(left.GetRange()), Ranges(right.GetRange())
c := len(a) + len(b)
if c == 0 {
return nil
}
x := make(Ranges, c)
if len(a) > 0 {
copy(x, a)
}
if len(b) > 0 {
copy(x[len(a):], b)
}
return &Value_Ranges{
Range: x.Sort().Squash(),
}
}
func (left *Value_Ranges) Subtract(right *Value_Ranges) *Value_Ranges {
a, b := Ranges(left.GetRange()), Ranges(right.GetRange())
if len(a) > 1 {
x := make(Ranges, len(a))
copy(x, a)
a = x.Sort().Squash()
}
for _, r := range b {
a = a.Remove(r)
}
if len(a) == 0 {
return nil
}
return &Value_Ranges{Range: a}
}
func (left *Value_Scalar) Add(right *Value_Scalar) *Value_Scalar {
sum := convertToFixed64(left.GetValue()) + convertToFixed64(right.GetValue())
return &Value_Scalar{Value: convertToFloat64(sum)}
}
func (left *Value_Scalar) Subtract(right *Value_Scalar) *Value_Scalar {
diff := convertToFixed64(left.GetValue()) - convertToFixed64(right.GetValue())
return &Value_Scalar{Value: convertToFloat64(diff)}
}

202
vendor/github.com/pquerna/ffjson/LICENSE generated vendored Normal file
View File

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
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.

8
vendor/github.com/pquerna/ffjson/NOTICE generated vendored Normal file
View File

@ -0,0 +1,8 @@
ffjson
Copyright (c) 2014, Paul Querna
This product includes software developed by
Paul Querna (http://paul.querna.org/).
Portions of this software were developed as
part of Go, Copyright (c) 2012 The Go Authors.

41
vendor/github.com/pquerna/ffjson/fflib/v1/BUILD generated vendored Normal file
View File

@ -0,0 +1,41 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"buffer.go",
"buffer_nopool.go",
"buffer_pool.go",
"bytenum.go",
"decimal.go",
"extfloat.go",
"fold.go",
"ftoa.go",
"iota.go",
"jsonstring.go",
"lexer.go",
"reader.go",
"reader_scan_generic.go",
],
importmap = "k8s.io/kubernetes/vendor/github.com/pquerna/ffjson/fflib/v1",
importpath = "github.com/pquerna/ffjson/fflib/v1",
visibility = ["//visibility:public"],
deps = ["//vendor/github.com/pquerna/ffjson/fflib/v1/internal:go_default_library"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//vendor/github.com/pquerna/ffjson/fflib/v1/internal:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

Some files were not shown because too many files have changed in this diff Show More