Merge pull request #4948 from medyagh/paralell_integration_tests4
refactor integration tests to run in parallelpull/4958/head
commit
f872767afe
|
@ -42,3 +42,5 @@ deploy/iso/minikube-iso/board/coreos/minikube/rootfs-overlay/etc/VERSION
|
|||
/.idea
|
||||
|
||||
/.vscode
|
||||
|
||||
test/integration/testdata/minikube-linux-amd64-latest-stable
|
||||
|
|
6
go.mod
6
go.mod
|
@ -8,6 +8,7 @@ require (
|
|||
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d // indirect
|
||||
github.com/blang/semver v3.5.0+incompatible
|
||||
github.com/c4milo/gotoolkit v0.0.0-20170318115440-bcc06269efa9 // indirect
|
||||
github.com/cenkalti/backoff v2.2.1+incompatible
|
||||
github.com/cloudfoundry-attic/jibber_jabber v0.0.0-20151120183258-bcc4c8345a21
|
||||
github.com/cloudfoundry/jibber_jabber v0.0.0-20151120183258-bcc4c8345a21 // indirect
|
||||
github.com/docker/docker v1.13.1 // indirect
|
||||
|
@ -15,7 +16,6 @@ require (
|
|||
github.com/docker/machine v0.16.1-0.20190718054102-a555e4f7a8f5
|
||||
github.com/elazarl/goproxy v0.0.0-20190421051319-9d40249d3c2f
|
||||
github.com/elazarl/goproxy/ext v0.0.0-20190421051319-9d40249d3c2f // indirect
|
||||
github.com/fatih/color v1.7.0 // indirect
|
||||
github.com/go-ole/go-ole v1.2.4 // indirect
|
||||
github.com/golang-collections/collections v0.0.0-20130729185459-604e922904d3
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b
|
||||
|
@ -24,9 +24,9 @@ require (
|
|||
github.com/google/go-github/v25 v25.0.2
|
||||
github.com/gorilla/mux v1.7.1 // indirect
|
||||
github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce // indirect
|
||||
github.com/hashicorp/go-getter v1.3.0
|
||||
github.com/hashicorp/go-multierror v0.0.0-20160811015721-8c5f0ad93604 // indirect
|
||||
github.com/hashicorp/go-retryablehttp v0.5.4
|
||||
github.com/hashicorp/go-version v1.1.0 // indirect
|
||||
github.com/hooklift/assert v0.0.0-20170704181755-9d1defd6d214 // indirect
|
||||
github.com/hooklift/iso9660 v0.0.0-20170318115843-1cf07e5970d8
|
||||
github.com/intel-go/cpuid v0.0.0-20181003105527-1a4a6f06a1c6 // indirect
|
||||
|
@ -36,7 +36,6 @@ require (
|
|||
github.com/machine-drivers/docker-machine-driver-vmware v0.1.1
|
||||
github.com/mattn/go-colorable v0.1.1 // indirect
|
||||
github.com/mattn/go-isatty v0.0.5
|
||||
github.com/mattn/go-runewidth v0.0.0-20161012013512-737072b4e32b // indirect
|
||||
github.com/mitchellh/go-ps v0.0.0-20170309133038-4fdf99ab2936
|
||||
github.com/moby/hyperkit v0.0.0-20171020124204-a12cd7250bcd
|
||||
github.com/olekukonko/tablewriter v0.0.0-20160923125401-bdcc175572fd
|
||||
|
@ -62,7 +61,6 @@ require (
|
|||
golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f
|
||||
golang.org/x/text v0.3.2
|
||||
gopkg.in/airbrake/gobrake.v2 v2.0.9 // indirect
|
||||
gopkg.in/cheggaaa/pb.v1 v1.0.6 // indirect
|
||||
gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2 // indirect
|
||||
k8s.io/api v0.0.0
|
||||
k8s.io/apimachinery v0.0.0
|
||||
|
|
168
go.sum
168
go.sum
|
@ -1,5 +1,14 @@
|
|||
bitbucket.org/bertimus9/systemstat v0.0.0-20180207000608-0eeff89b0690/go.mod h1:Ulb78X89vxKYgdL24HMTiXYHlyHEvruOj1ZPlqeNEZM=
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.31.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.36.0 h1:+aCSj7tOo2LODWVEuZDZeGCckdt6MlSF+X/rB3wUiS8=
|
||||
cloud.google.com/go v0.36.0/go.mod h1:RUoy9p/M4ge0HzT8L+SDZ8jg+Q6fth0CiBuhFJpSV40=
|
||||
dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU=
|
||||
dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBrvjyP0v+ecvNYvCpyZgu5/xkfAUhi6wJj28eUfSU=
|
||||
dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4=
|
||||
dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU=
|
||||
git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg=
|
||||
github.com/Azure/azure-sdk-for-go v21.4.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
|
||||
|
@ -24,23 +33,33 @@ github.com/Sirupsen/logrus v0.0.0-20170822132746-89742aefa4b2 h1:k1A7eIeUk6rnX2y
|
|||
github.com/Sirupsen/logrus v0.0.0-20170822132746-89742aefa4b2/go.mod h1:rmk17hk6i8ZSAJkSDa7nOxamrG+SP4P0mm+DAvExv4U=
|
||||
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d h1:G0m3OIz70MZUWq3EgK3CesDbo8upS2Vm9/P3FtgI+Jk=
|
||||
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
|
||||
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
|
||||
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
|
||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||
github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
|
||||
github.com/auth0/go-jwt-middleware v0.0.0-20170425171159-5493cabe49f7/go.mod h1:LWMyo4iOLWXHGdBki7NIht1kHru/0wM179h+d3g8ATM=
|
||||
github.com/aws/aws-sdk-go v1.15.78/go.mod h1:E3/ieXAlvM0XWO57iftYVDLLvQ824smPP3ATZkfNZeM=
|
||||
github.com/aws/aws-sdk-go v1.16.26 h1:GWkl3rkRO/JGRTWoLLIqwf7AWC4/W/1hMOUZqmX0js4=
|
||||
github.com/aws/aws-sdk-go v1.16.26/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
||||
github.com/bazelbuild/bazel-gazelle v0.0.0-20181012220611-c728ce9f663e/go.mod h1:uHBSeeATKpVazAACZBDPL/Nk/UhQDDsJWDlqYJo8/Us=
|
||||
github.com/bazelbuild/buildtools v0.0.0-20180226164855-80c7f0d45d7e/go.mod h1:5JP0TXzWDHXv8qvxRC4InIazwdyDseBDbzESUMKk1yU=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 h1:xJ4a3vCFaGF/jqvzLMYoU8P317H5OQ+Via4RmuPwCS0=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d h1:xDfNPAt8lFiC1UJrqV3uuy861HCTo708pDMbjHHdCas=
|
||||
github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ00z/TKoufEY6K/a0k6AhaJrQKdFe6OfVXsa4=
|
||||
github.com/blang/semver v3.5.0+incompatible h1:CGxCgetQ64DKk7rdZ++Vfnb1+ogGNnB17OJKJXD2Cfs=
|
||||
github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
|
||||
github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps=
|
||||
github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g=
|
||||
github.com/c4milo/gotoolkit v0.0.0-20170318115440-bcc06269efa9 h1:+ziP/wVJWuAORkjv7386TRidVKY57X0bXBZFMeFlW+U=
|
||||
github.com/c4milo/gotoolkit v0.0.0-20170318115440-bcc06269efa9/go.mod h1:txokOny9wavBtq2PWuHmj1P+eFwpCsj+gQeNNANChfU=
|
||||
github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4=
|
||||
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
|
||||
github.com/cespare/prettybench v0.0.0-20150116022406-03b8cfe5406c/go.mod h1:Xe6ZsFhtM8HrDku0pxJ3/Lr51rwykrzgFwpmTzleatY=
|
||||
github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5/go.mod h1:/iP1qXHoty45bqomnu2LM+VVyAEdWN+vtSHGlQgyxbw=
|
||||
github.com/cheggaaa/pb v1.0.27/go.mod h1:pQciLPpbU0oxA0h+VJYYLxO+XeDQb5pZijXscXHm81s=
|
||||
github.com/client9/misspell v0.0.0-20170928000206-9ce5d979ffda/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cloudflare/cfssl v0.0.0-20180726162950-56268a613adf/go.mod h1:yMWuSON2oQp+43nFtAV/uvKQIFpSPerB57DCt9t8sSA=
|
||||
github.com/cloudfoundry-attic/jibber_jabber v0.0.0-20151120183258-bcc4c8345a21 h1:Yg2hDs4b13Evkpj42FU2idX2cVXVFqQSheXYKM86Qsk=
|
||||
github.com/cloudfoundry-attic/jibber_jabber v0.0.0-20151120183258-bcc4c8345a21/go.mod h1:MgJyK38wkzZbiZSKeIeFankxxSA8gayko/nr5x5bgBA=
|
||||
|
@ -63,6 +82,7 @@ github.com/coreos/go-semver v0.0.0-20180108230905-e214231b295a/go.mod h1:nnelYz7
|
|||
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/coreos/pkg v0.0.0-20180108230652-97fdf19511ea/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/coreos/rkt v1.30.0/go.mod h1:O634mlH6U7qk87poQifK6M2rsFNt+FyUTWNMnP1hF1U=
|
||||
github.com/cpuguy83/go-md2man v1.0.4/go.mod h1:N6JayAiVKtlHSnuTCeuLSQVs75hb8q+dYQLjr7cDsKY=
|
||||
|
@ -71,8 +91,6 @@ github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwc
|
|||
github.com/cyphar/filepath-securejoin v0.0.0-20170720062807-ae69057f2299/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4=
|
||||
github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c/go.mod h1:Ct2BUK8SB0YC1SMSibvLzxjeJLnrYEVLULFNiHY9YfQ=
|
||||
github.com/d2g/dhcp4client v0.0.0-20170829104524-6e570ed0a266/go.mod h1:j0hNfjhrt2SxUOw55nL0ATM/z4Yt3t2Kd1mW34z5W5s=
|
||||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
|
@ -91,6 +109,7 @@ github.com/docker/machine v0.16.1-0.20190718054102-a555e4f7a8f5 h1:5OiV/JwT55JRK
|
|||
github.com/docker/machine v0.16.1-0.20190718054102-a555e4f7a8f5/go.mod h1:I8mPNDeK1uH+JTcUU7X0ZW8KiYz0jyAgNaeSJ1rCfDI=
|
||||
github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96 h1:cenwrSVm+Z7QLSV/BsnenAOcDXdX4cMv4wP0B/5QbPg=
|
||||
github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM=
|
||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
|
||||
github.com/elazarl/goproxy v0.0.0-20190421051319-9d40249d3c2f h1:8GDPb0tCY8LQ+OJ3dbHb5sA6YZWXFORQYZx5sdsTlMs=
|
||||
github.com/elazarl/goproxy v0.0.0-20190421051319-9d40249d3c2f/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
|
||||
|
@ -106,9 +125,12 @@ github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZM
|
|||
github.com/fatih/camelcase v0.0.0-20160318181535-f6a740d52f96/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc=
|
||||
github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
|
||||
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/ghodss/yaml v0.0.0-20180820084758-c7ce16629ff4/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
|
||||
github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
|
||||
github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
|
||||
github.com/go-ole/go-ole v1.2.4 h1:nNBDSCOigTSiarFpYE9J/KtEA1IOW4CNeqT9TQDqCxI=
|
||||
|
@ -137,25 +159,34 @@ github.com/go-ozzo/ozzo-validation v3.5.0+incompatible/go.mod h1:gsEKFIVnabGBt6m
|
|||
github.com/godbus/dbus v0.0.0-20151105175453-c7fdd8b5cd55/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw=
|
||||
github.com/gogo/protobuf v0.0.0-20171007142547-342cbe0a0415 h1:WSBJMqJbLxsn+bTCPyPYZfqHdJmc8MK4wrBjMft6BAM=
|
||||
github.com/gogo/protobuf v0.0.0-20171007142547-342cbe0a0415/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.1.1 h1:72R+M5VuhED/KujmZVcIquuo8mBgX4oVda//DQb3PXo=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/golang-collections/collections v0.0.0-20130729185459-604e922904d3 h1:zN2lZNZRflqFyxVaTIU61KNKQ9C0055u9CAfpmqUvo4=
|
||||
github.com/golang-collections/collections v0.0.0-20130729185459-604e922904d3/go.mod h1:nPpo7qLxd6XL3hWJG/O60sR8ZKfMCiIoNap5GvD12KU=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903 h1:LbsanbbD6LieFkXbj9YNNBupiGHJgFeLpO0j0Fza1h8=
|
||||
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E=
|
||||
github.com/golang/mock v0.0.0-20160127222235-bd3c8e81be01/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golangplus/bytes v0.0.0-20160111154220-45c989fe5450/go.mod h1:Bk6SMAONeMXrxql8uvOKuAZSu8aM5RUGv+1C6IJaEho=
|
||||
github.com/golangplus/fmt v0.0.0-20150411045040-2a5d6d7d2995/go.mod h1:lJgMEyOkYFkPcDKwRXegd+iM6E7matEszMG5HhwytU8=
|
||||
github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e/go.mod h1:0AA//k/eakGydO4jKRoRL2j92ZKSzTgj9tclaCrvXHk=
|
||||
github.com/google/btree v0.0.0-20160524151835-7d79101e329e/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/cadvisor v0.33.2-0.20190411163913-9db8c7dee20a/go.mod h1:1nql6U13uTHaLYB8rLS5x9IJc2qT6Xd/Tr1sTX6NE48=
|
||||
github.com/google/certificate-transparency-go v1.0.21/go.mod h1:QeJfpSbVSfYc7RgB3gJFj9cbuQMMchQxrWXz8Ruopmg=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-containerregistry v0.0.0-20190318164241-019cdfc6adf9 h1:YVdfjqpMrLPm95Jc5JBFaEeGoPfhFxr43VW/UHQ2NVo=
|
||||
github.com/google/go-containerregistry v0.0.0-20190318164241-019cdfc6adf9/go.mod h1:yZAFP63pRshzrEYLXLGPmUt0Ay+2zdjmMN1loCnRLUk=
|
||||
github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY=
|
||||
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
|
||||
github.com/google/go-github/v25 v25.0.2 h1:MqXE7nOlIF91NJ/PXAcvS2dC+XXCDbY7RvJzjyEPAoU=
|
||||
github.com/google/go-github/v25 v25.0.2/go.mod h1:6z5pC69qHtrPJ0sXPsj4BLnd82b+r6sLB7qcBoRZqpw=
|
||||
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
|
||||
|
@ -163,9 +194,15 @@ github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO
|
|||
github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
|
||||
github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
|
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/gax-go v2.0.0+incompatible h1:j0GKcs05QVmm7yesiZq2+9cxHkNK9YM6zKx4D2qucQU=
|
||||
github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY=
|
||||
github.com/googleapis/gax-go/v2 v2.0.3 h1:siORttZ36U2R/WjiJuDz8znElWBiAlO9rVt+mqJt0Cc=
|
||||
github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg=
|
||||
github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d h1:7XGaL1e6bYS1yIonGp9761ExpPPV1ui0SAC59Yube9k=
|
||||
github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
|
||||
github.com/gophercloud/gophercloud v0.0.0-20190126172459-c818fa66e4c8/go.mod h1:3WdhXV3rUYy9p6AUW8d94kr+HS62Y4VL9mBnFxsD8q4=
|
||||
|
@ -176,17 +213,23 @@ github.com/gorilla/mux v1.7.1 h1:Dw4jY2nghMMRsh1ol8dv1axHkDwMQK2DHerMNJsIpJU=
|
|||
github.com/gorilla/mux v1.7.1/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
github.com/gregjones/httpcache v0.0.0-20170728041850-787624de3eb7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
|
||||
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v0.0.0-20190222133341-cfaf5686ec79/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v0.0.0-20170330212424-2500245aa611/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.3.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw=
|
||||
github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce h1:prjrVgOk2Yg6w+PflHoszQNLTUh4kaByUcEWM/9uin4=
|
||||
github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.0 h1:wvCrVc9TjDls6+YGAF2hAifE1E5U1+b4tH6KdvN3Gig=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
|
||||
github.com/hashicorp/go-getter v1.3.0 h1:pFMSFlI9l5NaeuzkpE3L7BYk9qQ9juTAgXW/H0cqxcU=
|
||||
github.com/hashicorp/go-getter v1.3.0/go.mod h1:/O1k/AizTN0QmfEKknCYGvICeyKUDqCYA8vvWtGWDeQ=
|
||||
github.com/hashicorp/go-multierror v0.0.0-20160811015721-8c5f0ad93604 h1:VIq8E7fMiC4h3agg0ya56L0jHn7QisZZcWZXVKJb9jQ=
|
||||
github.com/hashicorp/go-multierror v0.0.0-20160811015721-8c5f0ad93604/go.mod h1:JMRHfdO9jKNzS/+BTlxCjKNQHg/jZAft8U7LloJvN7I=
|
||||
github.com/hashicorp/go-retryablehttp v0.5.4 h1:1BZvpawXoJCWX6pNtow9+rpEj+3itIlutiqnntI6jOE=
|
||||
github.com/hashicorp/go-retryablehttp v0.5.4/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs=
|
||||
github.com/hashicorp/go-safetemp v1.0.0 h1:2HR189eFNrjHQyENnQMMpCiBAsRxzbTMIgBhEyExpmo=
|
||||
github.com/hashicorp/go-safetemp v1.0.0/go.mod h1:oaerMy3BhqiTbVye6QuFhFtIceqFoDHxNAB65b+Rj1I=
|
||||
github.com/hashicorp/go-version v1.1.0 h1:bPIoEKD27tNdebFGGxxYwcL4nepeY4j1QP23PFRGzg0=
|
||||
github.com/hashicorp/go-version v1.1.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||
github.com/hashicorp/golang-lru v0.5.0 h1:CL2msUPvZTLb5O648aiLNJw3hnBxN2+1Jq8rCOH9wdo=
|
||||
|
@ -210,8 +253,11 @@ github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NH
|
|||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/intel-go/cpuid v0.0.0-20181003105527-1a4a6f06a1c6 h1:XboatR7lasl05yel5hNXF7kQBw2oFUGdMztcgisfhNU=
|
||||
github.com/intel-go/cpuid v0.0.0-20181003105527-1a4a6f06a1c6/go.mod h1:RmeVYf9XrPRbRc3XIx0gLYA8qOFvNoPOfaEZduRlEp4=
|
||||
github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU=
|
||||
github.com/jimmidyson/go-download v0.0.0-20161028105827-7f9a90c8c95b h1:3TknJxYSK1eDe21QorC3C2Yz8jylk6vlJG9YABnFzkU=
|
||||
github.com/jimmidyson/go-download v0.0.0-20161028105827-7f9a90c8c95b/go.mod h1:I3WsAhNNoG7a/d8HMlYUywJJlfOs/+/83NEUjuDp4lc=
|
||||
github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM=
|
||||
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||
github.com/johanneswuerbach/nfsexports v0.0.0-20181204082207-1aa528dcb345 h1:XP1VL9iOZu4yz/rq8zj+yvB23XEY5erXRzp8JYmkWu0=
|
||||
github.com/johanneswuerbach/nfsexports v0.0.0-20181204082207-1aa528dcb345/go.mod h1:+c1/kUpg2zlkoWqTOvzDs36Wpbm3Gd1nlmtXAEB0WGU=
|
||||
|
@ -225,11 +271,16 @@ github.com/jteeuwen/go-bindata v0.0.0-20151023091102-a0ff2567cfb7/go.mod h1:JVvh
|
|||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||
github.com/kardianos/osext v0.0.0-20150410034420-8fef92e41e22/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8=
|
||||
github.com/karrick/godirwalk v1.7.5/go.mod h1:2c9FRhkDxdIbgkOnCEvnSWs71Bhugbl46shStcFDJ34=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/fs v0.0.0-20131111012553-2788f0dbd169/go.mod h1:glhvuHOU9Hy7/8PwwdtnarXqLagOX0b/TbZx2zLMqEg=
|
||||
github.com/kr/pretty v0.0.0-20140812000539-f31442d60e51/go.mod h1:Bvhd+E3laJ0AVkG0c9rmtZcnhV0HQ3+c3YxxqTvc/gA=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.0.0-20130911015532-6807e777504f/go.mod h1:sjUstKUATFIcff4qlB53Kml0wQPtJVc/3fWrmuUmcfA=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/libopenstorage/openstorage v0.0.0-20170906232338-093a0c388875/go.mod h1:Sp1sIObHjat1BeXhfMqLZ14wnOzEhNx2YQedreMcUyc=
|
||||
github.com/libvirt/libvirt-go v3.4.0+incompatible h1:Cpyalgj1x8JIeTlL6SDYZBo7j8nY3+5XHqmi8DaunCk=
|
||||
github.com/libvirt/libvirt-go v3.4.0+incompatible/go.mod h1:34zsnB4iGeOv7Byj6qotuW8Ya4v4Tr43ttjz/F0wjLE=
|
||||
|
@ -243,24 +294,31 @@ github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDe
|
|||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/marstr/guid v0.0.0-20170427235115-8bdf7d1a087c/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho=
|
||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||
github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg=
|
||||
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
|
||||
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-isatty v0.0.5 h1:tHXDdz1cpzGaovsTB+TVB8q90WEokoVmfMqoVcrLUgw=
|
||||
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-runewidth v0.0.0-20161012013512-737072b4e32b h1:idzeyUe3K4aU/SIZWMykIkJJyTD7CgDkxUQEjV07fno=
|
||||
github.com/mattn/go-runewidth v0.0.0-20161012013512-737072b4e32b/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/mattn/go-runewidth v0.0.4 h1:2BvfKmzob6Bmd4YsL0zygOqfdFnK7GR4QL06Do4/p7Y=
|
||||
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/mattn/go-shellwords v0.0.0-20180605041737-f8471b0a71de/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o=
|
||||
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/mesos/mesos-go v0.0.9/go.mod h1:kPYCMQ9gsOXVAle1OsoY4I1+9kPu8GHkf88aV59fDr4=
|
||||
github.com/mholt/caddy v0.0.0-20180213163048-2de495001514/go.mod h1:Wb1PlT4DAYSqOEd03MsqkdkXnTxA8v9pKjdpxbqM1kY=
|
||||
github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4=
|
||||
github.com/miekg/dns v0.0.0-20160614162101-5d001d020961 h1:vX2vkMipgQZ8gfmAsFeZdcgmhHoB7jMo6chAtajG3AI=
|
||||
github.com/miekg/dns v0.0.0-20160614162101-5d001d020961/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||
github.com/mindprince/gonvml v0.0.0-20171110221305-fee913ce8fb2/go.mod h1:2eu9pRWp8mo84xCg6KswZ+USQHjwgRhNp06sozOdsTY=
|
||||
github.com/mistifyio/go-zfs v0.0.0-20151009155749-1b4ae6fb4e77/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4=
|
||||
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/mitchellh/go-ps v0.0.0-20170309133038-4fdf99ab2936 h1:kw1v0NlnN+GZcU8Ma8CLF2Zzgjfx95gs3/GN3vYAPpo=
|
||||
github.com/mitchellh/go-ps v0.0.0-20170309133038-4fdf99ab2936/go.mod h1:r1VsdOzOPt1ZSrGZWFoNhsAedKnEd6r9Np1+5blZCWk=
|
||||
github.com/mitchellh/go-testing-interface v1.0.0 h1:fzU/JVNcaqHQEcVFAKeR41fkiLdIPrefOvVG1VZ96U0=
|
||||
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
|
||||
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
|
||||
github.com/mitchellh/go-wordwrap v1.0.0 h1:6GlHJ/LTGMrIJbwgdqdl2eEH8o+Exx/0m8ir9Gns0u4=
|
||||
github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
|
||||
|
@ -279,6 +337,8 @@ github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8m
|
|||
github.com/mvdan/xurls v0.0.0-20160110113200-1b768d7c393a/go.mod h1:tQlNn3BED8bE/15hnSL2HLkDeLWpNPAwtw7wkEq44oU=
|
||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
|
||||
github.com/natefinch/lumberjack v2.0.0+incompatible/go.mod h1:Wi9p2TTF5DG5oU+6YfsmYQpsTIOm0B1VNzQg9Mw6nPk=
|
||||
github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo=
|
||||
github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM=
|
||||
github.com/olekukonko/tablewriter v0.0.0-20160923125401-bdcc175572fd h1:nEatQ6JnwCT9iYD5uqYUiFqq8tJGX25to8KVKXqya7k=
|
||||
github.com/olekukonko/tablewriter v0.0.0-20160923125401-bdcc175572fd/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
|
@ -292,12 +352,12 @@ github.com/opencontainers/image-spec v0.0.0-20170604055404-372ad780f634/go.mod h
|
|||
github.com/opencontainers/runc v0.0.0-20181113202123-f000fe11ece1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
|
||||
github.com/opencontainers/runtime-spec v1.0.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||
github.com/opencontainers/selinux v0.0.0-20170621221121-4a2974bf1ee9/go.mod h1:+BLncwf63G4dgOzykXAxcmnFlUaOlkDdmw/CqsW6pjs=
|
||||
github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8=
|
||||
github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g=
|
||||
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
|
||||
github.com/pelletier/go-toml v1.0.1/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
|
||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI=
|
||||
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
|
||||
github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2 h1:JhzVVoYvbOACxoUmOs6V/G4D5nPVUW73rKvXxP4XUJc=
|
||||
github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE=
|
||||
|
@ -312,12 +372,15 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
|
|||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA=
|
||||
github.com/pquerna/ffjson v0.0.0-20180717144149-af8b230fcd20/go.mod h1:YARuvh7BUWHNhzDq2OM5tzR2RiCcN2D7sapiKyCel/M=
|
||||
github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v0.9.2 h1:awm861/B8OKDd2I/6o1dy3ra4BamzKhYOiGItCeZ740=
|
||||
github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910 h1:idejC8f05m9MGOsuEi1ATq9shN03HrxNkD/luQvxCv8=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||
github.com/prometheus/common v0.0.0-20181126121408-4724e9255275 h1:PnBWHBf+6L0jOqq0gIVUe6Yk0/QMZ640k6NvkxcBf+8=
|
||||
github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||
github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a h1:9a8MnZMP0X2nLJdBg+pBmGgkJlSaKC2KaQmTCk1XDtE=
|
||||
github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/quobyte/api v0.1.2/go.mod h1:jL7lIHrmqQ7yh05OJ+eEEdHr0u/kmT1Ff9iHd+4H6VI=
|
||||
|
@ -332,18 +395,41 @@ github.com/samalba/dockerclient v0.0.0-20160414174713-91d7393ff859 h1:XRl74t6xHK
|
|||
github.com/samalba/dockerclient v0.0.0-20160414174713-91d7393ff859/go.mod h1:yeYR4SlaRZJct6lwNRKR+qd0CocnxxWDE7Vh5dxsn/w=
|
||||
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||
github.com/seccomp/libseccomp-golang v0.0.0-20150813023252-1b506fc7c24e/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo=
|
||||
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||
github.com/shirou/gopsutil v2.18.12+incompatible h1:1eaJvGomDnH74/5cF4CTmTbLHAriGFsTZppLXDX93OM=
|
||||
github.com/shirou/gopsutil v2.18.12+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
|
||||
github.com/shurcooL/sanitized_anchor_name v0.0.0-20151028001915-10ef21a441db h1:lrOUn8raSZS/V52c7elGaEyuogqSkEo/Qj2Auo2G1ik=
|
||||
github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY=
|
||||
github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM=
|
||||
github.com/shurcooL/github_flavored_markdown v0.0.0-20181002035957-2122de532470/go.mod h1:2dOwnU2uBioM+SGy2aZoq1f/Sd1l9OkAeAUvjSyvgU0=
|
||||
github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk=
|
||||
github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ=
|
||||
github.com/shurcooL/gofontwoff v0.0.0-20180329035133-29b52fc0a18d/go.mod h1:05UtEgK5zq39gLST6uB0cf3NEHjETfB4Fgr3Gx5R9Vw=
|
||||
github.com/shurcooL/gopherjslib v0.0.0-20160914041154-feb6d3990c2c/go.mod h1:8d3azKNyqcHP1GaQE/c6dDgjkgSx2BZ4IoEi4F1reUI=
|
||||
github.com/shurcooL/highlight_diff v0.0.0-20170515013008-09bb4053de1b/go.mod h1:ZpfEhSmds4ytuByIcDnOLkTHGUI6KNqRNPDLHDk+mUU=
|
||||
github.com/shurcooL/highlight_go v0.0.0-20181028180052-98c3abbbae20/go.mod h1:UDKB5a1T23gOMUJrI+uSuH0VRDStOiUVSjBTRDVBVag=
|
||||
github.com/shurcooL/home v0.0.0-20181020052607-80b7ffcb30f9/go.mod h1:+rgNQw2P9ARFAs37qieuu7ohDNQ3gds9msbT2yn85sg=
|
||||
github.com/shurcooL/htmlg v0.0.0-20170918183704-d01228ac9e50/go.mod h1:zPn1wHpTIePGnXSHpsVPWEktKXHr6+SS6x/IKRb7cpw=
|
||||
github.com/shurcooL/httperror v0.0.0-20170206035902-86b7830d14cc/go.mod h1:aYMfkZ6DWSJPJ6c4Wwz3QtW22G7mf/PEgaB9k/ik5+Y=
|
||||
github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
|
||||
github.com/shurcooL/httpgzip v0.0.0-20180522190206-b1c53ac65af9/go.mod h1:919LwcH0M7/W4fcZ0/jy0qGght1GIhqyS/EgWGH2j5Q=
|
||||
github.com/shurcooL/issues v0.0.0-20181008053335-6292fdc1e191/go.mod h1:e2qWDig5bLteJ4fwvDAc2NHzqFEthkqn7aOZAOpj+PQ=
|
||||
github.com/shurcooL/issuesapp v0.0.0-20180602232740-048589ce2241/go.mod h1:NPpHK2TI7iSaM0buivtFUc9offApnI0Alt/K8hcHy0I=
|
||||
github.com/shurcooL/notifications v0.0.0-20181007000457-627ab5aea122/go.mod h1:b5uSkrEVM1jQUspwbixRBhaIjIzL2xazXp6kntxYle0=
|
||||
github.com/shurcooL/octicon v0.0.0-20181028054416-fa4f57f9efb2/go.mod h1:eWdoE5JD4R5UVWDucdOPg1g2fqQRq78IQa9zlOV1vpQ=
|
||||
github.com/shurcooL/reactions v0.0.0-20181006231557-f2e0b4ca5b82/go.mod h1:TCR1lToEk4d2s07G3XGfz2QrgHXg4RJBvjrOozvoWfk=
|
||||
github.com/shurcooL/sanitized_anchor_name v0.0.0-20151028001915-10ef21a441db/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYEDaXHZDBsXlPCDqdhQuJkuw4NOtaxYe3xii4=
|
||||
github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw=
|
||||
github.com/sigma/go-inotify v0.0.0-20181102212354-c87b6cf5033d/go.mod h1:stlh9OsqBQSdwxTxX73mu41BBtRbIpZLQ7flcAoxAfo=
|
||||
github.com/sirupsen/logrus v1.2.0 h1:juTguoYk5qI21pwyTXY3B3Y5cOTH3ZUyZCg1v/mihuo=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.1 h1:GL2rEmy6nsikmW0r8opw9JIRScdMF5hA8cOYLH7In1k=
|
||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
github.com/soheilhy/cmux v0.1.3/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
||||
github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE=
|
||||
github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA=
|
||||
github.com/spf13/afero v0.0.0-20160816080757-b28a7effac97/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
||||
github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI=
|
||||
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
||||
|
@ -351,7 +437,6 @@ github.com/spf13/cast v0.0.0-20160730092037-e31f36ffc91a/go.mod h1:r2rcYCSwa1IEx
|
|||
github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8=
|
||||
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
github.com/spf13/cobra v0.0.0-20180319062004-c439c4fa0937/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
||||
github.com/spf13/cobra v0.0.4 h1:S0tLZ3VOKl2Te0hpq8+ke0eSJPfCnNTPiDlsfwi1/NE=
|
||||
github.com/spf13/cobra v0.0.4/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
|
||||
github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s=
|
||||
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
|
||||
|
@ -366,17 +451,16 @@ github.com/spf13/viper v1.3.2 h1:VUFqw5KcqRf7i70GOzW7N+Q7+gxVBkSSqiXB12+JQ4M=
|
|||
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
|
||||
github.com/storageos/go-api v0.0.0-20180912212459-343b3eff91fc/go.mod h1:ZrLn+e0ZuF3Y65PNF6dIwbJPZqfmtCXxFm9ckv0agOY=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
||||
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/syndtr/gocapability v0.0.0-20160928074757-e7cb7fa329f4/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
||||
github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
||||
github.com/ulikunitz/xz v0.5.5 h1:pFrO0lVpTBXLpYw+pnLj6TbvHuyjXMfjGeCwSqCVwok=
|
||||
github.com/ulikunitz/xz v0.5.5/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8=
|
||||
github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4=
|
||||
github.com/vishvananda/netlink v0.0.0-20171020171820-b2de5d10e38e/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk=
|
||||
github.com/vishvananda/netns v0.0.0-20171111001504-be1fbeda1936/go.mod h1:ZjcWmFBXmLKZu9Nxj3WKYEafiSqer2rnvPr0en9UNpI=
|
||||
|
@ -394,50 +478,62 @@ github.com/xlab/handysort v0.0.0-20150421192137-fb3537ed64a1/go.mod h1:QcJo0QPSf
|
|||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||
github.com/zchee/go-vmnet v0.0.0-20161021174912-97ebf9174097 h1:Ucx5I1l1+TWXvqFmBigYu4Ub4MLvUuUU/whjoUvV95I=
|
||||
github.com/zchee/go-vmnet v0.0.0-20161021174912-97ebf9174097/go.mod h1:lFZSWRIpCfE/pt91hHBBpV6+x87YlCjsp+aIR2qCPPU=
|
||||
go.opencensus.io v0.18.0 h1:Mk5rgZcggtbvtAun5aJzAtjKKN/t0R3jJPlWILlv938=
|
||||
go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA=
|
||||
go.uber.org/atomic v0.0.0-20181018215023-8dc6146f7569/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/multierr v0.0.0-20180122172545-ddea229ff1df/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||
go.uber.org/zap v0.0.0-20180814183419-67bc79d13d15/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE=
|
||||
golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181025213731-e84da0312774/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190228161510-8dd112bcdc25/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8 h1:1wopBVtVdWnn03fZelqdXTqk7U7zPQCb+T4rbU9ZEoU=
|
||||
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190312203227-4b39c73a6495/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20181217174547-8f45f776aaf1/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e h1:bRhVy7zSSasaqNksaRZiA5EEI+Ei4I1nO5Jh72wfHlg=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190206173232-65e2d4e15006/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190328230028-74de082e2cca/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 h1:0GoQqolDA55aaLxZyTzK/Y2ePZzZTUrRacwib7cNsYQ=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
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=
|
||||
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a h1:tImsplftrFpALCYumobsd0K86vlAs/eXGFms2txfJfA=
|
||||
golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
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=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6 h1:bjcUS9ztw9kFmmIxJInhon/0Is3p+EHBKNgquIzo1OI=
|
||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181004145325-8469e314837c/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU=
|
||||
golang.org/x/sys v0.0.0-20181213200352-4d1cda033e06/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
@ -445,33 +541,54 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||
golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f h1:25KHgbfyiSm6vwQLbM3zZIe1v9p/3ea4Rz+nnM5K/i4=
|
||||
golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/time v0.0.0-20161028155119-f51c12702a4d h1:TnM+PKb3ylGmZvyPXmo9m/wktg7Jn/a/fNmr33HSj8g=
|
||||
golang.org/x/time v0.0.0-20161028155119-f51c12702a4d/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c h1:fqgJT0MGcGpPgpWU7VRdRjuArfcOvC4AoJmILihzhDg=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20170824195420-5d2fd3ccab98/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485/go.mod h1:2ltnJ7xHfj0zHS40VVPYEAAMTa3ZGguvHGBSJeRWqE0=
|
||||
gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw=
|
||||
gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e/go.mod h1:kS+toOQn6AQKjmKJ7gzohV1XkqsFehRA2FbsbkopSuQ=
|
||||
google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
|
||||
google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
|
||||
google.golang.org/api v0.0.0-20181220000619-583d854617af/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
|
||||
google.golang.org/api v0.1.0 h1:K6z2u68e86TPdSdefXdzvXgR1zEMa+459vBSfWYAZkI=
|
||||
google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508=
|
||||
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=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.5.0 h1:KxkO13IPW4Lslp2bz+KHP2E3gtFlrIGNThxkZQ3g+4c=
|
||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/genproto v0.0.0-20170731182057-09f6ed296fc6/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
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=
|
||||
google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg=
|
||||
google.golang.org/genproto v0.0.0-20190201180003-4b09977fb922 h1:mBVYJnbrXLA/ZCBTCe7PtEgAUP+1bg92qTaFoPHdz+8=
|
||||
google.golang.org/genproto v0.0.0-20190201180003-4b09977fb922/go.mod h1:L3J43x8/uS+qIUoksaLKe6OS3nUKxOKuIFz1sl2/jx4=
|
||||
google.golang.org/grpc v1.13.0/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=
|
||||
google.golang.org/grpc v1.17.0 h1:TRJYBgMclJvGYn2rIMjj+h9KtMt5r1Ij7ODVRIZkwhk=
|
||||
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
||||
gopkg.in/airbrake/gobrake.v2 v2.0.9 h1:7z2uVWwn7oVeeugY1DtlPAy5H+KYgB1KeKTnqjNatLo=
|
||||
gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/cheggaaa/pb.v1 v1.0.6 h1:YQye4a1JysUfXYB6VihDfxb4lxOAei0xS44yN+srOew=
|
||||
gopkg.in/cheggaaa/pb.v1 v1.0.6/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
|
||||
gopkg.in/cheggaaa/pb.v1 v1.0.27 h1:kJdccidYzt3CaHD1crCFTS1hxyhSi059NhOFUf03YFo=
|
||||
gopkg.in/cheggaaa/pb.v1 v1.0.27/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
|
||||
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/gcfg.v1 v1.2.0/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
|
||||
|
@ -479,19 +596,22 @@ gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2 h1:OAj3g0cR6Dx/R07QgQe8wkA9RNj
|
|||
gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo=
|
||||
gopkg.in/inf.v0 v0.9.0 h1:3zYtXIO92bvsdS3ggAdA8Gb4Azj0YU+TVY1uGYNFA8o=
|
||||
gopkg.in/inf.v0 v0.9.0/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
|
||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
|
||||
gopkg.in/square/go-jose.v2 v2.0.0-20180411045311-89060dee6a84/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
|
||||
gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/warnings.v0 v0.1.1/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
|
||||
gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0 h1:POO/ycCATvegFmVuPpQzZFJ+pGZeX22Ufu6fibxDVjU=
|
||||
gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0/go.mod h1:WDnlLJ4WF5VGsH/HVa3CI79GS0ol3YnhVnKP89i0kNg=
|
||||
gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
||||
grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o=
|
||||
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
k8s.io/gengo v0.0.0-20190116091435-f8a0810f38af/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
|
||||
k8s.io/heapster v1.2.0-beta.1/go.mod h1:h1uhptVXMwC8xtZBYsPXKVi8fpdlYkTs6k949KozGrM=
|
||||
k8s.io/klog v0.3.1 h1:RVgyDHY/kFKtLqh67NvEWIgkMneNoIrdkN0CxDSQc68=
|
||||
|
@ -541,4 +661,6 @@ sigs.k8s.io/sig-storage-lib-external-provisioner v4.0.0+incompatible/go.mod h1:q
|
|||
sigs.k8s.io/structured-merge-diff v0.0.0-20190302045857-e85c7b244fd2/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI=
|
||||
sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs=
|
||||
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
||||
sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck=
|
||||
sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0=
|
||||
vbom.ml/util v0.0.0-20160121211510-db5cfe13f5cc/go.mod h1:so/NYdZXCz+E3ZpW0uAoCj6uzU2+8OWDFv/HxUSs7kI=
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
# EXTRA_START_ARGS: additional flags to pass into minikube start
|
||||
# EXTRA_ARGS: additional flags to pass into minikube
|
||||
# JOB_NAME: the name of the logfile and check name to update on github
|
||||
#
|
||||
# PARALLEL_COUNT: number of tests to run in parallel
|
||||
|
||||
|
||||
readonly TEST_ROOT="${HOME}/minikube-integration"
|
||||
|
@ -75,6 +75,7 @@ gsutil -qm cp \
|
|||
|
||||
gsutil -qm cp "gs://minikube-builds/${MINIKUBE_LOCATION}/testdata"/* testdata/
|
||||
|
||||
|
||||
# Set the executable bit on the e2e binary and out binary
|
||||
export MINIKUBE_BIN="out/minikube-${OS_ARCH}"
|
||||
export E2E_BIN="out/e2e-${OS_ARCH}"
|
||||
|
@ -82,7 +83,7 @@ chmod +x "${MINIKUBE_BIN}" "${E2E_BIN}" out/docker-machine-driver-*
|
|||
|
||||
procs=$(pgrep "minikube-${OS_ARCH}|e2e-${OS_ARCH}" || true)
|
||||
if [[ "${procs}" != "" ]]; then
|
||||
echo "ERROR: found stale test processes to kill:"
|
||||
echo "Warning: found stale test processes to kill:"
|
||||
ps -f -p ${procs} || true
|
||||
kill ${procs} || true
|
||||
kill -9 ${procs} || true
|
||||
|
@ -130,8 +131,13 @@ if type -P virsh; then
|
|||
| awk '{ print $2 }' \
|
||||
| xargs -I {} sh -c "virsh -c qemu:///system destroy {}; virsh -c qemu:///system undefine {}" \
|
||||
|| true
|
||||
# list again after clean up
|
||||
virsh -c qemu:///system list --all
|
||||
virsh -c qemu:///system list --all \
|
||||
| grep Test \
|
||||
| awk '{ print $2 }' \
|
||||
| xargs -I {} sh -c "virsh -c qemu:///system destroy {}; virsh -c qemu:///system undefine {}" \
|
||||
|| true
|
||||
echo ">> Virsh VM list after clean up (should be empty) :"
|
||||
virsh -c qemu:///system list --all || true
|
||||
fi
|
||||
|
||||
if type -P vboxmanage; then
|
||||
|
@ -141,6 +147,11 @@ if type -P vboxmanage; then
|
|||
| cut -d'"' -f2 \
|
||||
| xargs -I {} sh -c "vboxmanage startvm {} --type emergencystop; vboxmanage unregistervm {} --delete" \
|
||||
|| true
|
||||
vboxmanage list vms \
|
||||
| grep Test \
|
||||
| cut -d'"' -f2 \
|
||||
| xargs -I {} sh -c "vboxmanage startvm {} --type emergencystop; vboxmanage unregistervm {} --delete" \
|
||||
|| true
|
||||
|
||||
# remove inaccessible stale VMs https://github.com/kubernetes/minikube/issues/4872
|
||||
vboxmanage list vms \
|
||||
|
@ -148,6 +159,7 @@ if type -P vboxmanage; then
|
|||
| cut -d'"' -f3 \
|
||||
| xargs -I {} sh -c "vboxmanage startvm {} --type emergencystop; vboxmanage unregistervm {} --delete" \
|
||||
|| true
|
||||
|
||||
# list them again after clean up
|
||||
vboxmanage list vms || true
|
||||
fi
|
||||
|
@ -238,7 +250,7 @@ echo ">> Starting ${E2E_BIN} at $(date)"
|
|||
${SUDO_PREFIX}${E2E_BIN} \
|
||||
-minikube-start-args="--vm-driver=${VM_DRIVER} ${EXTRA_START_ARGS}" \
|
||||
-minikube-args="--v=10 --logtostderr ${EXTRA_ARGS}" \
|
||||
-test.v -test.timeout=100m -binary="${MINIKUBE_BIN}" && result=$? || result=$?
|
||||
-test.v -test.timeout=100m -test.parallel=${PARALLEL_COUNT} -binary="${MINIKUBE_BIN}" && result=$? || result=$?
|
||||
echo ">> ${E2E_BIN} exited with ${result} at $(date)"
|
||||
echo ""
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@ set -e
|
|||
OS_ARCH="linux-amd64"
|
||||
VM_DRIVER="kvm2"
|
||||
JOB_NAME="Linux-KVM"
|
||||
PARALLEL_COUNT=4
|
||||
|
||||
# Download files and set permissions
|
||||
source ./common.sh
|
||||
|
|
|
@ -30,6 +30,7 @@ OS_ARCH="linux-amd64"
|
|||
VM_DRIVER="none"
|
||||
JOB_NAME="Linux-None"
|
||||
EXTRA_ARGS="--bootstrapper=kubeadm"
|
||||
PARALLEL_COUNT=1
|
||||
|
||||
SUDO_PREFIX="sudo -E "
|
||||
export KUBECONFIG="/root/.kube/config"
|
||||
|
|
|
@ -28,6 +28,7 @@ set -e
|
|||
OS_ARCH="linux-amd64"
|
||||
VM_DRIVER="virtualbox"
|
||||
JOB_NAME="Linux-VirtualBox"
|
||||
PARALLEL_COUNT=4
|
||||
|
||||
# Download files and set permissions
|
||||
source ./common.sh
|
||||
|
|
|
@ -31,7 +31,7 @@ VM_DRIVER="hyperkit"
|
|||
JOB_NAME="OSX-Hyperkit"
|
||||
EXTRA_ARGS="--bootstrapper=kubeadm"
|
||||
EXTRA_START_ARGS=""
|
||||
|
||||
PARALLEL_COUNT=3
|
||||
|
||||
# Download files and set permissions
|
||||
source common.sh
|
||||
|
|
|
@ -29,6 +29,7 @@ OS_ARCH="darwin-amd64"
|
|||
VM_DRIVER="virtualbox"
|
||||
JOB_NAME="OSX-Virtualbox"
|
||||
EXTRA_ARGS="--bootstrapper=kubeadm"
|
||||
PARALLEL_COUNT=3
|
||||
|
||||
# Download files and set permissions
|
||||
source common.sh
|
||||
|
|
|
@ -71,9 +71,14 @@ func (s *PodStore) Stop() {
|
|||
}
|
||||
|
||||
// GetClient gets the client from config
|
||||
func GetClient() (kubernetes.Interface, error) {
|
||||
func GetClient(kubectlContext ...string) (kubernetes.Interface, error) {
|
||||
loadingRules := clientcmd.NewDefaultClientConfigLoadingRules()
|
||||
configOverrides := &clientcmd.ConfigOverrides{}
|
||||
if kubectlContext != nil {
|
||||
configOverrides = &clientcmd.ConfigOverrides{
|
||||
CurrentContext: kubectlContext[0],
|
||||
}
|
||||
}
|
||||
kubeConfig := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, configOverrides)
|
||||
config, err := kubeConfig.ClientConfig()
|
||||
if err != nil {
|
||||
|
|
|
@ -0,0 +1,90 @@
|
|||
// +build integration
|
||||
|
||||
/*
|
||||
Copyright 2019 The Kubernetes Authors 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.
|
||||
*/
|
||||
|
||||
// a_download_only_test.go filename starts with a, for the purpose that it runs before all parallel tests and downloads the images and caches them.
|
||||
package integration
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/go-getter"
|
||||
"github.com/pkg/errors"
|
||||
"k8s.io/minikube/pkg/minikube/constants"
|
||||
pkgutil "k8s.io/minikube/pkg/util"
|
||||
"k8s.io/minikube/test/integration/util"
|
||||
)
|
||||
|
||||
// Note this test runs before all because filename is alphabetically first
|
||||
// is used to cache images and binaries used by other parallel tests to avoid redownloading.
|
||||
// TestDownloadOnly tests the --download-only option
|
||||
func TestDownloadOnly(t *testing.T) {
|
||||
p := profileName(t)
|
||||
mk := NewMinikubeRunner(t, p)
|
||||
if !isTestNoneDriver(t) { // none driver doesnt need to be deleted
|
||||
defer mk.TearDown(t)
|
||||
}
|
||||
|
||||
t.Run("Oldest", func(t *testing.T) {
|
||||
stdout, stderr, err := mk.Start("--download-only", fmt.Sprintf("--kubernetes-version=%s", constants.OldestKubernetesVersion))
|
||||
if err != nil {
|
||||
t.Errorf("%s minikube --download-only failed : %v\nstdout: %s\nstderr: %s", p, err, stdout, stderr)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("Newest", func(t *testing.T) {
|
||||
stdout, stderr, err := mk.Start("--download-only", fmt.Sprintf("--kubernetes-version=%s", constants.NewestKubernetesVersion))
|
||||
if err != nil {
|
||||
t.Errorf("%s minikube --download-only failed : %v\nstdout: %s\nstderr: %s", p, err, stdout, stderr)
|
||||
}
|
||||
// TODO: add test to check if files are downloaded
|
||||
})
|
||||
|
||||
t.Run("DownloadLatestRelease", func(t *testing.T) {
|
||||
dest := filepath.Join(*testdataDir, fmt.Sprintf("minikube-%s-%s-latest-stable", runtime.GOOS, runtime.GOARCH))
|
||||
err := downloadMinikubeBinary(t, dest, "latest")
|
||||
if err != nil {
|
||||
t.Errorf("erorr downloading the latest minikube release %v", err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// downloadMinikubeBinary downloads the minikube binary from github used by TestVersionUpgrade
|
||||
// acts as a test setup for TestVersionUpgrade
|
||||
func downloadMinikubeBinary(t *testing.T, dest string, version string) error {
|
||||
t.Helper()
|
||||
// Grab latest release binary
|
||||
url := pkgutil.GetBinaryDownloadURL(version, runtime.GOOS)
|
||||
download := func() error {
|
||||
return getter.GetFile(dest, url)
|
||||
}
|
||||
|
||||
if err := util.RetryX(download, 13*time.Second, 5*time.Minute); err != nil {
|
||||
return errors.Wrap(err, "Failed to get latest release binary")
|
||||
}
|
||||
if runtime.GOOS != "windows" {
|
||||
if err := os.Chmod(dest, 0700); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,133 @@
|
|||
// +build integration
|
||||
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors 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 integration
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/machine/libmachine/state"
|
||||
"github.com/pkg/errors"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
commonutil "k8s.io/minikube/pkg/util"
|
||||
"k8s.io/minikube/test/integration/util"
|
||||
)
|
||||
|
||||
func TestContainerd(t *testing.T) {
|
||||
if isTestNoneDriver(t) {
|
||||
t.Skip("Can't run containerd backend with none driver")
|
||||
}
|
||||
if shouldRunInParallel(t) {
|
||||
t.Parallel()
|
||||
}
|
||||
|
||||
t.Run("GvisorRestart", testGvisorRestart)
|
||||
}
|
||||
|
||||
func testGvisorRestart(t *testing.T) {
|
||||
p := profileName(t)
|
||||
if shouldRunInParallel(t) {
|
||||
t.Parallel()
|
||||
}
|
||||
mk := NewMinikubeRunner(t, p, "--wait=false")
|
||||
defer mk.TearDown(t)
|
||||
|
||||
stdout, stderr, err := mk.Start("--container-runtime=containerd", "--docker-opt containerd=/var/run/containerd/containerd.sock")
|
||||
if err != nil {
|
||||
t.Fatalf("failed to start minikube (for profile %s) failed : %v\nstdout: %s\nstderr: %s", p, err, stdout, stderr)
|
||||
}
|
||||
|
||||
mk.RunCommand("addons enable gvisor", true)
|
||||
|
||||
t.Log("waiting for gvisor controller to come up")
|
||||
if err := waitForGvisorControllerRunning(p); err != nil {
|
||||
t.Errorf("waiting for gvisor controller to be up: %v", err)
|
||||
}
|
||||
|
||||
createUntrustedWorkload(t, p)
|
||||
t.Log("making sure untrusted workload is Running")
|
||||
if err := waitForUntrustedNginxRunning(p); err != nil {
|
||||
t.Errorf("waiting for nginx to be up: %v", err)
|
||||
}
|
||||
deleteUntrustedWorkload(t, p)
|
||||
|
||||
mk.RunCommand("delete", true)
|
||||
stdout, stderr, err = mk.Start()
|
||||
if err != nil {
|
||||
t.Fatalf("failed to start minikube (for profile %s) failed : %v \nstdout: %s \nstderr: %s", t.Name(), err, stdout, stderr)
|
||||
}
|
||||
mk.CheckStatus(state.Running.String())
|
||||
|
||||
t.Log("waiting for gvisor controller to come up")
|
||||
if err := waitForGvisorControllerRunning(p); err != nil {
|
||||
t.Errorf("waiting for gvisor controller to be up: %v", err)
|
||||
}
|
||||
|
||||
createUntrustedWorkload(t, p)
|
||||
t.Log("making sure untrusted workload is Running")
|
||||
if err := waitForUntrustedNginxRunning(p); err != nil {
|
||||
t.Errorf("waiting for nginx to be up: %v", err)
|
||||
}
|
||||
deleteUntrustedWorkload(t, p)
|
||||
}
|
||||
|
||||
func createUntrustedWorkload(t *testing.T, profile string) {
|
||||
kr := util.NewKubectlRunner(t, profile)
|
||||
untrustedPath := filepath.Join(*testdataDir, "nginx-untrusted.yaml")
|
||||
t.Log("creating pod with untrusted workload annotation")
|
||||
if _, err := kr.RunCommand([]string{"replace", "-f", untrustedPath, "--force"}); err != nil {
|
||||
t.Fatalf("creating untrusted nginx resource: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func deleteUntrustedWorkload(t *testing.T, profile string) {
|
||||
kr := util.NewKubectlRunner(t, profile)
|
||||
untrustedPath := filepath.Join(*testdataDir, "nginx-untrusted.yaml")
|
||||
if _, err := kr.RunCommand([]string{"delete", "-f", untrustedPath}); err != nil {
|
||||
t.Logf("error deleting untrusted nginx resource: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// waitForGvisorControllerRunning waits for the gvisor controller pod to be running
|
||||
func waitForGvisorControllerRunning(p string) error {
|
||||
client, err := commonutil.GetClient(p)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "getting kubernetes client")
|
||||
}
|
||||
|
||||
selector := labels.SelectorFromSet(labels.Set(map[string]string{"kubernetes.io/minikube-addons": "gvisor"}))
|
||||
if err := commonutil.WaitForPodsWithLabelRunning(client, "kube-system", selector); err != nil {
|
||||
return errors.Wrap(err, "waiting for gvisor controller pod to stabilize")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// waitForUntrustedNginxRunning waits for the untrusted nginx pod to start running
|
||||
func waitForUntrustedNginxRunning(miniProfile string) error {
|
||||
client, err := commonutil.GetClient(miniProfile)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "getting kubernetes client")
|
||||
}
|
||||
|
||||
selector := labels.SelectorFromSet(labels.Set(map[string]string{"run": "nginx"}))
|
||||
if err := commonutil.WaitForPodsWithLabelRunning(client, "default", selector); err != nil {
|
||||
return errors.Wrap(err, "waiting for nginx pods")
|
||||
}
|
||||
return nil
|
||||
}
|
|
@ -20,34 +20,38 @@ package integration
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/docker/machine/libmachine/state"
|
||||
)
|
||||
|
||||
func TestDocker(t *testing.T) {
|
||||
mk := NewMinikubeRunner(t, "--wait=false")
|
||||
if usingNoneDriver(mk) {
|
||||
if isTestNoneDriver(t) {
|
||||
t.Skip("skipping test as none driver does not bundle docker")
|
||||
}
|
||||
p := profileName(t)
|
||||
if shouldRunInParallel(t) {
|
||||
t.Parallel()
|
||||
}
|
||||
mk := NewMinikubeRunner(t, p, "--wait=false")
|
||||
defer mk.TearDown(t)
|
||||
|
||||
// Start a timer for all remaining commands, to display failure output before a panic.
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Minute)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Minute)
|
||||
defer cancel()
|
||||
|
||||
if _, _, err := mk.RunWithContext(ctx, "delete"); err != nil {
|
||||
t.Logf("pre-delete failed (probably ok): %v", err)
|
||||
}
|
||||
|
||||
startCmd := fmt.Sprintf("start %s %s %s", mk.StartArgs, mk.GlobalArgs,
|
||||
"--docker-env=FOO=BAR --docker-env=BAZ=BAT --docker-opt=debug --docker-opt=icc=true")
|
||||
stdout, stderr, err := mk.RunWithContext(ctx, startCmd)
|
||||
stdout, stderr, err := mk.Start("--docker-env=FOO=BAR", "--docker-env=BAZ=BAT", "--docker-opt=debug", " --docker-opt=icc=true")
|
||||
if err != nil {
|
||||
t.Fatalf("start: %v\nstdout: %s\nstderr: %s", err, stdout, stderr)
|
||||
t.Fatalf("TestDocker minikube start failed : %v\nstdout: %s\nstderr: %s", err, stdout, stderr)
|
||||
}
|
||||
|
||||
mk.EnsureRunning()
|
||||
mk.CheckStatus(state.Running.String())
|
||||
|
||||
stdout, stderr, err = mk.RunWithContext(ctx, "ssh -- systemctl show docker --property=Environment --no-pager")
|
||||
if err != nil {
|
||||
|
|
|
@ -21,6 +21,7 @@ import (
|
|||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"k8s.io/minikube/test/integration/util"
|
||||
)
|
||||
|
@ -31,19 +32,56 @@ func TestMain(m *testing.M) {
|
|||
os.Exit(m.Run())
|
||||
}
|
||||
|
||||
var startTimeout = flag.Int("timeout", 25, "number of minutes to wait for minikube start")
|
||||
var binaryPath = flag.String("binary", "../../out/minikube", "path to minikube binary")
|
||||
var globalArgs = flag.String("minikube-args", "", "Arguments to pass to minikube")
|
||||
var startArgs = flag.String("minikube-start-args", "", "Arguments to pass to minikube start")
|
||||
var mountArgs = flag.String("minikube-mount-args", "", "Arguments to pass to minikube mount")
|
||||
var testdataDir = flag.String("testdata-dir", "testdata", "the directory relative to test/integration where the testdata lives")
|
||||
var parallel = flag.Bool("parallel", true, "run the tests in parallel, set false for run sequentially")
|
||||
|
||||
// NewMinikubeRunner creates a new MinikubeRunner
|
||||
func NewMinikubeRunner(t *testing.T, extraArgs ...string) util.MinikubeRunner {
|
||||
func NewMinikubeRunner(t *testing.T, profile string, extraStartArgs ...string) util.MinikubeRunner {
|
||||
return util.MinikubeRunner{
|
||||
BinaryPath: *binaryPath,
|
||||
StartArgs: *startArgs + " " + strings.Join(extraArgs, " "),
|
||||
GlobalArgs: *globalArgs,
|
||||
MountArgs: *mountArgs,
|
||||
T: t,
|
||||
Profile: profile,
|
||||
BinaryPath: *binaryPath,
|
||||
StartArgs: *startArgs + " " + strings.Join(extraStartArgs, " "),
|
||||
GlobalArgs: *globalArgs,
|
||||
MountArgs: *mountArgs,
|
||||
TimeOutStart: time.Duration(*startTimeout) * time.Minute,
|
||||
T: t,
|
||||
}
|
||||
}
|
||||
|
||||
// isTestNoneDriver checks if the current test is for none driver
|
||||
func isTestNoneDriver(t *testing.T) bool {
|
||||
t.Helper()
|
||||
return strings.Contains(*startArgs, "--vm-driver=none")
|
||||
}
|
||||
|
||||
// profileName chooses a profile name based on the test name
|
||||
// to be used in minikube and kubecontext across that test
|
||||
func profileName(t *testing.T) string {
|
||||
t.Helper()
|
||||
if isTestNoneDriver(t) {
|
||||
return "minikube"
|
||||
}
|
||||
p := strings.Split(t.Name(), "/")[0] // for i.e, TestFunctional/SSH returns TestFunctional
|
||||
if p == "TestFunctional" {
|
||||
return "minikube"
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
// shouldRunInParallel deterimines if test should run in parallel or not
|
||||
func shouldRunInParallel(t *testing.T) bool {
|
||||
t.Helper()
|
||||
if !*parallel {
|
||||
return false
|
||||
}
|
||||
if isTestNoneDriver(t) {
|
||||
return false
|
||||
}
|
||||
p := strings.Split(t.Name(), "/")[0] // for i.e, TestFunctional/SSH returns TestFunctional
|
||||
return p != "TestFunctional" // gosimple lint: https://staticcheck.io/docs/checks#S1008
|
||||
}
|
||||
|
|
|
@ -25,22 +25,24 @@ import (
|
|||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/docker/machine/libmachine/state"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
retryablehttp "github.com/hashicorp/go-retryablehttp"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
commonutil "k8s.io/minikube/pkg/util"
|
||||
pkgutil "k8s.io/minikube/pkg/util"
|
||||
"k8s.io/minikube/test/integration/util"
|
||||
)
|
||||
|
||||
func testAddons(t *testing.T) {
|
||||
t.Parallel()
|
||||
client, err := pkgutil.GetClient()
|
||||
p := profileName(t)
|
||||
client, err := pkgutil.GetClient(p)
|
||||
if err != nil {
|
||||
t.Fatalf("Could not get kubernetes client: %v", err)
|
||||
}
|
||||
|
@ -76,7 +78,8 @@ func readLineWithTimeout(b *bufio.Reader, timeout time.Duration) (string, error)
|
|||
|
||||
func testDashboard(t *testing.T) {
|
||||
t.Parallel()
|
||||
mk := NewMinikubeRunner(t, "--wait=false")
|
||||
p := profileName(t)
|
||||
mk := NewMinikubeRunner(t, p, "--wait=false")
|
||||
cmd, out := mk.RunDaemon("dashboard --url")
|
||||
defer func() {
|
||||
err := cmd.Process.Kill()
|
||||
|
@ -85,7 +88,7 @@ func testDashboard(t *testing.T) {
|
|||
}
|
||||
}()
|
||||
|
||||
s, err := readLineWithTimeout(out, 180*time.Second)
|
||||
s, err := readLineWithTimeout(out, 240*time.Second)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to read url: %v", err)
|
||||
}
|
||||
|
@ -121,30 +124,27 @@ func testDashboard(t *testing.T) {
|
|||
|
||||
func testIngressController(t *testing.T) {
|
||||
t.Parallel()
|
||||
mk := NewMinikubeRunner(t, "--wait=false")
|
||||
kr := util.NewKubectlRunner(t)
|
||||
p := profileName(t)
|
||||
mk := NewMinikubeRunner(t, p, "--wait=false")
|
||||
kr := util.NewKubectlRunner(t, p)
|
||||
|
||||
mk.RunCommand("addons enable ingress", true)
|
||||
if err := util.WaitForIngressControllerRunning(t); err != nil {
|
||||
t.Fatalf("waiting for ingress-controller to be up: %v", err)
|
||||
if err := waitForIngressControllerRunning(p); err != nil {
|
||||
t.Fatalf("Failed waiting for ingress-controller to be up: %v", err)
|
||||
}
|
||||
|
||||
curdir, err := filepath.Abs("")
|
||||
if err != nil {
|
||||
t.Errorf("Error getting the file path for current directory: %s", curdir)
|
||||
}
|
||||
ingressPath := path.Join(curdir, "testdata", "nginx-ing.yaml")
|
||||
ingressPath := filepath.Join(*testdataDir, "nginx-ing.yaml")
|
||||
if _, err := kr.RunCommand([]string{"create", "-f", ingressPath}); err != nil {
|
||||
t.Fatalf("creating nginx ingress resource: %v", err)
|
||||
t.Fatalf("Failed creating nginx ingress resource: %v", err)
|
||||
}
|
||||
|
||||
podPath := path.Join(curdir, "testdata", "nginx-pod-svc.yaml")
|
||||
podPath := filepath.Join(*testdataDir, "nginx-pod-svc.yaml")
|
||||
if _, err := kr.RunCommand([]string{"create", "-f", podPath}); err != nil {
|
||||
t.Fatalf("creating nginx ingress resource: %v", err)
|
||||
t.Fatalf("Failed creating nginx ingress resource: %v", err)
|
||||
}
|
||||
|
||||
if err := util.WaitForNginxRunning(t); err != nil {
|
||||
t.Fatalf("waiting for nginx to be up: %v", err)
|
||||
if err := waitForNginxRunning(t, p); err != nil {
|
||||
t.Fatalf("Failed waiting for nginx to be up: %v", err)
|
||||
}
|
||||
|
||||
checkIngress := func() error {
|
||||
|
@ -157,7 +157,7 @@ func testIngressController(t *testing.T) {
|
|||
return nil
|
||||
}
|
||||
|
||||
if err := util.Retry(t, checkIngress, 3*time.Second, 5); err != nil {
|
||||
if err := util.Retry(t, checkIngress, 2*time.Second, 5); err != nil {
|
||||
t.Fatalf(err.Error())
|
||||
}
|
||||
|
||||
|
@ -173,12 +173,13 @@ func testIngressController(t *testing.T) {
|
|||
|
||||
func testServicesList(t *testing.T) {
|
||||
t.Parallel()
|
||||
mk := NewMinikubeRunner(t)
|
||||
p := profileName(t)
|
||||
mk := NewMinikubeRunner(t, p)
|
||||
|
||||
checkServices := func() error {
|
||||
output := mk.RunCommand("service list", false)
|
||||
output, stderr := mk.RunCommand("service list", false)
|
||||
if !strings.Contains(output, "kubernetes") {
|
||||
return fmt.Errorf("Error, kubernetes service missing from output %s", output)
|
||||
return fmt.Errorf("error, kubernetes service missing from output: %s, \n stderr: %s", output, stderr)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -188,9 +189,10 @@ func testServicesList(t *testing.T) {
|
|||
}
|
||||
func testRegistry(t *testing.T) {
|
||||
t.Parallel()
|
||||
mk := NewMinikubeRunner(t)
|
||||
p := profileName(t)
|
||||
mk := NewMinikubeRunner(t, p)
|
||||
mk.RunCommand("addons enable registry", true)
|
||||
client, err := pkgutil.GetClient()
|
||||
client, err := pkgutil.GetClient(p)
|
||||
if err != nil {
|
||||
t.Fatalf("getting kubernetes client: %v", err)
|
||||
}
|
||||
|
@ -208,12 +210,12 @@ func testRegistry(t *testing.T) {
|
|||
if err := pkgutil.WaitForPodsWithLabelRunning(client, "kube-system", ps); err != nil {
|
||||
t.Fatalf("waiting for registry-proxy pods: %v", err)
|
||||
}
|
||||
|
||||
ip := strings.TrimSpace(mk.RunCommand("ip", true))
|
||||
ip, stderr := mk.RunCommand("ip", true)
|
||||
ip = strings.TrimSpace(ip)
|
||||
endpoint := fmt.Sprintf("http://%s:%d", ip, 5000)
|
||||
u, err := url.Parse(endpoint)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to parse %q: %v", endpoint, err)
|
||||
t.Fatalf("failed to parse %q: %v stderr : %s", endpoint, err, stderr)
|
||||
}
|
||||
t.Log("checking registry access from outside cluster")
|
||||
|
||||
|
@ -235,7 +237,8 @@ func testRegistry(t *testing.T) {
|
|||
}
|
||||
|
||||
t.Log("checking registry access from inside cluster")
|
||||
kr := util.NewKubectlRunner(t)
|
||||
kr := util.NewKubectlRunner(t, p)
|
||||
// TODO: Fix this
|
||||
out, _ := kr.RunCommand([]string{
|
||||
"run",
|
||||
"registry-test",
|
||||
|
@ -259,88 +262,41 @@ func testRegistry(t *testing.T) {
|
|||
}()
|
||||
mk.RunCommand("addons disable registry", true)
|
||||
}
|
||||
func testGvisor(t *testing.T) {
|
||||
mk := NewMinikubeRunner(t, "--wait=false")
|
||||
mk.RunCommand("addons enable gvisor", true)
|
||||
|
||||
t.Log("waiting for gvisor controller to come up")
|
||||
if err := util.WaitForGvisorControllerRunning(t); err != nil {
|
||||
t.Fatalf("waiting for gvisor controller to be up: %v", err)
|
||||
}
|
||||
// waitForNginxRunning waits for nginx service to be up
|
||||
func waitForNginxRunning(t *testing.T, miniProfile string) error {
|
||||
client, err := commonutil.GetClient(miniProfile)
|
||||
|
||||
createUntrustedWorkload(t)
|
||||
|
||||
t.Log("making sure untrusted workload is Running")
|
||||
if err := util.WaitForUntrustedNginxRunning(); err != nil {
|
||||
t.Fatalf("waiting for nginx to be up: %v", err)
|
||||
}
|
||||
|
||||
t.Log("disabling gvisor addon")
|
||||
mk.RunCommand("addons disable gvisor", true)
|
||||
t.Log("waiting for gvisor controller pod to be deleted")
|
||||
if err := util.WaitForGvisorControllerDeleted(); err != nil {
|
||||
t.Fatalf("waiting for gvisor controller to be deleted: %v", err)
|
||||
}
|
||||
|
||||
createUntrustedWorkload(t)
|
||||
|
||||
t.Log("waiting for FailedCreatePodSandBox event")
|
||||
if err := util.WaitForFailedCreatePodSandBoxEvent(); err != nil {
|
||||
t.Fatalf("waiting for FailedCreatePodSandBox event: %v", err)
|
||||
}
|
||||
deleteUntrustedWorkload(t)
|
||||
}
|
||||
|
||||
func testGvisorRestart(t *testing.T) {
|
||||
mk := NewMinikubeRunner(t, "--wait=false")
|
||||
mk.EnsureRunning()
|
||||
mk.RunCommand("addons enable gvisor", true)
|
||||
|
||||
t.Log("waiting for gvisor controller to come up")
|
||||
if err := util.WaitForGvisorControllerRunning(t); err != nil {
|
||||
t.Fatalf("waiting for gvisor controller to be up: %v", err)
|
||||
}
|
||||
|
||||
// TODO: @priyawadhwa to add test for stop as well
|
||||
mk.RunCommand("delete", false)
|
||||
mk.CheckStatus(state.None.String())
|
||||
mk.Start()
|
||||
mk.CheckStatus(state.Running.String())
|
||||
|
||||
t.Log("waiting for gvisor controller to come up")
|
||||
if err := util.WaitForGvisorControllerRunning(t); err != nil {
|
||||
t.Fatalf("waiting for gvisor controller to be up: %v", err)
|
||||
}
|
||||
|
||||
createUntrustedWorkload(t)
|
||||
t.Log("making sure untrusted workload is Running")
|
||||
if err := util.WaitForUntrustedNginxRunning(); err != nil {
|
||||
t.Fatalf("waiting for nginx to be up: %v", err)
|
||||
}
|
||||
deleteUntrustedWorkload(t)
|
||||
}
|
||||
|
||||
func createUntrustedWorkload(t *testing.T) {
|
||||
kr := util.NewKubectlRunner(t)
|
||||
curdir, err := filepath.Abs("")
|
||||
if err != nil {
|
||||
t.Errorf("Error getting the file path for current directory: %s", curdir)
|
||||
return errors.Wrap(err, "getting kubernetes client")
|
||||
}
|
||||
untrustedPath := path.Join(curdir, "testdata", "nginx-untrusted.yaml")
|
||||
t.Log("creating pod with untrusted workload annotation")
|
||||
if _, err := kr.RunCommand([]string{"replace", "-f", untrustedPath, "--force"}); err != nil {
|
||||
t.Fatalf("creating untrusted nginx resource: %v", err)
|
||||
|
||||
selector := labels.SelectorFromSet(labels.Set(map[string]string{"run": "nginx"}))
|
||||
if err := commonutil.WaitForPodsWithLabelRunning(client, "default", selector); err != nil {
|
||||
return errors.Wrap(err, "waiting for nginx pods")
|
||||
}
|
||||
|
||||
if err := commonutil.WaitForService(client, "default", "nginx", true, time.Millisecond*500, time.Minute*10); err != nil {
|
||||
t.Errorf("Error waiting for nginx service to be up")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func deleteUntrustedWorkload(t *testing.T) {
|
||||
kr := util.NewKubectlRunner(t)
|
||||
curdir, err := filepath.Abs("")
|
||||
// waitForIngressControllerRunning waits until ingress controller pod to be running
|
||||
func waitForIngressControllerRunning(miniProfile string) error {
|
||||
client, err := commonutil.GetClient(miniProfile)
|
||||
if err != nil {
|
||||
t.Errorf("Error getting the file path for current directory: %s", curdir)
|
||||
return errors.Wrap(err, "getting kubernetes client")
|
||||
}
|
||||
untrustedPath := path.Join(curdir, "testdata", "nginx-untrusted.yaml")
|
||||
if _, err := kr.RunCommand([]string{"delete", "-f", untrustedPath}); err != nil {
|
||||
t.Logf("error deleting untrusted nginx resource: %v", err)
|
||||
|
||||
if err := commonutil.WaitForDeploymentToStabilize(client, "kube-system", "nginx-ingress-controller", time.Minute*10); err != nil {
|
||||
return errors.Wrap(err, "waiting for ingress-controller deployment to stabilize")
|
||||
}
|
||||
|
||||
selector := labels.SelectorFromSet(labels.Set(map[string]string{"app.kubernetes.io/name": "nginx-ingress-controller"}))
|
||||
if err := commonutil.WaitForPodsWithLabelRunning(client, "kube-system", selector); err != nil {
|
||||
return errors.Wrap(err, "waiting for ingress-controller pods")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -32,13 +32,14 @@ import (
|
|||
|
||||
func testClusterDNS(t *testing.T) {
|
||||
t.Parallel()
|
||||
client, err := pkgutil.GetClient()
|
||||
p := profileName(t)
|
||||
client, err := pkgutil.GetClient(p)
|
||||
if err != nil {
|
||||
t.Fatalf("Error getting kubernetes client %v", err)
|
||||
}
|
||||
|
||||
kr := util.NewKubectlRunner(t)
|
||||
busybox := busyBoxPod(t, client, kr)
|
||||
kr := util.NewKubectlRunner(t, p)
|
||||
busybox := busyBoxPod(t, client, kr, p)
|
||||
defer func() {
|
||||
if _, err := kr.RunCommand([]string{"delete", "po", busybox}); err != nil {
|
||||
t.Errorf("delete failed: %v", err)
|
||||
|
@ -61,12 +62,12 @@ func testClusterDNS(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func busyBoxPod(t *testing.T, c kubernetes.Interface, kr *util.KubectlRunner) string {
|
||||
func busyBoxPod(t *testing.T, c kubernetes.Interface, kr *util.KubectlRunner, profile string) string {
|
||||
if _, err := kr.RunCommand([]string{"create", "-f", filepath.Join(*testdataDir, "busybox.yaml")}); err != nil {
|
||||
t.Fatalf("creating busybox pod: %s", err)
|
||||
}
|
||||
// TODO(tstromberg): Refactor WaitForBusyboxRunning to return name of pod.
|
||||
if err := util.WaitForBusyboxRunning(t, "default"); err != nil {
|
||||
if err := util.WaitForBusyboxRunning(t, "default", profile); err != nil {
|
||||
t.Fatalf("Waiting for busybox pod to be up: %v", err)
|
||||
}
|
||||
|
|
@ -30,13 +30,14 @@ import (
|
|||
// Assert that docker-env subcommand outputs usable information for "docker ps"
|
||||
func testClusterEnv(t *testing.T) {
|
||||
t.Parallel()
|
||||
r := NewMinikubeRunner(t, "--wait=false")
|
||||
p := profileName(t)
|
||||
mk := NewMinikubeRunner(t, p, "--wait=false")
|
||||
|
||||
// Set a specific shell syntax so that we don't have to handle every possible user shell
|
||||
envOut := r.RunCommand("docker-env --shell=bash", true)
|
||||
vars := r.ParseEnvCmdOutput(envOut)
|
||||
envOut, stderr := mk.RunCommand("docker-env --shell=bash", true)
|
||||
vars := mk.ParseEnvCmdOutput(envOut)
|
||||
if len(vars) == 0 {
|
||||
t.Fatalf("Failed to parse env vars:\n%s", envOut)
|
||||
t.Fatalf("Failed to parse env vars:\n%s, \n stderr: %s ", envOut, stderr)
|
||||
}
|
||||
for k, v := range vars {
|
||||
t.Logf("Found: %s=%s", k, v)
|
|
@ -25,8 +25,8 @@ import (
|
|||
|
||||
func testClusterLogs(t *testing.T) {
|
||||
t.Parallel()
|
||||
mk := NewMinikubeRunner(t)
|
||||
mk.EnsureRunning()
|
||||
p := profileName(t)
|
||||
mk := NewMinikubeRunner(t, p)
|
||||
logsCmdOutput := mk.GetLogs()
|
||||
|
||||
// check for # of lines or check for strings
|
|
@ -25,10 +25,11 @@ import (
|
|||
|
||||
func testClusterSSH(t *testing.T) {
|
||||
t.Parallel()
|
||||
mk := NewMinikubeRunner(t, "--wait=false")
|
||||
p := profileName(t)
|
||||
mk := NewMinikubeRunner(t, p, "--wait=false")
|
||||
expectedStr := "hello"
|
||||
sshCmdOutput := mk.RunCommand("ssh echo "+expectedStr, true)
|
||||
sshCmdOutput, stderr := mk.RunCommand("ssh echo "+expectedStr, true)
|
||||
if !strings.Contains(sshCmdOutput, expectedStr) {
|
||||
t.Fatalf("ExpectedStr sshCmdOutput to be: %s. Output was: %s", expectedStr, sshCmdOutput)
|
||||
t.Fatalf("ExpectedStr sshCmdOutput to be: %s. Output was: %s Stderr: %s", expectedStr, sshCmdOutput, stderr)
|
||||
}
|
||||
}
|
|
@ -28,12 +28,13 @@ import (
|
|||
)
|
||||
|
||||
func testClusterStatus(t *testing.T) {
|
||||
kubectlRunner := util.NewKubectlRunner(t)
|
||||
p := profileName(t)
|
||||
kr := util.NewKubectlRunner(t, p)
|
||||
cs := api.ComponentStatusList{}
|
||||
|
||||
healthy := func() error {
|
||||
t.Log("Checking if cluster is healthy.")
|
||||
if err := kubectlRunner.RunCommandParseOutput([]string{"get", "cs"}, &cs); err != nil {
|
||||
if err := kr.RunCommandParseOutput([]string{"get", "cs"}, &cs); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, i := range cs.Items {
|
||||
|
@ -45,7 +46,7 @@ func testClusterStatus(t *testing.T) {
|
|||
status = c.Status
|
||||
}
|
||||
if status != api.ConditionTrue {
|
||||
err := fmt.Errorf("Component %s is not Healthy! Status: %s", i.GetName(), status)
|
||||
err := fmt.Errorf("component %s is not Healthy! Status: %s", i.GetName(), status)
|
||||
t.Logf("Retrying, %v", err)
|
||||
return err
|
||||
}
|
|
@ -22,7 +22,6 @@ import (
|
|||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
@ -38,12 +37,13 @@ func testMounting(t *testing.T) {
|
|||
if runtime.GOOS == "darwin" {
|
||||
t.Skip("mount tests disabled in darwin due to timeout (issue#3200)")
|
||||
}
|
||||
if strings.Contains(*globalArgs, "--vm-driver=none") {
|
||||
if isTestNoneDriver(t) {
|
||||
t.Skip("skipping test for none driver as it does not need mount")
|
||||
}
|
||||
|
||||
t.Parallel()
|
||||
mk := NewMinikubeRunner(t, "--wait=false")
|
||||
p := profileName(t)
|
||||
mk := NewMinikubeRunner(t, p, "--wait=false")
|
||||
|
||||
tempDir, err := ioutil.TempDir("", "mounttest")
|
||||
if err != nil {
|
||||
|
@ -60,14 +60,9 @@ func testMounting(t *testing.T) {
|
|||
}
|
||||
}()
|
||||
|
||||
kubectlRunner := util.NewKubectlRunner(t)
|
||||
kr := util.NewKubectlRunner(t, p)
|
||||
podName := "busybox-mount"
|
||||
curdir, err := filepath.Abs("")
|
||||
if err != nil {
|
||||
t.Errorf("Error getting the file path for current directory: %s", curdir)
|
||||
}
|
||||
podPath := path.Join(curdir, "testdata", "busybox-mount-test.yaml")
|
||||
|
||||
podPath := filepath.Join(*testdataDir, "busybox-mount-test.yaml")
|
||||
// Write file in mounted dir from host
|
||||
expected := "test\n"
|
||||
if err := writeFilesFromHost(tempDir, []string{"fromhost", "fromhostremove"}, expected); err != nil {
|
||||
|
@ -77,14 +72,14 @@ func testMounting(t *testing.T) {
|
|||
// Create the pods we need outside the main test loop.
|
||||
setupTest := func() error {
|
||||
t.Logf("Deploying pod from: %s", podPath)
|
||||
if _, err := kubectlRunner.RunCommand([]string{"create", "-f", podPath}); err != nil {
|
||||
if _, err := kr.RunCommand([]string{"create", "-f", podPath}); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
defer func() {
|
||||
t.Logf("Deleting pod from: %s", podPath)
|
||||
if out, err := kubectlRunner.RunCommand([]string{"delete", "-f", podPath}); err != nil {
|
||||
if out, err := kr.RunCommand([]string{"delete", "-f", podPath}); err != nil {
|
||||
t.Logf("delete -f %s failed: %v\noutput: %s\n", podPath, err, out)
|
||||
}
|
||||
}()
|
||||
|
@ -93,13 +88,13 @@ func testMounting(t *testing.T) {
|
|||
t.Fatal("mountTest failed with error:", err)
|
||||
}
|
||||
|
||||
if err := waitForPods(map[string]string{"integration-test": "busybox-mount"}); err != nil {
|
||||
if err := waitForPods(map[string]string{"integration-test": "busybox-mount"}, p); err != nil {
|
||||
t.Fatalf("Error waiting for busybox mount pod to be up: %v", err)
|
||||
}
|
||||
t.Logf("Pods appear to be running")
|
||||
|
||||
mountTest := func() error {
|
||||
if err := verifyFiles(mk, kubectlRunner, tempDir, podName, expected); err != nil {
|
||||
if err := verifyFiles(mk, kr, tempDir, podName, expected); err != nil {
|
||||
t.Fatalf(err.Error())
|
||||
}
|
||||
|
||||
|
@ -126,14 +121,14 @@ func writeFilesFromHost(mountedDir string, files []string, content string) error
|
|||
path := filepath.Join(mountedDir, file)
|
||||
err := ioutil.WriteFile(path, []byte(content), 0644)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Unexpected error while writing file %s: %v", path, err)
|
||||
return fmt.Errorf("unexpected error while writing file %s: %v", path, err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func waitForPods(s map[string]string) error {
|
||||
client, err := pkgutil.GetClient()
|
||||
func waitForPods(s map[string]string, profile string) error {
|
||||
client, err := pkgutil.GetClient(profile)
|
||||
if err != nil {
|
||||
return fmt.Errorf("getting kubernetes client: %v", err)
|
||||
}
|
||||
|
@ -144,7 +139,7 @@ func waitForPods(s map[string]string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func verifyFiles(mk util.MinikubeRunner, kubectlRunner *util.KubectlRunner, tempDir string, podName string, expected string) error {
|
||||
func verifyFiles(mk util.MinikubeRunner, kr *util.KubectlRunner, tempDir string, podName string, expected string) error {
|
||||
path := filepath.Join(tempDir, "frompod")
|
||||
out, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
|
@ -156,7 +151,7 @@ func verifyFiles(mk util.MinikubeRunner, kubectlRunner *util.KubectlRunner, temp
|
|||
}
|
||||
|
||||
// test that file written from host was read in by the pod via cat /mount-9p/fromhost;
|
||||
if out, err = kubectlRunner.RunCommand([]string{"logs", podName}); err != nil {
|
||||
if out, err = kr.RunCommand([]string{"logs", podName}); err != nil {
|
||||
return err
|
||||
}
|
||||
if string(out) != expected {
|
||||
|
@ -169,30 +164,30 @@ func verifyFiles(mk util.MinikubeRunner, kubectlRunner *util.KubectlRunner, temp
|
|||
statCmd := fmt.Sprintf("stat /mount-9p/%s", file)
|
||||
statOutput, err := mk.SSH(statCmd)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Unable to stat %s via SSH. error %v, %s", file, err, statOutput)
|
||||
return fmt.Errorf("inable to stat %s via SSH. error %v, %s", file, err, statOutput)
|
||||
}
|
||||
|
||||
if runtime.GOOS == "windows" {
|
||||
if strings.Contains(statOutput, "Access: 1970-01-01") {
|
||||
return fmt.Errorf("Invalid access time\n%s", statOutput)
|
||||
return fmt.Errorf("invalid access time\n%s", statOutput)
|
||||
}
|
||||
}
|
||||
|
||||
if strings.Contains(statOutput, "Modify: 1970-01-01") {
|
||||
return fmt.Errorf("Invalid modify time\n%s", statOutput)
|
||||
return fmt.Errorf("invalid modify time\n%s", statOutput)
|
||||
}
|
||||
}
|
||||
|
||||
// test that fromhostremove was deleted by the pod from the mount via rm /mount-9p/fromhostremove
|
||||
path = filepath.Join(tempDir, "fromhostremove")
|
||||
if _, err := os.Stat(path); err == nil {
|
||||
return fmt.Errorf("Expected file %s to be removed", path)
|
||||
return fmt.Errorf("expected file %s to be removed", path)
|
||||
}
|
||||
|
||||
// test that frompodremove can be deleted on the host
|
||||
path = filepath.Join(tempDir, "frompodremove")
|
||||
if err := os.Remove(path); err != nil {
|
||||
return fmt.Errorf("Unexpected error removing file %s: %v", path, err)
|
||||
return fmt.Errorf("unexpected error removing file %s: %v", path, err)
|
||||
}
|
||||
|
||||
return nil
|
|
@ -25,11 +25,11 @@ import (
|
|||
|
||||
// testProfileList tests the `minikube profile list` command
|
||||
func testProfileList(t *testing.T) {
|
||||
p := profileName(t)
|
||||
t.Parallel()
|
||||
profile := "minikube"
|
||||
mk := NewMinikubeRunner(t, "--wait=false")
|
||||
out := mk.RunCommand("profile list", true)
|
||||
if !strings.Contains(out, profile) {
|
||||
t.Errorf("Error , failed to read profile name (%s) in `profile list` command output : \n %q ", profile, out)
|
||||
mk := NewMinikubeRunner(t, p, "--wait=false")
|
||||
out, stderr := mk.RunCommand("profile list", true)
|
||||
if !strings.Contains(out, p) {
|
||||
t.Errorf("Error , failed to read profile name (%s) in `profile list` command output : \n %q : \n stderr: %s ", p, out, stderr)
|
||||
}
|
||||
}
|
|
@ -39,11 +39,13 @@ var (
|
|||
)
|
||||
|
||||
func testProvisioning(t *testing.T) {
|
||||
p := profileName(t)
|
||||
t.Parallel()
|
||||
kubectlRunner := util.NewKubectlRunner(t)
|
||||
|
||||
kr := util.NewKubectlRunner(t, p)
|
||||
|
||||
defer func() {
|
||||
if out, err := kubectlRunner.RunCommand([]string{"delete", "pvc", pvcName}); err != nil {
|
||||
if out, err := kr.RunCommand([]string{"delete", "pvc", pvcName}); err != nil {
|
||||
t.Logf("delete pvc %s failed: %v\noutput: %s\n", pvcName, err, out)
|
||||
}
|
||||
}()
|
||||
|
@ -53,7 +55,7 @@ func testProvisioning(t *testing.T) {
|
|||
|
||||
checkStorageClass := func() error {
|
||||
scl := storage.StorageClassList{}
|
||||
if err := kubectlRunner.RunCommandParseOutput([]string{"get", "storageclass"}, &scl); err != nil {
|
||||
if err := kr.RunCommandParseOutput([]string{"get", "storageclass"}, &scl); err != nil {
|
||||
return fmt.Errorf("get storageclass: %v", err)
|
||||
}
|
||||
|
||||
|
@ -63,14 +65,14 @@ func testProvisioning(t *testing.T) {
|
|||
return fmt.Errorf("no default StorageClass yet")
|
||||
}
|
||||
|
||||
if err := util.Retry(t, checkStorageClass, 5*time.Second, 20); err != nil {
|
||||
if err := util.Retry(t, checkStorageClass, 10*time.Second, 10); err != nil {
|
||||
t.Fatalf("no default storage class after retry: %v", err)
|
||||
}
|
||||
|
||||
// Check that the storage provisioner pod is running
|
||||
|
||||
checkPodRunning := func() error {
|
||||
client, err := commonutil.GetClient()
|
||||
client, err := commonutil.GetClient(p)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "getting kubernetes client")
|
||||
}
|
||||
|
@ -82,20 +84,20 @@ func testProvisioning(t *testing.T) {
|
|||
return nil
|
||||
}
|
||||
|
||||
if err := checkPodRunning(); err != nil {
|
||||
if err := util.Retry(t, checkPodRunning, 2*time.Second, 5); err != nil {
|
||||
t.Fatalf("Check storage-provisioner pod running failed with error: %v", err)
|
||||
}
|
||||
|
||||
// Now create the PVC
|
||||
pvcPath := filepath.Join(*testdataDir, "pvc.yaml")
|
||||
if _, err := kubectlRunner.RunCommand([]string{"create", "-f", pvcPath}); err != nil {
|
||||
if _, err := kr.RunCommand([]string{"create", "-f", pvcPath}); err != nil {
|
||||
t.Fatalf("Error creating pvc: %v", err)
|
||||
}
|
||||
|
||||
// And check that it gets bound to a PV.
|
||||
checkStorage := func() error {
|
||||
pvc := core.PersistentVolumeClaim{}
|
||||
if err := kubectlRunner.RunCommandParseOutput(pvcCmd, &pvc); err != nil {
|
||||
if err := kr.RunCommandParseOutput(pvcCmd, &pvc); err != nil {
|
||||
return err
|
||||
}
|
||||
// The test passes if the volume claim gets bound.
|
|
@ -21,7 +21,6 @@ import (
|
|||
"io/ioutil"
|
||||
"net/http"
|
||||
"os/exec"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
@ -46,11 +45,13 @@ func testTunnel(t *testing.T) {
|
|||
}
|
||||
|
||||
t.Log("starting tunnel test...")
|
||||
runner := NewMinikubeRunner(t, "--wait=false")
|
||||
p := profileName(t)
|
||||
mk := NewMinikubeRunner(t, p, "--wait=false")
|
||||
go func() {
|
||||
output := runner.RunCommand("tunnel --alsologtostderr -v 8 --logtostderr", true)
|
||||
output, stderr := mk.RunCommand("tunnel --alsologtostderr -v 8 --logtostderr", true)
|
||||
if t.Failed() {
|
||||
fmt.Println(output)
|
||||
t.Errorf("tunnel stderr : %s", stderr)
|
||||
t.Errorf("tunnel output : %s", output)
|
||||
}
|
||||
}()
|
||||
|
||||
|
@ -60,19 +61,15 @@ func testTunnel(t *testing.T) {
|
|||
t.Fatal(errors.Wrap(err, "cleaning up tunnels"))
|
||||
}
|
||||
|
||||
kubectlRunner := util.NewKubectlRunner(t)
|
||||
kr := util.NewKubectlRunner(t, p)
|
||||
|
||||
t.Log("deploying nginx...")
|
||||
curdir, err := filepath.Abs("")
|
||||
if err != nil {
|
||||
t.Errorf("Error getting the file path for current directory: %s", curdir)
|
||||
}
|
||||
podPath := path.Join(curdir, "testdata", "testsvc.yaml")
|
||||
if _, err := kubectlRunner.RunCommand([]string{"apply", "-f", podPath}); err != nil {
|
||||
podPath := filepath.Join(*testdataDir, "testsvc.yaml")
|
||||
if _, err := kr.RunCommand([]string{"apply", "-f", podPath}); err != nil {
|
||||
t.Fatalf("creating nginx ingress resource: %s", err)
|
||||
}
|
||||
|
||||
client, err := commonutil.GetClient()
|
||||
client, err := commonutil.GetClient(p)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(errors.Wrap(err, "getting kubernetes client"))
|
||||
|
@ -89,13 +86,13 @@ func testTunnel(t *testing.T) {
|
|||
|
||||
t.Log("getting nginx ingress...")
|
||||
|
||||
nginxIP, err := getIngress(kubectlRunner)
|
||||
nginxIP, err := getIngress(kr)
|
||||
if err != nil {
|
||||
t.Errorf("error getting ingress IP for nginx: %s", err)
|
||||
}
|
||||
|
||||
if len(nginxIP) == 0 {
|
||||
stdout, err := describeIngress(kubectlRunner)
|
||||
stdout, err := describeIngress(kr)
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("error debugging nginx service: %s", err)
|
||||
|
@ -113,12 +110,12 @@ func testTunnel(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func getIngress(kubectlRunner *util.KubectlRunner) (string, error) {
|
||||
func getIngress(kr *util.KubectlRunner) (string, error) {
|
||||
nginxIP := ""
|
||||
var ret error
|
||||
err := wait.PollImmediate(1*time.Second, 1*time.Minute, func() (bool, error) {
|
||||
cmd := []string{"get", "svc", "nginx-svc", "-o", "jsonpath={.status.loadBalancer.ingress[0].ip}"}
|
||||
stdout, err := kubectlRunner.RunCommand(cmd)
|
||||
stdout, err := kr.RunCommand(cmd)
|
||||
switch {
|
||||
case err == nil:
|
||||
nginxIP = string(stdout)
|
||||
|
@ -137,8 +134,8 @@ func getIngress(kubectlRunner *util.KubectlRunner) (string, error) {
|
|||
return nginxIP, ret
|
||||
}
|
||||
|
||||
func describeIngress(kubectlRunner *util.KubectlRunner) ([]byte, error) {
|
||||
return kubectlRunner.RunCommand([]string{"get", "svc", "nginx-svc", "-o", "jsonpath={.status}"})
|
||||
func describeIngress(kr *util.KubectlRunner) ([]byte, error) {
|
||||
return kr.RunCommand([]string{"get", "svc", "nginx-svc", "-o", "jsonpath={.status}"})
|
||||
}
|
||||
|
||||
// getResponseBody returns the contents of a URL
|
|
@ -19,54 +19,43 @@ limitations under the License.
|
|||
package integration
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/machine/libmachine/state"
|
||||
"k8s.io/minikube/test/integration/util"
|
||||
)
|
||||
|
||||
func TestFunctional(t *testing.T) {
|
||||
r := NewMinikubeRunner(t)
|
||||
r.EnsureRunning()
|
||||
// This one is not parallel, and ensures the cluster comes up
|
||||
// before we run any other tests.
|
||||
t.Run("Status", testClusterStatus)
|
||||
t.Run("ProfileList", testProfileList)
|
||||
t.Run("DNS", testClusterDNS)
|
||||
t.Run("Logs", testClusterLogs)
|
||||
t.Run("Addons", testAddons)
|
||||
t.Run("Registry", testRegistry)
|
||||
t.Run("Dashboard", testDashboard)
|
||||
t.Run("ServicesList", testServicesList)
|
||||
t.Run("Provisioning", testProvisioning)
|
||||
t.Run("Tunnel", testTunnel)
|
||||
|
||||
if !usingNoneDriver(r) {
|
||||
t.Run("EnvVars", testClusterEnv)
|
||||
t.Run("SSH", testClusterSSH)
|
||||
t.Run("IngressController", testIngressController)
|
||||
t.Run("Mounting", testMounting)
|
||||
p := profileName(t)
|
||||
mk := NewMinikubeRunner(t, p)
|
||||
stdout, stderr, err := mk.Start()
|
||||
if err != nil {
|
||||
t.Fatalf("failed to start minikube failed : %v\nstdout: %s\nstderr: %s", err, stdout, stderr)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFunctionalContainerd(t *testing.T) {
|
||||
r := NewMinikubeRunner(t)
|
||||
|
||||
if usingNoneDriver(r) {
|
||||
t.Skip("Can't run containerd backend with none driver")
|
||||
if !isTestNoneDriver(t) { // none driver doesn't need to be deleted
|
||||
defer mk.TearDown(t)
|
||||
}
|
||||
|
||||
if r.GetStatus() != state.None.String() {
|
||||
r.RunCommand("delete", true)
|
||||
}
|
||||
r.Start("--container-runtime=containerd", "--docker-opt containerd=/var/run/containerd/containerd.sock")
|
||||
t.Run("Gvisor", testGvisor)
|
||||
t.Run("GvisorRestart", testGvisorRestart)
|
||||
r.RunCommand("delete", true)
|
||||
}
|
||||
// group is needed to make sure tear down runs after parallel runs
|
||||
// https://github.com/golang/go/issues/17791#issuecomment-258476786
|
||||
t.Run("group", func(t *testing.T) {
|
||||
// This one is not parallel, and ensures the cluster comes up
|
||||
// before we run any other tests.
|
||||
t.Run("Status", testClusterStatus)
|
||||
t.Run("ProfileList", testProfileList)
|
||||
t.Run("DNS", testClusterDNS)
|
||||
t.Run("Logs", testClusterLogs)
|
||||
t.Run("Addons", testAddons)
|
||||
t.Run("Registry", testRegistry)
|
||||
t.Run("Dashboard", testDashboard)
|
||||
t.Run("ServicesList", testServicesList)
|
||||
t.Run("Provisioning", testProvisioning)
|
||||
t.Run("Tunnel", testTunnel)
|
||||
|
||||
if !isTestNoneDriver(t) {
|
||||
t.Run("EnvVars", testClusterEnv)
|
||||
t.Run("SSH", testClusterSSH)
|
||||
t.Run("IngressController", testIngressController)
|
||||
t.Run("Mounting", testMounting)
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
// usingNoneDriver returns true if using the none driver
|
||||
func usingNoneDriver(r util.MinikubeRunner) bool {
|
||||
return strings.Contains(r.StartArgs, "--vm-driver=none")
|
||||
}
|
||||
|
|
|
@ -25,19 +25,30 @@ import (
|
|||
)
|
||||
|
||||
func TestISO(t *testing.T) {
|
||||
p := profileName(t)
|
||||
if shouldRunInParallel(t) {
|
||||
t.Parallel()
|
||||
}
|
||||
|
||||
mk := NewMinikubeRunner(t, "--wait=false")
|
||||
|
||||
mk := NewMinikubeRunner(t, p, "--wait=false")
|
||||
mk.RunCommand("delete", false)
|
||||
mk.Start()
|
||||
stdout, stderr, err := mk.Start()
|
||||
if err != nil {
|
||||
t.Fatalf("failed to start minikube (for profile %s) %s) failed : %v\nstdout: %s\nstderr: %s", t.Name(), err, stdout, stderr)
|
||||
}
|
||||
if !isTestNoneDriver(t) { // none driver doesn't need to be deleted
|
||||
defer mk.TearDown(t)
|
||||
}
|
||||
|
||||
t.Run("permissions", testMountPermissions)
|
||||
t.Run("packages", testPackages)
|
||||
t.Run("persistence", testPersistence)
|
||||
|
||||
}
|
||||
|
||||
func testMountPermissions(t *testing.T) {
|
||||
mk := NewMinikubeRunner(t, "--wait=false")
|
||||
p := profileName(t)
|
||||
mk := NewMinikubeRunner(t, p, "--wait=false")
|
||||
// test mount permissions
|
||||
mountPoints := []string{"/Users", "/hosthome"}
|
||||
perms := "drwxr-xr-x"
|
||||
|
@ -59,7 +70,8 @@ func testMountPermissions(t *testing.T) {
|
|||
}
|
||||
|
||||
func testPackages(t *testing.T) {
|
||||
mk := NewMinikubeRunner(t, "--wait=false")
|
||||
p := profileName(t)
|
||||
mk := NewMinikubeRunner(t, p, "--wait=false")
|
||||
|
||||
packages := []string{
|
||||
"git",
|
||||
|
@ -81,7 +93,8 @@ func testPackages(t *testing.T) {
|
|||
}
|
||||
|
||||
func testPersistence(t *testing.T) {
|
||||
mk := NewMinikubeRunner(t, "--wait=false")
|
||||
p := profileName(t)
|
||||
mk := NewMinikubeRunner(t, p, "--wait=false")
|
||||
|
||||
for _, dir := range []string{
|
||||
"/data",
|
||||
|
|
|
@ -19,59 +19,51 @@ limitations under the License.
|
|||
package integration
|
||||
|
||||
import (
|
||||
"path"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/docker/machine/libmachine/state"
|
||||
"k8s.io/minikube/test/integration/util"
|
||||
)
|
||||
|
||||
func TestPersistence(t *testing.T) {
|
||||
mk := NewMinikubeRunner(t, "--wait=false")
|
||||
if usingNoneDriver(mk) {
|
||||
if isTestNoneDriver(t) {
|
||||
t.Skip("skipping test as none driver does not support persistence")
|
||||
}
|
||||
mk.EnsureRunning()
|
||||
p := profileName(t)
|
||||
if shouldRunInParallel(t) {
|
||||
t.Parallel()
|
||||
}
|
||||
|
||||
kubectlRunner := util.NewKubectlRunner(t)
|
||||
curdir, err := filepath.Abs("")
|
||||
mk := NewMinikubeRunner(t, p, "--wait=false")
|
||||
defer mk.TearDown(t)
|
||||
|
||||
stdout, stderr, err := mk.Start()
|
||||
if err != nil {
|
||||
t.Errorf("Error getting the file path for current directory: %s", curdir)
|
||||
t.Fatalf("failed to start minikube (for profile %s) failed : %v\nstdout: %s\nstderr: %s", t.Name(), err, stdout, stderr)
|
||||
}
|
||||
podPath := path.Join(curdir, "testdata", "busybox.yaml")
|
||||
|
||||
// Create a pod and wait for it to be running.
|
||||
if _, err := kubectlRunner.RunCommand([]string{"create", "-f", podPath}); err != nil {
|
||||
t.Fatalf("Error creating test pod: %v", err)
|
||||
kr := util.NewKubectlRunner(t, p)
|
||||
if _, err := kr.RunCommand([]string{"create", "-f", filepath.Join(*testdataDir, "busybox.yaml")}); err != nil {
|
||||
t.Fatalf("creating busybox pod: %s", err)
|
||||
}
|
||||
|
||||
verify := func(t *testing.T) {
|
||||
if err := util.WaitForBusyboxRunning(t, "default"); err != nil {
|
||||
verifyBusybox := func(t *testing.T) {
|
||||
if err := util.WaitForBusyboxRunning(t, "default", p); err != nil {
|
||||
t.Fatalf("waiting for busybox to be up: %v", err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Make sure everything is up before we stop.
|
||||
verify(t)
|
||||
verifyBusybox(t)
|
||||
|
||||
// Now restart minikube and make sure the pod is still there.
|
||||
// mk.RunCommand("stop", true)
|
||||
// mk.CheckStatus("Stopped")
|
||||
checkStop := func() error {
|
||||
mk.RunCommand("stop", true)
|
||||
return mk.CheckStatusNoFail(state.Stopped.String())
|
||||
mk.RunCommand("stop", true)
|
||||
mk.CheckStatus(state.Stopped.String())
|
||||
|
||||
stdout, stderr, err = mk.Start()
|
||||
if err != nil {
|
||||
t.Fatalf("failed to start minikube (for profile %s) failed : %v\nstdout: %s\nstderr: %s", t.Name(), err, stdout, stderr)
|
||||
}
|
||||
|
||||
if err := util.Retry(t, checkStop, 5*time.Second, 6); err != nil {
|
||||
t.Fatalf("timed out while checking stopped status: %v", err)
|
||||
}
|
||||
|
||||
mk.Start()
|
||||
mk.CheckStatus(state.Running.String())
|
||||
|
||||
// Make sure the same things come up after we've restarted.
|
||||
verify(t)
|
||||
verifyBusybox(t)
|
||||
}
|
||||
|
|
|
@ -31,86 +31,96 @@ import (
|
|||
)
|
||||
|
||||
func TestStartStop(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
args []string
|
||||
}{
|
||||
{"nocache_oldest", []string{
|
||||
"--cache-images=false",
|
||||
fmt.Sprintf("--kubernetes-version=%s", constants.OldestKubernetesVersion),
|
||||
// default is the network created by libvirt, if we change the name minikube won't boot
|
||||
// because the given network doesn't exist
|
||||
"--kvm-network=default",
|
||||
"--kvm-qemu-uri=qemu:///system",
|
||||
}},
|
||||
{"feature_gates_newest_cni", []string{
|
||||
"--feature-gates",
|
||||
"ServerSideApply=true",
|
||||
"--network-plugin=cni",
|
||||
"--extra-config=kubelet.network-plugin=cni",
|
||||
"--extra-config=kubeadm.pod-network-cidr=192.168.111.111/16",
|
||||
fmt.Sprintf("--kubernetes-version=%s", constants.NewestKubernetesVersion),
|
||||
}},
|
||||
{"containerd_and_non_default_apiserver_port", []string{
|
||||
"--container-runtime=containerd",
|
||||
"--docker-opt containerd=/var/run/containerd/containerd.sock",
|
||||
"--apiserver-port=8444",
|
||||
}},
|
||||
{"crio_ignore_preflights", []string{
|
||||
"--container-runtime=crio",
|
||||
"--extra-config",
|
||||
"kubeadm.ignore-preflight-errors=SystemVerification",
|
||||
}},
|
||||
p := profileName(t) // gets profile name used for minikube and kube context
|
||||
if shouldRunInParallel(t) {
|
||||
t.Parallel()
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
r := NewMinikubeRunner(t)
|
||||
if !strings.Contains(test.name, "docker") && usingNoneDriver(r) {
|
||||
t.Skipf("skipping %s - incompatible with none driver", test.name)
|
||||
}
|
||||
t.Run("group", func(t *testing.T) {
|
||||
if shouldRunInParallel(t) {
|
||||
t.Parallel()
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args []string
|
||||
}{
|
||||
{"oldest", []string{ // nocache_oldest
|
||||
"--cache-images=false",
|
||||
fmt.Sprintf("--kubernetes-version=%s", constants.OldestKubernetesVersion),
|
||||
// default is the network created by libvirt, if we change the name minikube won't boot
|
||||
// because the given network doesn't exist
|
||||
"--kvm-network=default",
|
||||
"--kvm-qemu-uri=qemu:///system",
|
||||
}},
|
||||
{"cni", []string{ // feature_gates_newest_cni
|
||||
"--feature-gates",
|
||||
"ServerSideApply=true",
|
||||
"--network-plugin=cni",
|
||||
"--extra-config=kubelet.network-plugin=cni",
|
||||
"--extra-config=kubeadm.pod-network-cidr=192.168.111.111/16",
|
||||
fmt.Sprintf("--kubernetes-version=%s", constants.NewestKubernetesVersion),
|
||||
}},
|
||||
{"containerd", []string{ // containerd_and_non_default_apiserver_port
|
||||
"--container-runtime=containerd",
|
||||
"--docker-opt containerd=/var/run/containerd/containerd.sock",
|
||||
"--apiserver-port=8444",
|
||||
}},
|
||||
{"crio", []string{ // crio_ignore_preflights
|
||||
"--container-runtime=crio",
|
||||
"--extra-config",
|
||||
"kubeadm.ignore-preflight-errors=SystemVerification",
|
||||
}},
|
||||
}
|
||||
|
||||
r.RunCommand("config set WantReportErrorPrompt false", true)
|
||||
r.RunCommand("delete", false)
|
||||
r.CheckStatus(state.None.String())
|
||||
r.Start(test.args...)
|
||||
r.CheckStatus(state.Running.String())
|
||||
for _, tc := range tests {
|
||||
n := tc.name // because similar to https://golang.org/doc/faq#closures_and_goroutines
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
if shouldRunInParallel(t) {
|
||||
t.Parallel()
|
||||
}
|
||||
|
||||
ip := r.RunCommand("ip", true)
|
||||
ip = strings.TrimRight(ip, "\n")
|
||||
if net.ParseIP(ip) == nil {
|
||||
t.Fatalf("IP command returned an invalid address: %s", ip)
|
||||
}
|
||||
pn := p + n // TestStartStopoldest
|
||||
mk := NewMinikubeRunner(t, pn, "--wait=false")
|
||||
// TODO : redundant first clause ? never happens?
|
||||
if !strings.Contains(pn, "docker") && isTestNoneDriver(t) {
|
||||
t.Skipf("skipping %s - incompatible with none driver", t.Name())
|
||||
}
|
||||
|
||||
// check for the current-context before and after the stop
|
||||
kubectlRunner := util.NewKubectlRunner(t)
|
||||
currentContext, err := kubectlRunner.RunCommand([]string{"config", "current-context"})
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to fetch current-context")
|
||||
}
|
||||
if strings.TrimRight(string(currentContext), "\n") != "minikube" {
|
||||
t.Fatalf("got current-context - %q, want current-context %q", string(currentContext), "minikube")
|
||||
}
|
||||
mk.RunCommand("config set WantReportErrorPrompt false", true)
|
||||
stdout, stderr, err := mk.Start(tc.args...)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to start minikube (for profile %s) failed : %v\nstdout: %s\nstderr: %s", pn, err, stdout, stderr)
|
||||
}
|
||||
|
||||
checkStop := func() error {
|
||||
r.RunCommand("stop", true)
|
||||
return r.CheckStatusNoFail(state.Stopped.String())
|
||||
}
|
||||
mk.CheckStatus(state.Running.String())
|
||||
|
||||
if err := util.Retry(t, checkStop, 5*time.Second, 6); err != nil {
|
||||
t.Fatalf("timed out while checking stopped status: %v", err)
|
||||
}
|
||||
ip, stderr := mk.RunCommand("ip", true)
|
||||
ip = strings.TrimRight(ip, "\n")
|
||||
if net.ParseIP(ip) == nil {
|
||||
t.Fatalf("IP command returned an invalid address: %s \n %s", ip, stderr)
|
||||
}
|
||||
|
||||
// running this command results in error when the current-context is not set
|
||||
if err := r.Run("config current-context"); err != nil {
|
||||
t.Logf("current-context is not set to minikube")
|
||||
}
|
||||
stop := func() error {
|
||||
stdout, stderr, err = mk.RunCommandRetriable("stop")
|
||||
return mk.CheckStatusNoFail(state.Stopped.String())
|
||||
}
|
||||
|
||||
r.Start(test.args...)
|
||||
r.CheckStatus(state.Running.String())
|
||||
err = util.RetryX(stop, 10*time.Second, 2*time.Minute)
|
||||
mk.CheckStatus(state.Stopped.String())
|
||||
|
||||
r.RunCommand("delete", true)
|
||||
r.CheckStatus(state.None.String())
|
||||
})
|
||||
}
|
||||
// TODO medyagh:
|
||||
// https://github.com/kubernetes/minikube/issues/4854
|
||||
|
||||
stdout, stderr, err = mk.Start(tc.args...)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to start minikube (for profile %s) failed : %v\nstdout: %s\nstderr: %s", t.Name(), err, stdout, stderr)
|
||||
}
|
||||
|
||||
mk.CheckStatus(state.Running.String())
|
||||
|
||||
mk.RunCommand("delete", true)
|
||||
mk.CheckStatus(state.None.String())
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
Copyright 2019 The Kubernetes Authors 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 util
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/cenkalti/backoff"
|
||||
"github.com/pkg/errors"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
commonutil "k8s.io/minikube/pkg/util"
|
||||
)
|
||||
|
||||
// WaitForBusyboxRunning waits until busybox pod to be running
|
||||
func WaitForBusyboxRunning(t *testing.T, namespace string, miniProfile string) error {
|
||||
client, err := commonutil.GetClient(miniProfile)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "getting kubernetes client")
|
||||
}
|
||||
selector := labels.SelectorFromSet(labels.Set(map[string]string{"integration-test": "busybox"}))
|
||||
return commonutil.WaitForPodsWithLabelRunning(client, namespace, selector)
|
||||
}
|
||||
|
||||
// Retry tries the callback for a number of attempts, with a delay between attempts
|
||||
func Retry(t *testing.T, callback func() error, d time.Duration, attempts int) (err error) {
|
||||
for i := 0; i < attempts; i++ {
|
||||
err = callback()
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
time.Sleep(d)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// Retry2 tries the callback for a number of attempts, with a delay without *testing.T
|
||||
func Retry2(callback func() error, d time.Duration, attempts int) (err error) {
|
||||
for i := 0; i < attempts; i++ {
|
||||
err = callback()
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
time.Sleep(d)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// RetryX is expontential backoff retry
|
||||
func RetryX(callback func() error, initInterv time.Duration, maxTime time.Duration) error {
|
||||
b := backoff.NewExponentialBackOff()
|
||||
b.MaxElapsedTime = maxTime
|
||||
b.InitialInterval = initInterv
|
||||
b.RandomizationFactor = 0.5
|
||||
b.Multiplier = 1.5
|
||||
b.Reset()
|
||||
return backoff.Retry(callback, b)
|
||||
}
|
||||
|
||||
// Logf writes logs to stdout if -v is set.
|
||||
func Logf(str string, args ...interface{}) {
|
||||
if !testing.Verbose() {
|
||||
return
|
||||
}
|
||||
fmt.Printf(" %s | ", time.Now().Format("15:04:05"))
|
||||
fmt.Println(fmt.Sprintf(str, args...))
|
||||
}
|
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
Copyright 2019 The Kubernetes Authors 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 util
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"os/exec"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
commonutil "k8s.io/minikube/pkg/util"
|
||||
)
|
||||
|
||||
const kubectlBinary = "kubectl"
|
||||
|
||||
// KubectlRunner runs a command using kubectl
|
||||
type KubectlRunner struct {
|
||||
Profile string // kube-context maps to a minikube profile
|
||||
T *testing.T
|
||||
BinaryPath string
|
||||
}
|
||||
|
||||
// NewKubectlRunner creates a new KubectlRunner
|
||||
func NewKubectlRunner(t *testing.T, profile ...string) *KubectlRunner {
|
||||
if profile == nil {
|
||||
profile = []string{"minikube"}
|
||||
}
|
||||
|
||||
p, err := exec.LookPath(kubectlBinary)
|
||||
if err != nil {
|
||||
t.Fatalf("Couldn't find kubectl on path.")
|
||||
}
|
||||
return &KubectlRunner{Profile: profile[0], BinaryPath: p, T: t}
|
||||
}
|
||||
|
||||
// RunCommandParseOutput runs a command and parses the JSON output
|
||||
func (k *KubectlRunner) RunCommandParseOutput(args []string, outputObj interface{}, useKubeContext ...bool) error {
|
||||
args = append(args, "-o=json")
|
||||
output, err := k.RunCommand(args, useKubeContext...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
d := json.NewDecoder(bytes.NewReader(output))
|
||||
if err := d.Decode(outputObj); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// RunCommand runs a command, returning stdout
|
||||
func (k *KubectlRunner) RunCommand(args []string, useKubeContext ...bool) (stdout []byte, err error) {
|
||||
|
||||
if useKubeContext == nil {
|
||||
useKubeContext = []bool{true}
|
||||
}
|
||||
if useKubeContext[0] {
|
||||
kubecContextArg := fmt.Sprintf("--context=%s", k.Profile)
|
||||
args = append([]string{kubecContextArg}, args...) // prepending --context so it can be with with -- space
|
||||
}
|
||||
|
||||
inner := func() error {
|
||||
cmd := exec.Command(k.BinaryPath, args...)
|
||||
stdout, err = cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
retriable := &commonutil.RetriableError{Err: fmt.Errorf("error running command %s: %v. Stdout: \n %s", args, err, stdout)}
|
||||
k.T.Log(retriable)
|
||||
return retriable
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
err = commonutil.RetryAfter(3, inner, 2*time.Second)
|
||||
return stdout, err
|
||||
}
|
||||
|
||||
// CreateRandomNamespace creates a random namespace
|
||||
func (k *KubectlRunner) CreateRandomNamespace() string {
|
||||
const strLen = 20
|
||||
name := genRandString(strLen)
|
||||
if _, err := k.RunCommand([]string{"create", "namespace", name}); err != nil {
|
||||
k.T.Fatalf("Error creating namespace: %v", err)
|
||||
}
|
||||
return name
|
||||
}
|
||||
|
||||
func genRandString(strLen int) string {
|
||||
const chars = "abcdefghijklmnopqrstuvwxyz0123456789"
|
||||
rand.Seed(time.Now().UTC().UnixNano())
|
||||
result := make([]byte, strLen)
|
||||
for i := 0; i < strLen; i++ {
|
||||
result[i] = chars[rand.Intn(len(chars))]
|
||||
}
|
||||
return string(result)
|
||||
}
|
||||
|
||||
// DeleteNamespace deletes the namespace
|
||||
func (k *KubectlRunner) DeleteNamespace(namespace string) error {
|
||||
_, err := k.RunCommand([]string{"delete", "namespace", namespace})
|
||||
return err
|
||||
}
|
|
@ -0,0 +1,318 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors 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 util
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/docker/machine/libmachine/state"
|
||||
"github.com/pkg/errors"
|
||||
"k8s.io/minikube/pkg/minikube/assets"
|
||||
commonutil "k8s.io/minikube/pkg/util"
|
||||
)
|
||||
|
||||
// MinikubeRunner runs a command
|
||||
type MinikubeRunner struct {
|
||||
Profile string
|
||||
T *testing.T
|
||||
BinaryPath string
|
||||
GlobalArgs string
|
||||
StartArgs string
|
||||
MountArgs string
|
||||
Runtime string
|
||||
TimeOutStart time.Duration // time to wait for minikube start before killing it
|
||||
}
|
||||
|
||||
// Remove removes a file
|
||||
func (m *MinikubeRunner) Remove(f assets.CopyableFile) error {
|
||||
_, err := m.SSH(fmt.Sprintf("rm -rf %s", filepath.Join(f.GetTargetDir(), f.GetTargetName())))
|
||||
return err
|
||||
}
|
||||
|
||||
// teeRun runs a command, streaming stdout, stderr to console
|
||||
func (m *MinikubeRunner) teeRun(cmd *exec.Cmd, waitForRun ...bool) (string, string, error) {
|
||||
w := true
|
||||
if waitForRun != nil {
|
||||
w = waitForRun[0]
|
||||
}
|
||||
|
||||
errPipe, err := cmd.StderrPipe()
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
outPipe, err := cmd.StdoutPipe()
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
if err := cmd.Start(); err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
if w {
|
||||
var outB bytes.Buffer
|
||||
var errB bytes.Buffer
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(2)
|
||||
go func() {
|
||||
if err := commonutil.TeePrefix(commonutil.ErrPrefix, errPipe, &errB, Logf); err != nil {
|
||||
m.T.Logf("tee: %v", err)
|
||||
}
|
||||
wg.Done()
|
||||
}()
|
||||
go func() {
|
||||
if err := commonutil.TeePrefix(commonutil.OutPrefix, outPipe, &outB, Logf); err != nil {
|
||||
m.T.Logf("tee: %v", err)
|
||||
}
|
||||
wg.Done()
|
||||
}()
|
||||
err = cmd.Wait()
|
||||
wg.Wait()
|
||||
return outB.String(), errB.String(), err
|
||||
|
||||
}
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
// RunCommand executes a command, optionally checking for error and by default waits for run to finish
|
||||
func (m *MinikubeRunner) RunCommand(cmdStr string, failError bool, waitForRun ...bool) (string, string) {
|
||||
profileArg := fmt.Sprintf("-p=%s ", m.Profile)
|
||||
cmdStr = profileArg + cmdStr
|
||||
cmdArgs := strings.Split(cmdStr, " ")
|
||||
path, _ := filepath.Abs(m.BinaryPath)
|
||||
|
||||
cmd := exec.Command(path, cmdArgs...)
|
||||
Logf("Run: %s", cmd.Args)
|
||||
stdout, stderr, err := m.teeRun(cmd, waitForRun...)
|
||||
if err != nil {
|
||||
errMsg := ""
|
||||
if exitError, ok := err.(*exec.ExitError); ok {
|
||||
errMsg = fmt.Sprintf("Error running command: %s %s. Output: %s Stderr: %s", cmdStr, exitError.Stderr, stdout, stderr)
|
||||
} else {
|
||||
errMsg = fmt.Sprintf("Error running command: %s %s. Output: %s", cmdStr, stderr, stdout)
|
||||
}
|
||||
if failError {
|
||||
m.T.Fatalf(errMsg)
|
||||
} else {
|
||||
m.T.Errorf(errMsg)
|
||||
}
|
||||
}
|
||||
return stdout, stderr
|
||||
}
|
||||
|
||||
// RunCommandRetriable Error executes a command, returns error
|
||||
// the purpose of this command is to make it retriable and
|
||||
// better logging for retrying
|
||||
func (m *MinikubeRunner) RunCommandRetriable(cmdStr string, waitForRun ...bool) (stdout string, stderr string, err error) {
|
||||
profileArg := fmt.Sprintf("-p=%s ", m.Profile)
|
||||
cmdStr = profileArg + cmdStr
|
||||
cmdArgs := strings.Split(cmdStr, " ")
|
||||
path, _ := filepath.Abs(m.BinaryPath)
|
||||
|
||||
cmd := exec.Command(path, cmdArgs...)
|
||||
Logf("Run: %s", cmd.Args)
|
||||
stdout, stderr, err = m.teeRun(cmd, waitForRun...)
|
||||
if err != nil {
|
||||
if exitError, ok := err.(*exec.ExitError); ok {
|
||||
m.T.Logf("temporary error: running command: %s %s. Output: \n%s", cmdStr, exitError.Stderr, stdout)
|
||||
} else {
|
||||
m.T.Logf("temporary error: running command: %s %s. Output: \n%s", cmdStr, stderr, stdout)
|
||||
}
|
||||
}
|
||||
return stdout, stderr, err
|
||||
}
|
||||
|
||||
// RunWithContext calls the minikube command with a context, useful for timeouts.
|
||||
func (m *MinikubeRunner) RunWithContext(ctx context.Context, cmdStr string, wait ...bool) (string, string, error) {
|
||||
profileArg := fmt.Sprintf("-p=%s ", m.Profile)
|
||||
cmdStr = profileArg + cmdStr
|
||||
cmdArgs := strings.Split(cmdStr, " ")
|
||||
path, _ := filepath.Abs(m.BinaryPath)
|
||||
|
||||
cmd := exec.CommandContext(ctx, path, cmdArgs...)
|
||||
Logf("Run: %s", cmd.Args)
|
||||
return m.teeRun(cmd, wait...)
|
||||
}
|
||||
|
||||
// RunDaemon executes a command, returning the stdout
|
||||
func (m *MinikubeRunner) RunDaemon(cmdStr string) (*exec.Cmd, *bufio.Reader) {
|
||||
profileArg := fmt.Sprintf("-p=%s ", m.Profile)
|
||||
cmdStr = profileArg + cmdStr
|
||||
cmdArgs := strings.Split(cmdStr, " ")
|
||||
path, _ := filepath.Abs(m.BinaryPath)
|
||||
|
||||
cmd := exec.Command(path, cmdArgs...)
|
||||
stdoutPipe, err := cmd.StdoutPipe()
|
||||
if err != nil {
|
||||
m.T.Fatalf("stdout pipe failed: %s %v", cmdStr, err)
|
||||
}
|
||||
stderrPipe, err := cmd.StderrPipe()
|
||||
if err != nil {
|
||||
m.T.Fatalf("stderr pipe failed: %s %v", cmdStr, err)
|
||||
}
|
||||
|
||||
var errB bytes.Buffer
|
||||
go func() {
|
||||
if err := commonutil.TeePrefix(commonutil.ErrPrefix, stderrPipe, &errB, Logf); err != nil {
|
||||
m.T.Logf("tee: %v", err)
|
||||
}
|
||||
}()
|
||||
|
||||
err = cmd.Start()
|
||||
if err != nil {
|
||||
m.T.Fatalf("Error running command: %s %v", cmdStr, err)
|
||||
}
|
||||
return cmd, bufio.NewReader(stdoutPipe)
|
||||
|
||||
}
|
||||
|
||||
// RunDaemon2 executes a command, returning the stdout and stderr
|
||||
func (m *MinikubeRunner) RunDaemon2(cmdStr string) (*exec.Cmd, *bufio.Reader, *bufio.Reader) {
|
||||
profileArg := fmt.Sprintf("-p=%s ", m.Profile)
|
||||
cmdStr = profileArg + cmdStr
|
||||
cmdArgs := strings.Split(cmdStr, " ")
|
||||
path, _ := filepath.Abs(m.BinaryPath)
|
||||
cmd := exec.Command(path, cmdArgs...)
|
||||
stdoutPipe, err := cmd.StdoutPipe()
|
||||
if err != nil {
|
||||
m.T.Fatalf("stdout pipe failed: %s %v", cmdStr, err)
|
||||
}
|
||||
stderrPipe, err := cmd.StderrPipe()
|
||||
if err != nil {
|
||||
m.T.Fatalf("stderr pipe failed: %s %v", cmdStr, err)
|
||||
}
|
||||
|
||||
err = cmd.Start()
|
||||
if err != nil {
|
||||
m.T.Fatalf("Error running command: %s %v", cmdStr, err)
|
||||
}
|
||||
return cmd, bufio.NewReader(stdoutPipe), bufio.NewReader(stderrPipe)
|
||||
}
|
||||
|
||||
// SSH returns the output of running a command using SSH
|
||||
func (m *MinikubeRunner) SSH(cmdStr string) (string, error) {
|
||||
profileArg := fmt.Sprintf("-p=%s", m.Profile)
|
||||
path, _ := filepath.Abs(m.BinaryPath)
|
||||
|
||||
cmd := exec.Command(path, profileArg, "ssh", cmdStr)
|
||||
Logf("SSH: %s", cmdStr)
|
||||
stdout, err := cmd.CombinedOutput()
|
||||
Logf("Output: %s", stdout)
|
||||
if err, ok := err.(*exec.ExitError); ok {
|
||||
return string(stdout), err
|
||||
}
|
||||
return string(stdout), nil
|
||||
}
|
||||
|
||||
// Start starts the cluster
|
||||
func (m *MinikubeRunner) Start(opts ...string) (stdout string, stderr string, err error) {
|
||||
cmd := fmt.Sprintf("start %s %s %s", m.StartArgs, m.GlobalArgs, strings.Join(opts, " "))
|
||||
s := func() error {
|
||||
stdout, stderr, err = m.RunCommandRetriable(cmd)
|
||||
return err
|
||||
}
|
||||
err = RetryX(s, 10*time.Second, m.TimeOutStart)
|
||||
return stdout, stderr, err
|
||||
}
|
||||
|
||||
// TearDown deletes minikube without waiting for it. used to free up ram/cpu after each test
|
||||
func (m *MinikubeRunner) TearDown(t *testing.T) {
|
||||
profileArg := fmt.Sprintf("-p=%s", m.Profile)
|
||||
path, _ := filepath.Abs(m.BinaryPath)
|
||||
cmd := exec.Command(path, profileArg, "delete")
|
||||
err := cmd.Start()
|
||||
if err != nil {
|
||||
t.Errorf("error tearing down minikube %s : %v", profileArg, err)
|
||||
}
|
||||
}
|
||||
|
||||
// EnsureRunning makes sure the container runtime is running
|
||||
func (m *MinikubeRunner) EnsureRunning(opts ...string) {
|
||||
s, _, err := m.Status()
|
||||
if err != nil {
|
||||
m.T.Errorf("error getting status for ensure running: %v", err)
|
||||
}
|
||||
if s != state.Running.String() {
|
||||
stdout, stderr, err := m.Start(opts...)
|
||||
if err != nil {
|
||||
m.T.Errorf("error starting while running EnsureRunning : %v , stdout %s stderr %s", err, stdout, stderr)
|
||||
}
|
||||
}
|
||||
m.CheckStatus(state.Running.String())
|
||||
}
|
||||
|
||||
// ParseEnvCmdOutput parses the output of `env` (assumes bash)
|
||||
func (m *MinikubeRunner) ParseEnvCmdOutput(out string) map[string]string {
|
||||
env := map[string]string{}
|
||||
re := regexp.MustCompile(`(\w+?) ?= ?"?(.+?)"?\n`)
|
||||
for _, m := range re.FindAllStringSubmatch(out, -1) {
|
||||
env[m[1]] = m[2]
|
||||
}
|
||||
return env
|
||||
}
|
||||
|
||||
// Status returns the status of a service
|
||||
func (m *MinikubeRunner) Status() (status string, stderr string, err error) {
|
||||
cmd := fmt.Sprintf("status --format={{.Host}} %s", m.GlobalArgs)
|
||||
s := func() error {
|
||||
status, stderr, err = m.RunCommandRetriable(cmd)
|
||||
status = strings.TrimRight(status, "\n")
|
||||
return err
|
||||
}
|
||||
err = RetryX(s, 15*time.Second, 1*time.Minute)
|
||||
if err != nil && (status == state.None.String() || status == state.Stopped.String()) {
|
||||
err = nil // because https://github.com/kubernetes/minikube/issues/4932
|
||||
}
|
||||
return status, stderr, err
|
||||
}
|
||||
|
||||
// GetLogs returns the logs of a service
|
||||
func (m *MinikubeRunner) GetLogs() string {
|
||||
// TODO: this test needs to check sterr too !
|
||||
stdout, _ := m.RunCommand(fmt.Sprintf("logs %s", m.GlobalArgs), true)
|
||||
return stdout
|
||||
}
|
||||
|
||||
// CheckStatus makes sure the service has the desired status, or cause fatal error
|
||||
func (m *MinikubeRunner) CheckStatus(desired string) {
|
||||
err := m.CheckStatusNoFail(desired)
|
||||
if err != nil { // none status returns 1 exit code
|
||||
m.T.Fatalf("%v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// CheckStatusNoFail makes sure the service has the desired status, returning error
|
||||
func (m *MinikubeRunner) CheckStatusNoFail(desired string) error {
|
||||
s, stderr, err := m.Status()
|
||||
if s != desired {
|
||||
return fmt.Errorf("got state: %q, expected %q : stderr: %s err: %v ", s, desired, stderr, err)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, stderr)
|
||||
}
|
||||
return nil
|
||||
}
|
|
@ -1,445 +0,0 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors 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 util
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/minikube/pkg/minikube/assets"
|
||||
commonutil "k8s.io/minikube/pkg/util"
|
||||
)
|
||||
|
||||
const kubectlBinary = "kubectl"
|
||||
|
||||
// MinikubeRunner runs a command
|
||||
type MinikubeRunner struct {
|
||||
T *testing.T
|
||||
BinaryPath string
|
||||
GlobalArgs string
|
||||
StartArgs string
|
||||
MountArgs string
|
||||
Runtime string
|
||||
}
|
||||
|
||||
// Logf writes logs to stdout if -v is set.
|
||||
func Logf(str string, args ...interface{}) {
|
||||
if !testing.Verbose() {
|
||||
return
|
||||
}
|
||||
fmt.Printf(" %s | ", time.Now().Format("15:04:05"))
|
||||
fmt.Println(fmt.Sprintf(str, args...))
|
||||
}
|
||||
|
||||
// Run executes a command
|
||||
func (m *MinikubeRunner) Run(cmd string) error {
|
||||
_, err := m.SSH(cmd)
|
||||
return err
|
||||
}
|
||||
|
||||
// Copy copies a file
|
||||
func (m *MinikubeRunner) Copy(f assets.CopyableFile) error {
|
||||
path, _ := filepath.Abs(m.BinaryPath)
|
||||
cmd := exec.Command("/bin/bash", "-c", path, "ssh", "--", fmt.Sprintf("cat >> %s", filepath.Join(f.GetTargetDir(), f.GetTargetName())))
|
||||
Logf("Running: %s", cmd.Args)
|
||||
return cmd.Run()
|
||||
}
|
||||
|
||||
// CombinedOutput executes a command, returning the combined stdout and stderr
|
||||
func (m *MinikubeRunner) CombinedOutput(cmd string) (string, error) {
|
||||
return m.SSH(cmd)
|
||||
}
|
||||
|
||||
// Remove removes a file
|
||||
func (m *MinikubeRunner) Remove(f assets.CopyableFile) error {
|
||||
_, err := m.SSH(fmt.Sprintf("rm -rf %s", filepath.Join(f.GetTargetDir(), f.GetTargetName())))
|
||||
return err
|
||||
}
|
||||
|
||||
// teeRun runs a command, streaming stdout, stderr to console
|
||||
func (m *MinikubeRunner) teeRun(cmd *exec.Cmd) (string, string, error) {
|
||||
errPipe, err := cmd.StderrPipe()
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
outPipe, err := cmd.StdoutPipe()
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
if err := cmd.Start(); err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
var outB bytes.Buffer
|
||||
var errB bytes.Buffer
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(2)
|
||||
go func() {
|
||||
if err := commonutil.TeePrefix(commonutil.ErrPrefix, errPipe, &errB, Logf); err != nil {
|
||||
m.T.Logf("tee: %v", err)
|
||||
}
|
||||
wg.Done()
|
||||
}()
|
||||
go func() {
|
||||
if err := commonutil.TeePrefix(commonutil.OutPrefix, outPipe, &outB, Logf); err != nil {
|
||||
m.T.Logf("tee: %v", err)
|
||||
}
|
||||
wg.Done()
|
||||
}()
|
||||
err = cmd.Wait()
|
||||
wg.Wait()
|
||||
return outB.String(), errB.String(), err
|
||||
}
|
||||
|
||||
// RunCommand executes a command, optionally checking for error
|
||||
func (m *MinikubeRunner) RunCommand(command string, checkError bool) string {
|
||||
commandArr := strings.Split(command, " ")
|
||||
path, _ := filepath.Abs(m.BinaryPath)
|
||||
cmd := exec.Command(path, commandArr...)
|
||||
Logf("Run: %s", cmd.Args)
|
||||
stdout, stderr, err := m.teeRun(cmd)
|
||||
if checkError && err != nil {
|
||||
if exitError, ok := err.(*exec.ExitError); ok {
|
||||
m.T.Fatalf("Error running command: %s %s. Output: %s", command, exitError.Stderr, stdout)
|
||||
} else {
|
||||
m.T.Fatalf("Error running command: %s %v. Output: %s", command, err, stderr)
|
||||
}
|
||||
}
|
||||
return stdout
|
||||
}
|
||||
|
||||
// RunWithContext calls the minikube command with a context, useful for timeouts.
|
||||
func (m *MinikubeRunner) RunWithContext(ctx context.Context, command string) (string, string, error) {
|
||||
commandArr := strings.Split(command, " ")
|
||||
path, _ := filepath.Abs(m.BinaryPath)
|
||||
cmd := exec.CommandContext(ctx, path, commandArr...)
|
||||
Logf("Run: %s", cmd.Args)
|
||||
return m.teeRun(cmd)
|
||||
}
|
||||
|
||||
// RunDaemon executes a command, returning the stdout
|
||||
func (m *MinikubeRunner) RunDaemon(command string) (*exec.Cmd, *bufio.Reader) {
|
||||
commandArr := strings.Split(command, " ")
|
||||
path, _ := filepath.Abs(m.BinaryPath)
|
||||
cmd := exec.Command(path, commandArr...)
|
||||
stdoutPipe, err := cmd.StdoutPipe()
|
||||
if err != nil {
|
||||
m.T.Fatalf("stdout pipe failed: %s %v", command, err)
|
||||
}
|
||||
stderrPipe, err := cmd.StderrPipe()
|
||||
if err != nil {
|
||||
m.T.Fatalf("stderr pipe failed: %s %v", command, err)
|
||||
}
|
||||
|
||||
var errB bytes.Buffer
|
||||
go func() {
|
||||
if err := commonutil.TeePrefix(commonutil.ErrPrefix, stderrPipe, &errB, Logf); err != nil {
|
||||
m.T.Logf("tee: %v", err)
|
||||
}
|
||||
}()
|
||||
|
||||
err = cmd.Start()
|
||||
if err != nil {
|
||||
m.T.Fatalf("Error running command: %s %v", command, err)
|
||||
}
|
||||
return cmd, bufio.NewReader(stdoutPipe)
|
||||
|
||||
}
|
||||
|
||||
// RunDaemon2 executes a command, returning the stdout and stderr
|
||||
func (m *MinikubeRunner) RunDaemon2(command string) (*exec.Cmd, *bufio.Reader, *bufio.Reader) {
|
||||
commandArr := strings.Split(command, " ")
|
||||
path, _ := filepath.Abs(m.BinaryPath)
|
||||
cmd := exec.Command(path, commandArr...)
|
||||
stdoutPipe, err := cmd.StdoutPipe()
|
||||
if err != nil {
|
||||
m.T.Fatalf("stdout pipe failed: %s %v", command, err)
|
||||
}
|
||||
stderrPipe, err := cmd.StderrPipe()
|
||||
if err != nil {
|
||||
m.T.Fatalf("stderr pipe failed: %s %v", command, err)
|
||||
}
|
||||
|
||||
err = cmd.Start()
|
||||
if err != nil {
|
||||
m.T.Fatalf("Error running command: %s %v", command, err)
|
||||
}
|
||||
return cmd, bufio.NewReader(stdoutPipe), bufio.NewReader(stderrPipe)
|
||||
}
|
||||
|
||||
// SSH returns the output of running a command using SSH
|
||||
func (m *MinikubeRunner) SSH(command string) (string, error) {
|
||||
path, _ := filepath.Abs(m.BinaryPath)
|
||||
cmd := exec.Command(path, "ssh", command)
|
||||
Logf("SSH: %s", command)
|
||||
|
||||
stdout, err := cmd.CombinedOutput()
|
||||
Logf("Output: %s", stdout)
|
||||
if err, ok := err.(*exec.ExitError); ok {
|
||||
return string(stdout), err
|
||||
}
|
||||
return string(stdout), nil
|
||||
}
|
||||
|
||||
// Start starts the cluster
|
||||
func (m *MinikubeRunner) Start(opts ...string) {
|
||||
cmd := fmt.Sprintf("start %s %s %s --alsologtostderr --v=2", m.StartArgs, m.GlobalArgs, strings.Join(opts, " "))
|
||||
m.RunCommand(cmd, true)
|
||||
}
|
||||
|
||||
// EnsureRunning makes sure the container runtime is running
|
||||
func (m *MinikubeRunner) EnsureRunning() {
|
||||
if m.GetStatus() != "Running" {
|
||||
m.Start()
|
||||
}
|
||||
m.CheckStatus("Running")
|
||||
}
|
||||
|
||||
// ParseEnvCmdOutput parses the output of `env` (assumes bash)
|
||||
func (m *MinikubeRunner) ParseEnvCmdOutput(out string) map[string]string {
|
||||
env := map[string]string{}
|
||||
re := regexp.MustCompile(`(\w+?) ?= ?"?(.+?)"?\n`)
|
||||
for _, m := range re.FindAllStringSubmatch(out, -1) {
|
||||
env[m[1]] = m[2]
|
||||
}
|
||||
return env
|
||||
}
|
||||
|
||||
// GetStatus returns the status of a service
|
||||
func (m *MinikubeRunner) GetStatus() string {
|
||||
return m.RunCommand(fmt.Sprintf("status --format={{.Host}} %s", m.GlobalArgs), false)
|
||||
}
|
||||
|
||||
// GetLogs returns the logs of a service
|
||||
func (m *MinikubeRunner) GetLogs() string {
|
||||
return m.RunCommand(fmt.Sprintf("logs %s", m.GlobalArgs), true)
|
||||
}
|
||||
|
||||
// CheckStatus makes sure the service has the desired status, or cause fatal error
|
||||
func (m *MinikubeRunner) CheckStatus(desired string) {
|
||||
if err := m.CheckStatusNoFail(desired); err != nil {
|
||||
m.T.Fatalf("%v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// CheckStatusNoFail makes sure the service has the desired status, returning error
|
||||
func (m *MinikubeRunner) CheckStatusNoFail(desired string) error {
|
||||
s := m.GetStatus()
|
||||
if s != desired {
|
||||
return fmt.Errorf("got state: %q, expected %q", s, desired)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// KubectlRunner runs a command using kubectl
|
||||
type KubectlRunner struct {
|
||||
T *testing.T
|
||||
BinaryPath string
|
||||
}
|
||||
|
||||
// NewKubectlRunner creates a new KubectlRunner
|
||||
func NewKubectlRunner(t *testing.T) *KubectlRunner {
|
||||
p, err := exec.LookPath(kubectlBinary)
|
||||
if err != nil {
|
||||
t.Fatalf("Couldn't find kubectl on path.")
|
||||
}
|
||||
return &KubectlRunner{BinaryPath: p, T: t}
|
||||
}
|
||||
|
||||
// RunCommandParseOutput runs a command and parses the JSON output
|
||||
func (k *KubectlRunner) RunCommandParseOutput(args []string, outputObj interface{}) error {
|
||||
args = append(args, "-o=json")
|
||||
output, err := k.RunCommand(args)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
d := json.NewDecoder(bytes.NewReader(output))
|
||||
if err := d.Decode(outputObj); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// RunCommand runs a command, returning stdout
|
||||
func (k *KubectlRunner) RunCommand(args []string) (stdout []byte, err error) {
|
||||
inner := func() error {
|
||||
cmd := exec.Command(k.BinaryPath, args...)
|
||||
stdout, err = cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
retriable := &commonutil.RetriableError{Err: fmt.Errorf("error running command %s: %v. Stdout: \n %s", args, err, stdout)}
|
||||
k.T.Log(retriable)
|
||||
return retriable
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
err = commonutil.RetryAfter(3, inner, 2*time.Second)
|
||||
return stdout, err
|
||||
}
|
||||
|
||||
// CreateRandomNamespace creates a random namespace
|
||||
func (k *KubectlRunner) CreateRandomNamespace() string {
|
||||
const strLen = 20
|
||||
name := genRandString(strLen)
|
||||
if _, err := k.RunCommand([]string{"create", "namespace", name}); err != nil {
|
||||
k.T.Fatalf("Error creating namespace: %v", err)
|
||||
}
|
||||
return name
|
||||
}
|
||||
|
||||
func genRandString(strLen int) string {
|
||||
const chars = "abcdefghijklmnopqrstuvwxyz0123456789"
|
||||
rand.Seed(time.Now().UTC().UnixNano())
|
||||
result := make([]byte, strLen)
|
||||
for i := 0; i < strLen; i++ {
|
||||
result[i] = chars[rand.Intn(len(chars))]
|
||||
}
|
||||
return string(result)
|
||||
}
|
||||
|
||||
// DeleteNamespace deletes the namespace
|
||||
func (k *KubectlRunner) DeleteNamespace(namespace string) error {
|
||||
_, err := k.RunCommand([]string{"delete", "namespace", namespace})
|
||||
return err
|
||||
}
|
||||
|
||||
// WaitForBusyboxRunning waits until busybox pod to be running
|
||||
func WaitForBusyboxRunning(t *testing.T, namespace string) error {
|
||||
client, err := commonutil.GetClient()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "getting kubernetes client")
|
||||
}
|
||||
selector := labels.SelectorFromSet(labels.Set(map[string]string{"integration-test": "busybox"}))
|
||||
return commonutil.WaitForPodsWithLabelRunning(client, namespace, selector)
|
||||
}
|
||||
|
||||
// WaitForIngressControllerRunning waits until ingress controller pod to be running
|
||||
func WaitForIngressControllerRunning(t *testing.T) error {
|
||||
client, err := commonutil.GetClient()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "getting kubernetes client")
|
||||
}
|
||||
|
||||
if err := commonutil.WaitForDeploymentToStabilize(client, "kube-system", "nginx-ingress-controller", time.Minute*10); err != nil {
|
||||
return errors.Wrap(err, "waiting for ingress-controller deployment to stabilize")
|
||||
}
|
||||
|
||||
selector := labels.SelectorFromSet(labels.Set(map[string]string{"app.kubernetes.io/name": "nginx-ingress-controller"}))
|
||||
if err := commonutil.WaitForPodsWithLabelRunning(client, "kube-system", selector); err != nil {
|
||||
return errors.Wrap(err, "waiting for ingress-controller pods")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// WaitForGvisorControllerRunning waits for the gvisor controller pod to be running
|
||||
func WaitForGvisorControllerRunning(t *testing.T) error {
|
||||
client, err := commonutil.GetClient()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "getting kubernetes client")
|
||||
}
|
||||
|
||||
selector := labels.SelectorFromSet(labels.Set(map[string]string{"kubernetes.io/minikube-addons": "gvisor"}))
|
||||
if err := commonutil.WaitForPodsWithLabelRunning(client, "kube-system", selector); err != nil {
|
||||
return errors.Wrap(err, "waiting for gvisor controller pod to stabilize")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// WaitForGvisorControllerDeleted waits for the gvisor controller pod to be deleted
|
||||
func WaitForGvisorControllerDeleted() error {
|
||||
client, err := commonutil.GetClient()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "getting kubernetes client")
|
||||
}
|
||||
|
||||
selector := labels.SelectorFromSet(labels.Set(map[string]string{"kubernetes.io/minikube-addons": "gvisor"}))
|
||||
if err := commonutil.WaitForPodDelete(client, "kube-system", selector); err != nil {
|
||||
return errors.Wrap(err, "waiting for gvisor controller pod deletion")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// WaitForUntrustedNginxRunning waits for the untrusted nginx pod to start running
|
||||
func WaitForUntrustedNginxRunning() error {
|
||||
client, err := commonutil.GetClient()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "getting kubernetes client")
|
||||
}
|
||||
|
||||
selector := labels.SelectorFromSet(labels.Set(map[string]string{"run": "nginx"}))
|
||||
if err := commonutil.WaitForPodsWithLabelRunning(client, "default", selector); err != nil {
|
||||
return errors.Wrap(err, "waiting for nginx pods")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// WaitForFailedCreatePodSandBoxEvent waits for a FailedCreatePodSandBox event to appear
|
||||
func WaitForFailedCreatePodSandBoxEvent() error {
|
||||
client, err := commonutil.GetClient()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "getting kubernetes client")
|
||||
}
|
||||
if err := commonutil.WaitForEvent(client, "default", "FailedCreatePodSandBox"); err != nil {
|
||||
return errors.Wrap(err, "waiting for FailedCreatePodSandBox event")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// WaitForNginxRunning waits for nginx service to be up
|
||||
func WaitForNginxRunning(t *testing.T) error {
|
||||
client, err := commonutil.GetClient()
|
||||
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "getting kubernetes client")
|
||||
}
|
||||
|
||||
selector := labels.SelectorFromSet(labels.Set(map[string]string{"run": "nginx"}))
|
||||
if err := commonutil.WaitForPodsWithLabelRunning(client, "default", selector); err != nil {
|
||||
return errors.Wrap(err, "waiting for nginx pods")
|
||||
}
|
||||
|
||||
if err := commonutil.WaitForService(client, "default", "nginx", true, time.Millisecond*500, time.Minute*10); err != nil {
|
||||
t.Errorf("Error waiting for nginx service to be up")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Retry tries the callback for a number of attempts, with a delay between attempts
|
||||
func Retry(t *testing.T, callback func() error, d time.Duration, attempts int) (err error) {
|
||||
for i := 0; i < attempts; i++ {
|
||||
err = callback()
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
time.Sleep(d)
|
||||
}
|
||||
return err
|
||||
}
|
|
@ -18,74 +18,77 @@ package integration
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/docker/machine/libmachine/state"
|
||||
retryablehttp "github.com/hashicorp/go-retryablehttp"
|
||||
"github.com/pkg/errors"
|
||||
"k8s.io/minikube/pkg/minikube/constants"
|
||||
pkgutil "k8s.io/minikube/pkg/util"
|
||||
"k8s.io/minikube/test/integration/util"
|
||||
)
|
||||
|
||||
func downloadMinikubeBinary(version string) (*os.File, error) {
|
||||
// Grab latest release binary
|
||||
url := pkgutil.GetBinaryDownloadURL(version, runtime.GOOS)
|
||||
resp, err := retryablehttp.Get(url)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Failed to get latest release binary")
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
tf, err := ioutil.TempFile("", "minikube")
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Failed to create binary file")
|
||||
}
|
||||
_, err = io.Copy(tf, resp.Body)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Failed to populate temp file")
|
||||
}
|
||||
if err := tf.Close(); err != nil {
|
||||
return nil, errors.Wrap(err, "Failed to close temp file")
|
||||
}
|
||||
|
||||
if runtime.GOOS != "windows" {
|
||||
if err := os.Chmod(tf.Name(), 0700); err != nil {
|
||||
return nil, err
|
||||
// t.Fatal(errors.Wrap(err, "Failed to make binary executable."))
|
||||
func fileExists(fname string) error {
|
||||
check := func() error {
|
||||
info, err := os.Stat(fname)
|
||||
if os.IsNotExist(err) {
|
||||
return err
|
||||
}
|
||||
if info.IsDir() {
|
||||
return fmt.Errorf("Error expect file got dir")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return tf, err
|
||||
|
||||
if err := util.Retry2(check, 1*time.Second, 3); err != nil {
|
||||
return errors.Wrap(err, fmt.Sprintf("Failed check if file (%q) exists,", fname))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// TestVersionUpgrade downloads latest version of minikube and runs with
|
||||
// the odlest supported k8s version and then runs the current head minikube
|
||||
// and it tries to upgrade from the older supported k8s to news supported k8s
|
||||
func TestVersionUpgrade(t *testing.T) {
|
||||
currentRunner := NewMinikubeRunner(t)
|
||||
currentRunner.RunCommand("delete", true)
|
||||
currentRunner.CheckStatus(state.None.String())
|
||||
tf, err := downloadMinikubeBinary("latest")
|
||||
if err != nil || tf == nil {
|
||||
t.Fatal(errors.Wrap(err, "Failed to download minikube binary."))
|
||||
p := profileName(t)
|
||||
if shouldRunInParallel(t) {
|
||||
t.Parallel()
|
||||
}
|
||||
defer os.Remove(tf.Name())
|
||||
// fname is the filename for the minikube's latetest binary. this file been pre-downloaded before test by hacks/jenkins/common.sh
|
||||
fname := filepath.Join(*testdataDir, fmt.Sprintf("minikube-%s-%s-latest-stable", runtime.GOOS, runtime.GOARCH))
|
||||
err := fileExists(fname)
|
||||
if err != nil { // download file if it is not downloaded by other test
|
||||
dest := filepath.Join(*testdataDir, fmt.Sprintf("minikube-%s-%s-latest-stable", runtime.GOOS, runtime.GOARCH))
|
||||
err := downloadMinikubeBinary(t, dest, "latest")
|
||||
if err != nil {
|
||||
// binary is needed for the test
|
||||
t.Fatalf("erorr downloading the latest minikube release %v", err)
|
||||
}
|
||||
}
|
||||
defer os.Remove(fname)
|
||||
|
||||
releaseRunner := NewMinikubeRunner(t)
|
||||
releaseRunner.BinaryPath = tf.Name()
|
||||
mkCurrent := NewMinikubeRunner(t, p)
|
||||
defer mkCurrent.TearDown(t)
|
||||
|
||||
mkRelease := NewMinikubeRunner(t, p)
|
||||
mkRelease.BinaryPath = fname
|
||||
// For full coverage: also test upgrading from oldest to newest supported k8s release
|
||||
releaseRunner.Start(fmt.Sprintf("--kubernetes-version=%s", constants.OldestKubernetesVersion))
|
||||
releaseRunner.CheckStatus(state.Running.String())
|
||||
releaseRunner.RunCommand("stop", true)
|
||||
releaseRunner.CheckStatus(state.Stopped.String())
|
||||
stdout, stderr, err := mkRelease.Start(fmt.Sprintf("--kubernetes-version=%s", constants.OldestKubernetesVersion))
|
||||
if err != nil {
|
||||
t.Fatalf("TestVersionUpgrade minikube start failed : %v\nstdout: %s\nstderr: %s", err, stdout, stderr)
|
||||
}
|
||||
|
||||
mkRelease.CheckStatus(state.Running.String())
|
||||
mkRelease.RunCommand("stop", true)
|
||||
mkRelease.CheckStatus(state.Stopped.String())
|
||||
|
||||
// Trim the leading "v" prefix to assert that we handle it properly.
|
||||
currentRunner.Start(fmt.Sprintf("--kubernetes-version=%s", strings.TrimPrefix(constants.NewestKubernetesVersion, "v")))
|
||||
currentRunner.CheckStatus(state.Running.String())
|
||||
currentRunner.RunCommand("delete", true)
|
||||
currentRunner.CheckStatus(state.None.String())
|
||||
stdout, stderr, err = mkCurrent.Start(fmt.Sprintf("--kubernetes-version=%s", strings.TrimPrefix(constants.NewestKubernetesVersion, "v")))
|
||||
if err != nil {
|
||||
t.Fatalf("TestVersionUpgrade mkCurrent.Start start failed : %v\nstdout: %s\nstderr: %s", err, stdout, stderr)
|
||||
}
|
||||
mkCurrent.CheckStatus(state.Running.String())
|
||||
}
|
||||
|
|
|
@ -16,6 +16,9 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
// the name of this file starts with z intentionally to make it run last after all other tests
|
||||
// the intent is to make sure os env proxy settings be done after all other tests.
|
||||
// for example in the case the test proxy clean up gets killed or fails
|
||||
package integration
|
||||
|
||||
import (
|
||||
|
@ -66,20 +69,20 @@ func setUpProxy(t *testing.T) (*http.Server, error) {
|
|||
func TestProxy(t *testing.T) {
|
||||
origHP := os.Getenv("HTTP_PROXY")
|
||||
origNP := os.Getenv("NO_PROXY")
|
||||
p := profileName(t) // profile name
|
||||
|
||||
if isTestNoneDriver(t) {
|
||||
// TODO fix this later
|
||||
t.Skip("Skipping proxy warning for none")
|
||||
}
|
||||
|
||||
srv, err := setUpProxy(t)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to set up the test proxy: %s", err)
|
||||
}
|
||||
|
||||
// making sure there is no running minikube to avoid https://github.com/kubernetes/minikube/issues/4132
|
||||
r := NewMinikubeRunner(t)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Minute)
|
||||
defer cancel()
|
||||
_, _, err = r.RunWithContext(ctx, "delete")
|
||||
if err != nil {
|
||||
t.Logf("Error deleting minikube before test setup %s : ", err)
|
||||
}
|
||||
|
||||
mk := NewMinikubeRunner(t, p)
|
||||
// Clean up after setting up proxy
|
||||
defer func(t *testing.T) {
|
||||
err = os.Setenv("HTTP_PROXY", origHP)
|
||||
|
@ -95,27 +98,23 @@ func TestProxy(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Errorf("Error shutting down the http proxy")
|
||||
}
|
||||
|
||||
_, _, err = r.RunWithContext(ctx, "delete")
|
||||
if err != nil {
|
||||
t.Logf("Error deleting minikube when cleaning up proxy setup: %s", err)
|
||||
if !isTestNoneDriver(t) {
|
||||
mk.TearDown(t)
|
||||
}
|
||||
}(t)
|
||||
|
||||
t.Run("Proxy Console Warnning", testProxyWarning)
|
||||
t.Run("Proxy Dashboard", testProxyDashboard)
|
||||
}(t)
|
||||
t.Run("ProxyConsoleWarnning", testProxyWarning)
|
||||
t.Run("ProxyDashboard", testProxyDashboard)
|
||||
|
||||
}
|
||||
|
||||
// testProxyWarning checks user is warned correctly about the proxy related env vars
|
||||
func testProxyWarning(t *testing.T) {
|
||||
r := NewMinikubeRunner(t, "--wait=false")
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Minute)
|
||||
defer cancel()
|
||||
startCmd := fmt.Sprintf("start %s %s", r.StartArgs, r.GlobalArgs)
|
||||
stdout, stderr, err := r.RunWithContext(ctx, startCmd)
|
||||
p := profileName(t) // profile name
|
||||
mk := NewMinikubeRunner(t, p)
|
||||
stdout, stderr, err := mk.Start()
|
||||
if err != nil {
|
||||
t.Fatalf("start: %v\nstdout: %s\nstderr: %s", err, stdout, stderr)
|
||||
t.Fatalf("failed to start minikube (for profile %s) failed : %v\nstdout: %s\nstderr: %s", t.Name(), err, stdout, stderr)
|
||||
}
|
||||
|
||||
msg := "Found network options:"
|
||||
|
@ -131,7 +130,8 @@ func testProxyWarning(t *testing.T) {
|
|||
|
||||
// testProxyDashboard checks if dashboard URL is accessible if proxy is set
|
||||
func testProxyDashboard(t *testing.T) {
|
||||
mk := NewMinikubeRunner(t, "--wait=false")
|
||||
p := profileName(t) // profile name
|
||||
mk := NewMinikubeRunner(t, p)
|
||||
cmd, out := mk.RunDaemon("dashboard --url")
|
||||
defer func() {
|
||||
err := cmd.Process.Kill()
|
Loading…
Reference in New Issue