diff --git a/.gitignore b/.gitignore index 60ed3d6910d..ee0861343f0 100644 --- a/.gitignore +++ b/.gitignore @@ -17,3 +17,4 @@ docs/themes docs/package-lock.json pkg/skaffold/color/debug.test cmd/skaffold/app/cmd/statik/statik.go +cmd/skaffold/app/secret/statik/statik.go diff --git a/cmd/skaffold/app/cmd/schema/print_test.go b/cmd/skaffold/app/cmd/schema/print_test.go index 79c4879547d..85e6889895d 100644 --- a/cmd/skaffold/app/cmd/schema/print_test.go +++ b/cmd/skaffold/app/cmd/schema/print_test.go @@ -18,45 +18,15 @@ package schema import ( "bytes" - "io" "net/http" - "os" "testing" "github.com/GoogleContainerTools/skaffold/cmd/skaffold/app/cmd/statik" "github.com/GoogleContainerTools/skaffold/testutil" ) -type fakeFileSystem struct { - Files map[string][]byte -} - -type fakeFile struct { - http.File - content io.Reader -} - -func (f *fakeFileSystem) Open(name string) (http.File, error) { - content, found := f.Files[name] - if !found { - return nil, os.ErrNotExist - } - - return &fakeFile{ - content: bytes.NewBuffer(content), - }, nil -} - -func (f *fakeFile) Read(p []byte) (n int, err error) { - return f.content.Read(p) -} - -func (f *fakeFile) Close() error { - return nil -} - func TestPrint(t *testing.T) { - fs := &fakeFileSystem{ + fs := &testutil.FakeFileSystem{ Files: map[string][]byte{ "/schemas/v1.json": []byte("{SCHEMA}"), }, diff --git a/cmd/skaffold/app/secret/statik/fs.go b/cmd/skaffold/app/secret/statik/fs.go new file mode 100644 index 00000000000..d88bd312d61 --- /dev/null +++ b/cmd/skaffold/app/secret/statik/fs.go @@ -0,0 +1,17 @@ +/* +Copyright 2020 The Skaffold Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package statik diff --git a/go.mod b/go.mod index 168cc29bf72..e01080676e5 100644 --- a/go.mod +++ b/go.mod @@ -15,8 +15,10 @@ replace ( require ( 4d63.com/tz v1.1.0 + cloud.google.com/go v0.72.0 // indirect cloud.google.com/go/storage v1.10.0 github.com/AlecAivazis/survey/v2 v2.0.5 + github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.13.0 github.com/Microsoft/go-winio v0.4.15 // indirect github.com/blang/semver v3.5.1+incompatible github.com/bmatcuk/doublestar v1.2.4 @@ -37,7 +39,7 @@ require ( github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e github.com/golang/protobuf v1.4.3 - github.com/google/go-cmp v0.5.2 + github.com/google/go-cmp v0.5.4 github.com/google/go-containerregistry v0.1.4 github.com/google/go-github v17.0.0+incompatible github.com/google/martian v2.1.1-0.20190517191504-25dcb96d9e51+incompatible // indirect @@ -67,15 +69,19 @@ require ( github.com/tektoncd/pipeline v0.5.1-0.20190731183258-9d7e37e85bf8 github.com/xeipuuv/gojsonschema v1.2.0 golang.org/x/crypto v0.0.0-20201117144127-c1f2f97bffc9 + go.opentelemetry.io/otel v0.13.0 + go.opentelemetry.io/otel/sdk v0.13.0 golang.org/x/mod v0.3.0 - golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43 + golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb // indirect + golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58 golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211 golang.org/x/term v0.0.0-20201117132131-f5c789dd3221 gomodules.xyz/jsonpatch/v2 v2.1.0 // indirect - google.golang.org/api v0.34.0 - google.golang.org/genproto v0.0.0-20201022181438-0ff5f38871d5 - google.golang.org/grpc v1.33.1 + google.golang.org/api v0.35.0 + google.golang.org/appengine v1.6.7 // indirect + google.golang.org/genproto v0.0.0-20201202151023-55d61f90c1ce + google.golang.org/grpc v1.33.2 gopkg.in/AlecAivazis/survey.v1 v1.8.8 gopkg.in/yaml.v2 v2.3.0 gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 diff --git a/go.sum b/go.sum index b3a1d49fb28..3278006c9b1 100644 --- a/go.sum +++ b/go.sum @@ -26,6 +26,8 @@ cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZ cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= cloud.google.com/go v0.65.0 h1:Dg9iHVQfrhq82rUNu9ZxUDrJLaxFUe/HlCVaLyRruq8= cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +cloud.google.com/go v0.72.0 h1:eWRCuwubtDrCJG0oSUMgnsbD4CmPFQF2ei4OFbXvwww= +cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= @@ -116,10 +118,15 @@ github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBp github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/DataDog/sketches-go v0.0.1 h1:RtG+76WKgZuz6FIaGsjoPePmadDBkuD/KC6+ZWu78b8= +github.com/DataDog/sketches-go v0.0.1/go.mod h1:Q5DbzQ+3AkgGwymQO7aZFNP7ns2lZKGtvRBzRXfdi60= github.com/Djarvur/go-err113 v0.0.0-20200410182137-af658d038157/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs= github.com/Djarvur/go-err113 v0.1.0/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs= github.com/GoogleCloudPlatform/cloudsql-proxy v0.0.0-20191009163259-e802c2cb94ae/go.mod h1:mjwGPas4yKduTyubHvD1Atl9r1rUq8DfVy+gkVvZ+oo= github.com/GoogleCloudPlatform/k8s-cloud-provider v0.0.0-20190822182118-27a4ced34534/go.mod h1:iroGtC8B3tQiqtds1l+mgk/BBOrxbqjH+eUfFQYRc14= +github.com/GoogleCloudPlatform/opentelemetry-operations-go v0.13.0 h1:Gx9IxOjR9ug5Ad8YbafxJ6N2g6oDj/Q419tYHdd1od4= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.13.0 h1:RbaN+/fPE1Rv/ZC/Z1vcD/qsd4XyYmzlTRqIPXnCAE0= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.13.0/go.mod h1:8MmJ2gqHtCH9fdAkpsnSYPdgn47SXsBodhYk6JfzA3M= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd h1:sjQovDkwrZp8u+gxLtPgKGjk5hCxuy2hrRejBTA9xFU= github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd/go.mod h1:64YHyfSL2R96J44Nlwm39UHepQbyR5q10x7iYa1ks2E= @@ -203,6 +210,8 @@ github.com/aws/aws-sdk-go v1.31.6/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU github.com/aws/aws-sdk-go v1.31.12/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59/go.mod h1:q/89r3U2H7sSsE2t6Kca0lfwTK8JdoNGS/yzM/4iH5I= +github.com/benbjohnson/clock v1.0.3 h1:vkLuvpK4fmtSCuo60+yC63p7y0BmQ8gm5ZXGuBCJyXg= +github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM= github.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= @@ -599,6 +608,10 @@ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.3 h1:x95R7cp+rSeeqAMI2knLtQ0DKlaBhv2NrtrOvafPHRo= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-containerregistry v0.0.0-20191010200024-a3d713f9b7f8/go.mod h1:KyKXa9ciM8+lgMXwOVsXi7UxGrsf9mM61Mzs+xKUrKE= github.com/google/go-containerregistry v0.0.0-20200311163244-4b1985e5ea21/go.mod h1:m8YvHwSOuBCq25yrj1DaX/fIMrv6ec3CNg8jY8+5PEA= github.com/google/go-containerregistry v0.1.2/go.mod h1:GPivBPgdAyd2SU+vf6EpsgOtWDuPqjW0hJZt4rNdTZ4= @@ -623,6 +636,7 @@ github.com/google/mako v0.0.0-20190821191249-122f8dcef9e3/go.mod h1:YzLcVlL+NqWn github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian v2.1.1-0.20190517191504-25dcb96d9e51+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= @@ -630,6 +644,7 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/rpmpack v0.0.0-20191226140753-aa36bfddb3a0/go.mod h1:RaTPr0KUf2K7fnZYLNDrr8rxAamWs3iNywJLtQ2AzBg= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= @@ -648,6 +663,8 @@ github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gnostic v0.4.1 h1:DLJCy1n/vrD4HPjOvYcT8aYQXpPIzoRZONaYwyycI+I= github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= +github.com/googleinterns/cloud-operations-api-mock v0.0.0-20200709193332-a1e58c29bdd3 h1:eHv/jVY/JNop1xg2J9cBb4EzyMpWZoNCP1BslSAIkOI= +github.com/googleinterns/cloud-operations-api-mock v0.0.0-20200709193332-a1e58c29bdd3/go.mod h1:h/KNeRx7oYU4SpA4SoY7W2/NxDKEEVuwA6j9A27L4OI= github.com/gookit/color v1.2.4/go.mod h1:AhIE+pS6D4Ql0SQWbBeXPHw7gY0/sjHoA4s/n1KB7xg= github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= @@ -723,6 +740,7 @@ github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174/go.mod h1:DqJ97dSdRW github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.9 h1:UauaLniWCFHWd+Jp9oCEkTBj8VO/9DKg3PV3VCNMDIg= @@ -1251,6 +1269,15 @@ go.opencensus.io v0.22.4-0.20200608061201-1901b56b9515/go.mod h1:yxeiOL68Rb0Xd1d go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5 h1:dntmOdLpSpHlVqbW5Eay97DelsZHe+55D+xC6i0dDS0= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.opentelemetry.io v0.1.0 h1:EANZoRCOP+A3faIlw/iN6YEWoYb1vleZRKm1EvH8T48= +go.opentelemetry.io/otel v0.13.0 h1:2isEnyzjjJZq6r2EKMsFj4TxiQiexsM04AVhwbR/oBA= +go.opentelemetry.io/otel v0.13.0/go.mod h1:dlSNewoRYikTkotEnxdmuBHgzT+k/idJSfDv/FxEnOY= +go.opentelemetry.io/otel v0.14.0 h1:YFBEfjCk9MTjaytCNSUkp9Q8lF7QJezA06T71FbQxLQ= +go.opentelemetry.io/otel v0.14.0/go.mod h1:vH5xEuwy7Rts0GNtsCW3HYQoZDY+OmBJ6t1bFGGlxgw= +go.opentelemetry.io/otel/sdk v0.13.0 h1:4VCfpKamZ8GtnepXxMRurSpHpMKkcxhtO33z1S4rGDQ= +go.opentelemetry.io/otel/sdk v0.13.0/go.mod h1:dKvLH8Uu8LcEPlSAUsfW7kMGaJBhk/1NYvpPZ6wIMbU= +go.opentelemetry.io/otel/sdk v0.14.0 h1:Pqgd85y5XhyvHQlOxkKW+FD4DAX7AoeaNIDKC2VhfHQ= +go.opentelemetry.io/otel/sdk v0.14.0/go.mod h1:kGO5pEMSNqSJppHAm8b73zztLxB5fgDQnD56/dl5xqE= go.starlark.net v0.0.0-20190528202925-30ae18b8564f/go.mod h1:c1/X6cHgvdXj6pUlmWKMkuqRnW4K8x2vwt6JAaaircg= go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5/go.mod h1:nmDLcffg48OtT/PSW0Hg7FvpRQsQh5OSqIylirxKC7o= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= @@ -1384,11 +1411,16 @@ golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200904194848-62affa334b73 h1:MXfv8rhZWmFeqX3GNZRsd6vOLoaCHjYEX3qkRo3YBUA= golang.org/x/net v0.0.0-20200904194848-62affa334b73/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb h1:eBmm0M9fYhWpKZLjQUUKka/LtIxf46G4fxeEz5KJr9U= +golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/oauth2 v0.0.0-20180724155351-3d292e4d0cdc/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1401,6 +1433,8 @@ golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4Iltr golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43 h1:ld7aEMNHoBnnDAX15v1T6z31v8HwR2A9FYOuAhWqkwc= golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58 h1:Mj83v+wSRNEar42a/MQgxk9X42TdEmrOl9i+y8WbxLo= +golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1485,15 +1519,19 @@ golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200828194041-157a740278f4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200916030750-2334cc1a136f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200917073148-efd3b9a0ff20/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200922070232-aee5d888a860/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201013081832-0aaa2718063a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211 h1:9UQO31fZ+0aKQOFldThf7BKPMJTiBfWycGh/u3UoO88= golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3 h1:kzM6+9dur93BcC2kVlYl34cHU+TYZLanmpSJHVMmL64= +golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221 h1:/ZHdbVpdR/jk3g30/d4yUL0JU9kksj8+F/bnQUVLGDM= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1503,6 +1541,8 @@ golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3 golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.4 h1:0YWbFKbhXG/wIiuHDSKpS0Iy7FSA+u45VtBMfQcFTTc= +golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1589,12 +1629,14 @@ golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200616133436-c1934b75d054/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200701151220-7cb253f4c4f8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= golang.org/x/tools v0.0.0-20200916195026-c9a70fc28ce3 h1:DywqrEscRX7O2phNjkT0L6lhHKGBoMLCNX+XcAe7t6s= golang.org/x/tools v0.0.0-20200916195026-c9a70fc28ce3/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= +golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1637,6 +1679,8 @@ google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSr google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= google.golang.org/api v0.34.0 h1:k40adF3uR+6x/+hO5Dh4ZFUqFp67vxvbpafFiJxl10A= google.golang.org/api v0.34.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= +google.golang.org/api v0.35.0 h1:TBCmTTxUrRDA1iTctnK/fIeitxIZ+TQuaf0j29fmCGo= +google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -1647,6 +1691,8 @@ google.golang.org/appengine v1.6.2/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/cloud v0.0.0-20151119220103-975617b05ea8/go.mod h1:0H1ncTHf11KCFhTc/+EFRbzSCOZx+VUbRMk55Yv5MYk= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= @@ -1682,13 +1728,18 @@ google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfG google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20200527145253-8367513e4ece/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200605102947-12044bf5ea91/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200831141814-d751682dd103/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201022181438-0ff5f38871d5 h1:YejJbGvoWsTXHab4OKNrzk27Dr7s4lPLnewbHue1+gM= google.golang.org/genproto v0.0.0-20201022181438-0ff5f38871d5/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201202151023-55d61f90c1ce h1:iS2R2xZpNiQFZrGqWisFYEYzOyKzvz07am2h/QXKqoY= +google.golang.org/genproto v0.0.0-20201202151023-55d61f90c1ce/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= @@ -1711,8 +1762,11 @@ google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3Iji google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.32.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.33.1 h1:DGeFlSan2f+WEtCERJ4J9GJWk15TxUi8QGagfI87Xyc= google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.33.2 h1:EQyQC3sa8M+p6Ulc8yy9SWSS2GVwyRc83gAbG8lrl4o= +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/hack/generate-statik.sh b/hack/generate-statik.sh index 6ec32488c16..d762df66e75 100755 --- a/hack/generate-statik.sh +++ b/hack/generate-statik.sh @@ -18,6 +18,7 @@ set -euo pipefail DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +SECRET=${SECRET:-${DIR}/../secrets} BIN=${DIR}/bin STATIK=${BIN}/statik LICENSES=${BIN}/go-licenses @@ -54,3 +55,8 @@ if ! [[ -f ${STATIK} ]]; then fi ${STATIK} -f -src=${TMP_DIR} -m -dest cmd/skaffold/app/cmd + +if [[ -d ${SECRET} ]]; then + echo "generating statik for secret" + ${STATIK} -f -src=${SECRET} -m -dest cmd/skaffold/app/secret +fi diff --git a/pkg/skaffold/instrumentation/meter.go b/pkg/skaffold/instrumentation/meter.go index eb131c529cb..9fe419133e2 100644 --- a/pkg/skaffold/instrumentation/meter.go +++ b/pkg/skaffold/instrumentation/meter.go @@ -17,17 +17,33 @@ limitations under the License. package instrumentation import ( + "context" "encoding/json" "fmt" "io/ioutil" + "math/rand" + "net/http" "os" "path/filepath" "runtime" + "strconv" "time" + mexporter "github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric" "github.com/mitchellh/go-homedir" + "github.com/rakyll/statik/fs" + "github.com/sirupsen/logrus" flag "github.com/spf13/pflag" + "go.opentelemetry.io/otel/api/global" + "go.opentelemetry.io/otel/api/metric" + "go.opentelemetry.io/otel/label" + "go.opentelemetry.io/otel/sdk/metric/controller/push" + "google.golang.org/api/option" + "github.com/GoogleContainerTools/skaffold/cmd/skaffold/app/cmd/statik" + + // import embedded secret for uploading metrics + _ "github.com/GoogleContainerTools/skaffold/cmd/skaffold/app/secret/statik" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/constants" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/runner/runcontext" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/latest" @@ -46,7 +62,7 @@ type skaffoldMeter struct { PlatformType string Deployers []string EnumFlags map[string]*flag.Flag - Builders map[string]bool + Builders map[string]int SyncType map[string]bool DevIterations []devIteration StartTime time.Time @@ -64,7 +80,7 @@ var ( OS: runtime.GOOS, Arch: runtime.GOARCH, EnumFlags: map[string]*flag.Flag{}, - Builders: map[string]bool{}, + Builders: map[string]int{}, SyncType: map[string]bool{}, DevIterations: []devIteration{}, StartTime: time.Now(), @@ -72,14 +88,31 @@ var ( ExitCode: 0, ErrorCode: proto.StatusCode_OK, } - skipExport = os.Getenv("SKAFFOLD_EXPORT_METRICS") + shouldExportMetrics = os.Getenv("SKAFFOLD_EXPORT_METRICS") == "true" + isOnline bool ) +func init() { + go func() { + if shouldExportMetrics { + r, err := http.Get("http://clients3.google.com/generate_204") + if err == nil { + r.Body.Close() + isOnline = true + } + } + }() +} + func InitMeter(runCtx *runcontext.RunContext, config *latest.SkaffoldConfig) { meter.Command = runCtx.Opts.Command meter.PlatformType = yamltags.GetYamlTag(config.Build.BuildType) for _, artifact := range config.Pipeline.Build.Artifacts { - meter.Builders[yamltags.GetYamlTag(artifact.ArtifactType)] = true + if _, ok := meter.Builders[yamltags.GetYamlTag(artifact.ArtifactType)]; ok { + meter.Builders[yamltags.GetYamlTag(artifact.ArtifactType)]++ + } else { + meter.Builders[yamltags.GetYamlTag(artifact.ArtifactType)] = 1 + } if artifact.Sync != nil { meter.SyncType[yamltags.GetYamlTag(artifact.Sync)] = true } @@ -108,30 +141,203 @@ func AddFlag(flag *flag.Flag) { } func ExportMetrics(exitCode int) error { + if !shouldExportMetrics { + return nil + } home, err := homedir.Dir() if err != nil { return fmt.Errorf("retrieving home directory: %w", err) } meter.ExitCode = exitCode meter.Duration = time.Since(meter.StartTime) - return exportMetrics(filepath.Join(home, constants.DefaultSkaffoldDir, constants.DefaultMetricFile), meter) + return exportMetrics(context.Background(), + filepath.Join(home, constants.DefaultSkaffoldDir, constants.DefaultMetricFile), + meter) } -func exportMetrics(filename string, meter skaffoldMeter) error { - if skipExport != "true" || meter.Command == "" { - return nil +func exportMetrics(ctx context.Context, filename string, meter skaffoldMeter) error { + logrus.Debug("exporting metrics") + p, err := initCloudMonitoringExporterMetrics() + if p == nil { + return err } + b, err := ioutil.ReadFile(filename) + fileExists := err == nil if err != nil && !os.IsNotExist(err) { return err } - var meters []skaffoldMeter err = json.Unmarshal(b, &meters) if err != nil { meters = []skaffoldMeter{} } meters = append(meters, meter) - b, _ = json.Marshal(meters) - return ioutil.WriteFile(filename, b, 0666) + if !isOnline { + b, _ = json.Marshal(meters) + return ioutil.WriteFile(filename, b, 0666) + } + + p.Start() + for _, m := range meters { + createMetrics(ctx, m) + } + p.Stop() + + if fileExists { + return os.Remove(filename) + } + return nil +} + +type creds struct { + ProjectID string `json:"project_id"` +} + +func initCloudMonitoringExporterMetrics() (*push.Controller, error) { + statikFS, err := statik.FS() + if err != nil { + return nil, err + } + b, err := fs.ReadFile(statikFS, "/keys.json") + if err != nil { + // No keys have been set in this version so do not attempt to write metrics + if os.IsNotExist(err) { + return nil, nil + } + return nil, err + } + + var c creds + err = json.Unmarshal(b, &c) + if err != nil { + return nil, fmt.Errorf("error unmarsharling metrics credentials: %v", err) + } + + formatter := func(desc *metric.Descriptor) string { + return fmt.Sprintf("custom.googleapis.com/skaffold/%s", desc.Name()) + } + + return mexporter.InstallNewPipeline( + []mexporter.Option{ + mexporter.WithProjectID(c.ProjectID), + mexporter.WithMetricDescriptorTypeFormatter(formatter), + mexporter.WithMonitoringClientOptions(option.WithCredentialsJSON(b)), + mexporter.WithOnError(func(err error) { + logrus.Debugf("Error with metrics: %v", err) + }), + }, + ) +} + +func createMetrics(ctx context.Context, meter skaffoldMeter) { + // There is a minimum 10 second interval that metrics are allowed to upload to Cloud monitoring + // A metric is uniquely identified by the metric name and the labels and corresponding values + // This random number is used as a label to differentiate the metrics per user so if two users + // run `skaffold build` at the same time they will both have their metrics recorded + randLabel := label.String("randomizer", strconv.Itoa(rand.Intn(75000))) + + m := global.Meter("skaffold") + labels := []label.KeyValue{ + label.String("version", meter.Version), + label.String("os", meter.OS), + label.String("arch", meter.Arch), + label.String("command", meter.Command), + label.String("error", strconv.Itoa(int(meter.ErrorCode))), + randLabel, + } + + runCounter := metric.Must(m).NewInt64ValueRecorder("launches", metric.WithDescription("Skaffold Invocations")) + runCounter.Record(ctx, 1, labels...) + + durationRecorder := metric.Must(m).NewFloat64ValueRecorder("launch/duration", + metric.WithDescription("durations of skaffold commands in seconds")) + durationRecorder.Record(ctx, meter.Duration.Seconds(), labels...) + if meter.Command != "" { + commandMetrics(ctx, meter, m, randLabel) + doesBuild := map[string]bool{"build": true, "render": true, "dev": true, "debug": true, "run": true} + doesDeploy := map[string]bool{"deploy": true, "dev": true, "debug": true, "run": true} + if _, ok := doesBuild[meter.Command]; ok { + builderMetrics(ctx, meter, m, randLabel) + } + if _, ok := doesDeploy[meter.Command]; ok { + deployerMetrics(ctx, meter, m, randLabel) + } + } + + if meter.ErrorCode != 0 { + errorMetrics(ctx, meter, m, randLabel) + } +} + +func commandMetrics(ctx context.Context, meter skaffoldMeter, m metric.Meter, randLabel label.KeyValue) { + commandCounter := metric.Must(m).NewInt64ValueRecorder(meter.Command, + metric.WithDescription(fmt.Sprintf("Number of times %s is used", meter.Command))) + labels := []label.KeyValue{ + label.String("error", strconv.Itoa(int(meter.ErrorCode))), + randLabel, + } + commandCounter.Record(ctx, 1, labels...) + + if meter.Command == "dev" { + iterationCounter := metric.Must(m).NewInt64ValueRecorder("dev/iterations", + metric.WithDescription("Number of iterations in a dev session")) + + counts := make(map[string]map[proto.StatusCode]int) + + for _, iteration := range meter.DevIterations { + if _, ok := counts[iteration.intent]; !ok { + counts[iteration.intent] = make(map[proto.StatusCode]int) + } + m := counts[iteration.intent] + if _, ok := m[iteration.errorCode]; !ok { + m[iteration.errorCode] = 0 + } + m[iteration.errorCode]++ + } + for intention, errorCounts := range counts { + for errorCode, count := range errorCounts { + iterationCounter.Record(ctx, int64(count), + label.String("intent", intention), + label.String("error", strconv.Itoa(int(errorCode))), + randLabel) + } + } + } +} + +func deployerMetrics(ctx context.Context, meter skaffoldMeter, m metric.Meter, randLabel label.KeyValue) { + deployerCounter := metric.Must(m).NewInt64ValueRecorder("deployer", metric.WithDescription("Deployers used")) + for _, deployer := range meter.Deployers { + deployerCounter.Record(ctx, 1, randLabel, label.String("deployer", deployer)) + } +} + +func builderMetrics(ctx context.Context, meter skaffoldMeter, m metric.Meter, randLabel label.KeyValue) { + builderCounter := metric.Must(m).NewInt64ValueRecorder("builders", metric.WithDescription("Builders used")) + artifactCounter := metric.Must(m).NewInt64ValueRecorder("artifacts", metric.WithDescription("Number of artifacts used")) + for builder, count := range meter.Builders { + bLabel := label.String("builder", builder) + builderCounter.Record(ctx, 1, bLabel, randLabel) + artifactCounter.Record(ctx, int64(count), bLabel, randLabel) + } +} + +func errorMetrics(ctx context.Context, meter skaffoldMeter, m metric.Meter, randLabel label.KeyValue) { + errCounter := metric.Must(m).NewInt64ValueRecorder("errors", metric.WithDescription("Skaffold errors")) + errCounter.Record(ctx, 1, label.String("error", strconv.Itoa(int(meter.ErrorCode))), randLabel) + + commandLabel := label.String("command", meter.Command) + + switch meter.ErrorCode { + case proto.StatusCode_UNKNOWN_ERROR: + unknownErrCounter := metric.Must(m).NewInt64ValueRecorder("errors/unknown", metric.WithDescription("Unknown Skaffold Errors")) + unknownErrCounter.Record(ctx, 1, randLabel) + case proto.StatusCode_DEPLOY_UNKNOWN: + unknownCounter := metric.Must(m).NewInt64ValueRecorder("deploy/unknown", metric.WithDescription("Unknown deploy Skaffold Errors")) + unknownCounter.Record(ctx, 1, commandLabel, randLabel) + case proto.StatusCode_BUILD_UNKNOWN: + unknownCounter := metric.Must(m).NewInt64ValueRecorder("build/unknown", metric.WithDescription("Unknown build Skaffold Errors")) + unknownCounter.Record(ctx, 1, commandLabel, randLabel) + } } diff --git a/pkg/skaffold/instrumentation/meter_test.go b/pkg/skaffold/instrumentation/meter_test.go index 9ab754b506a..fbc99ccc12c 100644 --- a/pkg/skaffold/instrumentation/meter_test.go +++ b/pkg/skaffold/instrumentation/meter_test.go @@ -17,19 +17,22 @@ limitations under the License. package instrumentation import ( + "context" "encoding/json" "io/ioutil" + "net/http" "os" "testing" "time" "github.com/spf13/pflag" + "github.com/GoogleContainerTools/skaffold/cmd/skaffold/app/cmd/statik" "github.com/GoogleContainerTools/skaffold/proto" "github.com/GoogleContainerTools/skaffold/testutil" ) -func TestExportMetrics(t *testing.T) { +func TestOfflineExportMetrics(t *testing.T) { startTime, _ := time.Parse(time.ANSIC, "Mon Jan 2 15:04:05 -0700 MST 2006") validMeter := skaffoldMeter{ Command: "build", @@ -37,12 +40,23 @@ func TestExportMetrics(t *testing.T) { Version: "vTest.0", Arch: "test arch", OS: "test os", - Builders: map[string]bool{"docker": true, "buildpacks": true}, + Builders: map[string]int{"docker": 1, "buildpacks": 1}, EnumFlags: map[string]*pflag.Flag{"test": {Name: "test", Shorthand: "t"}}, StartTime: startTime, Duration: time.Minute, } validMeterBytes, _ := json.Marshal(validMeter) + fs := &testutil.FakeFileSystem{ + Files: map[string][]byte{ + "/keys.json": []byte(`{ + "client_id": "test_id", + "client_secret": "test_secret", + "project_id": "test_project", + "refresh_token": "test_token", + "type": "authorized_user" + }`), + }, + } tests := []struct { name string @@ -85,7 +99,8 @@ func TestExportMetrics(t *testing.T) { } for _, test := range tests { testutil.Run(t, test.name, func(t *testutil.T) { - t.Override(&skipExport, "true") + t.Override(&isOnline, false) + t.Override(&statik.FS, func() (http.FileSystem, error) { return fs, nil }) filename := "metrics" tmp := t.NewTempDir() var savedMetrics []skaffoldMeter @@ -97,7 +112,7 @@ func TestExportMetrics(t *testing.T) { t.Error(err) } } - _ = exportMetrics(tmp.Path(filename), test.meter) + _ = exportMetrics(context.Background(), tmp.Path(filename), test.meter) if test.shouldSkip { _, err := os.Stat(filename) diff --git a/testutil/fake_fs.go b/testutil/fake_fs.go new file mode 100644 index 00000000000..8ab5d8534b4 --- /dev/null +++ b/testutil/fake_fs.go @@ -0,0 +1,52 @@ +/* +Copyright 2020 The Skaffold Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package testutil + +import ( + "bytes" + "io" + "net/http" + "os" +) + +type FakeFileSystem struct { + Files map[string][]byte +} + +type fakeFile struct { + http.File + content io.Reader +} + +func (f *FakeFileSystem) Open(name string) (http.File, error) { + content, found := f.Files[name] + if !found { + return nil, os.ErrNotExist + } + + return &fakeFile{ + content: bytes.NewBuffer(content), + }, nil +} + +func (f *fakeFile) Read(p []byte) (n int, err error) { + return f.content.Read(p) +} + +func (f *fakeFile) Close() error { + return nil +}