Update to latest cadvisor - cleanup mesos/rkt

Change-Id: Ib5ae0cb13b93f8c87bb74e3ba33040df5f3d6a6f
parent ca554325
...@@ -19,7 +19,7 @@ require ( ...@@ -19,7 +19,7 @@ require (
github.com/Microsoft/hcsshim v0.0.0-20190110205307-69ac8d3f7fc1 github.com/Microsoft/hcsshim v0.0.0-20190110205307-69ac8d3f7fc1
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect
github.com/PuerkitoBio/purell v1.1.0 github.com/PuerkitoBio/purell v1.1.0
github.com/Rican7/retry v0.0.0-20160712041035-272ad122d6e5 // indirect github.com/Rican7/retry v0.1.0 // indirect
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e
github.com/auth0/go-jwt-middleware v0.0.0-20170425171159-5493cabe49f7 // indirect github.com/auth0/go-jwt-middleware v0.0.0-20170425171159-5493cabe49f7 // indirect
github.com/aws/aws-sdk-go v1.16.26 github.com/aws/aws-sdk-go v1.16.26
...@@ -43,7 +43,7 @@ require ( ...@@ -43,7 +43,7 @@ require (
github.com/coreos/go-semver v0.0.0-20180108230905-e214231b295a github.com/coreos/go-semver v0.0.0-20180108230905-e214231b295a
github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7 github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7
github.com/coreos/pkg v0.0.0-20180108230652-97fdf19511ea github.com/coreos/pkg v0.0.0-20180108230652-97fdf19511ea
github.com/coreos/rkt v1.25.0 // indirect github.com/coreos/rkt v1.30.0 // indirect
github.com/cpuguy83/go-md2man v1.0.4 github.com/cpuguy83/go-md2man v1.0.4
github.com/cyphar/filepath-securejoin v0.0.0-20170720062807-ae69057f2299 // indirect github.com/cyphar/filepath-securejoin v0.0.0-20170720062807-ae69057f2299 // indirect
github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c
...@@ -78,7 +78,7 @@ require ( ...@@ -78,7 +78,7 @@ require (
github.com/golangplus/bytes v0.0.0-20160111154220-45c989fe5450 // indirect github.com/golangplus/bytes v0.0.0-20160111154220-45c989fe5450 // indirect
github.com/golangplus/fmt v0.0.0-20150411045040-2a5d6d7d2995 // indirect github.com/golangplus/fmt v0.0.0-20150411045040-2a5d6d7d2995 // indirect
github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e // indirect github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e // indirect
github.com/google/cadvisor v0.33.1 github.com/google/cadvisor v0.33.2-0.20190411163913-9db8c7dee20a
github.com/google/certificate-transparency-go v1.0.21 // indirect github.com/google/certificate-transparency-go v1.0.21 // indirect
github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf
github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d
...@@ -112,7 +112,7 @@ require ( ...@@ -112,7 +112,7 @@ require (
github.com/marstr/guid v0.0.0-20170427235115-8bdf7d1a087c // indirect github.com/marstr/guid v0.0.0-20170427235115-8bdf7d1a087c // indirect
github.com/mattn/go-shellwords v0.0.0-20180605041737-f8471b0a71de // indirect github.com/mattn/go-shellwords v0.0.0-20180605041737-f8471b0a71de // indirect
github.com/mattn/go-sqlite3 v1.6.0 // indirect github.com/mattn/go-sqlite3 v1.6.0 // indirect
github.com/mesos/mesos-go v0.0.0-20180906210748-ff8175bfda54 // indirect github.com/mesos/mesos-go v0.0.9 // indirect
github.com/mholt/caddy v0.0.0-20180213163048-2de495001514 github.com/mholt/caddy v0.0.0-20180213163048-2de495001514
github.com/miekg/dns v0.0.0-20160614162101-5d001d020961 github.com/miekg/dns v0.0.0-20160614162101-5d001d020961
github.com/mindprince/gonvml v0.0.0-20171110221305-fee913ce8fb2 // indirect github.com/mindprince/gonvml v0.0.0-20171110221305-fee913ce8fb2 // indirect
...@@ -226,7 +226,7 @@ replace ( ...@@ -226,7 +226,7 @@ replace (
github.com/Nvveen/Gotty => github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 github.com/Nvveen/Gotty => github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5
github.com/PuerkitoBio/purell => github.com/PuerkitoBio/purell v1.1.0 github.com/PuerkitoBio/purell => github.com/PuerkitoBio/purell v1.1.0
github.com/PuerkitoBio/urlesc => github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 github.com/PuerkitoBio/urlesc => github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578
github.com/Rican7/retry => github.com/Rican7/retry v0.0.0-20160712041035-272ad122d6e5 github.com/Rican7/retry => github.com/Rican7/retry v0.1.0
github.com/alecthomas/template => github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc github.com/alecthomas/template => github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc
github.com/alecthomas/units => github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf github.com/alecthomas/units => github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf
github.com/armon/circbuf => github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e github.com/armon/circbuf => github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e
...@@ -256,7 +256,7 @@ replace ( ...@@ -256,7 +256,7 @@ replace (
github.com/coreos/go-semver => github.com/coreos/go-semver v0.0.0-20180108230905-e214231b295a github.com/coreos/go-semver => github.com/coreos/go-semver v0.0.0-20180108230905-e214231b295a
github.com/coreos/go-systemd => github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7 github.com/coreos/go-systemd => github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7
github.com/coreos/pkg => github.com/coreos/pkg v0.0.0-20180108230652-97fdf19511ea github.com/coreos/pkg => github.com/coreos/pkg v0.0.0-20180108230652-97fdf19511ea
github.com/coreos/rkt => github.com/coreos/rkt v1.25.0 github.com/coreos/rkt => github.com/coreos/rkt v1.30.0
github.com/cpuguy83/go-md2man => github.com/cpuguy83/go-md2man v1.0.4 github.com/cpuguy83/go-md2man => github.com/cpuguy83/go-md2man v1.0.4
github.com/cyphar/filepath-securejoin => github.com/cyphar/filepath-securejoin v0.0.0-20170720062807-ae69057f2299 github.com/cyphar/filepath-securejoin => github.com/cyphar/filepath-securejoin v0.0.0-20170720062807-ae69057f2299
github.com/d2g/dhcp4 => github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c github.com/d2g/dhcp4 => github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c
...@@ -306,7 +306,7 @@ replace ( ...@@ -306,7 +306,7 @@ replace (
github.com/golangplus/fmt => github.com/golangplus/fmt v0.0.0-20150411045040-2a5d6d7d2995 github.com/golangplus/fmt => github.com/golangplus/fmt v0.0.0-20150411045040-2a5d6d7d2995
github.com/golangplus/testing => github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e github.com/golangplus/testing => github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e
github.com/google/btree => github.com/google/btree v0.0.0-20160524151835-7d79101e329e github.com/google/btree => github.com/google/btree v0.0.0-20160524151835-7d79101e329e
github.com/google/cadvisor => github.com/google/cadvisor v0.33.1 github.com/google/cadvisor => github.com/google/cadvisor v0.33.2-0.20190411163913-9db8c7dee20a
github.com/google/certificate-transparency-go => github.com/google/certificate-transparency-go v1.0.21 github.com/google/certificate-transparency-go => github.com/google/certificate-transparency-go v1.0.21
github.com/google/go-cmp => github.com/google/go-cmp v0.2.0 github.com/google/go-cmp => github.com/google/go-cmp v0.2.0
github.com/google/gofuzz => github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf github.com/google/gofuzz => github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf
...@@ -359,7 +359,7 @@ replace ( ...@@ -359,7 +359,7 @@ replace (
github.com/mattn/go-shellwords => github.com/mattn/go-shellwords v0.0.0-20180605041737-f8471b0a71de github.com/mattn/go-shellwords => github.com/mattn/go-shellwords v0.0.0-20180605041737-f8471b0a71de
github.com/mattn/go-sqlite3 => github.com/mattn/go-sqlite3 v1.6.0 github.com/mattn/go-sqlite3 => github.com/mattn/go-sqlite3 v1.6.0
github.com/matttproud/golang_protobuf_extensions => github.com/matttproud/golang_protobuf_extensions v1.0.1 github.com/matttproud/golang_protobuf_extensions => github.com/matttproud/golang_protobuf_extensions v1.0.1
github.com/mesos/mesos-go => github.com/mesos/mesos-go v0.0.0-20180906210748-ff8175bfda54 github.com/mesos/mesos-go => github.com/mesos/mesos-go v0.0.9
github.com/mholt/caddy => github.com/mholt/caddy v0.0.0-20180213163048-2de495001514 github.com/mholt/caddy => github.com/mholt/caddy v0.0.0-20180213163048-2de495001514
github.com/miekg/dns => github.com/miekg/dns v0.0.0-20160614162101-5d001d020961 github.com/miekg/dns => github.com/miekg/dns v0.0.0-20160614162101-5d001d020961
github.com/mindprince/gonvml => github.com/mindprince/gonvml v0.0.0-20171110221305-fee913ce8fb2 github.com/mindprince/gonvml => github.com/mindprince/gonvml v0.0.0-20171110221305-fee913ce8fb2
......
...@@ -31,8 +31,8 @@ github.com/PuerkitoBio/purell v1.1.0 h1:rmGxhojJlM0tuKtfdvliR84CFHljx9ag64t2xmVk ...@@ -31,8 +31,8 @@ github.com/PuerkitoBio/purell v1.1.0 h1:rmGxhojJlM0tuKtfdvliR84CFHljx9ag64t2xmVk
github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
github.com/Rican7/retry v0.0.0-20160712041035-272ad122d6e5 h1:lL761TuQsL4xn4Pn0CNk9YrPvrT8kzBMvW4YgCB7HMg= github.com/Rican7/retry v0.1.0 h1:FqK94z34ly8Baa6K+G8Mmza9rYWTKOJk+yckIBB5qVk=
github.com/Rican7/retry v0.0.0-20160712041035-272ad122d6e5/go.mod h1:FgOROf8P5bebcC1DS0PdOQiqGUridaZvikzUmkFW6gg= github.com/Rican7/retry v0.1.0/go.mod h1:FgOROf8P5bebcC1DS0PdOQiqGUridaZvikzUmkFW6gg=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e h1:QEF07wC0T1rKkctt1RINW/+RMTVmiwxETico2l3gxJA= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e h1:QEF07wC0T1rKkctt1RINW/+RMTVmiwxETico2l3gxJA=
...@@ -89,8 +89,8 @@ github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7 h1:u9SHYsPQNyt5t ...@@ -89,8 +89,8 @@ github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7 h1:u9SHYsPQNyt5t
github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/pkg v0.0.0-20180108230652-97fdf19511ea h1:n2Ltr3SrfQlf/9nOna1DoGKxLx3qTSI8Ttl6Xrqp6mw= github.com/coreos/pkg v0.0.0-20180108230652-97fdf19511ea h1:n2Ltr3SrfQlf/9nOna1DoGKxLx3qTSI8Ttl6Xrqp6mw=
github.com/coreos/pkg v0.0.0-20180108230652-97fdf19511ea/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/coreos/pkg v0.0.0-20180108230652-97fdf19511ea/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/coreos/rkt v1.25.0 h1:4rDjbXDtLwReumvn9/fH0D4aTXWXk2kpUcpjJNH2F/g= github.com/coreos/rkt v1.30.0 h1:Kkt6sYeEGKxA3Y7SCrY+nHoXkWed6Jr2BBY42GqMymM=
github.com/coreos/rkt v1.25.0/go.mod h1:O634mlH6U7qk87poQifK6M2rsFNt+FyUTWNMnP1hF1U= github.com/coreos/rkt v1.30.0/go.mod h1:O634mlH6U7qk87poQifK6M2rsFNt+FyUTWNMnP1hF1U=
github.com/cpuguy83/go-md2man v1.0.4 h1:OwjhDpK9YGCcI5CDf8HcdfsXqr6znFyAJfuZ27ixJsc= github.com/cpuguy83/go-md2man v1.0.4 h1:OwjhDpK9YGCcI5CDf8HcdfsXqr6znFyAJfuZ27ixJsc=
github.com/cpuguy83/go-md2man v1.0.4/go.mod h1:N6JayAiVKtlHSnuTCeuLSQVs75hb8q+dYQLjr7cDsKY= github.com/cpuguy83/go-md2man v1.0.4/go.mod h1:N6JayAiVKtlHSnuTCeuLSQVs75hb8q+dYQLjr7cDsKY=
github.com/cyphar/filepath-securejoin v0.0.0-20170720062807-ae69057f2299 h1:2pOMM/RaFhI52FyCITl8aTf5HZ9LoHD8SkjbghAEG1E= github.com/cyphar/filepath-securejoin v0.0.0-20170720062807-ae69057f2299 h1:2pOMM/RaFhI52FyCITl8aTf5HZ9LoHD8SkjbghAEG1E=
...@@ -186,8 +186,8 @@ github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e h1:KhcknUwkWHKZ ...@@ -186,8 +186,8 @@ github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e h1:KhcknUwkWHKZ
github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e/go.mod h1:0AA//k/eakGydO4jKRoRL2j92ZKSzTgj9tclaCrvXHk= github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e/go.mod h1:0AA//k/eakGydO4jKRoRL2j92ZKSzTgj9tclaCrvXHk=
github.com/google/btree v0.0.0-20160524151835-7d79101e329e h1:JHB7F/4TJCrYBW8+GZO8VkWDj1jxcWuCl6uxKODiyi4= github.com/google/btree v0.0.0-20160524151835-7d79101e329e h1:JHB7F/4TJCrYBW8+GZO8VkWDj1jxcWuCl6uxKODiyi4=
github.com/google/btree v0.0.0-20160524151835-7d79101e329e/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v0.0.0-20160524151835-7d79101e329e/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/cadvisor v0.33.1 h1:XdozWGjfQ3/mUSuk+m11M7uacH+iu4GV1cKbLGMrQDY= github.com/google/cadvisor v0.33.2-0.20190411163913-9db8c7dee20a h1:4N3IykedbdXG1ganAZbAKlViPjrtfrx2nC4qzUHieOk=
github.com/google/cadvisor v0.33.1/go.mod h1:1nql6U13uTHaLYB8rLS5x9IJc2qT6Xd/Tr1sTX6NE48= github.com/google/cadvisor v0.33.2-0.20190411163913-9db8c7dee20a/go.mod h1:1nql6U13uTHaLYB8rLS5x9IJc2qT6Xd/Tr1sTX6NE48=
github.com/google/certificate-transparency-go v1.0.21 h1:Yf1aXowfZ2nuboBsg7iYGLmwsOARdV86pfH3g95wXmE= github.com/google/certificate-transparency-go v1.0.21 h1:Yf1aXowfZ2nuboBsg7iYGLmwsOARdV86pfH3g95wXmE=
github.com/google/certificate-transparency-go v1.0.21/go.mod h1:QeJfpSbVSfYc7RgB3gJFj9cbuQMMchQxrWXz8Ruopmg= github.com/google/certificate-transparency-go v1.0.21/go.mod h1:QeJfpSbVSfYc7RgB3gJFj9cbuQMMchQxrWXz8Ruopmg=
github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ= github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
...@@ -289,8 +289,8 @@ github.com/mattn/go-sqlite3 v1.6.0 h1:TDwTWbeII+88Qy55nWlof0DclgAtI4LqGujkYMzmQI ...@@ -289,8 +289,8 @@ github.com/mattn/go-sqlite3 v1.6.0 h1:TDwTWbeII+88Qy55nWlof0DclgAtI4LqGujkYMzmQI
github.com/mattn/go-sqlite3 v1.6.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-sqlite3 v1.6.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mesos/mesos-go v0.0.0-20180906210748-ff8175bfda54 h1:xECydo+5ODuk5kTymjUybwJnS9Mg6mzbyM94dB5M+Bw= github.com/mesos/mesos-go v0.0.9 h1:w8V5sOEnxzHZ2kAOy273v/HgbolyI6XI+qe5jx5u+Y0=
github.com/mesos/mesos-go v0.0.0-20180906210748-ff8175bfda54/go.mod h1:kPYCMQ9gsOXVAle1OsoY4I1+9kPu8GHkf88aV59fDr4= github.com/mesos/mesos-go v0.0.9/go.mod h1:kPYCMQ9gsOXVAle1OsoY4I1+9kPu8GHkf88aV59fDr4=
github.com/mholt/caddy v0.0.0-20180213163048-2de495001514 h1:HQP0VPdc6NLcKWrpVDNyUZckK97MjCmK3qyXWn+j6L0= github.com/mholt/caddy v0.0.0-20180213163048-2de495001514 h1:HQP0VPdc6NLcKWrpVDNyUZckK97MjCmK3qyXWn+j6L0=
github.com/mholt/caddy v0.0.0-20180213163048-2de495001514/go.mod h1:Wb1PlT4DAYSqOEd03MsqkdkXnTxA8v9pKjdpxbqM1kY= github.com/mholt/caddy v0.0.0-20180213163048-2de495001514/go.mod h1:Wb1PlT4DAYSqOEd03MsqkdkXnTxA8v9pKjdpxbqM1kY=
github.com/miekg/dns v0.0.0-20160614162101-5d001d020961 h1:vX2vkMipgQZ8gfmAsFeZdcgmhHoB7jMo6chAtajG3AI= github.com/miekg/dns v0.0.0-20160614162101-5d001d020961 h1:vX2vkMipgQZ8gfmAsFeZdcgmhHoB7jMo6chAtajG3AI=
......
...@@ -31,6 +31,10 @@ go_library( ...@@ -31,6 +31,10 @@ go_library(
"@io_bazel_rules_go//go/platform:linux": [ "@io_bazel_rules_go//go/platform:linux": [
"//vendor/github.com/google/cadvisor/cache/memory:go_default_library", "//vendor/github.com/google/cadvisor/cache/memory:go_default_library",
"//vendor/github.com/google/cadvisor/container:go_default_library", "//vendor/github.com/google/cadvisor/container:go_default_library",
"//vendor/github.com/google/cadvisor/container/containerd/install:go_default_library",
"//vendor/github.com/google/cadvisor/container/crio/install:go_default_library",
"//vendor/github.com/google/cadvisor/container/docker/install:go_default_library",
"//vendor/github.com/google/cadvisor/container/systemd/install:go_default_library",
"//vendor/github.com/google/cadvisor/fs:go_default_library", "//vendor/github.com/google/cadvisor/fs:go_default_library",
"//vendor/github.com/google/cadvisor/manager:go_default_library", "//vendor/github.com/google/cadvisor/manager:go_default_library",
"//vendor/github.com/google/cadvisor/utils/sysfs:go_default_library", "//vendor/github.com/google/cadvisor/utils/sysfs:go_default_library",
......
...@@ -32,7 +32,6 @@ filegroup( ...@@ -32,7 +32,6 @@ filegroup(
"//vendor/github.com/Nvveen/Gotty:all-srcs", "//vendor/github.com/Nvveen/Gotty:all-srcs",
"//vendor/github.com/PuerkitoBio/purell:all-srcs", "//vendor/github.com/PuerkitoBio/purell:all-srcs",
"//vendor/github.com/PuerkitoBio/urlesc: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/armon/circbuf:all-srcs",
"//vendor/github.com/asaskevich/govalidator:all-srcs", "//vendor/github.com/asaskevich/govalidator:all-srcs",
"//vendor/github.com/aws/aws-sdk-go/aws:all-srcs", "//vendor/github.com/aws/aws-sdk-go/aws:all-srcs",
...@@ -165,7 +164,6 @@ filegroup( ...@@ -165,7 +164,6 @@ filegroup(
"//vendor/github.com/coreos/go-systemd/util:all-srcs", "//vendor/github.com/coreos/go-systemd/util:all-srcs",
"//vendor/github.com/coreos/pkg/capnslog:all-srcs", "//vendor/github.com/coreos/pkg/capnslog:all-srcs",
"//vendor/github.com/coreos/pkg/dlopen:all-srcs", "//vendor/github.com/coreos/pkg/dlopen:all-srcs",
"//vendor/github.com/coreos/rkt/api/v1alpha:all-srcs",
"//vendor/github.com/cpuguy83/go-md2man/md2man:all-srcs", "//vendor/github.com/cpuguy83/go-md2man/md2man:all-srcs",
"//vendor/github.com/cyphar/filepath-securejoin:all-srcs", "//vendor/github.com/cyphar/filepath-securejoin:all-srcs",
"//vendor/github.com/d2g/dhcp4:all-srcs", "//vendor/github.com/d2g/dhcp4:all-srcs",
...@@ -263,6 +261,7 @@ filegroup( ...@@ -263,6 +261,7 @@ filegroup(
"//vendor/github.com/google/cadvisor/summary:all-srcs", "//vendor/github.com/google/cadvisor/summary:all-srcs",
"//vendor/github.com/google/cadvisor/utils:all-srcs", "//vendor/github.com/google/cadvisor/utils:all-srcs",
"//vendor/github.com/google/cadvisor/version:all-srcs", "//vendor/github.com/google/cadvisor/version:all-srcs",
"//vendor/github.com/google/cadvisor/watcher:all-srcs",
"//vendor/github.com/google/cadvisor/zfs:all-srcs", "//vendor/github.com/google/cadvisor/zfs:all-srcs",
"//vendor/github.com/google/certificate-transparency-go:all-srcs", "//vendor/github.com/google/certificate-transparency-go:all-srcs",
"//vendor/github.com/google/gofuzz:all-srcs", "//vendor/github.com/google/gofuzz:all-srcs",
...@@ -311,7 +310,6 @@ filegroup( ...@@ -311,7 +310,6 @@ filegroup(
"//vendor/github.com/mattn/go-shellwords:all-srcs", "//vendor/github.com/mattn/go-shellwords:all-srcs",
"//vendor/github.com/mattn/go-sqlite3:all-srcs", "//vendor/github.com/mattn/go-sqlite3:all-srcs",
"//vendor/github.com/matttproud/golang_protobuf_extensions/pbutil: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/mholt/caddy/caddyfile:all-srcs",
"//vendor/github.com/miekg/dns:all-srcs", "//vendor/github.com/miekg/dns:all-srcs",
"//vendor/github.com/mindprince/gonvml:all-srcs", "//vendor/github.com/mindprince/gonvml:all-srcs",
...@@ -339,7 +337,6 @@ filegroup( ...@@ -339,7 +337,6 @@ filegroup(
"//vendor/github.com/pkg/sftp:all-srcs", "//vendor/github.com/pkg/sftp:all-srcs",
"//vendor/github.com/pmezard/go-difflib/difflib:all-srcs", "//vendor/github.com/pmezard/go-difflib/difflib:all-srcs",
"//vendor/github.com/pquerna/cachecontrol: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_golang/prometheus:all-srcs",
"//vendor/github.com/prometheus/client_model/go:all-srcs", "//vendor/github.com/prometheus/client_model/go:all-srcs",
"//vendor/github.com/prometheus/common/expfmt:all-srcs", "//vendor/github.com/prometheus/common/expfmt:all-srcs",
......
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
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"],
)
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.
# 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
# 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),
),
)
```
// 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)
}
}
// 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))
}
// 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
}
// 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
}
}
# WARNING
The API defined here is proposed, experimental, and (for now) subject to change at any time.
If you think you want to use it, or for any other queries, contact <rkt-dev@googlegroups.com> or file an [issue](https://github.com/coreos/rkt/issues/new)
For more information, see:
- #1208
- #1359
- #1468
- [API Service Subcommand](../../Documentation/subcommands/api-service.md)
## Protobuf
The rkt gRPC API uses Protocol Buffers for its services.
In order to rebuild the generated code make sure you have protobuf 3.0.0 installed (https://github.com/google/protobuf)
and execute from the top-level directory:
```
$ make protobuf
```
// Copyright 2015 The rkt 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.
// +build ignore
package main
import (
"flag"
"fmt"
"io"
"os"
"time"
"github.com/coreos/rkt/api/v1alpha"
"golang.org/x/net/context"
"google.golang.org/grpc"
)
func getLogsWithoutFollow(c v1alpha.PublicAPIClient, p *v1alpha.Pod) {
if len(p.Apps) == 0 {
fmt.Printf("Pod %q has no apps\n", p.Id)
return
}
logsResp, err := c.GetLogs(context.Background(), &v1alpha.GetLogsRequest{
PodId: p.Id,
Follow: false,
AppName: p.Apps[0].Name,
SinceTime: time.Now().Add(-time.Second * 5).Unix(),
Lines: 10,
})
if err != nil {
fmt.Println(err)
os.Exit(254)
}
logsRecvResp, err := logsResp.Recv()
if err == io.EOF {
return
}
if err != nil {
fmt.Println(err)
return
}
for _, l := range logsRecvResp.Lines {
fmt.Println(l)
}
}
func getLogsWithFollow(c v1alpha.PublicAPIClient, p *v1alpha.Pod) {
if len(p.Apps) == 0 {
fmt.Printf("Pod %q has no apps\n", p.Id)
return
}
logsResp, err := c.GetLogs(context.Background(), &v1alpha.GetLogsRequest{
PodId: p.Id,
Follow: true,
AppName: p.Apps[0].Name,
})
if err != nil {
fmt.Println(err)
os.Exit(254)
}
for {
logsRecvResp, err := logsResp.Recv()
if err == io.EOF {
return
}
if err != nil {
fmt.Println(err)
return
}
for _, l := range logsRecvResp.Lines {
fmt.Println(l)
}
}
}
func main() {
followFlag := flag.Bool("follow", false, "enable 'follow' option on GetLogs")
flag.Parse()
conn, err := grpc.Dial("localhost:15441", grpc.WithInsecure())
if err != nil {
fmt.Println(err)
os.Exit(254)
}
c := v1alpha.NewPublicAPIClient(conn)
defer conn.Close()
// List pods.
podResp, err := c.ListPods(context.Background(), &v1alpha.ListPodsRequest{
// Specify the request: Fetch and print only running pods and their details.
Detail: true,
Filters: []*v1alpha.PodFilter{
{
States: []v1alpha.PodState{v1alpha.PodState_POD_STATE_RUNNING},
},
},
})
if err != nil {
fmt.Println(err)
os.Exit(254)
}
for _, p := range podResp.Pods {
if *followFlag {
fmt.Printf("Pod %q is running. Following logs:\n", p.Id)
getLogsWithFollow(c, p)
} else {
fmt.Printf("Pod %q is running.\n", p.Id)
getLogsWithoutFollow(c, p)
}
}
// List images.
imgResp, err := c.ListImages(context.Background(), &v1alpha.ListImagesRequest{
// In this request, we fetch the details of images whose names are prefixed with "coreos.com".
Detail: true,
Filters: []*v1alpha.ImageFilter{
{
Prefixes: []string{"coreos.com"},
},
},
})
if err != nil {
fmt.Println(err)
os.Exit(254)
}
for _, im := range imgResp.Images {
fmt.Printf("Found image %q\n", im.Name)
}
}
...@@ -10,8 +10,9 @@ go_library( ...@@ -10,8 +10,9 @@ go_library(
importpath = "github.com/google/cadvisor/container", importpath = "github.com/google/cadvisor/container",
visibility = ["//visibility:public"], visibility = ["//visibility:public"],
deps = [ deps = [
"//vendor/github.com/google/cadvisor/fs:go_default_library",
"//vendor/github.com/google/cadvisor/info/v1: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/google/cadvisor/watcher:go_default_library",
"//vendor/k8s.io/klog:go_default_library", "//vendor/k8s.io/klog:go_default_library",
], ],
) )
...@@ -32,9 +33,7 @@ filegroup( ...@@ -32,9 +33,7 @@ filegroup(
"//vendor/github.com/google/cadvisor/container/crio:all-srcs", "//vendor/github.com/google/cadvisor/container/crio:all-srcs",
"//vendor/github.com/google/cadvisor/container/docker: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/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/raw:all-srcs",
"//vendor/github.com/google/cadvisor/container/rkt:all-srcs",
"//vendor/github.com/google/cadvisor/container/systemd:all-srcs", "//vendor/github.com/google/cadvisor/container/systemd:all-srcs",
], ],
tags = ["automanaged"], tags = ["automanaged"],
......
...@@ -7,6 +7,7 @@ go_library( ...@@ -7,6 +7,7 @@ go_library(
"factory.go", "factory.go",
"grpc.go", "grpc.go",
"handler.go", "handler.go",
"plugin.go",
], ],
importmap = "k8s.io/kubernetes/vendor/github.com/google/cadvisor/container/containerd", importmap = "k8s.io/kubernetes/vendor/github.com/google/cadvisor/container/containerd",
importpath = "github.com/google/cadvisor/container/containerd", importpath = "github.com/google/cadvisor/container/containerd",
...@@ -25,7 +26,7 @@ go_library( ...@@ -25,7 +26,7 @@ go_library(
"//vendor/github.com/google/cadvisor/container/libcontainer: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/fs:go_default_library",
"//vendor/github.com/google/cadvisor/info/v1: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/google/cadvisor/watcher:go_default_library",
"//vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs:go_default_library", "//vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs:go_default_library",
"//vendor/github.com/opencontainers/runc/libcontainer/configs:go_default_library", "//vendor/github.com/opencontainers/runc/libcontainer/configs:go_default_library",
"//vendor/github.com/opencontainers/runtime-spec/specs-go:go_default_library", "//vendor/github.com/opencontainers/runtime-spec/specs-go:go_default_library",
...@@ -44,7 +45,10 @@ filegroup( ...@@ -44,7 +45,10 @@ filegroup(
filegroup( filegroup(
name = "all-srcs", name = "all-srcs",
srcs = [":package-srcs"], srcs = [
":package-srcs",
"//vendor/github.com/google/cadvisor/container/containerd/install:all-srcs",
],
tags = ["automanaged"], tags = ["automanaged"],
visibility = ["//visibility:public"], visibility = ["//visibility:public"],
) )
...@@ -31,11 +31,6 @@ import ( ...@@ -31,11 +31,6 @@ import (
"google.golang.org/grpc" "google.golang.org/grpc"
) )
const (
// k8sNamespace is the namespace we use to connect containerd.
k8sNamespace = "k8s.io"
)
type client struct { type client struct {
containerService containersapi.ContainersClient containerService containersapi.ContainersClient
taskService tasksapi.TasksClient taskService tasksapi.TasksClient
...@@ -52,13 +47,12 @@ var once sync.Once ...@@ -52,13 +47,12 @@ var once sync.Once
var ctrdClient containerdClient = nil var ctrdClient containerdClient = nil
const ( const (
address = "/run/containerd/containerd.sock"
maxBackoffDelay = 3 * time.Second maxBackoffDelay = 3 * time.Second
connectionTimeout = 2 * time.Second connectionTimeout = 2 * time.Second
) )
// Client creates a containerd client // Client creates a containerd client
func Client() (containerdClient, error) { func Client(address, namespace string) (containerdClient, error) {
var retErr error var retErr error
once.Do(func() { once.Do(func() {
tryConn, err := net.DialTimeout("unix", address, connectionTimeout) tryConn, err := net.DialTimeout("unix", address, connectionTimeout)
...@@ -75,7 +69,7 @@ func Client() (containerdClient, error) { ...@@ -75,7 +69,7 @@ func Client() (containerdClient, error) {
grpc.WithBackoffMaxDelay(maxBackoffDelay), grpc.WithBackoffMaxDelay(maxBackoffDelay),
grpc.WithTimeout(connectionTimeout), grpc.WithTimeout(connectionTimeout),
} }
unary, stream := newNSInterceptors(k8sNamespace) unary, stream := newNSInterceptors(namespace)
gopts = append(gopts, gopts = append(gopts,
grpc.WithUnaryInterceptor(unary), grpc.WithUnaryInterceptor(unary),
grpc.WithStreamInterceptor(stream), grpc.WithStreamInterceptor(stream),
......
...@@ -28,10 +28,11 @@ import ( ...@@ -28,10 +28,11 @@ import (
"github.com/google/cadvisor/container/libcontainer" "github.com/google/cadvisor/container/libcontainer"
"github.com/google/cadvisor/fs" "github.com/google/cadvisor/fs"
info "github.com/google/cadvisor/info/v1" info "github.com/google/cadvisor/info/v1"
"github.com/google/cadvisor/manager/watcher" "github.com/google/cadvisor/watcher"
) )
var ArgContainerdEndpoint = flag.String("containerd", "unix:///var/run/containerd.sock", "containerd endpoint") var ArgContainerdEndpoint = flag.String("containerd", "/run/containerd/containerd.sock", "containerd endpoint")
var ArgContainerdNamespace = flag.String("containerd-namespace", "k8s.io", "containerd namespace")
// The namespace under which containerd aliases are unique. // The namespace under which containerd aliases are unique.
const k8sContainerdNamespace = "containerd" const k8sContainerdNamespace = "containerd"
...@@ -56,7 +57,7 @@ func (self *containerdFactory) String() string { ...@@ -56,7 +57,7 @@ func (self *containerdFactory) String() string {
} }
func (self *containerdFactory) NewContainerHandler(name string, inHostNamespace bool) (handler container.ContainerHandler, err error) { func (self *containerdFactory) NewContainerHandler(name string, inHostNamespace bool) (handler container.ContainerHandler, err error) {
client, err := Client() client, err := Client(*ArgContainerdEndpoint, *ArgContainerdNamespace)
if err != nil { if err != nil {
return return
} }
...@@ -118,7 +119,7 @@ func (self *containerdFactory) DebugInfo() map[string][]string { ...@@ -118,7 +119,7 @@ func (self *containerdFactory) DebugInfo() map[string][]string {
// Register root container before running this function! // Register root container before running this function!
func Register(factory info.MachineInfoFactory, fsInfo fs.FsInfo, includedMetrics container.MetricSet) error { func Register(factory info.MachineInfoFactory, fsInfo fs.FsInfo, includedMetrics container.MetricSet) error {
client, err := Client() client, err := Client(*ArgContainerdEndpoint, *ArgContainerdNamespace)
if err != nil { if err != nil {
return fmt.Errorf("unable to create containerd client: %v", err) return fmt.Errorf("unable to create containerd client: %v", err)
} }
......
...@@ -2,13 +2,14 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library") ...@@ -2,13 +2,14 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library( go_library(
name = "go_default_library", name = "go_default_library",
srcs = ["strategy.go"], srcs = ["install.go"],
importmap = "k8s.io/kubernetes/vendor/github.com/Rican7/retry/strategy", importmap = "k8s.io/kubernetes/vendor/github.com/google/cadvisor/container/containerd/install",
importpath = "github.com/Rican7/retry/strategy", importpath = "github.com/google/cadvisor/container/containerd/install",
visibility = ["//visibility:public"], visibility = ["//visibility:public"],
deps = [ deps = [
"//vendor/github.com/Rican7/retry/backoff:go_default_library", "//vendor/github.com/google/cadvisor/container:go_default_library",
"//vendor/github.com/Rican7/retry/jitter:go_default_library", "//vendor/github.com/google/cadvisor/container/containerd:go_default_library",
"//vendor/k8s.io/klog:go_default_library",
], ],
) )
......
// Copyright 2019 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.
// The install package registers containerd.NewPlugin() as the "containerd" container provider when imported
package install
import (
"github.com/google/cadvisor/container"
"github.com/google/cadvisor/container/containerd"
"k8s.io/klog"
)
func init() {
err := container.RegisterPlugin("containerd", containerd.NewPlugin())
if err != nil {
klog.Fatalf("Failed to register containerd plugin: %v", err)
}
}
// Copyright 2019 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 containerd
import (
"github.com/google/cadvisor/container"
"github.com/google/cadvisor/fs"
info "github.com/google/cadvisor/info/v1"
"github.com/google/cadvisor/watcher"
)
// NewPlugin returns an implementation of container.Plugin suitable for passing to container.RegisterPlugin()
func NewPlugin() container.Plugin {
return &plugin{}
}
type plugin struct{}
func (p *plugin) InitializeFSContext(context *fs.Context) error {
return nil
}
func (p *plugin) Register(factory info.MachineInfoFactory, fsInfo fs.FsInfo, includedMetrics container.MetricSet) (watcher.ContainerWatcher, error) {
err := Register(factory, fsInfo, includedMetrics)
return nil, err
}
...@@ -6,6 +6,7 @@ go_library( ...@@ -6,6 +6,7 @@ go_library(
"client.go", "client.go",
"factory.go", "factory.go",
"handler.go", "handler.go",
"plugin.go",
], ],
importmap = "k8s.io/kubernetes/vendor/github.com/google/cadvisor/container/crio", importmap = "k8s.io/kubernetes/vendor/github.com/google/cadvisor/container/crio",
importpath = "github.com/google/cadvisor/container/crio", importpath = "github.com/google/cadvisor/container/crio",
...@@ -16,7 +17,7 @@ go_library( ...@@ -16,7 +17,7 @@ go_library(
"//vendor/github.com/google/cadvisor/container/libcontainer: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/fs:go_default_library",
"//vendor/github.com/google/cadvisor/info/v1: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/google/cadvisor/watcher:go_default_library",
"//vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs:go_default_library", "//vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs:go_default_library",
"//vendor/github.com/opencontainers/runc/libcontainer/configs:go_default_library", "//vendor/github.com/opencontainers/runc/libcontainer/configs:go_default_library",
"//vendor/k8s.io/klog:go_default_library", "//vendor/k8s.io/klog:go_default_library",
...@@ -32,7 +33,10 @@ filegroup( ...@@ -32,7 +33,10 @@ filegroup(
filegroup( filegroup(
name = "all-srcs", name = "all-srcs",
srcs = [":package-srcs"], srcs = [
":package-srcs",
"//vendor/github.com/google/cadvisor/container/crio/install:all-srcs",
],
tags = ["automanaged"], tags = ["automanaged"],
visibility = ["//visibility:public"], visibility = ["//visibility:public"],
) )
...@@ -122,6 +122,13 @@ func (c *crioClientImpl) ContainerInfo(id string) (*ContainerInfo, error) { ...@@ -122,6 +122,13 @@ func (c *crioClientImpl) ContainerInfo(id string) (*ContainerInfo, error) {
return nil, err return nil, err
} }
defer resp.Body.Close() defer resp.Body.Close()
// golang's http.Do doesn't return an error if non 200 response code is returned
// handle this case here, rather than failing to decode the body
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("Error finding container %s: Status %d returned error %s", id, resp.StatusCode, resp.Body)
}
cInfo := ContainerInfo{} cInfo := ContainerInfo{}
if err := json.NewDecoder(resp.Body).Decode(&cInfo); err != nil { if err := json.NewDecoder(resp.Body).Decode(&cInfo); err != nil {
return nil, err return nil, err
......
...@@ -24,7 +24,7 @@ import ( ...@@ -24,7 +24,7 @@ import (
"github.com/google/cadvisor/container/libcontainer" "github.com/google/cadvisor/container/libcontainer"
"github.com/google/cadvisor/fs" "github.com/google/cadvisor/fs"
info "github.com/google/cadvisor/info/v1" info "github.com/google/cadvisor/info/v1"
"github.com/google/cadvisor/manager/watcher" "github.com/google/cadvisor/watcher"
"k8s.io/klog" "k8s.io/klog"
) )
......
...@@ -2,14 +2,14 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library") ...@@ -2,14 +2,14 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library( go_library(
name = "go_default_library", name = "go_default_library",
srcs = ["api.pb.go"], srcs = ["install.go"],
importmap = "k8s.io/kubernetes/vendor/github.com/coreos/rkt/api/v1alpha", importmap = "k8s.io/kubernetes/vendor/github.com/google/cadvisor/container/crio/install",
importpath = "github.com/coreos/rkt/api/v1alpha", importpath = "github.com/google/cadvisor/container/crio/install",
visibility = ["//visibility:public"], visibility = ["//visibility:public"],
deps = [ deps = [
"//vendor/github.com/golang/protobuf/proto:go_default_library", "//vendor/github.com/google/cadvisor/container:go_default_library",
"//vendor/golang.org/x/net/context:go_default_library", "//vendor/github.com/google/cadvisor/container/crio:go_default_library",
"//vendor/google.golang.org/grpc:go_default_library", "//vendor/k8s.io/klog:go_default_library",
], ],
) )
......
// Copyright 2019 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.
// The install package registers crio.NewPlugin() as the "crio" container provider when imported
package install
import (
"github.com/google/cadvisor/container"
"github.com/google/cadvisor/container/crio"
"k8s.io/klog"
)
func init() {
err := container.RegisterPlugin("crio", crio.NewPlugin())
if err != nil {
klog.Fatalf("Failed to register crio plugin: %v", err)
}
}
// Copyright 2015 Google Inc. All Rights Reserved. // Copyright 2019 Google Inc. All Rights Reserved.
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
...@@ -12,37 +12,39 @@ ...@@ -12,37 +12,39 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package cloudinfo package crio
import ( import (
"github.com/google/cadvisor/container"
"github.com/google/cadvisor/fs"
info "github.com/google/cadvisor/info/v1" info "github.com/google/cadvisor/info/v1"
"io/ioutil" "github.com/google/cadvisor/watcher"
"strings" "k8s.io/klog"
) )
const ( // NewPlugin returns an implementation of container.Plugin suitable for passing to container.RegisterPlugin()
SysVendorFileName = "/sys/class/dmi/id/sys_vendor" func NewPlugin() container.Plugin {
BiosUUIDFileName = "/sys/class/dmi/id/product_uuid" return &plugin{}
MicrosoftCorporation = "Microsoft Corporation" }
)
func onAzure() bool { type plugin struct{}
data, err := ioutil.ReadFile(SysVendorFileName)
func (p *plugin) InitializeFSContext(context *fs.Context) error {
crioClient, err := Client()
if err != nil { if err != nil {
return false return err
} }
return strings.Contains(string(data), MicrosoftCorporation)
}
// TODO: Implement method. crioInfo, err := crioClient.Info()
func getAzureInstanceType() info.InstanceType {
return info.UnknownInstance
}
func getAzureInstanceID() info.InstanceID {
data, err := ioutil.ReadFile(BiosUUIDFileName)
if err != nil { if err != nil {
return info.UnNamedInstance klog.V(5).Infof("CRI-O not connected: %v", err)
} else {
context.Crio = fs.CrioContext{Root: crioInfo.StorageRoot}
} }
return info.InstanceID(strings.TrimSuffix(string(data), "\n")) return nil
}
func (p *plugin) Register(factory info.MachineInfoFactory, fsInfo fs.FsInfo, includedMetrics container.MetricSet) (watcher.ContainerWatcher, error) {
err := Register(factory, fsInfo, includedMetrics)
return nil, err
} }
...@@ -7,6 +7,7 @@ go_library( ...@@ -7,6 +7,7 @@ go_library(
"docker.go", "docker.go",
"factory.go", "factory.go",
"handler.go", "handler.go",
"plugin.go",
], ],
importmap = "k8s.io/kubernetes/vendor/github.com/google/cadvisor/container/docker", importmap = "k8s.io/kubernetes/vendor/github.com/google/cadvisor/container/docker",
importpath = "github.com/google/cadvisor/container/docker", importpath = "github.com/google/cadvisor/container/docker",
...@@ -24,8 +25,8 @@ go_library( ...@@ -24,8 +25,8 @@ go_library(
"//vendor/github.com/google/cadvisor/fs: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/info/v1:go_default_library",
"//vendor/github.com/google/cadvisor/machine:go_default_library", "//vendor/github.com/google/cadvisor/machine:go_default_library",
"//vendor/github.com/google/cadvisor/manager/watcher:go_default_library",
"//vendor/github.com/google/cadvisor/utils/docker:go_default_library", "//vendor/github.com/google/cadvisor/utils/docker:go_default_library",
"//vendor/github.com/google/cadvisor/watcher:go_default_library",
"//vendor/github.com/google/cadvisor/zfs:go_default_library", "//vendor/github.com/google/cadvisor/zfs:go_default_library",
"//vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs:go_default_library", "//vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs:go_default_library",
"//vendor/github.com/opencontainers/runc/libcontainer/configs:go_default_library", "//vendor/github.com/opencontainers/runc/libcontainer/configs:go_default_library",
...@@ -43,7 +44,10 @@ filegroup( ...@@ -43,7 +44,10 @@ filegroup(
filegroup( filegroup(
name = "all-srcs", name = "all-srcs",
srcs = [":package-srcs"], srcs = [
":package-srcs",
"//vendor/github.com/google/cadvisor/container/docker/install:all-srcs",
],
tags = ["automanaged"], tags = ["automanaged"],
visibility = ["//visibility:public"], visibility = ["//visibility:public"],
) )
...@@ -31,8 +31,8 @@ import ( ...@@ -31,8 +31,8 @@ import (
"github.com/google/cadvisor/fs" "github.com/google/cadvisor/fs"
info "github.com/google/cadvisor/info/v1" info "github.com/google/cadvisor/info/v1"
"github.com/google/cadvisor/machine" "github.com/google/cadvisor/machine"
"github.com/google/cadvisor/manager/watcher"
dockerutil "github.com/google/cadvisor/utils/docker" dockerutil "github.com/google/cadvisor/utils/docker"
"github.com/google/cadvisor/watcher"
"github.com/google/cadvisor/zfs" "github.com/google/cadvisor/zfs"
docker "github.com/docker/docker/client" docker "github.com/docker/docker/client"
......
...@@ -2,15 +2,13 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library") ...@@ -2,15 +2,13 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library( go_library(
name = "go_default_library", name = "go_default_library",
srcs = ["rkt.go"], srcs = ["install.go"],
importmap = "k8s.io/kubernetes/vendor/github.com/google/cadvisor/manager/watcher/rkt", importmap = "k8s.io/kubernetes/vendor/github.com/google/cadvisor/container/docker/install",
importpath = "github.com/google/cadvisor/manager/watcher/rkt", importpath = "github.com/google/cadvisor/container/docker/install",
visibility = ["//visibility:public"], visibility = ["//visibility:public"],
deps = [ deps = [
"//vendor/github.com/coreos/rkt/api/v1alpha:go_default_library", "//vendor/github.com/google/cadvisor/container:go_default_library",
"//vendor/github.com/google/cadvisor/container/rkt:go_default_library", "//vendor/github.com/google/cadvisor/container/docker:go_default_library",
"//vendor/github.com/google/cadvisor/manager/watcher:go_default_library",
"//vendor/golang.org/x/net/context:go_default_library",
"//vendor/k8s.io/klog:go_default_library", "//vendor/k8s.io/klog:go_default_library",
], ],
) )
......
// Copyright 2019 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.
// The install package registers docker.NewPlugin() as the "docker" container provider when imported
package install
import (
"github.com/google/cadvisor/container"
"github.com/google/cadvisor/container/docker"
"k8s.io/klog"
)
func init() {
err := container.RegisterPlugin("docker", docker.NewPlugin())
if err != nil {
klog.Fatalf("Failed to register docker plugin: %v", err)
}
}
// Copyright 2019 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 docker
import (
"time"
"github.com/google/cadvisor/container"
"github.com/google/cadvisor/fs"
info "github.com/google/cadvisor/info/v1"
"github.com/google/cadvisor/watcher"
"golang.org/x/net/context"
"k8s.io/klog"
)
const dockerClientTimeout = 10 * time.Second
// NewPlugin returns an implementation of container.Plugin suitable for passing to container.RegisterPlugin()
func NewPlugin() container.Plugin {
return &plugin{}
}
type plugin struct{}
func (p *plugin) InitializeFSContext(context *fs.Context) error {
SetTimeout(dockerClientTimeout)
// Try to connect to docker indefinitely on startup.
dockerStatus := retryDockerStatus()
context.Docker = fs.DockerContext{
Root: RootDir(),
Driver: dockerStatus.Driver,
DriverStatus: dockerStatus.DriverStatus,
}
return nil
}
func (p *plugin) Register(factory info.MachineInfoFactory, fsInfo fs.FsInfo, includedMetrics container.MetricSet) (watcher.ContainerWatcher, error) {
err := Register(factory, fsInfo, includedMetrics)
return nil, err
}
func retryDockerStatus() info.DockerStatus {
startupTimeout := dockerClientTimeout
maxTimeout := 4 * startupTimeout
for {
ctx, _ := context.WithTimeout(context.Background(), startupTimeout)
dockerStatus, err := StatusWithContext(ctx)
if err == nil {
return dockerStatus
}
switch err {
case context.DeadlineExceeded:
klog.Warningf("Timeout trying to communicate with docker during initialization, will retry")
default:
klog.V(5).Infof("Docker not connected: %v", err)
return info.DockerStatus{}
}
startupTimeout = 2 * startupTimeout
if startupTimeout > maxTimeout {
startupTimeout = maxTimeout
}
}
}
...@@ -18,7 +18,9 @@ import ( ...@@ -18,7 +18,9 @@ import (
"fmt" "fmt"
"sync" "sync"
"github.com/google/cadvisor/manager/watcher" "github.com/google/cadvisor/fs"
info "github.com/google/cadvisor/info/v1"
"github.com/google/cadvisor/watcher"
"k8s.io/klog" "k8s.io/klog"
) )
...@@ -71,6 +73,61 @@ func (ms MetricSet) Add(mk MetricKind) { ...@@ -71,6 +73,61 @@ func (ms MetricSet) Add(mk MetricKind) {
ms[mk] = struct{}{} ms[mk] = struct{}{}
} }
// All registered auth provider plugins.
var pluginsLock sync.Mutex
var plugins = make(map[string]Plugin)
type Plugin interface {
// InitializeFSContext is invoked when populating an fs.Context object for a new manager.
// A returned error here is fatal.
InitializeFSContext(context *fs.Context) error
// Register is invoked when starting a manager. It can optionally return a container watcher.
// A returned error is logged, but is not fatal.
Register(factory info.MachineInfoFactory, fsInfo fs.FsInfo, includedMetrics MetricSet) (watcher.ContainerWatcher, error)
}
func RegisterPlugin(name string, plugin Plugin) error {
pluginsLock.Lock()
defer pluginsLock.Unlock()
if _, found := plugins[name]; found {
return fmt.Errorf("Plugin %q was registered twice", name)
}
klog.V(4).Infof("Registered Plugin %q", name)
plugins[name] = plugin
return nil
}
func InitializeFSContext(context *fs.Context) error {
pluginsLock.Lock()
defer pluginsLock.Unlock()
for name, plugin := range plugins {
err := plugin.InitializeFSContext(context)
if err != nil {
klog.V(5).Infof("Initialization of the %s context failed: %v", name, err)
return err
}
}
return nil
}
func InitializePlugins(factory info.MachineInfoFactory, fsInfo fs.FsInfo, includedMetrics MetricSet) []watcher.ContainerWatcher {
pluginsLock.Lock()
defer pluginsLock.Unlock()
containerWatchers := []watcher.ContainerWatcher{}
for name, plugin := range plugins {
watcher, err := plugin.Register(factory, fsInfo, includedMetrics)
if err != nil {
klog.V(5).Infof("Registration of the %s container factory failed: %v", name, err)
}
if watcher != nil {
containerWatchers = append(containerWatchers, watcher)
}
}
return containerWatchers
}
// TODO(vmarmol): Consider not making this global. // TODO(vmarmol): Consider not making this global.
// Global list of factories. // Global list of factories.
var ( var (
......
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/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",
"//vendor/k8s.io/klog: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"],
)
// 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))),
),
}
})
_, err := mesosClient.getVersion()
if err != nil {
return nil, fmt.Errorf("failed to get version")
}
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) getVersion() (string, error) {
req := calls.NonStreaming(calls.GetVersion())
result, err := self.fetchAndDecode(req)
if err != nil {
return "", fmt.Errorf("failed to get mesos version: %v", err)
}
version := result.GetVersion
if version == nil {
return "", fmt.Errorf("failed to get mesos version")
}
return version.VersionInfo.Version, nil
}
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
if cntrs == nil {
return nil, fmt.Errorf("failed to get mesos containers")
}
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
}
// 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/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"
"k8s.io/klog"
)
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(includedMetrics)
if err != nil {
return fmt.Errorf("failed to get cgroup subsystems: %v", err)
}
klog.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
}
// 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"
"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)
// 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
}
// 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
}
}
if t.Labels != nil {
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
}
...@@ -5,6 +5,7 @@ go_library( ...@@ -5,6 +5,7 @@ go_library(
srcs = [ srcs = [
"factory.go", "factory.go",
"handler.go", "handler.go",
"watcher.go",
], ],
importmap = "k8s.io/kubernetes/vendor/github.com/google/cadvisor/container/raw", importmap = "k8s.io/kubernetes/vendor/github.com/google/cadvisor/container/raw",
importpath = "github.com/google/cadvisor/container/raw", importpath = "github.com/google/cadvisor/container/raw",
...@@ -16,9 +17,10 @@ go_library( ...@@ -16,9 +17,10 @@ go_library(
"//vendor/github.com/google/cadvisor/fs: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/info/v1:go_default_library",
"//vendor/github.com/google/cadvisor/machine:go_default_library", "//vendor/github.com/google/cadvisor/machine:go_default_library",
"//vendor/github.com/google/cadvisor/manager/watcher:go_default_library", "//vendor/github.com/google/cadvisor/watcher:go_default_library",
"//vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs:go_default_library", "//vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs:go_default_library",
"//vendor/github.com/opencontainers/runc/libcontainer/configs:go_default_library", "//vendor/github.com/opencontainers/runc/libcontainer/configs:go_default_library",
"//vendor/github.com/sigma/go-inotify:go_default_library",
"//vendor/k8s.io/klog:go_default_library", "//vendor/k8s.io/klog:go_default_library",
], ],
) )
......
...@@ -24,7 +24,7 @@ import ( ...@@ -24,7 +24,7 @@ import (
"github.com/google/cadvisor/container/libcontainer" "github.com/google/cadvisor/container/libcontainer"
"github.com/google/cadvisor/fs" "github.com/google/cadvisor/fs"
info "github.com/google/cadvisor/info/v1" info "github.com/google/cadvisor/info/v1"
watch "github.com/google/cadvisor/manager/watcher" watch "github.com/google/cadvisor/watcher"
"k8s.io/klog" "k8s.io/klog"
) )
......
...@@ -25,7 +25,7 @@ import ( ...@@ -25,7 +25,7 @@ import (
"github.com/google/cadvisor/container/common" "github.com/google/cadvisor/container/common"
"github.com/google/cadvisor/container/libcontainer" "github.com/google/cadvisor/container/libcontainer"
"github.com/google/cadvisor/manager/watcher" "github.com/google/cadvisor/watcher"
inotify "github.com/sigma/go-inotify" inotify "github.com/sigma/go-inotify"
"k8s.io/klog" "k8s.io/klog"
......
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"client.go",
"factory.go",
"handler.go",
"helpers.go",
],
importmap = "k8s.io/kubernetes/vendor/github.com/google/cadvisor/container/rkt",
importpath = "github.com/google/cadvisor/container/rkt",
visibility = ["//visibility:public"],
deps = [
"//vendor/github.com/blang/semver:go_default_library",
"//vendor/github.com/coreos/rkt/api/v1alpha: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/opencontainers/runc/libcontainer/cgroups/fs:go_default_library",
"//vendor/github.com/opencontainers/runc/libcontainer/configs:go_default_library",
"//vendor/golang.org/x/net/context:go_default_library",
"//vendor/google.golang.org/grpc:go_default_library",
"//vendor/k8s.io/klog: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"],
)
// Copyright 2016 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package rkt
import (
"fmt"
"net"
"sync"
"time"
"github.com/blang/semver"
rktapi "github.com/coreos/rkt/api/v1alpha"
"golang.org/x/net/context"
"google.golang.org/grpc"
)
const (
defaultRktAPIServiceAddr = "localhost:15441"
timeout = 2 * time.Second
minimumRktBinVersion = "1.6.0"
)
var (
rktClient rktapi.PublicAPIClient
rktClientErr error
once sync.Once
)
func Client() (rktapi.PublicAPIClient, error) {
once.Do(func() {
conn, err := net.DialTimeout("tcp", defaultRktAPIServiceAddr, timeout)
if err != nil {
rktClient = nil
rktClientErr = fmt.Errorf("rkt: cannot tcp Dial rkt api service: %v", err)
return
}
conn.Close()
apisvcConn, err := grpc.Dial(defaultRktAPIServiceAddr, grpc.WithInsecure(), grpc.WithTimeout(timeout))
if err != nil {
rktClient = nil
rktClientErr = fmt.Errorf("rkt: cannot grpc Dial rkt api service: %v", err)
return
}
apisvc := rktapi.NewPublicAPIClient(apisvcConn)
resp, err := apisvc.GetInfo(context.Background(), &rktapi.GetInfoRequest{})
if err != nil {
rktClientErr = fmt.Errorf("rkt: GetInfo() failed: %v", err)
return
}
binVersion, err := semver.Make(resp.Info.RktVersion)
if err != nil {
rktClientErr = fmt.Errorf("rkt: couldn't parse RtVersion: %v", err)
return
}
if binVersion.LT(semver.MustParse(minimumRktBinVersion)) {
rktClientErr = fmt.Errorf("rkt: binary version is too old(%v), requires at least %v", resp.Info.RktVersion, minimumRktBinVersion)
return
}
rktClient = apisvc
})
return rktClient, rktClientErr
}
func RktPath() (string, error) {
client, err := Client()
if err != nil {
return "", err
}
resp, err := client.GetInfo(context.Background(), &rktapi.GetInfoRequest{})
if err != nil {
return "", fmt.Errorf("couldn't GetInfo from rkt api service: %v", err)
}
return resp.Info.GlobalFlags.Dir, nil
}
// Copyright 2016 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package rkt
import (
"fmt"
"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"
"k8s.io/klog"
)
const RktNamespace = "rkt"
type rktFactory struct {
machineInfoFactory info.MachineInfoFactory
cgroupSubsystems *libcontainer.CgroupSubsystems
fsInfo fs.FsInfo
includedMetrics container.MetricSet
rktPath string
}
func (self *rktFactory) String() string {
return "rkt"
}
func (self *rktFactory) NewContainerHandler(name string, inHostNamespace bool) (container.ContainerHandler, error) {
client, err := Client()
if err != nil {
return nil, err
}
rootFs := "/"
if !inHostNamespace {
rootFs = "/rootfs"
}
return newRktContainerHandler(name, client, self.rktPath, self.cgroupSubsystems, self.machineInfoFactory, self.fsInfo, rootFs, self.includedMetrics)
}
func (self *rktFactory) CanHandleAndAccept(name string) (bool, bool, error) {
accept, err := verifyPod(name)
return accept, accept, err
}
func (self *rktFactory) DebugInfo() map[string][]string {
return map[string][]string{}
}
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)
}
rktPath, err := RktPath()
if err != nil {
return fmt.Errorf("unable to get the RktPath variable %v", err)
}
cgroupSubsystems, err := libcontainer.GetCgroupSubsystems(includedMetrics)
if err != nil {
return fmt.Errorf("failed to get cgroup subsystems: %v", err)
}
if len(cgroupSubsystems.Mounts) == 0 {
return fmt.Errorf("failed to find supported cgroup mounts for the raw factory")
}
klog.V(1).Infof("Registering Rkt factory")
factory := &rktFactory{
machineInfoFactory: machineInfoFactory,
fsInfo: fsInfo,
cgroupSubsystems: &cgroupSubsystems,
includedMetrics: includedMetrics,
rktPath: rktPath,
}
container.RegisterContainerHandlerFactory(factory, []watcher.ContainerWatchSource{watcher.Rkt})
return nil
}
// Copyright 2016 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Handler for "rkt" containers.
package rkt
import (
"fmt"
"os"
rktapi "github.com/coreos/rkt/api/v1alpha"
"github.com/google/cadvisor/container"
"github.com/google/cadvisor/container/common"
"github.com/google/cadvisor/container/libcontainer"
"github.com/google/cadvisor/fs"
info "github.com/google/cadvisor/info/v1"
"golang.org/x/net/context"
cgroupfs "github.com/opencontainers/runc/libcontainer/cgroups/fs"
"github.com/opencontainers/runc/libcontainer/configs"
"k8s.io/klog"
)
type rktContainerHandler struct {
machineInfoFactory info.MachineInfoFactory
// Absolute path to the cgroup hierarchies of this container.
// (e.g.: "cpu" -> "/sys/fs/cgroup/cpu/test")
cgroupPaths map[string]string
fsInfo fs.FsInfo
isPod bool
rootfsStorageDir string
// Filesystem handler.
fsHandler common.FsHandler
includedMetrics container.MetricSet
apiPod *rktapi.Pod
labels map[string]string
reference info.ContainerReference
libcontainerHandler *libcontainer.Handler
}
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
apiPod := &rktapi.Pod{}
parsed, err := parseName(name)
if err != nil {
return nil, fmt.Errorf("this should be impossible!, new handler failing, but factory allowed, name = %s", name)
}
// rktnetes uses containerID: rkt://fff40827-b994-4e3a-8f88-6427c2c8a5ac:nginx
if parsed.Container == "" {
isPod = true
aliases = append(aliases, "rkt://"+parsed.Pod)
} else {
aliases = append(aliases, "rkt://"+parsed.Pod+":"+parsed.Container)
}
pid := os.Getpid()
labels := make(map[string]string)
resp, err := rktClient.InspectPod(context.Background(), &rktapi.InspectPodRequest{
Id: parsed.Pod,
})
if err != nil {
return nil, err
}
annotations := resp.Pod.Annotations
if parsed.Container != "" { // As not empty string, an App container
if contAnnotations, ok := findAnnotations(resp.Pod.Apps, parsed.Container); !ok {
klog.Warningf("couldn't find app %v in pod", parsed.Container)
} else {
annotations = append(annotations, contAnnotations...)
}
} else { // The Pod container
pid = int(resp.Pod.Pid)
apiPod = resp.Pod
}
labels = createLabels(annotations)
cgroupPaths := common.MakeCgroupPaths(cgroupSubsystems.MountPoints, name)
// Generate the equivalent cgroup manager for this container.
cgroupManager := &cgroupfs.Manager{
Cgroups: &configs.Cgroup{
Name: name,
},
Paths: cgroupPaths,
}
libcontainerHandler := libcontainer.NewHandler(cgroupManager, rootFs, pid, includedMetrics)
rootfsStorageDir := getRootFs(rktPath, parsed)
containerReference := info.ContainerReference{
Name: name,
Aliases: aliases,
Namespace: RktNamespace,
}
handler := &rktContainerHandler{
machineInfoFactory: machineInfoFactory,
cgroupPaths: cgroupPaths,
fsInfo: fsInfo,
isPod: isPod,
rootfsStorageDir: rootfsStorageDir,
includedMetrics: includedMetrics,
apiPod: apiPod,
labels: labels,
reference: containerReference,
libcontainerHandler: libcontainerHandler,
}
if includedMetrics.Has(container.DiskUsageMetrics) {
handler.fsHandler = common.NewFsHandler(common.DefaultPeriod, rootfsStorageDir, "", fsInfo)
}
return handler, nil
}
func findAnnotations(apps []*rktapi.App, container string) ([]*rktapi.KeyValue, bool) {
for _, app := range apps {
if app.Name == container {
return app.Annotations, true
}
}
return nil, false
}
func createLabels(annotations []*rktapi.KeyValue) map[string]string {
labels := make(map[string]string)
for _, kv := range annotations {
labels[kv.Key] = kv.Value
}
return labels
}
func (handler *rktContainerHandler) ContainerReference() (info.ContainerReference, error) {
return handler.reference, nil
}
func (handler *rktContainerHandler) Start() {
handler.fsHandler.Start()
}
func (handler *rktContainerHandler) Cleanup() {
handler.fsHandler.Stop()
}
func (handler *rktContainerHandler) GetSpec() (info.ContainerSpec, error) {
hasNetwork := handler.isPod && handler.includedMetrics.Has(container.NetworkUsageMetrics)
hasFilesystem := handler.includedMetrics.Has(container.DiskUsageMetrics)
spec, err := common.GetSpec(handler.cgroupPaths, handler.machineInfoFactory, hasNetwork, hasFilesystem)
spec.Labels = handler.labels
return spec, err
}
func (handler *rktContainerHandler) getFsStats(stats *info.ContainerStats) error {
mi, err := handler.machineInfoFactory.GetMachineInfo()
if err != nil {
return err
}
if handler.includedMetrics.Has(container.DiskIOMetrics) {
common.AssignDeviceNamesToDiskStats((*common.MachineInfoNamer)(mi), &stats.DiskIo)
}
if !handler.includedMetrics.Has(container.DiskUsageMetrics) {
return nil
}
deviceInfo, err := handler.fsInfo.GetDirFsDevice(handler.rootfsStorageDir)
if err != nil {
return err
}
var limit uint64 = 0
// Use capacity as limit.
for _, fs := range mi.Filesystems {
if fs.Device == deviceInfo.Device {
limit = fs.Capacity
break
}
}
fsStat := info.FsStats{Device: deviceInfo.Device, Limit: limit}
usage := handler.fsHandler.Usage()
fsStat.BaseUsage = usage.BaseUsageBytes
fsStat.Usage = usage.TotalUsageBytes
fsStat.Inodes = usage.InodeUsage
stats.Filesystem = append(stats.Filesystem, fsStat)
return nil
}
func (handler *rktContainerHandler) GetStats() (*info.ContainerStats, error) {
stats, err := handler.libcontainerHandler.GetStats()
if err != nil {
return stats, err
}
// Get filesystem stats.
err = handler.getFsStats(stats)
if err != nil {
return stats, err
}
return stats, nil
}
func (self *rktContainerHandler) GetContainerIPAddress() string {
// attempt to return the ip address of the pod
// if a specific ip address of the pod could not be determined, return the system ip address
if self.isPod && len(self.apiPod.Networks) > 0 {
address := self.apiPod.Networks[0].Ipv4
if address != "" {
return address
} else {
return self.apiPod.Networks[0].Ipv6
}
} else {
return "127.0.0.1"
}
}
func (handler *rktContainerHandler) GetCgroupPath(resource string) (string, error) {
path, ok := handler.cgroupPaths[resource]
if !ok {
return "", fmt.Errorf("could not find path for resource %q for container %q\n", resource, handler.reference.Name)
}
return path, nil
}
func (handler *rktContainerHandler) GetContainerLabels() map[string]string {
return handler.labels
}
func (handler *rktContainerHandler) ListContainers(listType container.ListType) ([]info.ContainerReference, error) {
return common.ListContainers(handler.reference.Name, handler.cgroupPaths, listType)
}
func (handler *rktContainerHandler) ListProcesses(listType container.ListType) ([]int, error) {
return handler.libcontainerHandler.GetProcesses()
}
func (handler *rktContainerHandler) Exists() bool {
return common.CgroupExists(handler.cgroupPaths)
}
func (handler *rktContainerHandler) Type() container.ContainerType {
return container.ContainerTypeRkt
}
// Copyright 2016 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package rkt
import (
"fmt"
"io/ioutil"
"path"
"strings"
rktapi "github.com/coreos/rkt/api/v1alpha"
"golang.org/x/net/context"
"k8s.io/klog"
)
type parsedName struct {
Pod string
Container string
}
func verifyPod(name string) (bool, error) {
pod, err := cgroupToPod(name)
if err != nil || pod == nil {
return false, err
}
// Anything handler can handle is also accepted.
// Accept cgroups that are sub the pod cgroup, except "system.slice"
// - "system.slice" doesn't contain any processes itself
accept := !strings.HasSuffix(name, "/system.slice")
return accept, nil
}
func cgroupToPod(name string) (*rktapi.Pod, error) {
rktClient, err := Client()
if err != nil {
return nil, fmt.Errorf("couldn't get rkt api service: %v", err)
}
resp, err := rktClient.ListPods(context.Background(), &rktapi.ListPodsRequest{
Filters: []*rktapi.PodFilter{
{
States: []rktapi.PodState{rktapi.PodState_POD_STATE_RUNNING},
PodSubCgroups: []string{name},
},
},
})
if err != nil {
return nil, fmt.Errorf("failed to list pods: %v", err)
}
if len(resp.Pods) == 0 {
return nil, nil
}
if len(resp.Pods) != 1 {
return nil, fmt.Errorf("returned %d (expected 1) pods for cgroup %v", len(resp.Pods), name)
}
return resp.Pods[0], nil
}
/* Parse cgroup name into a pod/container name struct
Example cgroup fs name
pod - /machine.slice/machine-rkt\\x2df556b64a\\x2d17a7\\x2d47d7\\x2d93ec\\x2def2275c3d67e.scope/
or /system.slice/k8s-..../
container under pod - /machine.slice/machine-rkt\\x2df556b64a\\x2d17a7\\x2d47d7\\x2d93ec\\x2def2275c3d67e.scope/system.slice/alpine-sh.service
or /system.slice/k8s-..../system.slice/pause.service
*/
func parseName(name string) (*parsedName, error) {
pod, err := cgroupToPod(name)
if err != nil {
return nil, fmt.Errorf("parseName: couldn't convert %v to a rkt pod: %v", name, err)
}
if pod == nil {
return nil, fmt.Errorf("parseName: didn't return a pod for %v", name)
}
splits := strings.Split(name, "/")
parsed := &parsedName{}
if len(splits) == 3 || len(splits) == 5 {
parsed.Pod = pod.Id
if len(splits) == 5 {
parsed.Container = strings.Replace(splits[4], ".service", "", -1)
}
return parsed, nil
}
return nil, fmt.Errorf("%s not handled by rkt handler", name)
}
// Gets a Rkt container's overlay upper dir
func getRootFs(root string, parsed *parsedName) string {
/* Example of where it stores the upper dir key
for container
/var/lib/rkt/pods/run/bc793ec6-c48f-4480-99b5-6bec16d52210/appsinfo/alpine-sh/treeStoreID
for pod
/var/lib/rkt/pods/run/f556b64a-17a7-47d7-93ec-ef2275c3d67e/stage1TreeStoreID
*/
var tree string
if parsed.Container == "" {
tree = path.Join(root, "pods/run", parsed.Pod, "stage1TreeStoreID")
} else {
tree = path.Join(root, "pods/run", parsed.Pod, "appsinfo", parsed.Container, "treeStoreID")
}
bytes, err := ioutil.ReadFile(tree)
if err != nil {
klog.Errorf("ReadFile failed, couldn't read %v to get upper dir: %v", tree, err)
return ""
}
s := string(bytes)
/* Example of where the upper dir is stored via key read above
/var/lib/rkt/pods/run/bc793ec6-c48f-4480-99b5-6bec16d52210/overlay/deps-sha512-82a099e560a596662b15dec835e9adabab539cad1f41776a30195a01a8f2f22b/
*/
return path.Join(root, "pods/run", parsed.Pod, "overlay", s)
}
...@@ -2,7 +2,10 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library") ...@@ -2,7 +2,10 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library( go_library(
name = "go_default_library", name = "go_default_library",
srcs = ["factory.go"], srcs = [
"factory.go",
"plugin.go",
],
importmap = "k8s.io/kubernetes/vendor/github.com/google/cadvisor/container/systemd", importmap = "k8s.io/kubernetes/vendor/github.com/google/cadvisor/container/systemd",
importpath = "github.com/google/cadvisor/container/systemd", importpath = "github.com/google/cadvisor/container/systemd",
visibility = ["//visibility:public"], visibility = ["//visibility:public"],
...@@ -10,7 +13,7 @@ go_library( ...@@ -10,7 +13,7 @@ go_library(
"//vendor/github.com/google/cadvisor/container:go_default_library", "//vendor/github.com/google/cadvisor/container:go_default_library",
"//vendor/github.com/google/cadvisor/fs: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/info/v1:go_default_library",
"//vendor/github.com/google/cadvisor/manager/watcher:go_default_library", "//vendor/github.com/google/cadvisor/watcher:go_default_library",
"//vendor/k8s.io/klog:go_default_library", "//vendor/k8s.io/klog:go_default_library",
], ],
) )
...@@ -24,7 +27,10 @@ filegroup( ...@@ -24,7 +27,10 @@ filegroup(
filegroup( filegroup(
name = "all-srcs", name = "all-srcs",
srcs = [":package-srcs"], srcs = [
":package-srcs",
"//vendor/github.com/google/cadvisor/container/systemd/install:all-srcs",
],
tags = ["automanaged"], tags = ["automanaged"],
visibility = ["//visibility:public"], visibility = ["//visibility:public"],
) )
...@@ -21,7 +21,7 @@ import ( ...@@ -21,7 +21,7 @@ import (
"github.com/google/cadvisor/container" "github.com/google/cadvisor/container"
"github.com/google/cadvisor/fs" "github.com/google/cadvisor/fs"
info "github.com/google/cadvisor/info/v1" info "github.com/google/cadvisor/info/v1"
"github.com/google/cadvisor/manager/watcher" "github.com/google/cadvisor/watcher"
"k8s.io/klog" "k8s.io/klog"
) )
......
...@@ -2,10 +2,15 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library") ...@@ -2,10 +2,15 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library( go_library(
name = "go_default_library", name = "go_default_library",
srcs = ["jitter.go"], srcs = ["install.go"],
importmap = "k8s.io/kubernetes/vendor/github.com/Rican7/retry/jitter", importmap = "k8s.io/kubernetes/vendor/github.com/google/cadvisor/container/systemd/install",
importpath = "github.com/Rican7/retry/jitter", importpath = "github.com/google/cadvisor/container/systemd/install",
visibility = ["//visibility:public"], visibility = ["//visibility:public"],
deps = [
"//vendor/github.com/google/cadvisor/container:go_default_library",
"//vendor/github.com/google/cadvisor/container/systemd:go_default_library",
"//vendor/k8s.io/klog:go_default_library",
],
) )
filegroup( filegroup(
......
// Copyright 2019 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.
// The install package registers systemd.NewPlugin() as the "systemd" container provider when imported
package install
import (
"github.com/google/cadvisor/container"
"github.com/google/cadvisor/container/systemd"
"k8s.io/klog"
)
func init() {
err := container.RegisterPlugin("systemd", systemd.NewPlugin())
if err != nil {
klog.Fatalf("Failed to register systemd plugin: %v", err)
}
}
// Copyright 2019 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 systemd
import (
"github.com/google/cadvisor/container"
"github.com/google/cadvisor/fs"
info "github.com/google/cadvisor/info/v1"
"github.com/google/cadvisor/watcher"
)
// NewPlugin returns an implementation of container.Plugin suitable for passing to container.RegisterPlugin()
func NewPlugin() container.Plugin {
return &plugin{}
}
type plugin struct{}
func (p *plugin) InitializeFSContext(context *fs.Context) error {
return nil
}
func (p *plugin) Register(factory info.MachineInfoFactory, fsInfo fs.FsInfo, includedMetrics container.MetricSet) (watcher.ContainerWatcher, error) {
err := Register(factory, fsInfo, includedMetrics)
return nil, err
}
...@@ -91,23 +91,6 @@ type RealFsInfo struct { ...@@ -91,23 +91,6 @@ type RealFsInfo struct {
fsUUIDToDeviceName map[string]string fsUUIDToDeviceName map[string]string
} }
type Context struct {
// docker root directory.
Docker DockerContext
RktPath string
Crio CrioContext
}
type DockerContext struct {
Root string
Driver string
DriverStatus map[string]string
}
type CrioContext struct {
Root string
}
func NewFsInfo(context Context) (FsInfo, error) { func NewFsInfo(context Context) (FsInfo, error) {
mounts, err := mount.GetMounts(nil) mounts, err := mount.GetMounts(nil)
if err != nil { if err != nil {
...@@ -410,8 +393,13 @@ func (self *RealFsInfo) GetFsInfoForPath(mountSet map[string]struct{}) ([]Fs, er ...@@ -410,8 +393,13 @@ func (self *RealFsInfo) GetFsInfoForPath(mountSet map[string]struct{}) ([]Fs, er
klog.V(5).Infof("got devicemapper fs capacity stats: capacity: %v free: %v available: %v:", fs.Capacity, fs.Free, fs.Available) klog.V(5).Infof("got devicemapper fs capacity stats: capacity: %v free: %v available: %v:", fs.Capacity, fs.Free, fs.Available)
fs.Type = DeviceMapper fs.Type = DeviceMapper
case ZFS.String(): case ZFS.String():
fs.Capacity, fs.Free, fs.Available, err = getZfstats(device) if _, devzfs := os.Stat("/dev/zfs"); os.IsExist(devzfs) {
fs.Type = ZFS fs.Capacity, fs.Free, fs.Available, err = getZfstats(device)
fs.Type = ZFS
break
}
// if /dev/zfs is not present default to VFS
fallthrough
default: default:
var inodes, inodesFree uint64 var inodes, inodesFree uint64
if utils.FileExists(partition.mountpoint) { if utils.FileExists(partition.mountpoint) {
......
...@@ -18,6 +18,23 @@ import ( ...@@ -18,6 +18,23 @@ import (
"errors" "errors"
) )
type Context struct {
// docker root directory.
Docker DockerContext
RktPath string
Crio CrioContext
}
type DockerContext struct {
Root string
Driver string
DriverStatus map[string]string
}
type CrioContext struct {
Root string
}
type DeviceInfo struct { type DeviceInfo struct {
Device string Device string
Major uint Major uint
......
...@@ -15,28 +15,20 @@ go_library( ...@@ -15,28 +15,20 @@ go_library(
"//vendor/github.com/google/cadvisor/cache/memory:go_default_library", "//vendor/github.com/google/cadvisor/cache/memory:go_default_library",
"//vendor/github.com/google/cadvisor/collector:go_default_library", "//vendor/github.com/google/cadvisor/collector:go_default_library",
"//vendor/github.com/google/cadvisor/container:go_default_library", "//vendor/github.com/google/cadvisor/container:go_default_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/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/raw:go_default_library",
"//vendor/github.com/google/cadvisor/container/rkt:go_default_library",
"//vendor/github.com/google/cadvisor/container/systemd:go_default_library",
"//vendor/github.com/google/cadvisor/events:go_default_library", "//vendor/github.com/google/cadvisor/events:go_default_library",
"//vendor/github.com/google/cadvisor/fs: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/info/v1:go_default_library",
"//vendor/github.com/google/cadvisor/info/v2:go_default_library", "//vendor/github.com/google/cadvisor/info/v2:go_default_library",
"//vendor/github.com/google/cadvisor/machine:go_default_library", "//vendor/github.com/google/cadvisor/machine:go_default_library",
"//vendor/github.com/google/cadvisor/manager/watcher:go_default_library",
"//vendor/github.com/google/cadvisor/manager/watcher/raw:go_default_library",
"//vendor/github.com/google/cadvisor/manager/watcher/rkt:go_default_library",
"//vendor/github.com/google/cadvisor/summary:go_default_library", "//vendor/github.com/google/cadvisor/summary:go_default_library",
"//vendor/github.com/google/cadvisor/utils/cpuload:go_default_library", "//vendor/github.com/google/cadvisor/utils/cpuload:go_default_library",
"//vendor/github.com/google/cadvisor/utils/oomparser:go_default_library", "//vendor/github.com/google/cadvisor/utils/oomparser:go_default_library",
"//vendor/github.com/google/cadvisor/utils/sysfs:go_default_library", "//vendor/github.com/google/cadvisor/utils/sysfs:go_default_library",
"//vendor/github.com/google/cadvisor/version:go_default_library", "//vendor/github.com/google/cadvisor/version:go_default_library",
"//vendor/github.com/google/cadvisor/watcher:go_default_library",
"//vendor/github.com/opencontainers/runc/libcontainer/cgroups:go_default_library", "//vendor/github.com/opencontainers/runc/libcontainer/cgroups:go_default_library",
"//vendor/golang.org/x/net/context:go_default_library",
"//vendor/k8s.io/klog:go_default_library", "//vendor/k8s.io/klog:go_default_library",
"//vendor/k8s.io/utils/clock:go_default_library", "//vendor/k8s.io/utils/clock:go_default_library",
], ],
...@@ -51,10 +43,7 @@ filegroup( ...@@ -51,10 +43,7 @@ filegroup(
filegroup( filegroup(
name = "all-srcs", name = "all-srcs",
srcs = [ srcs = [":package-srcs"],
":package-srcs",
"//vendor/github.com/google/cadvisor/manager/watcher:all-srcs",
],
tags = ["automanaged"], tags = ["automanaged"],
visibility = ["//visibility:public"], visibility = ["//visibility:public"],
) )
...@@ -30,27 +30,19 @@ import ( ...@@ -30,27 +30,19 @@ import (
"github.com/google/cadvisor/cache/memory" "github.com/google/cadvisor/cache/memory"
"github.com/google/cadvisor/collector" "github.com/google/cadvisor/collector"
"github.com/google/cadvisor/container" "github.com/google/cadvisor/container"
"github.com/google/cadvisor/container/containerd"
"github.com/google/cadvisor/container/crio"
"github.com/google/cadvisor/container/docker" "github.com/google/cadvisor/container/docker"
"github.com/google/cadvisor/container/mesos"
"github.com/google/cadvisor/container/raw" "github.com/google/cadvisor/container/raw"
"github.com/google/cadvisor/container/rkt"
"github.com/google/cadvisor/container/systemd"
"github.com/google/cadvisor/events" "github.com/google/cadvisor/events"
"github.com/google/cadvisor/fs" "github.com/google/cadvisor/fs"
info "github.com/google/cadvisor/info/v1" info "github.com/google/cadvisor/info/v1"
"github.com/google/cadvisor/info/v2" "github.com/google/cadvisor/info/v2"
"github.com/google/cadvisor/machine" "github.com/google/cadvisor/machine"
"github.com/google/cadvisor/manager/watcher"
rawwatcher "github.com/google/cadvisor/manager/watcher/raw"
rktwatcher "github.com/google/cadvisor/manager/watcher/rkt"
"github.com/google/cadvisor/utils/oomparser" "github.com/google/cadvisor/utils/oomparser"
"github.com/google/cadvisor/utils/sysfs" "github.com/google/cadvisor/utils/sysfs"
"github.com/google/cadvisor/version" "github.com/google/cadvisor/version"
"github.com/google/cadvisor/watcher"
"github.com/opencontainers/runc/libcontainer/cgroups" "github.com/opencontainers/runc/libcontainer/cgroups"
"golang.org/x/net/context"
"k8s.io/klog" "k8s.io/klog"
"k8s.io/utils/clock" "k8s.io/utils/clock"
) )
...@@ -62,8 +54,6 @@ var eventStorageAgeLimit = flag.String("event_storage_age_limit", "default=24h", ...@@ -62,8 +54,6 @@ var eventStorageAgeLimit = flag.String("event_storage_age_limit", "default=24h",
var eventStorageEventLimit = flag.String("event_storage_event_limit", "default=100000", "Max number of events to store (per type). Value is a comma separated list of key values, where the keys are event types (e.g.: creation, oom) or \"default\" and the value is an integer. Default is applied to all non-specified event types") var eventStorageEventLimit = flag.String("event_storage_event_limit", "default=100000", "Max number of events to store (per type). Value is a comma separated list of key values, where the keys are event types (e.g.: creation, oom) or \"default\" and the value is an integer. Default is applied to all non-specified event types")
var applicationMetricsCountLimit = flag.Int("application_metrics_count_limit", 100, "Max number of application metrics to store (per container)") var applicationMetricsCountLimit = flag.Int("application_metrics_count_limit", 100, "Max number of application metrics to store (per container)")
const dockerClientTimeout = 10 * time.Second
// The Manager interface defines operations for starting a manager and getting // The Manager interface defines operations for starting a manager and getting
// container and machine information. // container and machine information.
type Manager interface { type Manager interface {
...@@ -155,40 +145,12 @@ func New(memoryCache *memory.InMemoryCache, sysfs sysfs.SysFs, maxHousekeepingIn ...@@ -155,40 +145,12 @@ func New(memoryCache *memory.InMemoryCache, sysfs sysfs.SysFs, maxHousekeepingIn
} }
klog.V(2).Infof("cAdvisor running in container: %q", selfContainer) klog.V(2).Infof("cAdvisor running in container: %q", selfContainer)
var ( context := fs.Context{}
dockerStatus info.DockerStatus
rktPath string
)
docker.SetTimeout(dockerClientTimeout)
// Try to connect to docker indefinitely on startup.
dockerStatus = retryDockerStatus()
if tmpRktPath, err := rkt.RktPath(); err != nil { if err := container.InitializeFSContext(&context); err != nil {
klog.V(5).Infof("Rkt not connected: %v", err)
} else {
rktPath = tmpRktPath
}
crioClient, err := crio.Client()
if err != nil {
return nil, err return nil, err
} }
crioInfo, err := crioClient.Info()
if err != nil {
klog.V(5).Infof("CRI-O not connected: %v", err)
}
context := fs.Context{
Docker: fs.DockerContext{
Root: docker.RootDir(),
Driver: dockerStatus.Driver,
DriverStatus: dockerStatus.DriverStatus,
},
RktPath: rktPath,
Crio: fs.CrioContext{
Root: crioInfo.StorageRoot,
},
}
fsInfo, err := fs.NewFsInfo(context) fsInfo, err := fs.NewFsInfo(context)
if err != nil { if err != nil {
return nil, err return nil, err
...@@ -240,31 +202,6 @@ func New(memoryCache *memory.InMemoryCache, sysfs sysfs.SysFs, maxHousekeepingIn ...@@ -240,31 +202,6 @@ func New(memoryCache *memory.InMemoryCache, sysfs sysfs.SysFs, maxHousekeepingIn
return newManager, nil return newManager, nil
} }
func retryDockerStatus() info.DockerStatus {
startupTimeout := dockerClientTimeout
maxTimeout := 4 * startupTimeout
for {
ctx, _ := context.WithTimeout(context.Background(), startupTimeout)
dockerStatus, err := docker.StatusWithContext(ctx)
if err == nil {
return dockerStatus
}
switch err {
case context.DeadlineExceeded:
klog.Warningf("Timeout trying to communicate with docker during initialization, will retry")
default:
klog.V(5).Infof("Docker not connected: %v", err)
return info.DockerStatus{}
}
startupTimeout = 2 * startupTimeout
if startupTimeout > maxTimeout {
startupTimeout = maxTimeout
}
}
}
// A namespaced container name. // A namespaced container name.
type namespacedContainerName struct { type namespacedContainerName struct {
// The namespace of the container. Can be empty for the root namespace. // The namespace of the container. Can be empty for the root namespace.
...@@ -300,48 +237,14 @@ type manager struct { ...@@ -300,48 +237,14 @@ type manager struct {
// Start the container manager. // Start the container manager.
func (self *manager) Start() error { func (self *manager) Start() error {
err := docker.Register(self, self.fsInfo, self.includedMetrics) self.containerWatchers = container.InitializePlugins(self, self.fsInfo, self.includedMetrics)
if err != nil {
klog.V(5).Infof("Registration of the Docker container factory failed: %v.", err)
}
err = rkt.Register(self, self.fsInfo, self.includedMetrics)
if err != nil {
klog.V(5).Infof("Registration of the rkt container factory failed: %v", err)
} else {
watcher, err := rktwatcher.NewRktContainerWatcher()
if err != nil {
return err
}
self.containerWatchers = append(self.containerWatchers, watcher)
}
err = containerd.Register(self, self.fsInfo, self.includedMetrics)
if err != nil {
klog.V(5).Infof("Registration of the containerd container factory failed: %v", err)
}
err = crio.Register(self, self.fsInfo, self.includedMetrics)
if err != nil {
klog.V(5).Infof("Registration of the crio container factory failed: %v", err)
}
err = mesos.Register(self, self.fsInfo, self.includedMetrics)
if err != nil {
klog.V(5).Infof("Registration of the mesos container factory failed: %v", err)
}
err = systemd.Register(self, self.fsInfo, self.includedMetrics)
if err != nil {
klog.V(5).Infof("Registration of the systemd container factory failed: %v", err)
}
err = raw.Register(self, self.fsInfo, self.includedMetrics, self.rawContainerCgroupPathPrefixWhiteList) err := raw.Register(self, self.fsInfo, self.includedMetrics, self.rawContainerCgroupPathPrefixWhiteList)
if err != nil { if err != nil {
klog.Errorf("Registration of the raw container factory failed: %v", err) klog.Errorf("Registration of the raw container factory failed: %v", err)
} }
rawWatcher, err := rawwatcher.NewRawContainerWatcher() rawWatcher, err := raw.NewRawContainerWatcher()
if err != nil { if err != nil {
return err return err
} }
......
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = ["watcher.go"],
importmap = "k8s.io/kubernetes/vendor/github.com/google/cadvisor/manager/watcher",
importpath = "github.com/google/cadvisor/manager/watcher",
visibility = ["//visibility:public"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//vendor/github.com/google/cadvisor/manager/watcher/raw:all-srcs",
"//vendor/github.com/google/cadvisor/manager/watcher/rkt:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = ["raw.go"],
importmap = "k8s.io/kubernetes/vendor/github.com/google/cadvisor/manager/watcher/raw",
importpath = "github.com/google/cadvisor/manager/watcher/raw",
visibility = ["//visibility:public"],
deps = [
"//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/manager/watcher:go_default_library",
"//vendor/github.com/sigma/go-inotify:go_default_library",
"//vendor/k8s.io/klog: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"],
)
// Copyright 2016 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Package rkt implements the watcher interface for rkt
package rkt
import (
"path/filepath"
"time"
"github.com/google/cadvisor/container/rkt"
"github.com/google/cadvisor/manager/watcher"
rktapi "github.com/coreos/rkt/api/v1alpha"
"golang.org/x/net/context"
"k8s.io/klog"
)
type rktContainerWatcher struct {
// Signal for watcher thread to stop.
stopWatcher chan error
}
func NewRktContainerWatcher() (watcher.ContainerWatcher, error) {
watcher := &rktContainerWatcher{
stopWatcher: make(chan error),
}
return watcher, nil
}
func (self *rktContainerWatcher) Start(events chan watcher.ContainerEvent) error {
go self.detectRktContainers(events)
return nil
}
func (self *rktContainerWatcher) Stop() error {
// Rendezvous with the watcher thread.
self.stopWatcher <- nil
return nil
}
func (self *rktContainerWatcher) detectRktContainers(events chan watcher.ContainerEvent) {
klog.V(1).Infof("Starting detectRktContainers thread")
ticker := time.Tick(10 * time.Second)
curpods := make(map[string]*rktapi.Pod)
for {
select {
case <-ticker:
pods, err := listRunningPods()
if err != nil {
klog.Errorf("detectRktContainers: listRunningPods failed: %v", err)
continue
}
curpods = self.syncRunningPods(pods, events, curpods)
case <-self.stopWatcher:
klog.Infof("Exiting rktContainer Thread")
return
}
}
}
func (self *rktContainerWatcher) syncRunningPods(pods []*rktapi.Pod, events chan watcher.ContainerEvent, curpods map[string]*rktapi.Pod) map[string]*rktapi.Pod {
newpods := make(map[string]*rktapi.Pod)
for _, pod := range pods {
newpods[pod.Id] = pod
// if pods become mutable, have to handle this better
if _, ok := curpods[pod.Id]; !ok {
// should create all cgroups not including system.slice
// i.e. /system.slice/rkt-test.service and /system.slice/rkt-test.service/system.slice/pause.service
for _, cgroup := range podToCgroup(pod) {
self.sendUpdateEvent(cgroup, events)
}
}
}
for id, pod := range curpods {
if _, ok := newpods[id]; !ok {
for _, cgroup := range podToCgroup(pod) {
klog.V(2).Infof("cgroup to delete = %v", cgroup)
self.sendDestroyEvent(cgroup, events)
}
}
}
return newpods
}
func (self *rktContainerWatcher) sendUpdateEvent(cgroup string, events chan watcher.ContainerEvent) {
events <- watcher.ContainerEvent{
EventType: watcher.ContainerAdd,
Name: cgroup,
WatchSource: watcher.Rkt,
}
}
func (self *rktContainerWatcher) sendDestroyEvent(cgroup string, events chan watcher.ContainerEvent) {
events <- watcher.ContainerEvent{
EventType: watcher.ContainerDelete,
Name: cgroup,
WatchSource: watcher.Rkt,
}
}
func listRunningPods() ([]*rktapi.Pod, error) {
client, err := rkt.Client()
if err != nil {
return nil, err
}
resp, err := client.ListPods(context.Background(), &rktapi.ListPodsRequest{
// Specify the request: Fetch and print only running pods and their details.
Detail: true,
Filters: []*rktapi.PodFilter{
{
States: []rktapi.PodState{rktapi.PodState_POD_STATE_RUNNING},
},
},
})
if err != nil {
return nil, err
}
return resp.Pods, nil
}
func podToCgroup(pod *rktapi.Pod) []string {
cgroups := make([]string, 1+len(pod.Apps), 1+len(pod.Apps))
baseCgroup := pod.Cgroup
cgroups[0] = baseCgroup
for i, app := range pod.Apps {
cgroups[i+1] = filepath.Join(baseCgroup, "system.slice", app.Name+".service")
}
return cgroups
}
...@@ -2,20 +2,11 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library") ...@@ -2,20 +2,11 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library( go_library(
name = "go_default_library", name = "go_default_library",
srcs = [ srcs = ["cloudinfo.go"],
"aws.go",
"azure.go",
"cloudinfo.go",
"gce.go",
],
importmap = "k8s.io/kubernetes/vendor/github.com/google/cadvisor/utils/cloudinfo", importmap = "k8s.io/kubernetes/vendor/github.com/google/cadvisor/utils/cloudinfo",
importpath = "github.com/google/cadvisor/utils/cloudinfo", importpath = "github.com/google/cadvisor/utils/cloudinfo",
visibility = ["//visibility:public"], visibility = ["//visibility:public"],
deps = [ deps = [
"//vendor/cloud.google.com/go/compute/metadata:go_default_library",
"//vendor/github.com/aws/aws-sdk-go/aws:go_default_library",
"//vendor/github.com/aws/aws-sdk-go/aws/ec2metadata:go_default_library",
"//vendor/github.com/aws/aws-sdk-go/aws/session:go_default_library",
"//vendor/github.com/google/cadvisor/info/v1:go_default_library", "//vendor/github.com/google/cadvisor/info/v1:go_default_library",
"//vendor/k8s.io/klog:go_default_library", "//vendor/k8s.io/klog:go_default_library",
], ],
......
// Copyright 2015 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 cloudinfo
import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/ec2metadata"
"github.com/aws/aws-sdk-go/aws/session"
"io/ioutil"
"os"
"strings"
info "github.com/google/cadvisor/info/v1"
)
const (
ProductVerFileName = "/sys/class/dmi/id/product_version"
BiosVerFileName = "/sys/class/dmi/id/bios_vendor"
Amazon = "amazon"
)
func onAWS() bool {
var dataProduct []byte
var dataBios []byte
if _, err := os.Stat(ProductVerFileName); err == nil {
dataProduct, err = ioutil.ReadFile(ProductVerFileName)
if err != nil {
return false
}
}
if _, err := os.Stat(BiosVerFileName); err == nil {
dataBios, err = ioutil.ReadFile(BiosVerFileName)
if err != nil {
return false
}
}
return strings.Contains(string(dataProduct), Amazon) || strings.Contains(strings.ToLower(string(dataBios)), Amazon)
}
func getAwsMetadata(name string) string {
client := ec2metadata.New(session.New(&aws.Config{}))
data, err := client.GetMetadata(name)
if err != nil {
return info.UnknownInstance
}
return data
}
func getAwsInstanceType() info.InstanceType {
return info.InstanceType(getAwsMetadata("instance-type"))
}
func getAwsInstanceID() info.InstanceID {
return info.InstanceID(getAwsMetadata("instance-id"))
}
...@@ -18,6 +18,7 @@ package cloudinfo ...@@ -18,6 +18,7 @@ package cloudinfo
import ( import (
info "github.com/google/cadvisor/info/v1" info "github.com/google/cadvisor/info/v1"
"k8s.io/klog"
) )
type CloudInfo interface { type CloudInfo interface {
...@@ -26,6 +27,29 @@ type CloudInfo interface { ...@@ -26,6 +27,29 @@ type CloudInfo interface {
GetInstanceID() info.InstanceID GetInstanceID() info.InstanceID
} }
// CloudProvider is an abstraction for providing cloud-specific information.
type CloudProvider interface {
// IsActiveProvider determines whether this is the cloud provider operating
// this instance.
IsActiveProvider() bool
// GetInstanceType gets the type of instance this process is running on.
// The behavior is undefined if this is not the active provider.
GetInstanceType() info.InstanceType
// GetInstanceType gets the ID of the instance this process is running on.
// The behavior is undefined if this is not the active provider.
GetInstanceID() info.InstanceID
}
var providers = map[info.CloudProvider]CloudProvider{}
// RegisterCloudProvider registers the given cloud provider
func RegisterCloudProvider(name info.CloudProvider, provider CloudProvider) {
if _, alreadyRegistered := providers[name]; alreadyRegistered {
klog.Warningf("Duplicate registration of CloudProvider %s", name)
}
providers[name] = provider
}
type realCloudInfo struct { type realCloudInfo struct {
cloudProvider info.CloudProvider cloudProvider info.CloudProvider
instanceType info.InstanceType instanceType info.InstanceType
...@@ -33,13 +57,21 @@ type realCloudInfo struct { ...@@ -33,13 +57,21 @@ type realCloudInfo struct {
} }
func NewRealCloudInfo() CloudInfo { func NewRealCloudInfo() CloudInfo {
cloudProvider := detectCloudProvider() for name, provider := range providers {
instanceType := detectInstanceType(cloudProvider) if provider.IsActiveProvider() {
instanceID := detectInstanceID(cloudProvider) return &realCloudInfo{
cloudProvider: name,
instanceType: provider.GetInstanceType(),
instanceID: provider.GetInstanceID(),
}
}
}
// No registered active provider.
return &realCloudInfo{ return &realCloudInfo{
cloudProvider: cloudProvider, cloudProvider: info.UnknownProvider,
instanceType: instanceType, instanceType: info.UnknownInstance,
instanceID: instanceID, instanceID: info.UnNamedInstance,
} }
} }
...@@ -54,50 +86,3 @@ func (self *realCloudInfo) GetInstanceType() info.InstanceType { ...@@ -54,50 +86,3 @@ func (self *realCloudInfo) GetInstanceType() info.InstanceType {
func (self *realCloudInfo) GetInstanceID() info.InstanceID { func (self *realCloudInfo) GetInstanceID() info.InstanceID {
return self.instanceID return self.instanceID
} }
func detectCloudProvider() info.CloudProvider {
switch {
case onGCE():
return info.GCE
case onAWS():
return info.AWS
case onAzure():
return info.Azure
case onBaremetal():
return info.Baremetal
}
return info.UnknownProvider
}
func detectInstanceType(cloudProvider info.CloudProvider) info.InstanceType {
switch cloudProvider {
case info.GCE:
return getGceInstanceType()
case info.AWS:
return getAwsInstanceType()
case info.Azure:
return getAzureInstanceType()
case info.Baremetal:
return info.NoInstance
}
return info.UnknownInstance
}
func detectInstanceID(cloudProvider info.CloudProvider) info.InstanceID {
switch cloudProvider {
case info.GCE:
return getGceInstanceID()
case info.AWS:
return getAwsInstanceID()
case info.Azure:
return getAzureInstanceID()
case info.Baremetal:
return info.UnNamedInstance
}
return info.UnNamedInstance
}
// TODO: Implement method.
func onBaremetal() bool {
return false
}
// Copyright 2015 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 cloudinfo
import (
"io/ioutil"
"strings"
info "github.com/google/cadvisor/info/v1"
"cloud.google.com/go/compute/metadata"
"k8s.io/klog"
)
const (
gceProductName = "/sys/class/dmi/id/product_name"
google = "Google"
)
func onGCE() bool {
data, err := ioutil.ReadFile(gceProductName)
if err != nil {
klog.V(2).Infof("Error while reading product_name: %v", err)
return false
}
return strings.Contains(string(data), google)
}
func getGceInstanceType() info.InstanceType {
machineType, err := metadata.Get("instance/machine-type")
if err != nil {
return info.UnknownInstance
}
responseParts := strings.Split(machineType, "/") // Extract the instance name from the machine type.
return info.InstanceType(responseParts[len(responseParts)-1])
}
func getGceInstanceID() info.InstanceID {
instanceID, err := metadata.Get("instance/id")
if err != nil {
return info.UnknownInstance
}
return info.InstanceID(info.InstanceType(instanceID))
}
...@@ -2,9 +2,9 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library") ...@@ -2,9 +2,9 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library( go_library(
name = "go_default_library", name = "go_default_library",
srcs = ["backoff.go"], srcs = ["watcher.go"],
importmap = "k8s.io/kubernetes/vendor/github.com/Rican7/retry/backoff", importmap = "k8s.io/kubernetes/vendor/github.com/google/cadvisor/watcher",
importpath = "github.com/Rican7/retry/backoff", importpath = "github.com/google/cadvisor/watcher",
visibility = ["//visibility:public"], visibility = ["//visibility:public"],
) )
......
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.
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"],
)
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"],
)
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
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"],
)
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,
},
}
}
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
}
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
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{})
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"],
)
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
)
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"],
)
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...)
}
}
// 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
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"],
)
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"],
)
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,
},
}
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"],
)
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)
}
}
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
}
}
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment