cmd/gateway: use a separate repository
Change-Id: Idbb0b2b6cf0e60c6d5d91218c24524d72285cf26
This commit is contained in:
parent
5011e78311
commit
e30f7b35b6
2
Makefile
2
Makefile
@ -82,9 +82,9 @@ install-sim: ## install storj-sim
|
||||
storj.io/storj/cmd/storj-sim \
|
||||
storj.io/storj/cmd/versioncontrol \
|
||||
storj.io/storj/cmd/uplink \
|
||||
storj.io/storj/cmd/gateway \
|
||||
storj.io/storj/cmd/identity \
|
||||
storj.io/storj/cmd/certificates
|
||||
cd cmd/gateway && go install -race -v storj.io/storj/cmd/gateway
|
||||
|
||||
##@ Test
|
||||
|
||||
|
57
cmd/gateway/go.mod
Normal file
57
cmd/gateway/go.mod
Normal file
@ -0,0 +1,57 @@
|
||||
module storj.io/storj/cmd/gateway
|
||||
|
||||
go 1.13
|
||||
|
||||
// force specific versions for minio
|
||||
require github.com/garyburd/redigo v1.0.1-0.20170216214944-0d253a66e6e1 // indirect
|
||||
|
||||
replace storj.io/storj => ../../
|
||||
|
||||
require storj.io/gateway v0.0.0-20200221161528-36f00ab51fa7
|
||||
|
||||
exclude gopkg.in/olivere/elastic.v5 v5.0.72 // buggy import, see https://github.com/olivere/elastic/pull/869
|
||||
|
||||
replace google.golang.org/grpc => github.com/storj/grpc-go v1.23.1-0.20190918084400-1c4561bf5127
|
||||
|
||||
require (
|
||||
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da // indirect
|
||||
github.com/cheggaaa/pb v1.0.5-0.20160713104425-73ae1d68fe0b // indirect
|
||||
github.com/djherbis/atime v1.0.0 // indirect
|
||||
github.com/dustin/go-humanize v1.0.0 // indirect
|
||||
github.com/eclipse/paho.mqtt.golang v1.1.1 // indirect
|
||||
github.com/elazarl/go-bindata-assetfs v1.0.0 // indirect
|
||||
github.com/fatih/structs v1.0.0 // indirect
|
||||
github.com/go-ini/ini v1.52.0 // indirect
|
||||
github.com/gorilla/handlers v1.4.0 // indirect
|
||||
github.com/gorilla/rpc v1.1.0 // indirect
|
||||
github.com/hashicorp/go-immutable-radix v1.0.0 // indirect
|
||||
github.com/hashicorp/go-msgpack v0.5.3 // indirect
|
||||
github.com/hashicorp/raft v1.0.0 // indirect
|
||||
github.com/inconshreveable/go-update v0.0.0-20160112193335-8152e7eb6ccf // indirect
|
||||
github.com/klauspost/cpuid v0.0.0-20180405133222-e7e905edc00e // indirect
|
||||
github.com/klauspost/reedsolomon v0.0.0-20180704173009-925cb01d6510 // indirect
|
||||
github.com/minio/dsync v0.0.0-20180124070302-439a0961af70 // indirect
|
||||
github.com/minio/highwayhash v0.0.0-20180501080913-85fc8a2dacad // indirect
|
||||
github.com/minio/lsync v0.0.0-20180328070428-f332c3883f63 // indirect
|
||||
github.com/minio/mc v0.0.0-20180926130011-a215fbb71884 // indirect
|
||||
github.com/minio/sio v0.0.0-20180327104954-6a41828a60f0 // indirect
|
||||
github.com/nats-io/gnatsd v1.3.0 // indirect
|
||||
github.com/nats-io/go-nats v1.6.0 // indirect
|
||||
github.com/nats-io/go-nats-streaming v0.4.2 // indirect
|
||||
github.com/nats-io/nats v1.6.0 // indirect
|
||||
github.com/nats-io/nats-streaming-server v0.12.2 // indirect
|
||||
github.com/nats-io/nuid v1.0.0 // indirect
|
||||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c // indirect
|
||||
github.com/pkg/profile v1.2.1 // indirect
|
||||
github.com/prometheus/procfs v0.0.0-20190517135640-51af30a78b0e // indirect
|
||||
github.com/rs/cors v1.5.0 // indirect
|
||||
github.com/smartystreets/goconvey v1.6.4 // indirect
|
||||
github.com/streadway/amqp v0.0.0-20180806233856-70e15c650864 // indirect
|
||||
github.com/tidwall/gjson v1.1.3 // indirect
|
||||
github.com/tidwall/match v0.0.0-20171002075945-1731857f09b1 // indirect
|
||||
google.golang.org/appengine v1.6.0 // indirect
|
||||
gopkg.in/Shopify/sarama.v1 v1.18.0 // indirect
|
||||
gopkg.in/cheggaaa/pb.v1 v1.0.25 // indirect
|
||||
gopkg.in/ini.v1 v1.52.0 // indirect
|
||||
gopkg.in/olivere/elastic.v5 v5.0.76 // indirect
|
||||
)
|
573
cmd/gateway/go.sum
Normal file
573
cmd/gateway/go.sum
Normal file
@ -0,0 +1,573 @@
|
||||
cloud.google.com/go v0.26.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.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw=
|
||||
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=
|
||||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/Microsoft/go-winio v0.4.11 h1:zoIOcVf0xPN1tnMVbTtEdI+P8OofVk3NObnwOQ6nK2Q=
|
||||
github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
|
||||
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk=
|
||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||
github.com/Shopify/go-lua v0.0.0-20181106184032-48449c60c0a9/go.mod h1:lvS2IGWEGk+KQkRrCXuWlcsHO5BitT0HyhnP51rh3gA=
|
||||
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
|
||||
github.com/Shopify/toxiproxy v2.1.4+incompatible h1:TKdv8HiTLgE5wdJuEML90aBgNWsokNbMijUGhmcoBJc=
|
||||
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
|
||||
github.com/VividCortex/ewma v1.1.1 h1:MnEK4VOv6n0RSY4vtRe3h11qjxL3+t0B8yOL8iMXdcM=
|
||||
github.com/VividCortex/ewma v1.1.1/go.mod h1:2Tkkvm3sRDVXaiyucHiACn4cqf7DpdyLvmxzcbUokwA=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alessio/shellescape v0.0.0-20190409004728-b115ca0f9053/go.mod h1:xW8sBma2LE3QxFSzCnH9qe6gAE2yO9GvQaWwX89HxbE=
|
||||
github.com/alicebob/gopher-json v0.0.0-20180125190556-5a6b3ba71ee6 h1:45bxf7AZMwWcqkLzDAQugVEwedisr5nRJ1r+7LYnv0U=
|
||||
github.com/alicebob/gopher-json v0.0.0-20180125190556-5a6b3ba71ee6/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc=
|
||||
github.com/alicebob/miniredis/v2 v2.11.1 h1:wuZ/ZHHELZ8DUF5sahK2T6V4Do2SdyKHnjrl/opkP8w=
|
||||
github.com/alicebob/miniredis/v2 v2.11.1/go.mod h1:UA48pmi7aSazcGAvcdKcBB49z521IC9VjTTRz2nIaJE=
|
||||
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da h1:8GUt8eRujhVEGZFFEjBj46YV4rDjvGrNxb0KMWYkL2I=
|
||||
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
|
||||
github.com/aws/aws-sdk-go v1.17.7/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0=
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932/go.mod h1:NOuUCSz6Q9T7+igc/hlvDOUdtWKryOrtFyIVABv/p7k=
|
||||
github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ=
|
||||
github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
|
||||
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=
|
||||
github.com/boltdb/bolt v1.3.1 h1:JQmyP4ZBrce+ZQu0dY660FMfatumYDLun9hBCUVIkF4=
|
||||
github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps=
|
||||
github.com/btcsuite/btcutil v0.0.0-20180706230648-ab6388e0c60a h1:RQMUrEILyYJEoAT34XS/kLu40vC0+po/UfxrBBA4qZE=
|
||||
github.com/btcsuite/btcutil v0.0.0-20180706230648-ab6388e0c60a/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg=
|
||||
github.com/calebcase/tmpfile v1.0.1 h1:vD8FSrbsbexhep39/6mvtbIHS3GzIRqiprDNCF6QqSk=
|
||||
github.com/calebcase/tmpfile v1.0.1/go.mod h1:iErLeG/iqJr8LaQ/gYRv4GXdqssi3jg4iSzvrA06/lw=
|
||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||
github.com/cheggaaa/pb v1.0.5-0.20160713104425-73ae1d68fe0b h1:CMRCnhHx4xVxJy+wPsS67xmi9RHGNctLMoVn9Q1Kit8=
|
||||
github.com/cheggaaa/pb v1.0.5-0.20160713104425-73ae1d68fe0b/go.mod h1:pQciLPpbU0oxA0h+VJYYLxO+XeDQb5pZijXscXHm81s=
|
||||
github.com/cheggaaa/pb/v3 v3.0.1 h1:m0BngUk2LuSRYdx4fujDKNRXNDpbNCfptPfVT2m6OJY=
|
||||
github.com/cheggaaa/pb/v3 v3.0.1/go.mod h1:SqqeMF/pMOIu3xgGoxtPYhMNQP258xE4x/XRTYua+KU=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cloudfoundry/gosigar v1.1.0 h1:V/dVCzhKOdIU3WRB5inQU20s4yIgL9Dxx/Mhi0SF8eM=
|
||||
github.com/cloudfoundry/gosigar v1.1.0/go.mod h1:3qLfc2GlfmwOx2+ZDaRGH3Y9fwQ0sQeaAleo2GV5pH0=
|
||||
github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I=
|
||||
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
|
||||
github.com/cockroachdb/cockroach-go v0.0.0-20181001143604-e0a95dfd547c/go.mod h1:XGLbWH/ujMcbPbhZq52Nv6UrCghb1yGn//133kEsvDk=
|
||||
github.com/containerd/containerd v1.2.7 h1:8lqLbl7u1j3MmiL9cJ/O275crSq7bfwUayvvatEupQk=
|
||||
github.com/containerd/containerd v1.2.7/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
|
||||
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
|
||||
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
|
||||
github.com/cznic/b v0.0.0-20180115125044-35e9bbe41f07/go.mod h1:URriBxXwVq5ijiJ12C7iIZqlA69nTlI+LgI6/pwftG8=
|
||||
github.com/cznic/fileutil v0.0.0-20180108211300-6a051e75936f/go.mod h1:8S58EK26zhXSxzv7NQFpnliaOQsmDUxvoQO3rt154Vg=
|
||||
github.com/cznic/golex v0.0.0-20170803123110-4ab7c5e190e4/go.mod h1:+bmmJDNmKlhWNG+gwWCkaBoTy39Fs+bzRxVBzoTQbIc=
|
||||
github.com/cznic/internal v0.0.0-20180608152220-f44710a21d00/go.mod h1:olo7eAdKwJdXxb55TKGLiJ6xt1H0/tiiRCWKVLmtjY4=
|
||||
github.com/cznic/lldb v1.1.0/go.mod h1:FIZVUmYUVhPwRiPzL8nD/mpFcJ/G7SSXjjXYG4uRI3A=
|
||||
github.com/cznic/mathutil v0.0.0-20180504122225-ca4c9f2c1369/go.mod h1:e6NPNENfs9mPDVNRekM7lKScauxd5kXTr1Mfyig6TDM=
|
||||
github.com/cznic/ql v1.2.0/go.mod h1:FbpzhyZrqr0PVlK6ury+PoW3T0ODUV22OeWIxcaOrSE=
|
||||
github.com/cznic/sortutil v0.0.0-20150617083342-4c7342852e65/go.mod h1:q2w6Bg5jeox1B+QkJ6Wp/+Vn0G/bo3f1uY7Fn3vivIQ=
|
||||
github.com/cznic/strutil v0.0.0-20171016134553-529a34b1c186/go.mod h1:AHHPPPXTw0h6pVabbcbyGRK1DckRn7r/STdZEeIDzZc=
|
||||
github.com/cznic/zappy v0.0.0-20160723133515-2533cb5b45cc/go.mod h1:Y1SNZ4dRUOKXshKUbwUapqNncRrho4mkjQebgEHZLj8=
|
||||
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=
|
||||
github.com/denisenkom/go-mssqldb v0.0.0-20190515213511-eb9f6a1743f3/go.mod h1:zAg7JM8CkOJ43xKXIj7eRO9kmWm/TW578qo+oDO6tuM=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
||||
github.com/dhui/dktest v0.3.0 h1:kwX5a7EkLcjo7VpsPQSYJcKGbXBXdjI9FGjuUj1jn6I=
|
||||
github.com/dhui/dktest v0.3.0/go.mod h1:cyzIUfGsBEbZ6BT7tnXqAShHSXCZhSNmFl70sZ7c1yc=
|
||||
github.com/djherbis/atime v1.0.0 h1:ySLvBAM0EvOGaX7TI4dAM5lWj+RdJUCKtGSEHN8SGBg=
|
||||
github.com/djherbis/atime v1.0.0/go.mod h1:5W+KBIuTwVGcqjIfaTwt+KSYX1o6uep8dtevevQP/f8=
|
||||
github.com/docker/distribution v2.7.0+incompatible h1:neUDAlf3wX6Ml4HdqTrbcOHXtfRN0TFIwt6YFL7N9RU=
|
||||
github.com/docker/distribution v2.7.0+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
github.com/docker/docker v0.7.3-0.20190103212154-2b7e084dc98b/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker v0.7.3-0.20190817195342-4760db040282 h1:mzrx39dGtGq0VEnTHjnakmczd4uFbhx2cZU3BJDsLdc=
|
||||
github.com/docker/docker v0.7.3-0.20190817195342-4760db040282/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
|
||||
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
|
||||
github.com/docker/go-units v0.3.3 h1:Xk8S3Xj5sLGlG5g67hJmYMmUgXv5N4PhkjJHHqrwnTk=
|
||||
github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
|
||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/eapache/go-resiliency v1.1.0 h1:1NtRmCAqadE2FN4ZcN6g90TP3uk8cg9rn9eNK2197aU=
|
||||
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
|
||||
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21 h1:YEetp8/yCZMuEPMUDHG0CW/brkkEp8mzqk2+ODEitlw=
|
||||
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
|
||||
github.com/eapache/queue v1.1.0 h1:YOEu7KNc61ntiQlcEeUIoDTJ2o8mQznoNvUhiigpIqc=
|
||||
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
|
||||
github.com/eclipse/paho.mqtt.golang v1.1.1 h1:iPJYXJLaViCshRTW/PSqImSS6HJ2Rf671WR0bXZ2GIU=
|
||||
github.com/eclipse/paho.mqtt.golang v1.1.1/go.mod h1:H9keYFcgq3Qr5OUJm/JZI/i6U7joQ8SYLhZwfeOo6Ts=
|
||||
github.com/edsrzf/mmap-go v0.0.0-20170320065105-0bce6a688712/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
|
||||
github.com/elazarl/go-bindata-assetfs v1.0.0 h1:G/bYguwHIzWq9ZoyUQqrjTmJbbYn3j3CKKpKinvZLFk=
|
||||
github.com/elazarl/go-bindata-assetfs v1.0.0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4=
|
||||
github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/fatih/structs v1.0.0 h1:BrX964Rv5uQ3wwS+KRUAJCBBw5PQmgJfJ6v4yly5QwU=
|
||||
github.com/fatih/structs v1.0.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
|
||||
github.com/fortytw2/leaktest v1.2.0 h1:cj6GCiwJDH7l3tMHLjZDo0QqPtrXJiWSI9JgpeQKw+Q=
|
||||
github.com/fortytw2/leaktest v1.2.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=
|
||||
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/fsouza/fake-gcs-server v1.7.0/go.mod h1:5XIRs4YvwNbNoz+1JF8j6KLAyDh7RHGAyAK3EP2EsNk=
|
||||
github.com/garyburd/redigo v1.0.1-0.20170216214944-0d253a66e6e1 h1:YmyuMm99D7kezPc0ZVWYnaUIWfMKR81lVVXttKTnDbw=
|
||||
github.com/garyburd/redigo v1.0.1-0.20170216214944-0d253a66e6e1/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/go-ini/ini v1.52.0 h1:3UeUAveYUTCYV/G0jNDiIrrtIeAl1oAjshYyU2PaAlQ=
|
||||
github.com/go-ini/ini v1.52.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
github.com/go-redis/redis v6.14.1+incompatible h1:kSJohAREGMr344uMa8PzuIg5OU6ylCbyDkWkkNOfEik=
|
||||
github.com/go-redis/redis v6.14.1+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
|
||||
github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA=
|
||||
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/gocql/gocql v0.0.0-20190301043612-f6df8288f9b4/go.mod h1:4Fw1eo5iaEhDUs8XyuhSVCVy52Jq3L+/3GJgYkwc+/0=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE=
|
||||
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
|
||||
github.com/golang-migrate/migrate/v4 v4.7.0 h1:gONcHxHApDTKXDyLH/H97gEHmpu1zcnnbAaq2zgrPrs=
|
||||
github.com/golang-migrate/migrate/v4 v4.7.0/go.mod h1:Qvut3N4xKWjoH3sokBccML6WyHSnggXm/DvMMnTsQIc=
|
||||
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-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
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/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
|
||||
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/gomodule/redigo v1.7.1-0.20190322064113-39e2c31b7ca3/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=
|
||||
github.com/gomodule/redigo v2.0.0+incompatible h1:K/R+8tc58AaqLkqG2Ol3Qk+DR/TlNuhuh457pBFPtt0=
|
||||
github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
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-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
|
||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||
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/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
|
||||
github.com/gorilla/handlers v1.4.0 h1:XulKRWSQK5uChr4pEgSE4Tc/OcmnU9GJuSwdog/tZsA=
|
||||
github.com/gorilla/handlers v1.4.0/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
|
||||
github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
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/rpc v1.1.0 h1:marKfvVP0Gpd/jHlVBKCQ8RAoUPdX7K1Nuh6l1BNh7A=
|
||||
github.com/gorilla/rpc v1.1.0/go.mod h1:V4h9r+4sF5HnzqbwIez0fKSpANP0zlYd3qR7p36jkTQ=
|
||||
github.com/gorilla/schema v1.1.0 h1:CamqUDOFUBqzrvxuz2vEwo8+SUdwsluFh7IlzJh30LY=
|
||||
github.com/gorilla/schema v1.1.0/go.mod h1:kgLaKoK1FELgZqMAVxx/5cbj0kT+57qxUrAlIO2eleU=
|
||||
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
github.com/graphql-go/graphql v0.7.9-0.20190403165646-199d20bbfed7 h1:E45QFM7IqRdFnuyFk8GSamb42EckUSyJ55rtVB/w8VQ=
|
||||
github.com/graphql-go/graphql v0.7.9-0.20190403165646-199d20bbfed7/go.mod h1:k6yrAYQaSP59DC5UVxbgxESlmVyojThKdORUqGDGmrI=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4=
|
||||
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/go-immutable-radix v1.0.0 h1:AKDB1HM5PWEA7i4nhcpwOrO2byshxBjXVn/J/3+z5/0=
|
||||
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
||||
github.com/hashicorp/go-msgpack v0.5.3 h1:zKjpN5BK/P5lMYrLmBHdBULWbJ0XpYR+7NGzqkZzoD4=
|
||||
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
|
||||
github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o=
|
||||
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
|
||||
github.com/hashicorp/go-uuid v1.0.0 h1:RS8zrF7PhGwyNPOtxSClXXj9HA8feRnJzgnI1RJCSnM=
|
||||
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU=
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/hashicorp/raft v1.0.0 h1:htBVktAOtGs4Le5Z7K8SF5H2+oWsQFYVmOgH5loro7Y=
|
||||
github.com/hashicorp/raft v1.0.0/go.mod h1:DVSAWItjLjTOkVbSpWQ0j0kUADIvDaCtBxIcbNAQLkI=
|
||||
github.com/howeyc/gopass v0.0.0-20170109162249-bf9dde6d0d2c h1:kQWxfPIHVLbgLzphqk3QUflDy9QdksZR4ygR807bpy0=
|
||||
github.com/howeyc/gopass v0.0.0-20170109162249-bf9dde6d0d2c/go.mod h1:lADxMC39cJJqL93Duh1xhAs4I2Zs8mKS89XWXFGp9cs=
|
||||
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/inconshreveable/go-update v0.0.0-20160112193335-8152e7eb6ccf h1:WfD7VjIE6z8dIvMsI4/s+1qr5EL+zoIGev1BQj1eoJ8=
|
||||
github.com/inconshreveable/go-update v0.0.0-20160112193335-8152e7eb6ccf/go.mod h1:hyb9oH7vZsitZCiBt0ZvifOrB+qc8PS5IiilCIb87rg=
|
||||
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/jackc/fake v0.0.0-20150926172116-812a484cc733 h1:vr3AYkKovP8uR8AvSGGUK1IDqRa5lAAvEkZG1LKaCRc=
|
||||
github.com/jackc/fake v0.0.0-20150926172116-812a484cc733/go.mod h1:WrMFNQdiFJ80sQsxDoMokWK1W5TQtxBFNpzWTD84ibQ=
|
||||
github.com/jackc/pgx v3.2.0+incompatible h1:0Vihzu20St42/UDsvZGdNE6jak7oi/UOeMzwMPHkgFY=
|
||||
github.com/jackc/pgx v3.2.0+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I=
|
||||
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
|
||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||
github.com/jtolds/go-luar v0.0.0-20170419063437-0786921db8c0/go.mod h1:OtVLEpPHGJkn8jgGrHlYELCA3uXLU0YSfNN0faeDM2M=
|
||||
github.com/jtolds/monkit-hw/v2 v2.0.0-20191108235325-141a0da276b3 h1:dITCBge70U9RDyZUL/Thn/yAT/ct4Rz40mNUX51dFCk=
|
||||
github.com/jtolds/monkit-hw/v2 v2.0.0-20191108235325-141a0da276b3/go.mod h1:eo5po8nCwRcvZIIR8eGi7PKthzXuunpXzUmXzxCBfBc=
|
||||
github.com/jtolds/tracetagger/v2 v2.0.0-rc2 h1:pxmt5o+WRYffMwMYuFlI3wKwYbPVAyiX8EEyM8a/U7o=
|
||||
github.com/jtolds/tracetagger/v2 v2.0.0-rc2/go.mod h1:EeqZ0b80feEwRK+FutrQ/GJxruNqamJBKOezZVfzSxA=
|
||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8=
|
||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/klauspost/cpuid v0.0.0-20180405133222-e7e905edc00e h1:+lIPJOWl+jSiJOc70QXJ07+2eg2Jy2EC7Mi11BWujeM=
|
||||
github.com/klauspost/cpuid v0.0.0-20180405133222-e7e905edc00e/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||
github.com/klauspost/reedsolomon v0.0.0-20180704173009-925cb01d6510 h1:9eOgsI7EIGhJWPMBvSY+x0SEpeGGWUSijOrwK0XhpIk=
|
||||
github.com/klauspost/reedsolomon v0.0.0-20180704173009-925cb01d6510/go.mod h1:CwCi+NUr9pqSVktrkN+Ondf06rkhYZ/pcNv7fu+8Un4=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
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/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kshvakov/clickhouse v1.3.5/go.mod h1:DMzX7FxRymoNkVgizH0DWAL8Cur7wHLgx3MUnGwJqpE=
|
||||
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.3.0 h1:/qkRGz8zljWiDcFvgpwUpwIAPu3r07TDvs3Rws+o/pU=
|
||||
github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/loov/hrtime v0.0.0-20181214195526-37a208e8344e/go.mod h1:2871C3urfEJnq/bpTYjFdMOdgxVd8otLLEL6vMNy/Iw=
|
||||
github.com/loov/plot v0.0.0-20180510142208-e59891ae1271/go.mod h1:3yy5HBPbe5e1UmEffbO0n0g6A8h6ChHaCTeundr6H60=
|
||||
github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY=
|
||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/mailru/easyjson v0.0.0-20180730094502-03f2033d19d5 h1:0x4qcEHDpruK6ML/m/YSlFUUu0UpRD3I2PHsNCuGnyA=
|
||||
github.com/mailru/easyjson v0.0.0-20180730094502-03f2033d19d5/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU=
|
||||
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.9 h1:d5US/mDsogSGW37IV293h//ZFaeajb69h+EHFsv2xGg=
|
||||
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
|
||||
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-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/mattn/go-sqlite3 v2.0.2+incompatible h1:qzw9c2GNT8UFrgWNDhCTqRqYUSmu/Dav/9Z58LGpk7U=
|
||||
github.com/mattn/go-sqlite3 v2.0.2+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/minio/cli v1.3.0 h1:vB0iUpmyaH54+1jJJj62Aa0qFF3xO3i0J3IcKiM6bHM=
|
||||
github.com/minio/cli v1.3.0/go.mod h1:hLsWNQy2wIf3FKFnMlH69f4RdEyn8nbRA2shaulTjGY=
|
||||
github.com/minio/dsync v0.0.0-20180124070302-439a0961af70 h1:pRHQdPOlUhelWqNUF3icFrBSC6VYH1hvF6HigVfgMoI=
|
||||
github.com/minio/dsync v0.0.0-20180124070302-439a0961af70/go.mod h1:eLQe3mXL0h02kNpPtBJiLr1fIEIJftgXRAjncjQbxJo=
|
||||
github.com/minio/highwayhash v0.0.0-20180501080913-85fc8a2dacad h1:L+8skVz2lusCbtlalLXmJp+TK8XaGAsZ3utSC3k5Jc0=
|
||||
github.com/minio/highwayhash v0.0.0-20180501080913-85fc8a2dacad/go.mod h1:NL8wme5P5MoscwAkXfGroz3VgpCdhBw3KYOu5mEsvpU=
|
||||
github.com/minio/lsync v0.0.0-20180328070428-f332c3883f63 h1:utJHim4C0K4CmD+Qgod/tgHvo7QNOlH6HN5O8QUvPEI=
|
||||
github.com/minio/lsync v0.0.0-20180328070428-f332c3883f63/go.mod h1:ni10+iSX7FO8N2rv41XM444V6w4rYO0dZo5KIkbn/YA=
|
||||
github.com/minio/mc v0.0.0-20180926130011-a215fbb71884 h1:co3kRW9cEI65yolYtcLcNxp2a9yk5T/eEt7gw14tJVs=
|
||||
github.com/minio/mc v0.0.0-20180926130011-a215fbb71884/go.mod h1:pPcAoOwWUSIBqoLtp+0LEACUBUPhodkXwisyYrNgQ5o=
|
||||
github.com/minio/minio v0.0.0-20180508161510-54cd29b51c38 h1:F7p0ZU9AQuxlA6SWwhXr0H/rYrA9fOiBk2OzOj7GtfM=
|
||||
github.com/minio/minio v0.0.0-20180508161510-54cd29b51c38/go.mod h1:lXcp05uxYaW99ebgI6ZKIGYU7tqZkM5xSsG0xRt4VIU=
|
||||
github.com/minio/minio-go v6.0.3+incompatible h1:yTq5mJOcWg6ot6STkEMnrNN896L0aDDu6njDB+8Ply0=
|
||||
github.com/minio/minio-go v6.0.3+incompatible/go.mod h1:7guKYtitv8dktvNUGrhzmNlA5wrAABTQXCoesZdFQO8=
|
||||
github.com/minio/sha256-simd v0.0.0-20190328051042-05b4dd3047e5 h1:l16XLUUJ34wIz+RIvLhSwGvLvKyy+W598b135bJN6mg=
|
||||
github.com/minio/sha256-simd v0.0.0-20190328051042-05b4dd3047e5/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U=
|
||||
github.com/minio/sio v0.0.0-20180327104954-6a41828a60f0 h1:ys4bbOlPvaUBlA0byjm6TqydsXZu614ZIUTfF+4MRY0=
|
||||
github.com/minio/sio v0.0.0-20180327104954-6a41828a60f0/go.mod h1:PDJGYr8GXjiOTIst0hQMOSK5FdXLwObr2cGbiMddDPc=
|
||||
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/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c h1:nXxl5PrvVm2L/wCy8dQu6DMTwH4oIuGN8GJDAlqDdVE=
|
||||
github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/nakagami/firebirdsql v0.0.0-20190310045651-3c02a58cfed8/go.mod h1:86wM1zFnC6/uDBfZGNwB65O+pR2OFi5q/YQaEUid1qA=
|
||||
github.com/nats-io/gnatsd v1.3.0 h1:+5d80klu3QaJgNbdavVBjWJP7cHd11U2CLnRTFM9ICI=
|
||||
github.com/nats-io/gnatsd v1.3.0/go.mod h1:nqco77VO78hLCJpIcVfygDP2rPGfsEHkGTUk94uh5DQ=
|
||||
github.com/nats-io/go-nats v1.6.0 h1:FznPwMfrVwGnSCh7JTXyJDRW0TIkD4Tr+M1LPJt9T70=
|
||||
github.com/nats-io/go-nats v1.6.0/go.mod h1:+t7RHT5ApZebkrQdnn6AhQJmhJJiKAvJUio1PiiCtj0=
|
||||
github.com/nats-io/go-nats-streaming v0.4.2 h1:e7Fs4yxvFTs8N5xKFoJyw0sVW2heJwYvrUWfdf9VQlE=
|
||||
github.com/nats-io/go-nats-streaming v0.4.2/go.mod h1:gfq4R3c9sKAINOpelo0gn/b9QDMBZnmrttcsNF+lqyo=
|
||||
github.com/nats-io/nats v1.6.0 h1:U5b2apHOTZlUou+NGfCRWG4ZEeivbt2hpsZO4kHKIVU=
|
||||
github.com/nats-io/nats v1.6.0/go.mod h1:PpmYZwlgTfBI56QypJLfIMOfLnMRuVs+VL6r8mQ2SoQ=
|
||||
github.com/nats-io/nats-streaming-server v0.12.2 h1:EpyLfUBZgwu5c0mdSSytQsapm615AyitPssq7jgafdw=
|
||||
github.com/nats-io/nats-streaming-server v0.12.2/go.mod h1:RyqtDJZvMZO66YmyjIYdIvS69zu/wDAkyNWa8PIUa5c=
|
||||
github.com/nats-io/nuid v1.0.0 h1:44QGdhbiANq8ZCbUkdn6W5bqtg+mHuDE4wOUuxxndFs=
|
||||
github.com/nats-io/nuid v1.0.0/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
|
||||
github.com/nsf/jsondiff v0.0.0-20160203110537-7de28ed2b6e3/go.mod h1:uFMI8w+ref4v2r9jz+c9i1IfIttS/OkmLfrk1jne5hs=
|
||||
github.com/nsf/termbox-go v0.0.0-20190121233118-02980233997d/go.mod h1:IuKpRQcYE1Tfu+oAQqaLisqDeXgjyyltCfsaoYN18NQ=
|
||||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.10.3 h1:OoxbjfXVZyod1fmWYhI7SEyaD8B00ynP3T+D5GiyHOY=
|
||||
github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/onsi/gomega v1.7.1 h1:K0jcRCwNQM3vFGh1ppMtDh/+7ApJrjldlX8fA0jDTLQ=
|
||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||
github.com/opencontainers/go-digest v1.0.0-rc1 h1:WzifXhOVOEOuFYOJAW6aQqW0TooG2iki3E3Ii+WN7gQ=
|
||||
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||
github.com/opencontainers/image-spec v1.0.1 h1:JMemWkRwHx4Zj+fVxWoMCFm/8sYGGrUVojFA6h/TRcI=
|
||||
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
|
||||
github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
|
||||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c h1:Lgl0gzECD8GnQ5QCWA8o6BtfL6mDH5rQgM4/fX3avOs=
|
||||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||
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/pierrec/lz4 v2.0.5+incompatible h1:2xWsjqPFWcplujydGg4WmhC/6fZqK42wMM8aXeqhl0I=
|
||||
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/profile v1.2.1 h1:F++O52m40owAmADcojzM+9gyjmMOY/T4oYJkgFDH8RE=
|
||||
github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
|
||||
github.com/prometheus/client_golang v0.9.3 h1:9iH4JKXLzFbOAdtqv/a+j8aewx2Y8lAjAydhbaScPF8=
|
||||
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 h1:S/YWwWx/RA8rT8tKFRuGUZhuA90OyIBpPCXkcbwU8DE=
|
||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||
github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.4.0 h1:7etb9YClo3a6HjLzfl6rIQaU+FDfi0VSX39io3aQ+DM=
|
||||
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/procfs v0.0.0-20190517135640-51af30a78b0e h1:zK8d1aZ+gw/Ne4uMfZTFRxj08PUOp+gGwm4HWUeGI1k=
|
||||
github.com/prometheus/procfs v0.0.0-20190517135640-51af30a78b0e/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a h1:9ZKAASQSHhDYGoxY8uLVpewe1GDZ2vu2Tr/vTdVAkFQ=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||
github.com/rs/cors v1.5.0 h1:dgSHE6+ia18arGOTIYQKKGWLvEbGvmbNE6NfxhoNHUY=
|
||||
github.com/rs/cors v1.5.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
|
||||
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||
github.com/segmentio/go-prompt v1.2.1-0.20161017233205-f0d19b6901ad h1:EqOdoSJGI7CsBQczPcIgmpm3hJE7X8Hj3jrgI002whs=
|
||||
github.com/segmentio/go-prompt v1.2.1-0.20161017233205-f0d19b6901ad/go.mod h1:B3ehdD1xPoWDKgrQgUaGk+m8H1xb1J5TyYDfKpKNeEE=
|
||||
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
|
||||
github.com/shopspring/decimal v0.0.0-20200105231215-408a2507e114 h1:Pm6R878vxWWWR+Sa3ppsLce/Zq+JNTs6aVvRu13jv9A=
|
||||
github.com/shopspring/decimal v0.0.0-20200105231215-408a2507e114/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
|
||||
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/skyrings/skyring-common v0.0.0-20160929130248-d1c0bb1cbd5e h1:jrZSSgPUDtBeJbGXqgGUeupQH8I+ZvGXfhpIahye2Bc=
|
||||
github.com/skyrings/skyring-common v0.0.0-20160929130248-d1c0bb1cbd5e/go.mod h1:d8hQseuYt4rJoOo21lFzYJdhMjmDqLY++ayArbgYjWI=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9/go.mod h1:SnhjPscd9TpLiy1LpzGSKh3bXCfxxXuqd9xmQJy3slM=
|
||||
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
|
||||
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
||||
github.com/spacemonkeygo/errors v0.0.0-20171212215202-9064522e9fd1 h1:xHQewZjohU9/wUsyC99navCjQDNHtTgUOM/J1jAbzfw=
|
||||
github.com/spacemonkeygo/errors v0.0.0-20171212215202-9064522e9fd1/go.mod h1:7NL9UAYQnRM5iKHUCld3tf02fKb5Dft+41+VckASUy0=
|
||||
github.com/spacemonkeygo/monkit/v3 v3.0.0-20191108235033-eacca33b3037/go.mod h1:JcK1pCbReQsOsMKF/POFSZCq7drXFybgGmbc27tuwes=
|
||||
github.com/spacemonkeygo/monkit/v3 v3.0.1 h1:mSZQU+LOFuN5KSUvE1EiU1lxlFcOz/r0N5Tz8z+TwN0=
|
||||
github.com/spacemonkeygo/monkit/v3 v3.0.1/go.mod h1:JcK1pCbReQsOsMKF/POFSZCq7drXFybgGmbc27tuwes=
|
||||
github.com/spacemonkeygo/monotime v0.0.0-20180824235756-e3f48a95f98a h1:8+cCjxhToanKmxLIbuyBNe2EnpgwhiivsIaRJstDRFA=
|
||||
github.com/spacemonkeygo/monotime v0.0.0-20180824235756-e3f48a95f98a/go.mod h1:ul4bvvnCOPZgq8w0nTkSmWVg/hauVpFS97Am1YM1XXo=
|
||||
github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU=
|
||||
github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc=
|
||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||
github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI=
|
||||
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
||||
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.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s=
|
||||
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
|
||||
github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk=
|
||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
|
||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
|
||||
github.com/spf13/viper v1.4.0 h1:yXHLWeravcrgGyFSyCgdYpXQ9dR9c/WED3pg1RhxqEU=
|
||||
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
|
||||
github.com/storj/grpc-go v1.23.1-0.20190918084400-1c4561bf5127 h1:sJtPW3g23UOuV+b5o3ARQ7467NzjjacUoBBPTyvIP9c=
|
||||
github.com/storj/grpc-go v1.23.1-0.20190918084400-1c4561bf5127/go.mod h1:b+NmczNXvOWokHOVTM0zzTDhQEV+xRmnFVmFTVlkg8Q=
|
||||
github.com/streadway/amqp v0.0.0-20180806233856-70e15c650864 h1:Oj3PUEs+OUSYUpn35O+BE/ivHGirKixA3+vqA0Atu9A=
|
||||
github.com/streadway/amqp v0.0.0-20180806233856-70e15c650864/go.mod h1:1WNBiOZtZQLpVAyu0iTduoJL9hEsMloAK5XWrtW0xdY=
|
||||
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/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stripe/stripe-go v63.1.1+incompatible h1:OpGp55VzHcnu5O/MtVVU42xS2xeAWosx3xELvuoMMMw=
|
||||
github.com/stripe/stripe-go v63.1.1+incompatible/go.mod h1:A1dQZmO/QypXmsL0T8axYZkSN/uA/T/A64pfKdBAMiY=
|
||||
github.com/tidwall/gjson v1.1.3 h1:u4mspaByxY+Qk4U1QYYVzGFI8qxN/3jtEV0ZDb2vRic=
|
||||
github.com/tidwall/gjson v1.1.3/go.mod h1:c/nTNbUr0E0OrXEhq1pwa8iEgc2DOt4ZZqAt1HtCkPA=
|
||||
github.com/tidwall/match v0.0.0-20171002075945-1731857f09b1 h1:pWIN9LOlFRCJFqWIOEbHLvY0WWJddsjH2FQ6N0HKZdU=
|
||||
github.com/tidwall/match v0.0.0-20171002075945-1731857f09b1/go.mod h1:LujAq0jyVjBy028G1WhWfIzbpQfMO8bBZ6Tyb0+pL9E=
|
||||
github.com/tidwall/pretty v0.0.0-20180105212114-65a9db5fad51/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
|
||||
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
||||
github.com/vivint/infectious v0.0.0-20190108171102-2455b059135b h1:dLkqBELopfQNhe8S9ucnSf+HhiUCgK/hPIjVG0f9GlY=
|
||||
github.com/vivint/infectious v0.0.0-20190108171102-2455b059135b/go.mod h1:5oyMAv4hrBEKqBwORFsiqIrCNCmL2qcZLQTdJLYeYIc=
|
||||
github.com/xanzy/go-gitlab v0.15.0/go.mod h1:8zdQa/ri1dfn8eS3Ir1SyfvOKlw7WBJ8DVThkpGiXrs=
|
||||
github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I=
|
||||
github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||
github.com/yuin/gopher-lua v0.0.0-20190206043414-8bfc7677f583 h1:SZPG5w7Qxq7bMcMVl6e3Ht2X7f+AAGQdzjkbyOnNNZ8=
|
||||
github.com/yuin/gopher-lua v0.0.0-20190206043414-8bfc7677f583/go.mod h1:gqRgreBUhTSL0GeU64rtZ3Uq3wtjOa/TB2YfrtkCbVQ=
|
||||
github.com/zeebo/admission/v2 v2.0.0 h1:220NPZzKmyfklysKFO95L7E2Gt5NwlxTWGE14VP8heE=
|
||||
github.com/zeebo/admission/v2 v2.0.0/go.mod h1:gSeHGelDHW7Vq6UyJo2boeSt/6Dsnqpisv0i4YZSOyM=
|
||||
github.com/zeebo/assert v0.0.0-20181109011804-10f827ce2ed6/go.mod h1:yssERNPivllc1yU3BvpjYI5BUW+zglcz6QWqeVRL5t0=
|
||||
github.com/zeebo/assert v1.0.0/go.mod h1:yssERNPivllc1yU3BvpjYI5BUW+zglcz6QWqeVRL5t0=
|
||||
github.com/zeebo/assert v1.1.0 h1:hU1L1vLTHsnO8x8c9KAR5GmM5QscxHg5RNU5z5qbUWY=
|
||||
github.com/zeebo/assert v1.1.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0=
|
||||
github.com/zeebo/errs v1.1.1/go.mod h1:Yj8dHrUQwls1bF3dr/vcSIu+qf4mI7idnTcHfoACc6I=
|
||||
github.com/zeebo/errs v1.2.2 h1:5NFypMTuSdoySVTqlNs1dEoU21QVamMQJxW/Fii5O7g=
|
||||
github.com/zeebo/errs v1.2.2/go.mod h1:sgbWHsvVuTPHcqJJGQ1WhI5KbWlHYz+2+2C/LSEtCw4=
|
||||
github.com/zeebo/float16 v0.1.0 h1:kRqxv5og6z1emEyz5FpW0/BVHe5VfxEAw6b1ljCZlUc=
|
||||
github.com/zeebo/float16 v0.1.0/go.mod h1:fssGvvXu+XS8MH57cKmyrLB/cqioYeYX/2mXCN3a5wo=
|
||||
github.com/zeebo/incenc v0.0.0-20180505221441-0d92902eec54 h1:+cwNE5KJ3pika4HuzmDHkDlK5myo0G9Sv+eO7WWxnUQ=
|
||||
github.com/zeebo/incenc v0.0.0-20180505221441-0d92902eec54/go.mod h1:EI8LcOBDlSL3POyqwC1eJhOYlMBMidES+613EtmmT5w=
|
||||
github.com/zeebo/structs v1.0.2 h1:kvcd7s2LqXuO9cdV5LqrGHCOAfCBXaZpKCA3jD9SJIc=
|
||||
github.com/zeebo/structs v1.0.2/go.mod h1:LphfpprlqJQcbCq+eA3iIK/NsejMwk9mlfH/tM1XuKQ=
|
||||
gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b/go.mod h1:T3BPAOm2cqquPa0MKWeNkmOM5RQsRhkrwMWonFMN7fE=
|
||||
go.etcd.io/bbolt v1.3.2 h1:Z/90sZLPOeCy2PwprqkFa25PdkusRzaj9P8zm/KNyvk=
|
||||
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
go.mongodb.org/mongo-driver v1.1.0/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
|
||||
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU=
|
||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
|
||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||
go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM=
|
||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975 h1:/Tl7pH94bvbAAHBdZJT947M/+gp0+CqQXDtMRC0fseo=
|
||||
golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/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-20181108082009-03003ca0c849/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-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190424112056-4829fb13d2c6/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20190923162816-aa69164e4478 h1:l5EDrHhldLYb3ZRHDUhXF7Om7MvYXnkV9/iQNo1lX6g=
|
||||
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
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/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
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-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/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-20190102155601-82a175fd1598/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190204203706-41f3e6584952/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-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190426135247-a129542de9ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191210023423-ac6580df4449/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200107144601-ef85f5a75ddf h1:9cZxTVBvFZgOnVi/DobY3JsafbPFPnP2rtN81d4wPpw=
|
||||
golang.org/x/sys v0.0.0-20200107144601-ef85f5a75ddf/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.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-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/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-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190425222832-ad9eeb80039a/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
|
||||
google.golang.org/api v0.3.2/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
|
||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
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/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.6.0 h1:Tfd7cKwKbFRsI8RMAD3oqqw7JPFRrvFlOsfbgVkjOOw=
|
||||
google.golang.org/appengine v1.6.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190716160619-c506a9f90610 h1:Ygq9/SRJX9+dU0WCIICM8RkWvDw03lvB77hrhJnpxfU=
|
||||
google.golang.org/genproto v0.0.0-20190716160619-c506a9f90610/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
gopkg.in/Shopify/sarama.v1 v1.18.0 h1:f9aTXuIEFEjVvLG9p+kMSk01dMfFumHsySRk1okTdqU=
|
||||
gopkg.in/Shopify/sarama.v1 v1.18.0/go.mod h1:AxnvoaevB2nBjNK17cG61A3LleFcWFwVBHBt+cot4Oc=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/cheggaaa/pb.v1 v1.0.25 h1:Ev7yu1/f6+d+b3pi5vPdRPc6nNtP1umSfcWiEfRqv6I=
|
||||
gopkg.in/cheggaaa/pb.v1 v1.0.25/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/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
gopkg.in/ini.v1 v1.52.0 h1:j+Lt/M1oPPejkniCg1TkWE2J3Eh1oZTsHSXzMTzUXn4=
|
||||
gopkg.in/ini.v1 v1.52.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/olivere/elastic.v5 v5.0.76 h1:A6W7X4yLPQDINHiYAqIwqev+rD5hIQ4G0e1d5H//VXk=
|
||||
gopkg.in/olivere/elastic.v5 v5.0.76/go.mod h1:uhHoB4o3bvX5sorxBU29rPcmBQdV2Qfg0FBrx5D6pV0=
|
||||
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
||||
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/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
|
||||
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
storj.io/common v0.0.0-20200214070817-cfd197b055d7/go.mod h1:MlYmhIuKHfD15puGH7Su5lv0bt4ojZ7IfrPnAmR4NeI=
|
||||
storj.io/common v0.0.0-20200214110758-9e3820f574f6 h1:6Le0tbcmQDPYqWCiXRzd4fbp7ltpLaiPP6n6ZhEyguk=
|
||||
storj.io/common v0.0.0-20200214110758-9e3820f574f6/go.mod h1:MlYmhIuKHfD15puGH7Su5lv0bt4ojZ7IfrPnAmR4NeI=
|
||||
storj.io/common v0.0.0-20200221161141-79b008e3eff0 h1:lN5HVfeSa7uwbVYQ1CyQZ3I5nUeZzgejrGJZVjRsktg=
|
||||
storj.io/common v0.0.0-20200221161141-79b008e3eff0/go.mod h1:lCc2baFO7GQlKsPTri8xwCsCPO2LsEUUiAGeRQuXY48=
|
||||
storj.io/drpc v0.0.7-0.20191115031725-2171c57838d2/go.mod h1:/ascUDbzNAv0A3Jj7wUIKFBH2JdJ2uJIBO/b9+2yHgQ=
|
||||
storj.io/drpc v0.0.8 h1:wu68cMmtoT0vSWIAZz29RpJkWdi4o0S8BIrLslpH5FQ=
|
||||
storj.io/drpc v0.0.8/go.mod h1:v39uWro/EbXXk+gNnrM9FQuVVS2zUBWBfeduydgeXUA=
|
||||
storj.io/gateway v0.0.0-20200221161528-36f00ab51fa7 h1:y9j0csaF76taOBELm3OrrBdyWsVkhYf2AyOfVqkngq8=
|
||||
storj.io/gateway v0.0.0-20200221161528-36f00ab51fa7/go.mod h1:VtLc0oGOFi7Aslw33HG2nVibeyMBNNwYpiLRjE+O+rs=
|
||||
storj.io/uplink v0.0.0-20200221135851-60db51e97359 h1:8IYCBjyXW4PAbhFhghZEXH8ZNbxD6lrfmNvotrD2G/E=
|
||||
storj.io/uplink v0.0.0-20200221135851-60db51e97359/go.mod h1:SAetpjpLjDx0bH/TgfMaD2O/S283bn/Kcz8f/juI03I=
|
||||
storj.io/uplink v0.0.0-20200221171743-26268cdd3552 h1:yXojx6mQXtJfwh5qdUEakWvh+EXkJbTV4qWE1aPJzTU=
|
||||
storj.io/uplink v0.0.0-20200221171743-26268cdd3552/go.mod h1:SAetpjpLjDx0bH/TgfMaD2O/S283bn/Kcz8f/juI03I=
|
@ -4,331 +4,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/btcsuite/btcutil/base58"
|
||||
"github.com/minio/cli"
|
||||
minio "github.com/minio/minio/cmd"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/zeebo/errs"
|
||||
"go.uber.org/zap"
|
||||
|
||||
"storj.io/common/fpath"
|
||||
"storj.io/storj/cmd/internal/wizard"
|
||||
"storj.io/storj/cmd/uplink/cmd"
|
||||
"storj.io/storj/pkg/cfgstruct"
|
||||
"storj.io/storj/pkg/miniogw"
|
||||
"storj.io/storj/pkg/process"
|
||||
"storj.io/storj/private/version"
|
||||
"storj.io/storj/private/version/checker"
|
||||
"storj.io/uplink"
|
||||
"storj.io/gateway/private/cmd"
|
||||
)
|
||||
|
||||
// GatewayFlags configuration flags
|
||||
type GatewayFlags struct {
|
||||
NonInteractive bool `help:"disable interactive mode" default:"false" setup:"true"`
|
||||
|
||||
Server miniogw.ServerConfig
|
||||
Minio miniogw.MinioConfig
|
||||
|
||||
cmd.Config
|
||||
|
||||
Version checker.Config
|
||||
|
||||
PBKDFConcurrency int `help:"Unfortunately, up until v0.26.2, keys generated from passphrases depended on the number of cores the local CPU had. If you entered a passphrase with v0.26.2 earlier, you'll want to set this number to the number of CPU cores your computer had at the time. This flag may go away in the future. For new installations the default value is highly recommended." default:"0"`
|
||||
}
|
||||
|
||||
var (
|
||||
// Error is the default gateway setup errs class
|
||||
Error = errs.Class("gateway setup error")
|
||||
// rootCmd represents the base gateway command when called without any subcommands
|
||||
rootCmd = &cobra.Command{
|
||||
Use: "gateway",
|
||||
Short: "The Storj client-side S3 gateway",
|
||||
Args: cobra.OnlyValidArgs,
|
||||
}
|
||||
setupCmd = &cobra.Command{
|
||||
Use: "setup",
|
||||
Short: "Create a gateway config file",
|
||||
RunE: cmdSetup,
|
||||
Annotations: map[string]string{"type": "setup"},
|
||||
}
|
||||
runCmd = &cobra.Command{
|
||||
Use: "run",
|
||||
Short: "Run the S3 gateway",
|
||||
RunE: cmdRun,
|
||||
}
|
||||
|
||||
setupCfg GatewayFlags
|
||||
runCfg GatewayFlags
|
||||
|
||||
confDir string
|
||||
identityDir string
|
||||
)
|
||||
|
||||
func init() {
|
||||
defaultConfDir := fpath.ApplicationDir("storj", "gateway")
|
||||
defaultIdentityDir := fpath.ApplicationDir("storj", "identity", "gateway")
|
||||
cfgstruct.SetupFlag(zap.L(), rootCmd, &confDir, "config-dir", defaultConfDir, "main directory for gateway configuration")
|
||||
cfgstruct.SetupFlag(zap.L(), rootCmd, &identityDir, "identity-dir", defaultIdentityDir, "main directory for gateway identity credentials")
|
||||
defaults := cfgstruct.DefaultsFlag(rootCmd)
|
||||
|
||||
rootCmd.AddCommand(runCmd)
|
||||
rootCmd.AddCommand(setupCmd)
|
||||
process.Bind(runCmd, &runCfg, defaults, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir))
|
||||
process.Bind(setupCmd, &setupCfg, defaults, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir), cfgstruct.SetupMode())
|
||||
}
|
||||
|
||||
func cmdSetup(cmd *cobra.Command, args []string) (err error) {
|
||||
setupDir, err := filepath.Abs(confDir)
|
||||
if err != nil {
|
||||
return Error.Wrap(err)
|
||||
}
|
||||
|
||||
valid, _ := fpath.IsValidSetupDir(setupDir)
|
||||
if !valid {
|
||||
return Error.New("gateway configuration already exists (%v)", setupDir)
|
||||
}
|
||||
|
||||
err = os.MkdirAll(setupDir, 0700)
|
||||
if err != nil {
|
||||
return Error.Wrap(err)
|
||||
}
|
||||
|
||||
overrides := map[string]interface{}{}
|
||||
|
||||
accessKeyFlag := cmd.Flag("minio.access-key")
|
||||
if !accessKeyFlag.Changed {
|
||||
accessKey, err := generateKey()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
overrides[accessKeyFlag.Name] = accessKey
|
||||
}
|
||||
|
||||
secretKeyFlag := cmd.Flag("minio.secret-key")
|
||||
if !secretKeyFlag.Changed {
|
||||
secretKey, err := generateKey()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
overrides[secretKeyFlag.Name] = secretKey
|
||||
}
|
||||
|
||||
if setupCfg.NonInteractive {
|
||||
return setupCfg.nonInteractive(cmd, setupDir, overrides)
|
||||
}
|
||||
return setupCfg.interactive(cmd, setupDir, overrides)
|
||||
}
|
||||
|
||||
func cmdRun(cmd *cobra.Command, args []string) (err error) {
|
||||
address := runCfg.Server.Address
|
||||
host, port, err := net.SplitHostPort(address)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if host == "" {
|
||||
address = net.JoinHostPort("127.0.0.1", port)
|
||||
}
|
||||
|
||||
ctx, _ := process.Ctx(cmd)
|
||||
|
||||
if err := process.InitMetrics(ctx, zap.L(), nil, ""); err != nil {
|
||||
zap.S().Warn("Failed to initialize telemetry batcher: ", err)
|
||||
}
|
||||
|
||||
err = checker.CheckProcessVersion(ctx, zap.L(), runCfg.Version, version.Build, "Gateway")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
zap.S().Infof("Starting Storj S3-compatible gateway!\n\n")
|
||||
zap.S().Infof("Endpoint: %s\n", address)
|
||||
zap.S().Infof("Access key: %s\n", runCfg.Minio.AccessKey)
|
||||
zap.S().Infof("Secret key: %s\n", runCfg.Minio.SecretKey)
|
||||
|
||||
err = checkCfg(ctx)
|
||||
if err != nil {
|
||||
zap.S().Warn("Failed to contact Satellite. Perhaps your configuration is invalid?")
|
||||
return err
|
||||
}
|
||||
|
||||
return runCfg.Run(ctx)
|
||||
}
|
||||
|
||||
func generateKey() (key string, err error) {
|
||||
var buf [20]byte
|
||||
_, err = rand.Read(buf[:])
|
||||
if err != nil {
|
||||
return "", Error.Wrap(err)
|
||||
}
|
||||
return base58.Encode(buf[:]), nil
|
||||
}
|
||||
|
||||
func checkCfg(ctx context.Context) (err error) {
|
||||
project, err := runCfg.openProject(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() { err = errs.Combine(err, project.Close()) }()
|
||||
|
||||
buckets := project.ListBuckets(ctx, nil)
|
||||
_ = buckets.Next()
|
||||
return buckets.Err()
|
||||
}
|
||||
|
||||
// Run starts a Minio Gateway given proper config
|
||||
func (flags GatewayFlags) Run(ctx context.Context) (err error) {
|
||||
err = minio.RegisterGatewayCommand(cli.Command{
|
||||
Name: "storj",
|
||||
Usage: "Storj",
|
||||
Action: func(cliCtx *cli.Context) error {
|
||||
return flags.action(ctx, cliCtx)
|
||||
},
|
||||
HideHelpCommand: true,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// TODO(jt): Surely there is a better way. This is so upsetting
|
||||
err = os.Setenv("MINIO_ACCESS_KEY", flags.Minio.AccessKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = os.Setenv("MINIO_SECRET_KEY", flags.Minio.SecretKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
minio.Main([]string{"storj", "gateway", "storj",
|
||||
"--address", flags.Server.Address, "--config-dir", flags.Minio.Dir, "--quiet"})
|
||||
return errs.New("unexpected minio exit")
|
||||
}
|
||||
|
||||
func (flags GatewayFlags) action(ctx context.Context, cliCtx *cli.Context) (err error) {
|
||||
gw, err := flags.NewGateway(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
minio.StartGateway(cliCtx, miniogw.Logging(gw, zap.L()))
|
||||
return errs.New("unexpected minio exit")
|
||||
}
|
||||
|
||||
// NewGateway creates a new minio Gateway
|
||||
func (flags GatewayFlags) NewGateway(ctx context.Context) (gw minio.Gateway, err error) {
|
||||
project, err := flags.openProject(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return miniogw.NewStorjGateway(
|
||||
project,
|
||||
), nil
|
||||
}
|
||||
|
||||
func (flags *GatewayFlags) newUplinkConfig(ctx context.Context) uplink.Config {
|
||||
// Transform the gateway config flags to the uplink config object
|
||||
uplinkCfg := uplink.Config{}
|
||||
uplinkCfg.DialTimeout = flags.Client.DialTimeout
|
||||
return uplinkCfg
|
||||
}
|
||||
|
||||
func (flags GatewayFlags) openProject(ctx context.Context) (*uplink.Project, error) {
|
||||
oldAccess, err := flags.GetAccess()
|
||||
if err != nil {
|
||||
return nil, Error.Wrap(err)
|
||||
}
|
||||
|
||||
serializedAccess, err := oldAccess.Serialize()
|
||||
if err != nil {
|
||||
return nil, Error.Wrap(err)
|
||||
}
|
||||
|
||||
access, err := uplink.ParseAccess(serializedAccess)
|
||||
if err != nil {
|
||||
return nil, Error.Wrap(err)
|
||||
}
|
||||
|
||||
config := flags.newUplinkConfig(ctx)
|
||||
project, err := config.OpenProject(ctx, access)
|
||||
if err != nil {
|
||||
return nil, Error.Wrap(err)
|
||||
}
|
||||
return project, nil
|
||||
}
|
||||
|
||||
// interactive creates the configuration of the gateway interactively.
|
||||
func (flags GatewayFlags) interactive(cmd *cobra.Command, setupDir string, overrides map[string]interface{}) error {
|
||||
ctx, _ := process.Ctx(cmd)
|
||||
|
||||
satelliteAddress, err := wizard.PromptForSatellite(cmd)
|
||||
if err != nil {
|
||||
return Error.Wrap(err)
|
||||
}
|
||||
|
||||
apiKey, err := wizard.PromptForAPIKey()
|
||||
if err != nil {
|
||||
return Error.Wrap(err)
|
||||
}
|
||||
|
||||
passphrase, err := wizard.PromptForEncryptionPassphrase()
|
||||
if err != nil {
|
||||
return Error.Wrap(err)
|
||||
}
|
||||
|
||||
access, err := uplink.RequestAccessWithPassphrase(ctx, satelliteAddress, apiKey, passphrase)
|
||||
if err != nil {
|
||||
return Error.Wrap(err)
|
||||
}
|
||||
|
||||
accessData, err := access.Serialize()
|
||||
if err != nil {
|
||||
return Error.Wrap(err)
|
||||
}
|
||||
overrides["access"] = accessData
|
||||
|
||||
err = process.SaveConfig(cmd, filepath.Join(setupDir, "config.yaml"),
|
||||
process.SaveConfigWithOverrides(overrides),
|
||||
process.SaveConfigRemovingDeprecated())
|
||||
if err != nil {
|
||||
return Error.Wrap(err)
|
||||
}
|
||||
|
||||
fmt.Println(`
|
||||
Your S3 Gateway is configured and ready to use!
|
||||
|
||||
Some things to try next:
|
||||
|
||||
* See https://documentation.tardigrade.io/api-reference/s3-gateway for some example commands`)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// nonInteractive creates the configuration of the gateway non-interactively.
|
||||
func (flags GatewayFlags) nonInteractive(cmd *cobra.Command, setupDir string, overrides map[string]interface{}) error {
|
||||
// ensure we're using the access for the setup
|
||||
access, err := setupCfg.GetAccess()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
accessData, err := access.Serialize()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
overrides["access"] = accessData
|
||||
|
||||
return Error.Wrap(process.SaveConfig(cmd, filepath.Join(setupDir, "config.yaml"),
|
||||
process.SaveConfigWithOverrides(overrides),
|
||||
process.SaveConfigRemovingDeprecated()))
|
||||
}
|
||||
|
||||
func main() {
|
||||
process.Exec(rootCmd)
|
||||
}
|
||||
func main() { cmd.Main() }
|
||||
|
@ -64,8 +64,9 @@ func main() {
|
||||
default:
|
||||
log.Println("unknown client name ", *clientName, " defaulting to minio")
|
||||
fallthrough
|
||||
case "minio":
|
||||
client, err = s3client.NewMinio(conf)
|
||||
// TODO: reenable
|
||||
// case "minio":
|
||||
// client, err = s3client.NewMinio(conf)
|
||||
case "aws-cli":
|
||||
client, err = s3client.NewAWSCLI(conf)
|
||||
case "uplink":
|
||||
|
58
go.mod
58
go.mod
@ -2,16 +2,7 @@ module storj.io/storj
|
||||
|
||||
go 1.13
|
||||
|
||||
// force specific versions for minio
|
||||
require (
|
||||
github.com/btcsuite/btcutil v0.0.0-20180706230648-ab6388e0c60a
|
||||
github.com/garyburd/redigo v1.0.1-0.20170216214944-0d253a66e6e1 // indirect
|
||||
github.com/graphql-go/graphql v0.7.9-0.20190403165646-199d20bbfed7
|
||||
github.com/minio/minio v0.0.0-20180508161510-54cd29b51c38
|
||||
github.com/segmentio/go-prompt v1.2.1-0.20161017233205-f0d19b6901ad
|
||||
)
|
||||
|
||||
exclude gopkg.in/olivere/elastic.v5 v5.0.72 // buggy import, see https://github.com/olivere/elastic/pull/869
|
||||
require github.com/graphql-go/graphql v0.7.9-0.20190403165646-199d20bbfed7
|
||||
|
||||
replace google.golang.org/grpc => github.com/storj/grpc-go v1.23.1-0.20190918084400-1c4561bf5127
|
||||
|
||||
@ -20,79 +11,41 @@ require (
|
||||
github.com/Shopify/go-lua v0.0.0-20181106184032-48449c60c0a9
|
||||
github.com/alessio/shellescape v0.0.0-20190409004728-b115ca0f9053
|
||||
github.com/alicebob/miniredis/v2 v2.11.1
|
||||
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da // indirect
|
||||
github.com/blang/semver v3.5.1+incompatible
|
||||
github.com/boltdb/bolt v1.3.1
|
||||
github.com/cheggaaa/pb v1.0.5-0.20160713104425-73ae1d68fe0b // indirect
|
||||
github.com/btcsuite/btcutil v0.0.0-20180706230648-ab6388e0c60a
|
||||
github.com/cheggaaa/pb/v3 v3.0.1
|
||||
github.com/djherbis/atime v1.0.0 // indirect
|
||||
github.com/dustin/go-humanize v1.0.0 // indirect
|
||||
github.com/eclipse/paho.mqtt.golang v1.1.1 // indirect
|
||||
github.com/elazarl/go-bindata-assetfs v1.0.0 // indirect
|
||||
github.com/fatih/color v1.7.0
|
||||
github.com/fatih/structs v1.0.0 // indirect
|
||||
github.com/go-ini/ini v1.38.2 // indirect
|
||||
github.com/go-redis/redis v6.14.1+incompatible
|
||||
github.com/gogo/protobuf v1.2.1
|
||||
github.com/golang-migrate/migrate/v4 v4.7.0
|
||||
github.com/golang/protobuf v1.3.2
|
||||
github.com/gomodule/redigo v2.0.0+incompatible // indirect
|
||||
github.com/google/go-cmp v0.3.0
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e // indirect
|
||||
github.com/gorilla/handlers v1.4.0 // indirect
|
||||
github.com/gorilla/mux v1.7.1
|
||||
github.com/gorilla/rpc v1.1.0 // indirect
|
||||
github.com/gorilla/schema v1.1.0
|
||||
github.com/hashicorp/go-immutable-radix v1.0.0 // indirect
|
||||
github.com/hashicorp/go-msgpack v0.5.3 // indirect
|
||||
github.com/hashicorp/raft v1.0.0 // indirect
|
||||
github.com/howeyc/gopass v0.0.0-20170109162249-bf9dde6d0d2c // indirect
|
||||
github.com/inconshreveable/go-update v0.0.0-20160112193335-8152e7eb6ccf // indirect
|
||||
github.com/jackc/pgx v3.2.0+incompatible
|
||||
github.com/jtolds/gls v4.2.1+incompatible // indirect
|
||||
github.com/jtolds/go-luar v0.0.0-20170419063437-0786921db8c0
|
||||
github.com/jtolds/monkit-hw/v2 v2.0.0-20191108235325-141a0da276b3
|
||||
github.com/jtolds/tracetagger/v2 v2.0.0-rc2
|
||||
github.com/klauspost/cpuid v0.0.0-20180405133222-e7e905edc00e // indirect
|
||||
github.com/klauspost/reedsolomon v0.0.0-20180704173009-925cb01d6510 // indirect
|
||||
github.com/lib/pq v1.3.0
|
||||
github.com/loov/hrtime v0.0.0-20181214195526-37a208e8344e
|
||||
github.com/loov/plot v0.0.0-20180510142208-e59891ae1271
|
||||
github.com/mattn/go-isatty v0.0.9 // indirect
|
||||
github.com/mattn/go-sqlite3 v2.0.2+incompatible
|
||||
github.com/minio/cli v1.3.0
|
||||
github.com/minio/dsync v0.0.0-20180124070302-439a0961af70 // indirect
|
||||
github.com/minio/highwayhash v0.0.0-20180501080913-85fc8a2dacad // indirect
|
||||
github.com/minio/lsync v0.0.0-20180328070428-f332c3883f63 // indirect
|
||||
github.com/minio/mc v0.0.0-20180926130011-a215fbb71884 // indirect
|
||||
github.com/minio/minio-go v6.0.3+incompatible
|
||||
github.com/minio/sio v0.0.0-20180327104954-6a41828a60f0 // indirect
|
||||
github.com/nats-io/gnatsd v1.3.0 // indirect
|
||||
github.com/nats-io/go-nats v1.6.0 // indirect
|
||||
github.com/nats-io/go-nats-streaming v0.4.2 // indirect
|
||||
github.com/nats-io/nats v1.6.0 // indirect
|
||||
github.com/nats-io/nats-streaming-server v0.12.2 // indirect
|
||||
github.com/nats-io/nuid v1.0.0 // indirect
|
||||
github.com/nsf/jsondiff v0.0.0-20160203110537-7de28ed2b6e3
|
||||
github.com/nsf/termbox-go v0.0.0-20190121233118-02980233997d
|
||||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c // indirect
|
||||
github.com/pkg/profile v1.2.1 // indirect
|
||||
github.com/prometheus/procfs v0.0.0-20190517135640-51af30a78b0e // indirect
|
||||
github.com/rs/cors v1.5.0 // indirect
|
||||
github.com/segmentio/go-prompt v1.2.1-0.20161017233205-f0d19b6901ad
|
||||
github.com/shopspring/decimal v0.0.0-20200105231215-408a2507e114
|
||||
github.com/skyrings/skyring-common v0.0.0-20160929130248-d1c0bb1cbd5e
|
||||
github.com/smartystreets/assertions v0.0.0-20180820201707-7c9eb446e3cf // indirect
|
||||
github.com/smartystreets/goconvey v0.0.0-20180222194500-ef6db91d284a // indirect
|
||||
github.com/spacemonkeygo/monkit/v3 v3.0.1
|
||||
github.com/spf13/cast v1.3.0
|
||||
github.com/spf13/cobra v0.0.5
|
||||
github.com/spf13/pflag v1.0.3
|
||||
github.com/spf13/viper v1.4.0
|
||||
github.com/streadway/amqp v0.0.0-20180806233856-70e15c650864 // indirect
|
||||
github.com/stretchr/testify v1.4.0
|
||||
github.com/stripe/stripe-go v63.1.1+incompatible
|
||||
github.com/tidwall/gjson v1.1.3 // indirect
|
||||
github.com/tidwall/match v0.0.0-20171002075945-1731857f09b1 // indirect
|
||||
github.com/vivint/infectious v0.0.0-20190108171102-2455b059135b
|
||||
github.com/zeebo/admission/v2 v2.0.0
|
||||
github.com/zeebo/errs v1.2.2
|
||||
@ -102,12 +55,7 @@ require (
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e
|
||||
golang.org/x/sys v0.0.0-20200107144601-ef85f5a75ddf
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0
|
||||
google.golang.org/appengine v1.6.0 // indirect
|
||||
google.golang.org/grpc v1.23.1
|
||||
gopkg.in/Shopify/sarama.v1 v1.18.0 // indirect
|
||||
gopkg.in/cheggaaa/pb.v1 v1.0.25 // indirect
|
||||
gopkg.in/ini.v1 v1.38.2 // indirect
|
||||
gopkg.in/olivere/elastic.v5 v5.0.76 // indirect
|
||||
gopkg.in/yaml.v2 v2.2.4
|
||||
storj.io/common v0.0.0-20200221161141-79b008e3eff0
|
||||
storj.io/drpc v0.0.8
|
||||
|
103
go.sum
103
go.sum
@ -26,8 +26,6 @@ github.com/alicebob/miniredis/v2 v2.11.1 h1:wuZ/ZHHELZ8DUF5sahK2T6V4Do2SdyKHnjrl
|
||||
github.com/alicebob/miniredis/v2 v2.11.1/go.mod h1:UA48pmi7aSazcGAvcdKcBB49z521IC9VjTTRz2nIaJE=
|
||||
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da h1:8GUt8eRujhVEGZFFEjBj46YV4rDjvGrNxb0KMWYkL2I=
|
||||
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
|
||||
github.com/aws/aws-sdk-go v1.17.7/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0=
|
||||
@ -43,8 +41,6 @@ github.com/btcsuite/btcutil v0.0.0-20180706230648-ab6388e0c60a/go.mod h1:+5NJ2+q
|
||||
github.com/calebcase/tmpfile v1.0.1 h1:vD8FSrbsbexhep39/6mvtbIHS3GzIRqiprDNCF6QqSk=
|
||||
github.com/calebcase/tmpfile v1.0.1/go.mod h1:iErLeG/iqJr8LaQ/gYRv4GXdqssi3jg4iSzvrA06/lw=
|
||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||
github.com/cheggaaa/pb v1.0.5-0.20160713104425-73ae1d68fe0b h1:CMRCnhHx4xVxJy+wPsS67xmi9RHGNctLMoVn9Q1Kit8=
|
||||
github.com/cheggaaa/pb v1.0.5-0.20160713104425-73ae1d68fe0b/go.mod h1:pQciLPpbU0oxA0h+VJYYLxO+XeDQb5pZijXscXHm81s=
|
||||
github.com/cheggaaa/pb/v3 v3.0.1 h1:m0BngUk2LuSRYdx4fujDKNRXNDpbNCfptPfVT2m6OJY=
|
||||
github.com/cheggaaa/pb/v3 v3.0.1/go.mod h1:SqqeMF/pMOIu3xgGoxtPYhMNQP258xE4x/XRTYua+KU=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
@ -84,8 +80,6 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZm
|
||||
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
||||
github.com/dhui/dktest v0.3.0 h1:kwX5a7EkLcjo7VpsPQSYJcKGbXBXdjI9FGjuUj1jn6I=
|
||||
github.com/dhui/dktest v0.3.0/go.mod h1:cyzIUfGsBEbZ6BT7tnXqAShHSXCZhSNmFl70sZ7c1yc=
|
||||
github.com/djherbis/atime v1.0.0 h1:ySLvBAM0EvOGaX7TI4dAM5lWj+RdJUCKtGSEHN8SGBg=
|
||||
github.com/djherbis/atime v1.0.0/go.mod h1:5W+KBIuTwVGcqjIfaTwt+KSYX1o6uep8dtevevQP/f8=
|
||||
github.com/docker/distribution v2.7.0+incompatible h1:neUDAlf3wX6Ml4HdqTrbcOHXtfRN0TFIwt6YFL7N9RU=
|
||||
github.com/docker/distribution v2.7.0+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
github.com/docker/docker v0.7.3-0.20190103212154-2b7e084dc98b/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
@ -95,33 +89,19 @@ github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKoh
|
||||
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
|
||||
github.com/docker/go-units v0.3.3 h1:Xk8S3Xj5sLGlG5g67hJmYMmUgXv5N4PhkjJHHqrwnTk=
|
||||
github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
|
||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/eapache/go-resiliency v1.1.0 h1:1NtRmCAqadE2FN4ZcN6g90TP3uk8cg9rn9eNK2197aU=
|
||||
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
|
||||
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21 h1:YEetp8/yCZMuEPMUDHG0CW/brkkEp8mzqk2+ODEitlw=
|
||||
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
|
||||
github.com/eapache/queue v1.1.0 h1:YOEu7KNc61ntiQlcEeUIoDTJ2o8mQznoNvUhiigpIqc=
|
||||
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
|
||||
github.com/eclipse/paho.mqtt.golang v1.1.1 h1:iPJYXJLaViCshRTW/PSqImSS6HJ2Rf671WR0bXZ2GIU=
|
||||
github.com/eclipse/paho.mqtt.golang v1.1.1/go.mod h1:H9keYFcgq3Qr5OUJm/JZI/i6U7joQ8SYLhZwfeOo6Ts=
|
||||
github.com/edsrzf/mmap-go v0.0.0-20170320065105-0bce6a688712/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
|
||||
github.com/elazarl/go-bindata-assetfs v1.0.0 h1:G/bYguwHIzWq9ZoyUQqrjTmJbbYn3j3CKKpKinvZLFk=
|
||||
github.com/elazarl/go-bindata-assetfs v1.0.0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4=
|
||||
github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/fatih/structs v1.0.0 h1:BrX964Rv5uQ3wwS+KRUAJCBBw5PQmgJfJ6v4yly5QwU=
|
||||
github.com/fatih/structs v1.0.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
|
||||
github.com/fortytw2/leaktest v1.2.0 h1:cj6GCiwJDH7l3tMHLjZDo0QqPtrXJiWSI9JgpeQKw+Q=
|
||||
github.com/fortytw2/leaktest v1.2.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=
|
||||
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/fsouza/fake-gcs-server v1.7.0/go.mod h1:5XIRs4YvwNbNoz+1JF8j6KLAyDh7RHGAyAK3EP2EsNk=
|
||||
github.com/garyburd/redigo v1.0.1-0.20170216214944-0d253a66e6e1 h1:YmyuMm99D7kezPc0ZVWYnaUIWfMKR81lVVXttKTnDbw=
|
||||
github.com/garyburd/redigo v1.0.1-0.20170216214944-0d253a66e6e1/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/go-ini/ini v1.38.2 h1:6Hl/z3p3iFkA0dlDfzYxuFuUGD+kaweypF6btsR2/Q4=
|
||||
github.com/go-ini/ini v1.38.2/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
@ -163,16 +143,10 @@ github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO
|
||||
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/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e h1:JKmoR8x90Iww1ks85zJ1lfDGgIiMDuIptTOhJq+zKyg=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
|
||||
github.com/gorilla/handlers v1.4.0 h1:XulKRWSQK5uChr4pEgSE4Tc/OcmnU9GJuSwdog/tZsA=
|
||||
github.com/gorilla/handlers v1.4.0/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
|
||||
github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
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/rpc v1.1.0 h1:marKfvVP0Gpd/jHlVBKCQ8RAoUPdX7K1Nuh6l1BNh7A=
|
||||
github.com/gorilla/rpc v1.1.0/go.mod h1:V4h9r+4sF5HnzqbwIez0fKSpANP0zlYd3qR7p36jkTQ=
|
||||
github.com/gorilla/schema v1.1.0 h1:CamqUDOFUBqzrvxuz2vEwo8+SUdwsluFh7IlzJh30LY=
|
||||
github.com/gorilla/schema v1.1.0/go.mod h1:kgLaKoK1FELgZqMAVxx/5cbj0kT+57qxUrAlIO2eleU=
|
||||
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
@ -184,27 +158,17 @@ github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t
|
||||
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4=
|
||||
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/go-immutable-radix v1.0.0 h1:AKDB1HM5PWEA7i4nhcpwOrO2byshxBjXVn/J/3+z5/0=
|
||||
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
||||
github.com/hashicorp/go-msgpack v0.5.3 h1:zKjpN5BK/P5lMYrLmBHdBULWbJ0XpYR+7NGzqkZzoD4=
|
||||
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
|
||||
github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o=
|
||||
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
|
||||
github.com/hashicorp/go-uuid v1.0.0 h1:RS8zrF7PhGwyNPOtxSClXXj9HA8feRnJzgnI1RJCSnM=
|
||||
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU=
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/hashicorp/raft v1.0.0 h1:htBVktAOtGs4Le5Z7K8SF5H2+oWsQFYVmOgH5loro7Y=
|
||||
github.com/hashicorp/raft v1.0.0/go.mod h1:DVSAWItjLjTOkVbSpWQ0j0kUADIvDaCtBxIcbNAQLkI=
|
||||
github.com/howeyc/gopass v0.0.0-20170109162249-bf9dde6d0d2c h1:kQWxfPIHVLbgLzphqk3QUflDy9QdksZR4ygR807bpy0=
|
||||
github.com/howeyc/gopass v0.0.0-20170109162249-bf9dde6d0d2c/go.mod h1:lADxMC39cJJqL93Duh1xhAs4I2Zs8mKS89XWXFGp9cs=
|
||||
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/inconshreveable/go-update v0.0.0-20160112193335-8152e7eb6ccf h1:WfD7VjIE6z8dIvMsI4/s+1qr5EL+zoIGev1BQj1eoJ8=
|
||||
github.com/inconshreveable/go-update v0.0.0-20160112193335-8152e7eb6ccf/go.mod h1:hyb9oH7vZsitZCiBt0ZvifOrB+qc8PS5IiilCIb87rg=
|
||||
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/jackc/fake v0.0.0-20150926172116-812a484cc733 h1:vr3AYkKovP8uR8AvSGGUK1IDqRa5lAAvEkZG1LKaCRc=
|
||||
@ -214,8 +178,6 @@ github.com/jackc/pgx v3.2.0+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGk
|
||||
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/jtolds/gls v4.2.1+incompatible h1:fSuqC+Gmlu6l/ZYAoZzx2pyucC8Xza35fpRVWLVmUEE=
|
||||
github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||
github.com/jtolds/go-luar v0.0.0-20170419063437-0786921db8c0 h1:UyVaeqfY1fLPMt1iUTaWsxUNxYAzZVyK+7G+a3sRfhk=
|
||||
github.com/jtolds/go-luar v0.0.0-20170419063437-0786921db8c0/go.mod h1:OtVLEpPHGJkn8jgGrHlYELCA3uXLU0YSfNN0faeDM2M=
|
||||
github.com/jtolds/monkit-hw/v2 v2.0.0-20191108235325-141a0da276b3 h1:dITCBge70U9RDyZUL/Thn/yAT/ct4Rz40mNUX51dFCk=
|
||||
@ -226,10 +188,6 @@ github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7V
|
||||
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8=
|
||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/klauspost/cpuid v0.0.0-20180405133222-e7e905edc00e h1:+lIPJOWl+jSiJOc70QXJ07+2eg2Jy2EC7Mi11BWujeM=
|
||||
github.com/klauspost/cpuid v0.0.0-20180405133222-e7e905edc00e/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||
github.com/klauspost/reedsolomon v0.0.0-20180704173009-925cb01d6510 h1:9eOgsI7EIGhJWPMBvSY+x0SEpeGGWUSijOrwK0XhpIk=
|
||||
github.com/klauspost/reedsolomon v0.0.0-20180704173009-925cb01d6510/go.mod h1:CwCi+NUr9pqSVktrkN+Ondf06rkhYZ/pcNv7fu+8Un4=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
@ -249,8 +207,6 @@ github.com/loov/plot v0.0.0-20180510142208-e59891ae1271 h1:51ToN6N0TDtCruf681guf
|
||||
github.com/loov/plot v0.0.0-20180510142208-e59891ae1271/go.mod h1:3yy5HBPbe5e1UmEffbO0n0g6A8h6ChHaCTeundr6H60=
|
||||
github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY=
|
||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/mailru/easyjson v0.0.0-20180730094502-03f2033d19d5 h1:0x4qcEHDpruK6ML/m/YSlFUUu0UpRD3I2PHsNCuGnyA=
|
||||
github.com/mailru/easyjson v0.0.0-20180730094502-03f2033d19d5/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU=
|
||||
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
@ -263,24 +219,8 @@ github.com/mattn/go-sqlite3 v2.0.2+incompatible h1:qzw9c2GNT8UFrgWNDhCTqRqYUSmu/
|
||||
github.com/mattn/go-sqlite3 v2.0.2+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/minio/cli v1.3.0 h1:vB0iUpmyaH54+1jJJj62Aa0qFF3xO3i0J3IcKiM6bHM=
|
||||
github.com/minio/cli v1.3.0/go.mod h1:hLsWNQy2wIf3FKFnMlH69f4RdEyn8nbRA2shaulTjGY=
|
||||
github.com/minio/dsync v0.0.0-20180124070302-439a0961af70 h1:pRHQdPOlUhelWqNUF3icFrBSC6VYH1hvF6HigVfgMoI=
|
||||
github.com/minio/dsync v0.0.0-20180124070302-439a0961af70/go.mod h1:eLQe3mXL0h02kNpPtBJiLr1fIEIJftgXRAjncjQbxJo=
|
||||
github.com/minio/highwayhash v0.0.0-20180501080913-85fc8a2dacad h1:L+8skVz2lusCbtlalLXmJp+TK8XaGAsZ3utSC3k5Jc0=
|
||||
github.com/minio/highwayhash v0.0.0-20180501080913-85fc8a2dacad/go.mod h1:NL8wme5P5MoscwAkXfGroz3VgpCdhBw3KYOu5mEsvpU=
|
||||
github.com/minio/lsync v0.0.0-20180328070428-f332c3883f63 h1:utJHim4C0K4CmD+Qgod/tgHvo7QNOlH6HN5O8QUvPEI=
|
||||
github.com/minio/lsync v0.0.0-20180328070428-f332c3883f63/go.mod h1:ni10+iSX7FO8N2rv41XM444V6w4rYO0dZo5KIkbn/YA=
|
||||
github.com/minio/mc v0.0.0-20180926130011-a215fbb71884 h1:co3kRW9cEI65yolYtcLcNxp2a9yk5T/eEt7gw14tJVs=
|
||||
github.com/minio/mc v0.0.0-20180926130011-a215fbb71884/go.mod h1:pPcAoOwWUSIBqoLtp+0LEACUBUPhodkXwisyYrNgQ5o=
|
||||
github.com/minio/minio v0.0.0-20180508161510-54cd29b51c38 h1:F7p0ZU9AQuxlA6SWwhXr0H/rYrA9fOiBk2OzOj7GtfM=
|
||||
github.com/minio/minio v0.0.0-20180508161510-54cd29b51c38/go.mod h1:lXcp05uxYaW99ebgI6ZKIGYU7tqZkM5xSsG0xRt4VIU=
|
||||
github.com/minio/minio-go v6.0.3+incompatible h1:yTq5mJOcWg6ot6STkEMnrNN896L0aDDu6njDB+8Ply0=
|
||||
github.com/minio/minio-go v6.0.3+incompatible/go.mod h1:7guKYtitv8dktvNUGrhzmNlA5wrAABTQXCoesZdFQO8=
|
||||
github.com/minio/sha256-simd v0.0.0-20190328051042-05b4dd3047e5 h1:l16XLUUJ34wIz+RIvLhSwGvLvKyy+W598b135bJN6mg=
|
||||
github.com/minio/sha256-simd v0.0.0-20190328051042-05b4dd3047e5/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U=
|
||||
github.com/minio/sio v0.0.0-20180327104954-6a41828a60f0 h1:ys4bbOlPvaUBlA0byjm6TqydsXZu614ZIUTfF+4MRY0=
|
||||
github.com/minio/sio v0.0.0-20180327104954-6a41828a60f0/go.mod h1:PDJGYr8GXjiOTIst0hQMOSK5FdXLwObr2cGbiMddDPc=
|
||||
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/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
|
||||
@ -289,18 +229,6 @@ github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c h1:nXxl5PrvVm2L/wCy8d
|
||||
github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/nakagami/firebirdsql v0.0.0-20190310045651-3c02a58cfed8/go.mod h1:86wM1zFnC6/uDBfZGNwB65O+pR2OFi5q/YQaEUid1qA=
|
||||
github.com/nats-io/gnatsd v1.3.0 h1:+5d80klu3QaJgNbdavVBjWJP7cHd11U2CLnRTFM9ICI=
|
||||
github.com/nats-io/gnatsd v1.3.0/go.mod h1:nqco77VO78hLCJpIcVfygDP2rPGfsEHkGTUk94uh5DQ=
|
||||
github.com/nats-io/go-nats v1.6.0 h1:FznPwMfrVwGnSCh7JTXyJDRW0TIkD4Tr+M1LPJt9T70=
|
||||
github.com/nats-io/go-nats v1.6.0/go.mod h1:+t7RHT5ApZebkrQdnn6AhQJmhJJiKAvJUio1PiiCtj0=
|
||||
github.com/nats-io/go-nats-streaming v0.4.2 h1:e7Fs4yxvFTs8N5xKFoJyw0sVW2heJwYvrUWfdf9VQlE=
|
||||
github.com/nats-io/go-nats-streaming v0.4.2/go.mod h1:gfq4R3c9sKAINOpelo0gn/b9QDMBZnmrttcsNF+lqyo=
|
||||
github.com/nats-io/nats v1.6.0 h1:U5b2apHOTZlUou+NGfCRWG4ZEeivbt2hpsZO4kHKIVU=
|
||||
github.com/nats-io/nats v1.6.0/go.mod h1:PpmYZwlgTfBI56QypJLfIMOfLnMRuVs+VL6r8mQ2SoQ=
|
||||
github.com/nats-io/nats-streaming-server v0.12.2 h1:EpyLfUBZgwu5c0mdSSytQsapm615AyitPssq7jgafdw=
|
||||
github.com/nats-io/nats-streaming-server v0.12.2/go.mod h1:RyqtDJZvMZO66YmyjIYdIvS69zu/wDAkyNWa8PIUa5c=
|
||||
github.com/nats-io/nuid v1.0.0 h1:44QGdhbiANq8ZCbUkdn6W5bqtg+mHuDE4wOUuxxndFs=
|
||||
github.com/nats-io/nuid v1.0.0/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
|
||||
github.com/nsf/jsondiff v0.0.0-20160203110537-7de28ed2b6e3 h1:OqFSgO6CJ8heZRAbXLpT+ojX+jnnGij4qZwUz/SJJ9I=
|
||||
github.com/nsf/jsondiff v0.0.0-20160203110537-7de28ed2b6e3/go.mod h1:uFMI8w+ref4v2r9jz+c9i1IfIttS/OkmLfrk1jne5hs=
|
||||
github.com/nsf/termbox-go v0.0.0-20190121233118-02980233997d h1:x3S6kxmy49zXVVyhcnrFqxvNVCBPb2KZ9hV2RBdS840=
|
||||
@ -318,8 +246,6 @@ github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQ
|
||||
github.com/opencontainers/image-spec v1.0.1 h1:JMemWkRwHx4Zj+fVxWoMCFm/8sYGGrUVojFA6h/TRcI=
|
||||
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
|
||||
github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
|
||||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c h1:Lgl0gzECD8GnQ5QCWA8o6BtfL6mDH5rQgM4/fX3avOs=
|
||||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||
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/pierrec/lz4 v2.0.5+incompatible h1:2xWsjqPFWcplujydGg4WmhC/6fZqK42wMM8aXeqhl0I=
|
||||
@ -327,8 +253,6 @@ github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/profile v1.2.1 h1:F++O52m40owAmADcojzM+9gyjmMOY/T4oYJkgFDH8RE=
|
||||
github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
@ -346,14 +270,10 @@ github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/procfs v0.0.0-20190517135640-51af30a78b0e h1:zK8d1aZ+gw/Ne4uMfZTFRxj08PUOp+gGwm4HWUeGI1k=
|
||||
github.com/prometheus/procfs v0.0.0-20190517135640-51af30a78b0e/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a h1:9ZKAASQSHhDYGoxY8uLVpewe1GDZ2vu2Tr/vTdVAkFQ=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||
github.com/rs/cors v1.5.0 h1:dgSHE6+ia18arGOTIYQKKGWLvEbGvmbNE6NfxhoNHUY=
|
||||
github.com/rs/cors v1.5.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
|
||||
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||
@ -367,11 +287,6 @@ github.com/sirupsen/logrus v1.4.1 h1:GL2rEmy6nsikmW0r8opw9JIRScdMF5hA8cOYLH7In1k
|
||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||
github.com/skyrings/skyring-common v0.0.0-20160929130248-d1c0bb1cbd5e h1:jrZSSgPUDtBeJbGXqgGUeupQH8I+ZvGXfhpIahye2Bc=
|
||||
github.com/skyrings/skyring-common v0.0.0-20160929130248-d1c0bb1cbd5e/go.mod h1:d8hQseuYt4rJoOo21lFzYJdhMjmDqLY++ayArbgYjWI=
|
||||
github.com/smartystreets/assertions v0.0.0-20180820201707-7c9eb446e3cf h1:6V1qxN6Usn4jy8unvggSJz/NC790tefw8Zdy6OZS5co=
|
||||
github.com/smartystreets/assertions v0.0.0-20180820201707-7c9eb446e3cf/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9/go.mod h1:SnhjPscd9TpLiy1LpzGSKh3bXCfxxXuqd9xmQJy3slM=
|
||||
github.com/smartystreets/goconvey v0.0.0-20180222194500-ef6db91d284a h1:JSvGDIbmil4Ui/dDdFBExb7/cmkNjyX5F97oglmvCDo=
|
||||
github.com/smartystreets/goconvey v0.0.0-20180222194500-ef6db91d284a/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s=
|
||||
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
||||
github.com/spacemonkeygo/errors v0.0.0-20171212215202-9064522e9fd1 h1:xHQewZjohU9/wUsyC99navCjQDNHtTgUOM/J1jAbzfw=
|
||||
github.com/spacemonkeygo/errors v0.0.0-20171212215202-9064522e9fd1/go.mod h1:7NL9UAYQnRM5iKHUCld3tf02fKb5Dft+41+VckASUy0=
|
||||
@ -398,8 +313,6 @@ github.com/spf13/viper v1.4.0 h1:yXHLWeravcrgGyFSyCgdYpXQ9dR9c/WED3pg1RhxqEU=
|
||||
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
|
||||
github.com/storj/grpc-go v1.23.1-0.20190918084400-1c4561bf5127 h1:sJtPW3g23UOuV+b5o3ARQ7467NzjjacUoBBPTyvIP9c=
|
||||
github.com/storj/grpc-go v1.23.1-0.20190918084400-1c4561bf5127/go.mod h1:b+NmczNXvOWokHOVTM0zzTDhQEV+xRmnFVmFTVlkg8Q=
|
||||
github.com/streadway/amqp v0.0.0-20180806233856-70e15c650864 h1:Oj3PUEs+OUSYUpn35O+BE/ivHGirKixA3+vqA0Atu9A=
|
||||
github.com/streadway/amqp v0.0.0-20180806233856-70e15c650864/go.mod h1:1WNBiOZtZQLpVAyu0iTduoJL9hEsMloAK5XWrtW0xdY=
|
||||
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/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
@ -408,10 +321,6 @@ github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJy
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stripe/stripe-go v63.1.1+incompatible h1:OpGp55VzHcnu5O/MtVVU42xS2xeAWosx3xELvuoMMMw=
|
||||
github.com/stripe/stripe-go v63.1.1+incompatible/go.mod h1:A1dQZmO/QypXmsL0T8axYZkSN/uA/T/A64pfKdBAMiY=
|
||||
github.com/tidwall/gjson v1.1.3 h1:u4mspaByxY+Qk4U1QYYVzGFI8qxN/3jtEV0ZDb2vRic=
|
||||
github.com/tidwall/gjson v1.1.3/go.mod h1:c/nTNbUr0E0OrXEhq1pwa8iEgc2DOt4ZZqAt1HtCkPA=
|
||||
github.com/tidwall/match v0.0.0-20171002075945-1731857f09b1 h1:pWIN9LOlFRCJFqWIOEbHLvY0WWJddsjH2FQ6N0HKZdU=
|
||||
github.com/tidwall/match v0.0.0-20171002075945-1731857f09b1/go.mod h1:LujAq0jyVjBy028G1WhWfIzbpQfMO8bBZ6Tyb0+pL9E=
|
||||
github.com/tidwall/pretty v0.0.0-20180105212114-65a9db5fad51/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
|
||||
@ -529,29 +438,19 @@ google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9Ywl
|
||||
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/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.6.0 h1:Tfd7cKwKbFRsI8RMAD3oqqw7JPFRrvFlOsfbgVkjOOw=
|
||||
google.golang.org/appengine v1.6.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190716160619-c506a9f90610 h1:Ygq9/SRJX9+dU0WCIICM8RkWvDw03lvB77hrhJnpxfU=
|
||||
google.golang.org/genproto v0.0.0-20190716160619-c506a9f90610/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
gopkg.in/Shopify/sarama.v1 v1.18.0 h1:f9aTXuIEFEjVvLG9p+kMSk01dMfFumHsySRk1okTdqU=
|
||||
gopkg.in/Shopify/sarama.v1 v1.18.0/go.mod h1:AxnvoaevB2nBjNK17cG61A3LleFcWFwVBHBt+cot4Oc=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/cheggaaa/pb.v1 v1.0.25 h1:Ev7yu1/f6+d+b3pi5vPdRPc6nNtP1umSfcWiEfRqv6I=
|
||||
gopkg.in/cheggaaa/pb.v1 v1.0.25/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/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
gopkg.in/ini.v1 v1.38.2 h1:dGcbywv4RufeGeiMycPT/plKB5FtmLKLnWKwBiLhUA4=
|
||||
gopkg.in/ini.v1 v1.38.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/olivere/elastic.v5 v5.0.76 h1:A6W7X4yLPQDINHiYAqIwqev+rD5hIQ4G0e1d5H//VXk=
|
||||
gopkg.in/olivere/elastic.v5 v5.0.76/go.mod h1:uhHoB4o3bvX5sorxBU29rPcmBQdV2Qfg0FBrx5D6pV0=
|
||||
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
||||
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=
|
||||
@ -571,7 +470,5 @@ storj.io/common v0.0.0-20200221161141-79b008e3eff0/go.mod h1:lCc2baFO7GQlKsPTri8
|
||||
storj.io/drpc v0.0.7-0.20191115031725-2171c57838d2/go.mod h1:/ascUDbzNAv0A3Jj7wUIKFBH2JdJ2uJIBO/b9+2yHgQ=
|
||||
storj.io/drpc v0.0.8 h1:wu68cMmtoT0vSWIAZz29RpJkWdi4o0S8BIrLslpH5FQ=
|
||||
storj.io/drpc v0.0.8/go.mod h1:v39uWro/EbXXk+gNnrM9FQuVVS2zUBWBfeduydgeXUA=
|
||||
storj.io/uplink v0.0.0-20200221135851-60db51e97359 h1:8IYCBjyXW4PAbhFhghZEXH8ZNbxD6lrfmNvotrD2G/E=
|
||||
storj.io/uplink v0.0.0-20200221135851-60db51e97359/go.mod h1:SAetpjpLjDx0bH/TgfMaD2O/S283bn/Kcz8f/juI03I=
|
||||
storj.io/uplink v0.0.0-20200221171743-26268cdd3552 h1:yXojx6mQXtJfwh5qdUEakWvh+EXkJbTV4qWE1aPJzTU=
|
||||
storj.io/uplink v0.0.0-20200221171743-26268cdd3552/go.mod h1:SAetpjpLjDx0bH/TgfMaD2O/S283bn/Kcz8f/juI03I=
|
||||
|
@ -1,17 +0,0 @@
|
||||
// Copyright (C) 2019 Storj Labs, Inc.
|
||||
// See LICENSE for copying information.
|
||||
|
||||
package miniogw
|
||||
|
||||
// MinioConfig is a configuration struct that keeps details about starting
|
||||
// Minio
|
||||
type MinioConfig struct {
|
||||
AccessKey string `help:"Minio Access Key to use" default:"insecure-dev-access-key"`
|
||||
SecretKey string `help:"Minio Secret Key to use" default:"insecure-dev-secret-key"`
|
||||
Dir string `help:"Minio generic server config path" default:"$CONFDIR/minio"`
|
||||
}
|
||||
|
||||
// ServerConfig determines how minio listens for requests
|
||||
type ServerConfig struct {
|
||||
Address string `help:"address to serve S3 api over" default:"127.0.0.1:7777"`
|
||||
}
|
@ -1,476 +0,0 @@
|
||||
// Copyright (C) 2019 Storj Labs, Inc.
|
||||
// See LICENSE for copying information.
|
||||
|
||||
package miniogw
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"io"
|
||||
|
||||
minio "github.com/minio/minio/cmd"
|
||||
"github.com/minio/minio/pkg/auth"
|
||||
"github.com/minio/minio/pkg/hash"
|
||||
"github.com/spacemonkeygo/monkit/v3"
|
||||
"github.com/zeebo/errs"
|
||||
|
||||
"storj.io/common/storj"
|
||||
"storj.io/uplink"
|
||||
)
|
||||
|
||||
var (
|
||||
mon = monkit.Package()
|
||||
|
||||
// Error is the errs class of standard End User Client errors
|
||||
Error = errs.Class("Storj Gateway error")
|
||||
)
|
||||
|
||||
// NewStorjGateway creates a new Storj S3 gateway.
|
||||
func NewStorjGateway(project *uplink.Project) *Gateway {
|
||||
return &Gateway{
|
||||
project: project,
|
||||
multipart: NewMultipartUploads(),
|
||||
}
|
||||
}
|
||||
|
||||
// Gateway is the implementation of a minio cmd.Gateway
|
||||
type Gateway struct {
|
||||
project *uplink.Project
|
||||
multipart *MultipartUploads
|
||||
}
|
||||
|
||||
// Name implements cmd.Gateway
|
||||
func (gateway *Gateway) Name() string {
|
||||
return "storj"
|
||||
}
|
||||
|
||||
// NewGatewayLayer implements cmd.Gateway
|
||||
func (gateway *Gateway) NewGatewayLayer(creds auth.Credentials) (minio.ObjectLayer, error) {
|
||||
return &gatewayLayer{gateway: gateway}, nil
|
||||
}
|
||||
|
||||
// Production implements cmd.Gateway
|
||||
func (gateway *Gateway) Production() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
type gatewayLayer struct {
|
||||
minio.GatewayUnsupported
|
||||
gateway *Gateway
|
||||
}
|
||||
|
||||
func (layer *gatewayLayer) DeleteBucket(ctx context.Context, bucketName string) (err error) {
|
||||
defer mon.Task()(&ctx)(&err)
|
||||
|
||||
_, err = layer.gateway.project.DeleteBucket(ctx, bucketName)
|
||||
|
||||
return convertError(err, bucketName, "")
|
||||
}
|
||||
|
||||
func (layer *gatewayLayer) DeleteObject(ctx context.Context, bucketName, objectPath string) (err error) {
|
||||
defer mon.Task()(&ctx)(&err)
|
||||
|
||||
// TODO this should be removed and implemented on satellite side
|
||||
_, err = layer.gateway.project.StatBucket(ctx, bucketName)
|
||||
if err != nil {
|
||||
return convertError(err, bucketName, objectPath)
|
||||
}
|
||||
|
||||
_, err = layer.gateway.project.DeleteObject(ctx, bucketName, objectPath)
|
||||
|
||||
return convertError(err, bucketName, objectPath)
|
||||
}
|
||||
|
||||
func (layer *gatewayLayer) GetBucketInfo(ctx context.Context, bucketName string) (bucketInfo minio.BucketInfo, err error) {
|
||||
defer mon.Task()(&ctx)(&err)
|
||||
|
||||
bucket, err := layer.gateway.project.StatBucket(ctx, bucketName)
|
||||
|
||||
if err != nil {
|
||||
return minio.BucketInfo{}, convertError(err, bucketName, "")
|
||||
}
|
||||
|
||||
return minio.BucketInfo{
|
||||
Name: bucket.Name,
|
||||
Created: bucket.Created,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (layer *gatewayLayer) GetObject(ctx context.Context, bucketName, objectPath string, startOffset int64, length int64, writer io.Writer, etag string) (err error) {
|
||||
defer mon.Task()(&ctx)(&err)
|
||||
|
||||
// TODO this should be removed and implemented on satellite side
|
||||
_, err = layer.gateway.project.StatBucket(ctx, bucketName)
|
||||
if err != nil {
|
||||
return convertError(err, bucketName, objectPath)
|
||||
}
|
||||
|
||||
download, err := layer.gateway.project.DownloadObject(ctx, bucketName, objectPath, &uplink.DownloadOptions{
|
||||
Offset: startOffset,
|
||||
Length: length,
|
||||
})
|
||||
if err != nil {
|
||||
return convertError(err, bucketName, objectPath)
|
||||
}
|
||||
defer func() { err = errs.Combine(err, download.Close()) }()
|
||||
|
||||
object := download.Info()
|
||||
if startOffset < 0 || length < -1 || startOffset+length > object.Standard.ContentLength {
|
||||
return minio.InvalidRange{
|
||||
OffsetBegin: startOffset,
|
||||
OffsetEnd: startOffset + length,
|
||||
ResourceSize: object.Standard.ContentLength,
|
||||
}
|
||||
}
|
||||
|
||||
_, err = io.Copy(writer, download)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (layer *gatewayLayer) GetObjectInfo(ctx context.Context, bucketName, objectPath string) (objInfo minio.ObjectInfo, err error) {
|
||||
defer mon.Task()(&ctx)(&err)
|
||||
|
||||
// TODO this should be removed and implemented on satellite side
|
||||
_, err = layer.gateway.project.StatBucket(ctx, bucketName)
|
||||
if err != nil {
|
||||
return minio.ObjectInfo{}, convertError(err, bucketName, objectPath)
|
||||
}
|
||||
|
||||
object, err := layer.gateway.project.StatObject(ctx, bucketName, objectPath)
|
||||
if err != nil {
|
||||
return minio.ObjectInfo{}, convertError(err, bucketName, objectPath)
|
||||
}
|
||||
|
||||
return minioObjectInfo(bucketName, "", object), nil
|
||||
}
|
||||
|
||||
func (layer *gatewayLayer) ListBuckets(ctx context.Context) (items []minio.BucketInfo, err error) {
|
||||
defer mon.Task()(&ctx)(&err)
|
||||
|
||||
buckets := layer.gateway.project.ListBuckets(ctx, nil)
|
||||
for buckets.Next() {
|
||||
info := buckets.Item()
|
||||
items = append(items, minio.BucketInfo{
|
||||
Name: info.Name,
|
||||
Created: info.Created,
|
||||
})
|
||||
}
|
||||
if buckets.Err() != nil {
|
||||
return nil, buckets.Err()
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
func (layer *gatewayLayer) ListObjects(ctx context.Context, bucketName, prefix, marker, delimiter string, maxKeys int) (result minio.ListObjectsInfo, err error) {
|
||||
defer mon.Task()(&ctx)(&err)
|
||||
|
||||
// TODO maybe this should be checked by project.ListObjects
|
||||
if bucketName == "" {
|
||||
return minio.ListObjectsInfo{}, minio.BucketNameInvalid{}
|
||||
}
|
||||
|
||||
if delimiter != "" && delimiter != "/" {
|
||||
return minio.ListObjectsInfo{}, minio.UnsupportedDelimiter{Delimiter: delimiter}
|
||||
}
|
||||
|
||||
// TODO this should be removed and implemented on satellite side
|
||||
_, err = layer.gateway.project.StatBucket(ctx, bucketName)
|
||||
if err != nil {
|
||||
return result, convertError(err, bucketName, "")
|
||||
}
|
||||
|
||||
list := layer.gateway.project.ListObjects(ctx, bucketName, &uplink.ListObjectsOptions{
|
||||
Prefix: prefix,
|
||||
Cursor: marker,
|
||||
Recursive: delimiter == "",
|
||||
|
||||
Info: true,
|
||||
Standard: true,
|
||||
Custom: true,
|
||||
})
|
||||
|
||||
startAfter := marker
|
||||
var objects []minio.ObjectInfo
|
||||
var prefixes []string
|
||||
|
||||
limit := maxKeys
|
||||
for (limit > 0 || maxKeys == 0) && list.Next() {
|
||||
limit--
|
||||
object := list.Item()
|
||||
if object.IsPrefix {
|
||||
prefixes = append(prefixes, object.Key)
|
||||
continue
|
||||
}
|
||||
|
||||
objects = append(objects, minioObjectInfo(bucketName, "", object))
|
||||
|
||||
startAfter = object.Key
|
||||
|
||||
}
|
||||
if list.Err() != nil {
|
||||
return result, convertError(list.Err(), bucketName, "")
|
||||
}
|
||||
|
||||
more := list.Next()
|
||||
if list.Err() != nil {
|
||||
return result, convertError(list.Err(), bucketName, "")
|
||||
}
|
||||
|
||||
result = minio.ListObjectsInfo{
|
||||
IsTruncated: more,
|
||||
Objects: objects,
|
||||
Prefixes: prefixes,
|
||||
}
|
||||
if more {
|
||||
result.NextMarker = startAfter
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (layer *gatewayLayer) ListObjectsV2(ctx context.Context, bucketName, prefix, continuationToken, delimiter string, maxKeys int, fetchOwner bool, startAfter string) (result minio.ListObjectsV2Info, err error) {
|
||||
defer mon.Task()(&ctx)(&err)
|
||||
|
||||
if delimiter != "" && delimiter != "/" {
|
||||
return minio.ListObjectsV2Info{ContinuationToken: continuationToken}, minio.UnsupportedDelimiter{Delimiter: delimiter}
|
||||
}
|
||||
|
||||
// TODO this should be removed and implemented on satellite side
|
||||
_, err = layer.gateway.project.StatBucket(ctx, bucketName)
|
||||
if err != nil {
|
||||
return minio.ListObjectsV2Info{ContinuationToken: continuationToken}, convertError(err, bucketName, "")
|
||||
}
|
||||
|
||||
recursive := delimiter == ""
|
||||
|
||||
var startAfterPath storj.Path
|
||||
if continuationToken != "" {
|
||||
startAfterPath = continuationToken
|
||||
}
|
||||
if startAfterPath == "" && startAfter != "" {
|
||||
startAfterPath = startAfter
|
||||
}
|
||||
|
||||
var objects []minio.ObjectInfo
|
||||
var prefixes []string
|
||||
|
||||
list := layer.gateway.project.ListObjects(ctx, bucketName, &uplink.ListObjectsOptions{
|
||||
Prefix: prefix,
|
||||
Cursor: startAfterPath,
|
||||
Recursive: recursive,
|
||||
|
||||
Info: true,
|
||||
Standard: true,
|
||||
Custom: true,
|
||||
})
|
||||
|
||||
limit := maxKeys
|
||||
for (limit > 0 || maxKeys == 0) && list.Next() {
|
||||
limit--
|
||||
object := list.Item()
|
||||
if object.IsPrefix {
|
||||
prefixes = append(prefixes, object.Key)
|
||||
continue
|
||||
}
|
||||
|
||||
objects = append(objects, minioObjectInfo(bucketName, "", object))
|
||||
|
||||
startAfter = object.Key
|
||||
}
|
||||
if list.Err() != nil {
|
||||
return result, convertError(list.Err(), bucketName, "")
|
||||
}
|
||||
|
||||
more := list.Next()
|
||||
if list.Err() != nil {
|
||||
return result, convertError(list.Err(), bucketName, "")
|
||||
}
|
||||
|
||||
result = minio.ListObjectsV2Info{
|
||||
IsTruncated: more,
|
||||
ContinuationToken: startAfter,
|
||||
Objects: objects,
|
||||
Prefixes: prefixes,
|
||||
}
|
||||
if more {
|
||||
result.NextContinuationToken = startAfter
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (layer *gatewayLayer) MakeBucketWithLocation(ctx context.Context, bucketName string, location string) (err error) {
|
||||
defer mon.Task()(&ctx)(&err)
|
||||
|
||||
// TODO: maybe this should return an error since we don't support locations
|
||||
|
||||
_, err = layer.gateway.project.CreateBucket(ctx, bucketName)
|
||||
|
||||
return convertError(err, bucketName, "")
|
||||
}
|
||||
|
||||
func (layer *gatewayLayer) CopyObject(ctx context.Context, srcBucket, srcObject, destBucket, destObject string, srcInfo minio.ObjectInfo) (objInfo minio.ObjectInfo, err error) {
|
||||
defer mon.Task()(&ctx)(&err)
|
||||
|
||||
if srcObject == "" {
|
||||
return minio.ObjectInfo{}, minio.ObjectNameInvalid{Bucket: srcBucket}
|
||||
}
|
||||
if destObject == "" {
|
||||
return minio.ObjectInfo{}, minio.ObjectNameInvalid{Bucket: destBucket}
|
||||
}
|
||||
|
||||
// TODO this should be removed and implemented on satellite side
|
||||
_, err = layer.gateway.project.StatBucket(ctx, srcBucket)
|
||||
if err != nil {
|
||||
return minio.ObjectInfo{}, convertError(err, srcBucket, "")
|
||||
}
|
||||
|
||||
// TODO this should be removed and implemented on satellite side
|
||||
_, err = layer.gateway.project.StatBucket(ctx, destBucket)
|
||||
if err != nil {
|
||||
return minio.ObjectInfo{}, convertError(err, destBucket, "")
|
||||
}
|
||||
|
||||
download, err := layer.gateway.project.DownloadObject(ctx, srcBucket, srcObject, nil)
|
||||
if err != nil {
|
||||
return minio.ObjectInfo{}, convertError(err, srcBucket, srcObject)
|
||||
}
|
||||
defer func() {
|
||||
// TODO: this hides minio error
|
||||
err = errs.Combine(err, download.Close())
|
||||
}()
|
||||
|
||||
upload, err := layer.gateway.project.UploadObject(ctx, destBucket, destObject, nil)
|
||||
if err != nil {
|
||||
return minio.ObjectInfo{}, convertError(err, destBucket, destObject)
|
||||
}
|
||||
|
||||
info := download.Info()
|
||||
err = upload.SetMetadata(ctx, &info.Standard, info.Custom)
|
||||
if err != nil {
|
||||
abortErr := upload.Abort()
|
||||
err = errs.Combine(err, abortErr)
|
||||
return minio.ObjectInfo{}, convertError(err, destBucket, destObject)
|
||||
}
|
||||
|
||||
reader, err := hash.NewReader(download, info.Standard.ContentLength, "", "")
|
||||
if err != nil {
|
||||
abortErr := upload.Abort()
|
||||
err = errs.Combine(err, abortErr)
|
||||
return minio.ObjectInfo{}, convertError(err, destBucket, destObject)
|
||||
}
|
||||
|
||||
_, err = io.Copy(upload, reader)
|
||||
if err != nil {
|
||||
abortErr := upload.Abort()
|
||||
err = errs.Combine(err, abortErr)
|
||||
return minio.ObjectInfo{}, convertError(err, destBucket, destObject)
|
||||
}
|
||||
|
||||
err = upload.Commit()
|
||||
if err != nil {
|
||||
return minio.ObjectInfo{}, convertError(err, destBucket, destObject)
|
||||
}
|
||||
|
||||
return minioObjectInfo(destBucket, hex.EncodeToString(reader.MD5Current()), upload.Info()), nil
|
||||
}
|
||||
|
||||
func (layer *gatewayLayer) PutObject(ctx context.Context, bucketName, objectPath string, data *hash.Reader, metadata map[string]string) (objInfo minio.ObjectInfo, err error) {
|
||||
defer mon.Task()(&ctx)(&err)
|
||||
|
||||
// TODO this should be removed and implemented on satellite side
|
||||
_, err = layer.gateway.project.StatBucket(ctx, bucketName)
|
||||
if err != nil {
|
||||
return minio.ObjectInfo{}, convertError(err, bucketName, objectPath)
|
||||
}
|
||||
|
||||
if data == nil {
|
||||
data, err = hash.NewReader(bytes.NewReader([]byte{}), 0, "", "")
|
||||
if err != nil {
|
||||
return minio.ObjectInfo{}, convertError(err, bucketName, objectPath)
|
||||
}
|
||||
}
|
||||
|
||||
upload, err := layer.gateway.project.UploadObject(ctx, bucketName, objectPath, nil)
|
||||
if err != nil {
|
||||
return minio.ObjectInfo{}, convertError(err, bucketName, objectPath)
|
||||
}
|
||||
|
||||
n, err := io.Copy(upload, data)
|
||||
if err != nil {
|
||||
abortErr := upload.Abort()
|
||||
err = errs.Combine(err, abortErr)
|
||||
return minio.ObjectInfo{}, convertError(err, bucketName, objectPath)
|
||||
}
|
||||
|
||||
contentType := metadata["content-type"]
|
||||
delete(metadata, "content-type")
|
||||
|
||||
err = upload.SetMetadata(ctx, &uplink.StandardMetadata{
|
||||
ContentLength: n,
|
||||
ContentType: contentType,
|
||||
}, metadata)
|
||||
if err != nil {
|
||||
abortErr := upload.Abort()
|
||||
err = errs.Combine(err, abortErr)
|
||||
return minio.ObjectInfo{}, convertError(err, bucketName, objectPath)
|
||||
}
|
||||
|
||||
err = upload.Commit()
|
||||
if err != nil {
|
||||
return minio.ObjectInfo{}, convertError(err, bucketName, objectPath)
|
||||
}
|
||||
|
||||
return minioObjectInfo(bucketName, data.MD5HexString(), upload.Info()), nil
|
||||
}
|
||||
|
||||
func (layer *gatewayLayer) Shutdown(ctx context.Context) (err error) {
|
||||
defer mon.Task()(&ctx)(&err)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (layer *gatewayLayer) StorageInfo(context.Context) minio.StorageInfo {
|
||||
return minio.StorageInfo{}
|
||||
}
|
||||
|
||||
func convertError(err error, bucket, object string) error {
|
||||
if uplink.ErrBucketNameInvalid.Has(err) {
|
||||
return minio.BucketNameInvalid{Bucket: bucket}
|
||||
}
|
||||
|
||||
if uplink.ErrBucketAlreadyExists.Has(err) {
|
||||
return minio.BucketAlreadyExists{Bucket: bucket}
|
||||
}
|
||||
|
||||
if uplink.ErrBucketNotFound.Has(err) {
|
||||
return minio.BucketNotFound{Bucket: bucket}
|
||||
}
|
||||
|
||||
if uplink.ErrBucketNotEmpty.Has(err) {
|
||||
return minio.BucketNotEmpty{Bucket: bucket}
|
||||
}
|
||||
|
||||
if uplink.ErrObjectKeyInvalid.Has(err) {
|
||||
return minio.ObjectNameInvalid{Bucket: bucket, Object: object}
|
||||
}
|
||||
|
||||
if uplink.ErrObjectNotFound.Has(err) {
|
||||
return minio.ObjectNotFound{Bucket: bucket, Object: object}
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func minioObjectInfo(bucket, etag string, object *uplink.Object) minio.ObjectInfo {
|
||||
return minio.ObjectInfo{
|
||||
Bucket: bucket,
|
||||
Name: object.Key,
|
||||
Size: object.Standard.ContentLength,
|
||||
ETag: etag,
|
||||
ModTime: object.Info.Created,
|
||||
ContentType: object.Standard.ContentType,
|
||||
UserDefined: object.Custom,
|
||||
}
|
||||
}
|
@ -1,799 +0,0 @@
|
||||
// Copyright (C) 2019 Storj Labs, Inc.
|
||||
// See LICENSE for copying information.
|
||||
|
||||
package miniogw_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
minio "github.com/minio/minio/cmd"
|
||||
"github.com/minio/minio/pkg/auth"
|
||||
"github.com/minio/minio/pkg/hash"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/zeebo/errs"
|
||||
|
||||
"storj.io/common/memory"
|
||||
"storj.io/common/pb"
|
||||
"storj.io/common/storj"
|
||||
"storj.io/common/testcontext"
|
||||
olduplink "storj.io/storj/lib/uplink"
|
||||
"storj.io/storj/pkg/miniogw"
|
||||
"storj.io/storj/private/testplanet"
|
||||
"storj.io/uplink"
|
||||
"storj.io/uplink/private/ecclient"
|
||||
"storj.io/uplink/private/metainfo/kvmetainfo"
|
||||
"storj.io/uplink/private/storage/segments"
|
||||
"storj.io/uplink/private/storage/streams"
|
||||
"storj.io/uplink/private/stream"
|
||||
)
|
||||
|
||||
const (
|
||||
TestEncKey = "test-encryption-key"
|
||||
TestBucket = "test-bucket"
|
||||
TestFile = "test-file"
|
||||
DestBucket = "dest-bucket"
|
||||
DestFile = "dest-file"
|
||||
TestAPIKey = "test-api-key"
|
||||
)
|
||||
|
||||
var (
|
||||
defaultRS = storj.RedundancyScheme{
|
||||
RequiredShares: 2,
|
||||
RepairShares: 2,
|
||||
OptimalShares: 3,
|
||||
TotalShares: 4,
|
||||
ShareSize: 256 * memory.B.Int32(),
|
||||
}
|
||||
|
||||
defaultEP = storj.EncryptionParameters{
|
||||
CipherSuite: storj.EncAESGCM,
|
||||
BlockSize: defaultRS.StripeSize(),
|
||||
}
|
||||
|
||||
defaultBucket = storj.Bucket{
|
||||
PathCipher: storj.EncAESGCM,
|
||||
DefaultRedundancyScheme: defaultRS,
|
||||
DefaultEncryptionParameters: defaultEP,
|
||||
}
|
||||
)
|
||||
|
||||
func TestMakeBucketWithLocation(t *testing.T) {
|
||||
runTest(t, func(t *testing.T, ctx context.Context, layer minio.ObjectLayer, m *kvmetainfo.DB, strms streams.Store) {
|
||||
// Check the error when creating bucket with empty name
|
||||
err := layer.MakeBucketWithLocation(ctx, "", "")
|
||||
assert.Equal(t, minio.BucketNameInvalid{}, err)
|
||||
|
||||
// Create a bucket with the Minio API
|
||||
err = layer.MakeBucketWithLocation(ctx, TestBucket, "")
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Check that the bucket is created using the Metainfo API
|
||||
bucket, err := m.GetBucket(ctx, TestBucket)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, TestBucket, bucket.Name)
|
||||
assert.True(t, time.Since(bucket.Created) < 1*time.Minute)
|
||||
assert.Equal(t, storj.EncAESGCM, bucket.PathCipher)
|
||||
|
||||
// Check the error when trying to create an existing bucket
|
||||
err = layer.MakeBucketWithLocation(ctx, TestBucket, "")
|
||||
assert.Equal(t, minio.BucketAlreadyExists{Bucket: TestBucket}, err)
|
||||
})
|
||||
}
|
||||
|
||||
func TestGetBucketInfo(t *testing.T) {
|
||||
runTest(t, func(t *testing.T, ctx context.Context, layer minio.ObjectLayer, m *kvmetainfo.DB, strms streams.Store) {
|
||||
// Check the error when getting info about bucket with empty name
|
||||
_, err := layer.GetBucketInfo(ctx, "")
|
||||
assert.Equal(t, minio.BucketNameInvalid{}, err)
|
||||
|
||||
// Check the error when getting info about non-existing bucket
|
||||
_, err = layer.GetBucketInfo(ctx, TestBucket)
|
||||
assert.Equal(t, minio.BucketNotFound{Bucket: TestBucket}, err)
|
||||
|
||||
// Create the bucket using the Metainfo API
|
||||
info, err := m.CreateBucket(ctx, TestBucket, &defaultBucket)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Check the bucket info using the Minio API
|
||||
bucket, err := layer.GetBucketInfo(ctx, TestBucket)
|
||||
if assert.NoError(t, err) {
|
||||
assert.Equal(t, TestBucket, bucket.Name)
|
||||
assert.Equal(t, info.Created, bucket.Created)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestDeleteBucket(t *testing.T) {
|
||||
runTest(t, func(t *testing.T, ctx context.Context, layer minio.ObjectLayer, m *kvmetainfo.DB, strms streams.Store) {
|
||||
// Check the error when deleting bucket with empty name
|
||||
err := layer.DeleteBucket(ctx, "")
|
||||
assert.Equal(t, minio.BucketNameInvalid{}, err)
|
||||
|
||||
// Check the error when deleting non-existing bucket
|
||||
err = layer.DeleteBucket(ctx, TestBucket)
|
||||
assert.Equal(t, minio.BucketNotFound{Bucket: TestBucket}, err)
|
||||
|
||||
// Create a bucket with a file using the Metainfo API
|
||||
bucket, err := m.CreateBucket(ctx, TestBucket, &defaultBucket)
|
||||
assert.NoError(t, err)
|
||||
|
||||
_, err = createFile(ctx, m, strms, bucket, TestFile, nil, nil)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Check the error when deleting non-empty bucket
|
||||
err = layer.DeleteBucket(ctx, TestBucket)
|
||||
assert.Equal(t, minio.BucketNotEmpty{Bucket: TestBucket}, err)
|
||||
|
||||
// Delete the file using the Metainfo API, so the bucket becomes empty
|
||||
err = m.DeleteObject(ctx, bucket, TestFile)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Delete the bucket info using the Minio API
|
||||
err = layer.DeleteBucket(ctx, TestBucket)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Check that the bucket is deleted using the Metainfo API
|
||||
_, err = m.GetBucket(ctx, TestBucket)
|
||||
assert.True(t, storj.ErrBucketNotFound.Has(err))
|
||||
})
|
||||
}
|
||||
|
||||
func TestListBuckets(t *testing.T) {
|
||||
runTest(t, func(t *testing.T, ctx context.Context, layer minio.ObjectLayer, m *kvmetainfo.DB, strms streams.Store) {
|
||||
// Check that empty list is return if no buckets exist yet
|
||||
bucketInfos, err := layer.ListBuckets(ctx)
|
||||
assert.NoError(t, err)
|
||||
assert.Empty(t, bucketInfos)
|
||||
|
||||
// Create all expected buckets using the Metainfo API
|
||||
bucketNames := []string{"bucket-1", "bucket-2", "bucket-3"}
|
||||
buckets := make([]storj.Bucket, len(bucketNames))
|
||||
for i, bucketName := range bucketNames {
|
||||
bucket, err := m.CreateBucket(ctx, bucketName, &defaultBucket)
|
||||
buckets[i] = bucket
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
// Check that the expected buckets can be listed using the Minio API
|
||||
bucketInfos, err = layer.ListBuckets(ctx)
|
||||
if assert.NoError(t, err) {
|
||||
assert.Equal(t, len(bucketNames), len(bucketInfos))
|
||||
for i, bucketInfo := range bucketInfos {
|
||||
assert.Equal(t, bucketNames[i], bucketInfo.Name)
|
||||
assert.Equal(t, buckets[i].Created, bucketInfo.Created)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestPutObject(t *testing.T) {
|
||||
runTest(t, func(t *testing.T, ctx context.Context, layer minio.ObjectLayer, m *kvmetainfo.DB, strms streams.Store) {
|
||||
data, err := hash.NewReader(bytes.NewReader([]byte("test")),
|
||||
int64(len("test")),
|
||||
"098f6bcd4621d373cade4e832627b4f6",
|
||||
"9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08")
|
||||
require.NoError(t, err)
|
||||
|
||||
metadata := map[string]string{
|
||||
"content-type": "media/foo",
|
||||
"key1": "value1",
|
||||
"key2": "value2",
|
||||
}
|
||||
|
||||
serMetaInfo := pb.SerializableMeta{
|
||||
ContentType: metadata["content-type"],
|
||||
UserDefined: map[string]string{
|
||||
"key1": metadata["key1"],
|
||||
"key2": metadata["key2"],
|
||||
},
|
||||
}
|
||||
|
||||
// Check the error when putting an object to a bucket with empty name
|
||||
_, err = layer.PutObject(ctx, "", "", nil, nil)
|
||||
assert.Equal(t, minio.BucketNameInvalid{}, err)
|
||||
|
||||
// Check the error when putting an object to a non-existing bucket
|
||||
_, err = layer.PutObject(ctx, TestBucket, TestFile, nil, nil)
|
||||
assert.Equal(t, minio.BucketNotFound{Bucket: TestBucket}, err)
|
||||
|
||||
// Create the bucket using the Metainfo API
|
||||
testBucketInfo, err := m.CreateBucket(ctx, TestBucket, &defaultBucket)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Check the error when putting an object with empty name
|
||||
_, err = layer.PutObject(ctx, TestBucket, "", nil, nil)
|
||||
assert.Equal(t, minio.ObjectNameInvalid{Bucket: TestBucket}, err)
|
||||
|
||||
// Put the object using the Minio API
|
||||
info, err := layer.PutObject(ctx, TestBucket, TestFile, data, metadata)
|
||||
if assert.NoError(t, err) {
|
||||
assert.Equal(t, TestFile, info.Name)
|
||||
assert.Equal(t, TestBucket, info.Bucket)
|
||||
assert.False(t, info.IsDir)
|
||||
assert.True(t, time.Since(info.ModTime) < 1*time.Minute)
|
||||
assert.Equal(t, data.Size(), info.Size)
|
||||
// assert.Equal(t, data.SHA256HexString(), info.ETag) TODO: when we start calculating checksums
|
||||
assert.Equal(t, serMetaInfo.ContentType, info.ContentType)
|
||||
assert.Equal(t, serMetaInfo.UserDefined, info.UserDefined)
|
||||
}
|
||||
|
||||
// Check that the object is uploaded using the Metainfo API
|
||||
obj, err := m.GetObjectExtended(ctx, testBucketInfo, TestFile)
|
||||
if assert.NoError(t, err) {
|
||||
assert.Equal(t, TestFile, obj.Path)
|
||||
assert.Equal(t, TestBucket, obj.Bucket.Name)
|
||||
assert.False(t, obj.IsPrefix)
|
||||
|
||||
// TODO upload.Info() is using StreamID creation time but this value is different
|
||||
// than last segment creation time, CommitObject request should return latest info
|
||||
// about object and those values should be used with upload.Info()
|
||||
// This should be working after final fix
|
||||
// assert.Equal(t, info.ModTime, obj.Info.Created)
|
||||
assert.WithinDuration(t, info.ModTime, obj.Info.Created, 1*time.Second)
|
||||
|
||||
assert.Equal(t, info.Size, obj.Size)
|
||||
// TODO disabled until we will store ETag with object
|
||||
// assert.Equal(t, info.ETag, hex.EncodeToString(obj.Checksum))
|
||||
assert.Equal(t, info.ContentType, obj.Standard.ContentType)
|
||||
assert.Equal(t, info.UserDefined, obj.Custom)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestGetObjectInfo(t *testing.T) {
|
||||
runTest(t, func(t *testing.T, ctx context.Context, layer minio.ObjectLayer, m *kvmetainfo.DB, strms streams.Store) {
|
||||
// Check the error when getting an object from a bucket with empty name
|
||||
_, err := layer.GetObjectInfo(ctx, "", "")
|
||||
assert.Equal(t, minio.BucketNameInvalid{}, err)
|
||||
|
||||
// Check the error when getting an object from non-existing bucket
|
||||
_, err = layer.GetObjectInfo(ctx, TestBucket, TestFile)
|
||||
assert.Equal(t, minio.BucketNotFound{Bucket: TestBucket}, err)
|
||||
|
||||
// Create the bucket using the Metainfo API
|
||||
testBucketInfo, err := m.CreateBucket(ctx, TestBucket, &defaultBucket)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Check the error when getting an object with empty name
|
||||
_, err = layer.GetObjectInfo(ctx, TestBucket, "")
|
||||
assert.Equal(t, minio.ObjectNameInvalid{Bucket: TestBucket}, err)
|
||||
|
||||
// Check the error when getting a non-existing object
|
||||
_, err = layer.GetObjectInfo(ctx, TestBucket, TestFile)
|
||||
assert.Equal(t, minio.ObjectNotFound{Bucket: TestBucket, Object: TestFile}, err)
|
||||
|
||||
// Create the object using the Metainfo API
|
||||
createInfo := kvmetainfo.CreateObject{
|
||||
ContentType: "text/plain",
|
||||
Metadata: map[string]string{"key1": "value1", "key2": "value2"},
|
||||
}
|
||||
obj, err := createFile(ctx, m, strms, testBucketInfo, TestFile, &createInfo, []byte("test"))
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Get the object info using the Minio API
|
||||
info, err := layer.GetObjectInfo(ctx, TestBucket, TestFile)
|
||||
if assert.NoError(t, err) {
|
||||
assert.Equal(t, TestFile, info.Name)
|
||||
assert.Equal(t, TestBucket, info.Bucket)
|
||||
assert.False(t, info.IsDir)
|
||||
assert.Equal(t, obj.Created, info.ModTime)
|
||||
assert.Equal(t, obj.Size, info.Size)
|
||||
assert.Equal(t, hex.EncodeToString(obj.Checksum), info.ETag)
|
||||
assert.Equal(t, createInfo.ContentType, info.ContentType)
|
||||
assert.Equal(t, createInfo.Metadata, info.UserDefined)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestGetObject(t *testing.T) {
|
||||
runTest(t, func(t *testing.T, ctx context.Context, layer minio.ObjectLayer, m *kvmetainfo.DB, strms streams.Store) {
|
||||
// Check the error when getting an object from a bucket with empty name
|
||||
err := layer.GetObject(ctx, "", "", 0, 0, nil, "")
|
||||
assert.Equal(t, minio.BucketNameInvalid{}, err)
|
||||
|
||||
// Check the error when getting an object from non-existing bucket
|
||||
err = layer.GetObject(ctx, TestBucket, TestFile, 0, 0, nil, "")
|
||||
assert.Equal(t, minio.BucketNotFound{Bucket: TestBucket}, err)
|
||||
|
||||
// Create the bucket using the Metainfo API
|
||||
testBucketInfo, err := m.CreateBucket(ctx, TestBucket, &defaultBucket)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Check the error when getting an object with empty name
|
||||
err = layer.GetObject(ctx, TestBucket, "", 0, 0, nil, "")
|
||||
assert.Equal(t, minio.ObjectNameInvalid{Bucket: TestBucket}, err)
|
||||
|
||||
// Check the error when getting a non-existing object
|
||||
err = layer.GetObject(ctx, TestBucket, TestFile, 0, 0, nil, "")
|
||||
assert.Equal(t, minio.ObjectNotFound{Bucket: TestBucket, Object: TestFile}, err)
|
||||
|
||||
// Create the object using the Metainfo API
|
||||
createInfo := kvmetainfo.CreateObject{
|
||||
ContentType: "text/plain",
|
||||
Metadata: map[string]string{"key1": "value1", "key2": "value2"},
|
||||
}
|
||||
_, err = createFile(ctx, m, strms, testBucketInfo, TestFile, &createInfo, []byte("abcdef"))
|
||||
assert.NoError(t, err)
|
||||
|
||||
for i, tt := range []struct {
|
||||
offset, length int64
|
||||
substr string
|
||||
err error
|
||||
}{
|
||||
{offset: 0, length: 0, substr: ""},
|
||||
{offset: 3, length: 0, substr: ""},
|
||||
{offset: 0, length: -1, substr: "abcdef"},
|
||||
{offset: 0, length: 6, substr: "abcdef"},
|
||||
{offset: 0, length: 5, substr: "abcde"},
|
||||
{offset: 0, length: 4, substr: "abcd"},
|
||||
{offset: 1, length: 4, substr: "bcde"},
|
||||
{offset: 2, length: 4, substr: "cdef"},
|
||||
{offset: 0, length: 7, substr: "", err: minio.InvalidRange{OffsetBegin: 0, OffsetEnd: 7, ResourceSize: 6}},
|
||||
{offset: -1, length: 7, substr: "", err: minio.InvalidRange{OffsetBegin: -1, OffsetEnd: 6, ResourceSize: 6}},
|
||||
{offset: 0, length: -2, substr: "", err: minio.InvalidRange{OffsetBegin: 0, OffsetEnd: -2, ResourceSize: 6}},
|
||||
} {
|
||||
errTag := fmt.Sprintf("%d. %+v", i, tt)
|
||||
|
||||
var buf bytes.Buffer
|
||||
|
||||
// Get the object info using the Minio API
|
||||
err = layer.GetObject(ctx, TestBucket, TestFile, tt.offset, tt.length, &buf, "")
|
||||
|
||||
if tt.err != nil {
|
||||
assert.Equal(t, tt.err, err, errTag)
|
||||
} else if assert.NoError(t, err) {
|
||||
assert.Equal(t, tt.substr, buf.String(), errTag)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestCopyObject(t *testing.T) {
|
||||
runTest(t, func(t *testing.T, ctx context.Context, layer minio.ObjectLayer, m *kvmetainfo.DB, strms streams.Store) {
|
||||
// Check the error when copying an object from a bucket with empty name
|
||||
_, err := layer.CopyObject(ctx, "", TestFile, DestBucket, DestFile, minio.ObjectInfo{})
|
||||
assert.Equal(t, minio.BucketNameInvalid{}, err)
|
||||
|
||||
// Check the error when copying an object from non-existing bucket
|
||||
_, err = layer.CopyObject(ctx, TestBucket, TestFile, DestBucket, DestFile, minio.ObjectInfo{})
|
||||
assert.Equal(t, minio.BucketNotFound{Bucket: TestBucket}, err)
|
||||
|
||||
// Create the source bucket using the Metainfo API
|
||||
testBucketInfo, err := m.CreateBucket(ctx, TestBucket, &defaultBucket)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Check the error when copying an object with empty name
|
||||
_, err = layer.CopyObject(ctx, TestBucket, "", DestBucket, DestFile, minio.ObjectInfo{})
|
||||
assert.Equal(t, minio.ObjectNameInvalid{Bucket: TestBucket}, err)
|
||||
|
||||
// Create the source object using the Metainfo API
|
||||
createInfo := kvmetainfo.CreateObject{
|
||||
ContentType: "text/plain",
|
||||
Metadata: map[string]string{"key1": "value1", "key2": "value2"},
|
||||
}
|
||||
obj, err := createFile(ctx, m, strms, testBucketInfo, TestFile, &createInfo, []byte("test"))
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Get the source object info using the Minio API
|
||||
srcInfo, err := layer.GetObjectInfo(ctx, TestBucket, TestFile)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Check the error when copying an object to a bucket with empty name
|
||||
_, err = layer.CopyObject(ctx, TestBucket, TestFile, "", DestFile, srcInfo)
|
||||
assert.Equal(t, minio.BucketNameInvalid{}, err)
|
||||
|
||||
// Check the error when copying an object to a non-existing bucket
|
||||
_, err = layer.CopyObject(ctx, TestBucket, TestFile, DestBucket, DestFile, srcInfo)
|
||||
assert.Equal(t, minio.BucketNotFound{Bucket: DestBucket}, err)
|
||||
|
||||
// Create the destination bucket using the Metainfo API
|
||||
destBucketInfo, err := m.CreateBucket(ctx, DestBucket, &defaultBucket)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Copy the object using the Minio API
|
||||
info, err := layer.CopyObject(ctx, TestBucket, TestFile, DestBucket, DestFile, srcInfo)
|
||||
if assert.NoError(t, err) {
|
||||
assert.Equal(t, DestFile, info.Name)
|
||||
assert.Equal(t, DestBucket, info.Bucket)
|
||||
assert.False(t, info.IsDir)
|
||||
assert.True(t, info.ModTime.Sub(obj.Modified) < 1*time.Minute)
|
||||
assert.Equal(t, obj.Size, info.Size)
|
||||
assert.Equal(t, createInfo.ContentType, info.ContentType)
|
||||
assert.Equal(t, createInfo.Metadata, info.UserDefined)
|
||||
}
|
||||
|
||||
// Check that the destination object is uploaded using the Metainfo API
|
||||
obj, err = m.GetObject(ctx, destBucketInfo, DestFile)
|
||||
if assert.NoError(t, err) {
|
||||
assert.Equal(t, DestFile, obj.Path)
|
||||
assert.Equal(t, DestBucket, obj.Bucket.Name)
|
||||
assert.False(t, obj.IsPrefix)
|
||||
|
||||
// TODO upload.Info() is using StreamID creation time but this value is different
|
||||
// than last segment creation time, CommitObject request should return latest info
|
||||
// about object and those values should be used with upload.Info()
|
||||
// This should be working after final fix
|
||||
// assert.Equal(t, info.ModTime, obj.Info.Created)
|
||||
assert.WithinDuration(t, info.ModTime, obj.Modified, 1*time.Second)
|
||||
|
||||
assert.Equal(t, info.Size, obj.Size)
|
||||
assert.Equal(t, info.ContentType, obj.ContentType)
|
||||
assert.Equal(t, info.UserDefined, obj.Metadata)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestDeleteObject(t *testing.T) {
|
||||
runTest(t, func(t *testing.T, ctx context.Context, layer minio.ObjectLayer, m *kvmetainfo.DB, strms streams.Store) {
|
||||
// Check the error when deleting an object from a bucket with empty name
|
||||
err := layer.DeleteObject(ctx, "", "")
|
||||
assert.Equal(t, minio.BucketNameInvalid{}, err)
|
||||
|
||||
// Check the error when deleting an object from non-existing bucket
|
||||
err = layer.DeleteObject(ctx, TestBucket, TestFile)
|
||||
assert.Equal(t, minio.BucketNotFound{Bucket: TestBucket}, err)
|
||||
|
||||
// Create the bucket using the Metainfo API
|
||||
testBucketInfo, err := m.CreateBucket(ctx, TestBucket, &defaultBucket)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Check the error when deleting an object with empty name
|
||||
err = layer.DeleteObject(ctx, TestBucket, "")
|
||||
assert.Equal(t, minio.ObjectNameInvalid{Bucket: TestBucket}, err)
|
||||
|
||||
// Check the error when deleting a non-existing object
|
||||
err = layer.DeleteObject(ctx, TestBucket, TestFile)
|
||||
assert.Equal(t, minio.ObjectNotFound{Bucket: TestBucket, Object: TestFile}, err)
|
||||
|
||||
// Create the object using the Metainfo API
|
||||
_, err = createFile(ctx, m, strms, testBucketInfo, TestFile, nil, nil)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Delete the object info using the Minio API
|
||||
err = layer.DeleteObject(ctx, TestBucket, TestFile)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Check that the object is deleted using the Metainfo API
|
||||
_, err = m.GetObject(ctx, testBucketInfo, TestFile)
|
||||
assert.True(t, storj.ErrObjectNotFound.Has(err))
|
||||
})
|
||||
}
|
||||
|
||||
func TestListObjects(t *testing.T) {
|
||||
testListObjects(t, func(t *testing.T, ctx context.Context, layer minio.ObjectLayer, bucket, prefix, marker, delimiter string, maxKeys int) ([]string, []minio.ObjectInfo, bool, error) {
|
||||
list, err := layer.ListObjects(ctx, TestBucket, prefix, marker, delimiter, maxKeys)
|
||||
if err != nil {
|
||||
return nil, nil, false, err
|
||||
}
|
||||
return list.Prefixes, list.Objects, list.IsTruncated, nil
|
||||
})
|
||||
}
|
||||
|
||||
func TestListObjectsV2(t *testing.T) {
|
||||
testListObjects(t, func(t *testing.T, ctx context.Context, layer minio.ObjectLayer, bucket, prefix, marker, delimiter string, maxKeys int) ([]string, []minio.ObjectInfo, bool, error) {
|
||||
list, err := layer.ListObjectsV2(ctx, TestBucket, prefix, marker, delimiter, maxKeys, false, "")
|
||||
if err != nil {
|
||||
return nil, nil, false, err
|
||||
}
|
||||
return list.Prefixes, list.Objects, list.IsTruncated, nil
|
||||
})
|
||||
}
|
||||
|
||||
func testListObjects(t *testing.T, listObjects func(*testing.T, context.Context, minio.ObjectLayer, string, string, string, string, int) ([]string, []minio.ObjectInfo, bool, error)) {
|
||||
runTestWithPathCipher(t, storj.EncNull, func(t *testing.T, ctx context.Context, layer minio.ObjectLayer, m *kvmetainfo.DB, strms streams.Store) {
|
||||
// Check the error when listing objects with unsupported delimiter
|
||||
_, err := layer.ListObjects(ctx, TestBucket, "", "", "#", 0)
|
||||
assert.Equal(t, minio.UnsupportedDelimiter{Delimiter: "#"}, err)
|
||||
|
||||
// Check the error when listing objects in a bucket with empty name
|
||||
_, err = layer.ListObjects(ctx, "", "", "", "/", 0)
|
||||
assert.Equal(t, minio.BucketNameInvalid{}, err)
|
||||
|
||||
// Check the error when listing objects in a non-existing bucket
|
||||
_, err = layer.ListObjects(ctx, TestBucket, "", "", "", 0)
|
||||
assert.Equal(t, minio.BucketNotFound{Bucket: TestBucket}, err)
|
||||
|
||||
// Create the bucket and files using the Metainfo API
|
||||
testBucketInfo, err := m.CreateBucket(ctx, TestBucket, &storj.Bucket{
|
||||
PathCipher: storj.EncNull,
|
||||
DefaultRedundancyScheme: defaultRS,
|
||||
DefaultEncryptionParameters: defaultEP,
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
|
||||
filePaths := []string{
|
||||
"a", "aa", "b", "bb", "c",
|
||||
"a/xa", "a/xaa", "a/xb", "a/xbb", "a/xc",
|
||||
"b/ya", "b/yaa", "b/yb", "b/ybb", "b/yc",
|
||||
}
|
||||
|
||||
type expected struct {
|
||||
object storj.Object
|
||||
kvObject kvmetainfo.CreateObject
|
||||
}
|
||||
|
||||
files := make(map[string]expected, len(filePaths))
|
||||
|
||||
createInfo := kvmetainfo.CreateObject{
|
||||
ContentType: "text/plain",
|
||||
Metadata: map[string]string{"key1": "value1", "key2": "value2"},
|
||||
}
|
||||
|
||||
for _, filePath := range filePaths {
|
||||
file, err := createFile(ctx, m, strms, testBucketInfo, filePath, &createInfo, []byte("test"))
|
||||
files[filePath] = expected{
|
||||
object: file,
|
||||
kvObject: createInfo,
|
||||
}
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
for i, tt := range []struct {
|
||||
prefix string
|
||||
marker string
|
||||
delimiter string
|
||||
maxKeys int
|
||||
more bool
|
||||
prefixes []string
|
||||
objects []string
|
||||
}{
|
||||
{
|
||||
delimiter: "/",
|
||||
prefixes: []string{"a/", "b/"},
|
||||
objects: []string{"a", "aa", "b", "bb", "c"},
|
||||
}, {
|
||||
marker: "`",
|
||||
delimiter: "/",
|
||||
prefixes: []string{"a/", "b/"},
|
||||
objects: []string{"a", "aa", "b", "bb", "c"},
|
||||
}, {
|
||||
marker: "b",
|
||||
delimiter: "/",
|
||||
prefixes: []string{"b/"},
|
||||
objects: []string{"bb", "c"},
|
||||
}, {
|
||||
marker: "c",
|
||||
delimiter: "/",
|
||||
}, {
|
||||
marker: "ca",
|
||||
delimiter: "/",
|
||||
}, {
|
||||
delimiter: "/",
|
||||
maxKeys: 1,
|
||||
more: true,
|
||||
objects: []string{"a"},
|
||||
}, {
|
||||
marker: "`",
|
||||
delimiter: "/",
|
||||
maxKeys: 1,
|
||||
more: true,
|
||||
objects: []string{"a"},
|
||||
}, {
|
||||
marker: "aa",
|
||||
delimiter: "/",
|
||||
maxKeys: 1,
|
||||
more: true,
|
||||
objects: []string{"b"},
|
||||
}, {
|
||||
marker: "c",
|
||||
delimiter: "/",
|
||||
maxKeys: 1,
|
||||
}, {
|
||||
marker: "ca",
|
||||
delimiter: "/",
|
||||
maxKeys: 1,
|
||||
}, {
|
||||
delimiter: "/",
|
||||
maxKeys: 2,
|
||||
more: true,
|
||||
prefixes: []string{"a/"},
|
||||
objects: []string{"a"},
|
||||
}, {
|
||||
marker: "`",
|
||||
delimiter: "/",
|
||||
maxKeys: 2,
|
||||
more: true,
|
||||
prefixes: []string{"a/"},
|
||||
objects: []string{"a"},
|
||||
}, {
|
||||
marker: "aa",
|
||||
delimiter: "/",
|
||||
maxKeys: 2,
|
||||
more: true,
|
||||
prefixes: []string{"b/"},
|
||||
objects: []string{"b"},
|
||||
}, {
|
||||
marker: "bb",
|
||||
delimiter: "/",
|
||||
maxKeys: 2,
|
||||
objects: []string{"c"},
|
||||
}, {
|
||||
marker: "c",
|
||||
delimiter: "/",
|
||||
maxKeys: 2,
|
||||
}, {
|
||||
marker: "ca",
|
||||
delimiter: "/",
|
||||
maxKeys: 2,
|
||||
}, {
|
||||
objects: []string{"a", "a/xa", "a/xaa", "a/xb", "a/xbb", "a/xc", "aa", "b", "b/ya", "b/yaa", "b/yb", "b/ybb", "b/yc", "bb", "c"},
|
||||
}, {
|
||||
prefix: "a/",
|
||||
delimiter: "/",
|
||||
objects: []string{"xa", "xaa", "xb", "xbb", "xc"},
|
||||
}, {
|
||||
prefix: "a/",
|
||||
delimiter: "/",
|
||||
objects: []string{"xa", "xaa", "xb", "xbb", "xc"},
|
||||
}, {
|
||||
prefix: "a/",
|
||||
marker: "xb",
|
||||
delimiter: "/",
|
||||
objects: []string{"xbb", "xc"},
|
||||
}, {
|
||||
marker: "a/xbb",
|
||||
maxKeys: 5,
|
||||
more: true,
|
||||
objects: []string{"a/xc", "aa", "b", "b/ya", "b/yaa"},
|
||||
}, {
|
||||
prefix: "a/",
|
||||
marker: "xaa",
|
||||
delimiter: "/",
|
||||
maxKeys: 2,
|
||||
more: true,
|
||||
objects: []string{"xb", "xbb"},
|
||||
},
|
||||
} {
|
||||
errTag := fmt.Sprintf("%d. %+v", i, tt)
|
||||
|
||||
// Check that the expected objects can be listed using the Minio API
|
||||
prefixes, objects, isTruncated, err := listObjects(t, ctx, layer, TestBucket, tt.prefix, tt.marker, tt.delimiter, tt.maxKeys)
|
||||
if assert.NoError(t, err, errTag) {
|
||||
assert.Equal(t, tt.more, isTruncated, errTag)
|
||||
assert.Equal(t, tt.prefixes, prefixes, errTag)
|
||||
assert.Equal(t, len(tt.objects), len(objects), errTag)
|
||||
for i, objectInfo := range objects {
|
||||
path := objectInfo.Name
|
||||
expected, found := files[path]
|
||||
|
||||
if assert.True(t, found) {
|
||||
if tt.prefix != "" {
|
||||
assert.Equal(t, storj.JoinPaths(strings.TrimSuffix(tt.prefix, "/"), tt.objects[i]), objectInfo.Name, errTag)
|
||||
} else {
|
||||
assert.Equal(t, tt.objects[i], objectInfo.Name, errTag)
|
||||
}
|
||||
assert.Equal(t, TestBucket, objectInfo.Bucket, errTag)
|
||||
assert.False(t, objectInfo.IsDir, errTag)
|
||||
assert.Equal(t, expected.object.Modified, objectInfo.ModTime, errTag)
|
||||
assert.Equal(t, expected.object.Size, objectInfo.Size, errTag)
|
||||
// assert.Equal(t, hex.EncodeToString(obj.Checksum), objectInfo.ETag, errTag)
|
||||
assert.Equal(t, expected.kvObject.ContentType, objectInfo.ContentType, errTag)
|
||||
assert.Equal(t, expected.kvObject.Metadata, objectInfo.UserDefined, errTag)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func runTest(t *testing.T, test func(*testing.T, context.Context, minio.ObjectLayer, *kvmetainfo.DB, streams.Store)) {
|
||||
runTestWithPathCipher(t, storj.EncNull, test)
|
||||
}
|
||||
|
||||
func runTestWithPathCipher(t *testing.T, pathCipher storj.CipherSuite, test func(*testing.T, context.Context, minio.ObjectLayer, *kvmetainfo.DB, streams.Store)) {
|
||||
testplanet.Run(t, testplanet.Config{
|
||||
SatelliteCount: 1, StorageNodeCount: 4, UplinkCount: 1,
|
||||
}, func(t *testing.T, ctx *testcontext.Context, planet *testplanet.Planet) {
|
||||
layer, m, strms, err := initEnv(ctx, t, planet, pathCipher)
|
||||
require.NoError(t, err)
|
||||
|
||||
test(t, ctx, layer, m, strms)
|
||||
})
|
||||
}
|
||||
|
||||
func initEnv(ctx context.Context, t *testing.T, planet *testplanet.Planet, pathCipher storj.CipherSuite) (minio.ObjectLayer, *kvmetainfo.DB, streams.Store, error) {
|
||||
apiKey := planet.Uplinks[0].APIKey[planet.Satellites[0].ID()]
|
||||
|
||||
m, err := planet.Uplinks[0].DialMetainfo(ctx, planet.Satellites[0], apiKey)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
// TODO(leak): close m metainfo.Client somehow
|
||||
|
||||
access, err := uplink.RequestAccessWithPassphrase(ctx, planet.Satellites[0].URL().String(), apiKey.Serialize(), "passphrase")
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
|
||||
serializedAccess, err := access.Serialize()
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
|
||||
oldAccess, err := olduplink.ParseScope(serializedAccess)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
oldAccess.EncryptionAccess.SetDefaultPathCipher(pathCipher)
|
||||
encStore := oldAccess.EncryptionAccess.Store()
|
||||
|
||||
serializedOldAccess, err := oldAccess.Serialize()
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
|
||||
// workaround to set proper path cipher for uplink.Access
|
||||
access, err = uplink.ParseAccess(serializedOldAccess)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
|
||||
ec := ecclient.NewClient(planet.Uplinks[0].Log.Named("ecclient"), planet.Uplinks[0].Dialer, 0)
|
||||
|
||||
segments := segments.NewSegmentStore(m, ec)
|
||||
|
||||
blockSize := 1 * memory.KiB.Int()
|
||||
inlineThreshold := 4 * memory.KiB.Int()
|
||||
strms, err := streams.NewStreamStore(m, segments, 64*memory.MiB.Int64(), encStore, blockSize, storj.EncAESGCM, inlineThreshold, 8*memory.MiB.Int64())
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
|
||||
p, err := kvmetainfo.SetupProject(m)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
kvm := kvmetainfo.New(p, m, strms, segments, encStore)
|
||||
|
||||
project, err := uplink.OpenProject(ctx, access)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
|
||||
gateway := miniogw.NewStorjGateway(project)
|
||||
layer, err := gateway.NewGatewayLayer(auth.Credentials{})
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
return layer, kvm, strms, err
|
||||
}
|
||||
|
||||
func createFile(ctx context.Context, m *kvmetainfo.DB, strms streams.Store, bucket storj.Bucket, path storj.Path, createInfo *kvmetainfo.CreateObject, data []byte) (storj.Object, error) {
|
||||
mutableObject, err := m.CreateObject(ctx, bucket, path, createInfo)
|
||||
if err != nil {
|
||||
return storj.Object{}, err
|
||||
}
|
||||
|
||||
err = upload(ctx, strms, mutableObject, bytes.NewReader(data))
|
||||
if err != nil {
|
||||
return storj.Object{}, err
|
||||
}
|
||||
|
||||
err = mutableObject.Commit(ctx)
|
||||
if err != nil {
|
||||
return storj.Object{}, err
|
||||
}
|
||||
|
||||
return mutableObject.Info(), nil
|
||||
}
|
||||
|
||||
func upload(ctx context.Context, streams streams.Store, mutableObject kvmetainfo.MutableObject, reader io.Reader) error {
|
||||
mutableStream, err := mutableObject.CreateStream(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
upload := stream.NewUpload(ctx, mutableStream, streams)
|
||||
|
||||
_, err = io.Copy(upload, reader)
|
||||
|
||||
return errs.Wrap(errs.Combine(err, upload.Close()))
|
||||
}
|
@ -1,162 +0,0 @@
|
||||
// Copyright (C) 2019 Storj Labs, Inc.
|
||||
// See LICENSE for copying information.
|
||||
|
||||
package miniogw_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"flag"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/minio/cli"
|
||||
minio "github.com/minio/minio/cmd"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.uber.org/zap"
|
||||
"go.uber.org/zap/zaptest"
|
||||
|
||||
"storj.io/common/identity"
|
||||
"storj.io/common/identity/testidentity"
|
||||
"storj.io/common/testcontext"
|
||||
"storj.io/storj/cmd/uplink/cmd"
|
||||
"storj.io/storj/pkg/miniogw"
|
||||
"storj.io/storj/private/s3client"
|
||||
"storj.io/storj/private/testplanet"
|
||||
"storj.io/storj/satellite/console"
|
||||
"storj.io/uplink"
|
||||
)
|
||||
|
||||
type config struct {
|
||||
Server miniogw.ServerConfig
|
||||
Minio miniogw.MinioConfig
|
||||
}
|
||||
|
||||
func TestUploadDownload(t *testing.T) {
|
||||
t.Skip("disable because, keeps stalling CI intermittently")
|
||||
|
||||
testplanet.Run(t, testplanet.Config{
|
||||
SatelliteCount: 1, StorageNodeCount: 4, UplinkCount: 1,
|
||||
}, func(t *testing.T, ctx *testcontext.Context, planet *testplanet.Planet) {
|
||||
// add project to satisfy constraint
|
||||
_, err := planet.Satellites[0].DB.Console().Projects().Insert(ctx, &console.Project{
|
||||
Name: "testProject",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
var gwCfg config
|
||||
gwCfg.Minio.Dir = ctx.Dir("minio")
|
||||
gwCfg.Server.Address = "127.0.0.1:7777"
|
||||
|
||||
uplinkCfg := planet.Uplinks[0].GetConfig(planet.Satellites[0])
|
||||
|
||||
planet.Start(ctx)
|
||||
|
||||
// create identity for gateway
|
||||
ca, err := testidentity.NewTestCA(ctx)
|
||||
assert.NoError(t, err)
|
||||
identity, err := ca.NewIdentity()
|
||||
assert.NoError(t, err)
|
||||
|
||||
// setup and start gateway
|
||||
go func() {
|
||||
// TODO: this leaks the gateway server, however it shouldn't
|
||||
err := runGateway(ctx, gwCfg, uplinkCfg, zaptest.NewLogger(t), identity)
|
||||
if err != nil {
|
||||
t.Log(err)
|
||||
}
|
||||
}()
|
||||
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
|
||||
client, err := s3client.NewMinio(s3client.Config{
|
||||
S3Gateway: gwCfg.Server.Address,
|
||||
Satellite: planet.Satellites[0].Addr(),
|
||||
AccessKey: gwCfg.Minio.AccessKey,
|
||||
SecretKey: gwCfg.Minio.SecretKey,
|
||||
APIKey: uplinkCfg.Legacy.Client.APIKey,
|
||||
EncryptionKey: "fake-encryption-key",
|
||||
NoSSL: true,
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
|
||||
bucket := "bucket"
|
||||
|
||||
err = client.MakeBucket(bucket, "")
|
||||
assert.NoError(t, err)
|
||||
|
||||
// generate enough data for a remote segment
|
||||
data := []byte{}
|
||||
for i := 0; i < 5000; i++ {
|
||||
data = append(data, 'a')
|
||||
}
|
||||
|
||||
objectName := "testdata"
|
||||
|
||||
err = client.Upload(bucket, objectName, data)
|
||||
assert.NoError(t, err)
|
||||
|
||||
buffer := make([]byte, len(data))
|
||||
|
||||
bytes, err := client.Download(bucket, objectName, buffer)
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.Equal(t, string(data), string(bytes))
|
||||
})
|
||||
}
|
||||
|
||||
// runGateway creates and starts a gateway
|
||||
func runGateway(ctx context.Context, gwCfg config, uplinkCfg cmd.Config, log *zap.Logger, ident *identity.FullIdentity) (err error) {
|
||||
|
||||
// set gateway flags
|
||||
flags := flag.NewFlagSet("gateway", flag.ExitOnError)
|
||||
flags.String("address", gwCfg.Server.Address, "")
|
||||
flags.String("config-dir", gwCfg.Minio.Dir, "")
|
||||
flags.Bool("quiet", true, "")
|
||||
|
||||
// create *cli.Context with gateway flags
|
||||
cliCtx := cli.NewContext(cli.NewApp(), flags, nil)
|
||||
|
||||
// TODO: setting the flag on flagset and cliCtx seems redundant, but output is not quiet otherwise
|
||||
err = cliCtx.Set("quiet", "true")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = os.Setenv("MINIO_ACCESS_KEY", gwCfg.Minio.AccessKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = os.Setenv("MINIO_SECRET_KEY", gwCfg.Minio.SecretKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
oldAccess, err := uplinkCfg.GetAccess()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
serializedAccess, err := oldAccess.Serialize()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
access, err := uplink.ParseAccess(serializedAccess)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
project, err := uplink.OpenProject(ctx, access)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
gw := miniogw.NewStorjGateway(project)
|
||||
|
||||
minio.StartGateway(cliCtx, miniogw.Logging(gw, log))
|
||||
return errors.New("unexpected minio exit")
|
||||
}
|
@ -1,208 +0,0 @@
|
||||
// Copyright (C) 2019 Storj Labs, Inc.
|
||||
// See LICENSE for copying information.
|
||||
|
||||
package miniogw
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"reflect"
|
||||
"time"
|
||||
|
||||
minio "github.com/minio/minio/cmd"
|
||||
"github.com/minio/minio/pkg/auth"
|
||||
"github.com/minio/minio/pkg/hash"
|
||||
"github.com/minio/minio/pkg/madmin"
|
||||
"github.com/minio/minio/pkg/policy"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type gatewayLogging struct {
|
||||
gateway minio.Gateway
|
||||
log *zap.Logger
|
||||
}
|
||||
|
||||
// Logging returns a wrapper of minio.Gateway that logs errors before returning them.
|
||||
func Logging(gateway minio.Gateway, log *zap.Logger) minio.Gateway {
|
||||
return &gatewayLogging{gateway, log}
|
||||
}
|
||||
|
||||
func (lg *gatewayLogging) Name() string { return lg.gateway.Name() }
|
||||
func (lg *gatewayLogging) Production() bool { return lg.gateway.Production() }
|
||||
func (lg *gatewayLogging) NewGatewayLayer(creds auth.Credentials) (minio.ObjectLayer, error) {
|
||||
layer, err := lg.gateway.NewGatewayLayer(creds)
|
||||
return &layerLogging{layer: layer, logger: lg.log}, err
|
||||
}
|
||||
|
||||
type layerLogging struct {
|
||||
layer minio.ObjectLayer
|
||||
logger *zap.Logger
|
||||
}
|
||||
|
||||
// minioError checks if the given error is a minio error.
|
||||
func minioError(err error) bool {
|
||||
return reflect.TypeOf(err).ConvertibleTo(reflect.TypeOf(minio.GenericError{}))
|
||||
}
|
||||
|
||||
// log unexpected errors, i.e. non-minio errors. It will return the given error
|
||||
// to allow method chaining.
|
||||
func (log *layerLogging) log(err error) error {
|
||||
if err != nil && !minioError(err) {
|
||||
log.logger.Error("gateway error:", zap.Error(err))
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (log *layerLogging) Shutdown(ctx context.Context) error {
|
||||
return log.log(log.layer.Shutdown(ctx))
|
||||
}
|
||||
|
||||
func (log *layerLogging) StorageInfo(ctx context.Context) minio.StorageInfo {
|
||||
return log.layer.StorageInfo(ctx)
|
||||
}
|
||||
|
||||
func (log *layerLogging) MakeBucketWithLocation(ctx context.Context, bucket string, location string) error {
|
||||
return log.log(log.layer.MakeBucketWithLocation(ctx, bucket, location))
|
||||
}
|
||||
|
||||
func (log *layerLogging) GetBucketInfo(ctx context.Context, bucket string) (bucketInfo minio.BucketInfo, err error) {
|
||||
bucketInfo, err = log.layer.GetBucketInfo(ctx, bucket)
|
||||
return bucketInfo, log.log(err)
|
||||
}
|
||||
|
||||
func (log *layerLogging) ListBuckets(ctx context.Context) (buckets []minio.BucketInfo, err error) {
|
||||
buckets, err = log.layer.ListBuckets(ctx)
|
||||
return buckets, log.log(err)
|
||||
}
|
||||
|
||||
func (log *layerLogging) DeleteBucket(ctx context.Context, bucket string) error {
|
||||
return log.log(log.layer.DeleteBucket(ctx, bucket))
|
||||
}
|
||||
|
||||
func (log *layerLogging) ListObjects(ctx context.Context, bucket, prefix, marker, delimiter string, maxKeys int) (result minio.ListObjectsInfo, err error) {
|
||||
result, err = log.layer.ListObjects(ctx, bucket, prefix, marker, delimiter,
|
||||
maxKeys)
|
||||
return result, log.log(err)
|
||||
}
|
||||
|
||||
func (log *layerLogging) ListObjectsV2(ctx context.Context, bucket, prefix, continuationToken, delimiter string, maxKeys int, fetchOwner bool, startAfter string) (result minio.ListObjectsV2Info, err error) {
|
||||
result, err = log.layer.ListObjectsV2(ctx, bucket, prefix, continuationToken, delimiter, maxKeys, fetchOwner, startAfter)
|
||||
return result, log.log(err)
|
||||
}
|
||||
|
||||
func (log *layerLogging) GetObject(ctx context.Context, bucket, object string, startOffset int64, length int64, writer io.Writer, etag string) (err error) {
|
||||
return log.log(log.layer.GetObject(ctx, bucket, object, startOffset, length, writer, etag))
|
||||
}
|
||||
|
||||
func (log *layerLogging) GetObjectInfo(ctx context.Context, bucket, object string) (objInfo minio.ObjectInfo, err error) {
|
||||
objInfo, err = log.layer.GetObjectInfo(ctx, bucket, object)
|
||||
return objInfo, log.log(err)
|
||||
}
|
||||
|
||||
func (log *layerLogging) PutObject(ctx context.Context, bucket, object string, data *hash.Reader, metadata map[string]string) (objInfo minio.ObjectInfo, err error) {
|
||||
objInfo, err = log.layer.PutObject(ctx, bucket, object, data, metadata)
|
||||
return objInfo, log.log(err)
|
||||
}
|
||||
|
||||
func (log *layerLogging) CopyObject(ctx context.Context, srcBucket, srcObject, destBucket, destObject string, srcInfo minio.ObjectInfo) (objInfo minio.ObjectInfo, err error) {
|
||||
objInfo, err = log.layer.CopyObject(ctx, srcBucket, srcObject, destBucket, destObject, srcInfo)
|
||||
return objInfo, log.log(err)
|
||||
}
|
||||
|
||||
func (log *layerLogging) DeleteObject(ctx context.Context, bucket, object string) (err error) {
|
||||
return log.log(log.layer.DeleteObject(ctx, bucket, object))
|
||||
}
|
||||
|
||||
func (log *layerLogging) ListMultipartUploads(ctx context.Context, bucket, prefix, keyMarker, uploadIDMarker, delimiter string, maxUploads int) (result minio.ListMultipartsInfo, err error) {
|
||||
result, err = log.layer.ListMultipartUploads(ctx, bucket, prefix, keyMarker, uploadIDMarker, delimiter, maxUploads)
|
||||
return result, log.log(err)
|
||||
}
|
||||
|
||||
func (log *layerLogging) NewMultipartUpload(ctx context.Context, bucket, object string, metadata map[string]string) (uploadID string, err error) {
|
||||
uploadID, err = log.layer.NewMultipartUpload(ctx, bucket, object, metadata)
|
||||
return uploadID, log.log(err)
|
||||
}
|
||||
|
||||
func (log *layerLogging) CopyObjectPart(ctx context.Context, srcBucket, srcObject, destBucket, destObject string, uploadID string, partID int, startOffset int64, length int64, srcInfo minio.ObjectInfo) (info minio.PartInfo, err error) {
|
||||
info, err = log.layer.CopyObjectPart(ctx, srcBucket, srcObject, destBucket, destObject, uploadID, partID, startOffset, length, srcInfo)
|
||||
return info, log.log(err)
|
||||
}
|
||||
|
||||
func (log *layerLogging) PutObjectPart(ctx context.Context, bucket, object, uploadID string, partID int, data *hash.Reader) (info minio.PartInfo, err error) {
|
||||
info, err = log.layer.PutObjectPart(ctx, bucket, object, uploadID, partID, data)
|
||||
return info, log.log(err)
|
||||
}
|
||||
|
||||
func (log *layerLogging) ListObjectParts(ctx context.Context, bucket, object, uploadID string, partNumberMarker int, maxParts int) (result minio.ListPartsInfo, err error) {
|
||||
result, err = log.layer.ListObjectParts(ctx, bucket, object, uploadID,
|
||||
partNumberMarker, maxParts)
|
||||
return result, log.log(err)
|
||||
}
|
||||
|
||||
func (log *layerLogging) AbortMultipartUpload(ctx context.Context, bucket, object, uploadID string) error {
|
||||
return log.log(log.layer.AbortMultipartUpload(ctx, bucket, object, uploadID))
|
||||
}
|
||||
|
||||
func (log *layerLogging) CompleteMultipartUpload(ctx context.Context, bucket, object, uploadID string, uploadedParts []minio.CompletePart) (objInfo minio.ObjectInfo, err error) {
|
||||
objInfo, err = log.layer.CompleteMultipartUpload(ctx, bucket, object, uploadID, uploadedParts)
|
||||
return objInfo, log.log(err)
|
||||
}
|
||||
|
||||
func (log *layerLogging) ReloadFormat(ctx context.Context, dryRun bool) error {
|
||||
return log.log(log.layer.ReloadFormat(ctx, dryRun))
|
||||
}
|
||||
|
||||
func (log *layerLogging) HealFormat(ctx context.Context, dryRun bool) (madmin.HealResultItem, error) {
|
||||
rv, err := log.layer.HealFormat(ctx, dryRun)
|
||||
return rv, log.log(err)
|
||||
}
|
||||
|
||||
func (log *layerLogging) HealBucket(ctx context.Context, bucket string, dryRun bool) ([]madmin.HealResultItem, error) {
|
||||
rv, err := log.layer.HealBucket(ctx, bucket, dryRun)
|
||||
return rv, log.log(err)
|
||||
}
|
||||
|
||||
func (log *layerLogging) HealObject(ctx context.Context, bucket, object string, dryRun bool) (madmin.HealResultItem, error) {
|
||||
rv, err := log.layer.HealObject(ctx, bucket, object, dryRun)
|
||||
return rv, log.log(err)
|
||||
}
|
||||
|
||||
func (log *layerLogging) ListBucketsHeal(ctx context.Context) (buckets []minio.BucketInfo, err error) {
|
||||
buckets, err = log.layer.ListBucketsHeal(ctx)
|
||||
return buckets, log.log(err)
|
||||
}
|
||||
|
||||
func (log *layerLogging) ListObjectsHeal(ctx context.Context, bucket, prefix, marker, delimiter string, maxKeys int) (minio.ListObjectsInfo, error) {
|
||||
rv, err := log.layer.ListObjectsHeal(ctx, bucket, prefix, marker, delimiter, maxKeys)
|
||||
return rv, log.log(err)
|
||||
}
|
||||
|
||||
func (log *layerLogging) ListLocks(ctx context.Context, bucket, prefix string, duration time.Duration) ([]minio.VolumeLockInfo, error) {
|
||||
rv, err := log.layer.ListLocks(ctx, bucket, prefix, duration)
|
||||
return rv, log.log(err)
|
||||
}
|
||||
|
||||
func (log *layerLogging) ClearLocks(ctx context.Context, lockInfos []minio.VolumeLockInfo) error {
|
||||
return log.log(log.layer.ClearLocks(ctx, lockInfos))
|
||||
}
|
||||
|
||||
func (log *layerLogging) SetBucketPolicy(ctx context.Context, n string, p *policy.Policy) error {
|
||||
return log.log(log.layer.SetBucketPolicy(ctx, n, p))
|
||||
}
|
||||
|
||||
func (log *layerLogging) GetBucketPolicy(ctx context.Context, n string) (*policy.Policy, error) {
|
||||
p, err := log.layer.GetBucketPolicy(ctx, n)
|
||||
return p, log.log(err)
|
||||
}
|
||||
|
||||
func (log *layerLogging) DeleteBucketPolicy(ctx context.Context, n string) error {
|
||||
return log.log(log.layer.DeleteBucketPolicy(ctx, n))
|
||||
}
|
||||
|
||||
func (log *layerLogging) IsNotificationSupported() bool {
|
||||
return log.layer.IsNotificationSupported()
|
||||
}
|
||||
|
||||
func (log *layerLogging) IsEncryptionSupported() bool {
|
||||
return log.layer.IsEncryptionSupported()
|
||||
}
|
@ -1,475 +0,0 @@
|
||||
// Copyright (C) 2019 Storj Labs, Inc.
|
||||
// See LICENSE for copying information.
|
||||
|
||||
package miniogw
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"sort"
|
||||
"strconv"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
minio "github.com/minio/minio/cmd"
|
||||
"github.com/minio/minio/pkg/hash"
|
||||
"github.com/zeebo/errs"
|
||||
|
||||
"storj.io/uplink"
|
||||
)
|
||||
|
||||
func (layer *gatewayLayer) NewMultipartUpload(ctx context.Context, bucket, object string, metadata map[string]string) (uploadID string, err error) {
|
||||
defer mon.Task()(&ctx)(&err)
|
||||
|
||||
uploads := layer.gateway.multipart
|
||||
|
||||
upload, err := uploads.Create(bucket, object, metadata)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// TODO: this can now be done without this separate goroutine
|
||||
|
||||
go func() {
|
||||
stream, err := layer.gateway.project.UploadObject(ctx, bucket, object, nil)
|
||||
if err != nil {
|
||||
uploads.RemoveByID(upload.ID)
|
||||
upload.fail(err)
|
||||
return
|
||||
}
|
||||
|
||||
// TODO: should we add prefixes to metadata?
|
||||
// TODO: are there other fields we can extract to standard?
|
||||
contentType := metadata["content-type"]
|
||||
delete(metadata, "content-type")
|
||||
|
||||
err = stream.SetMetadata(ctx, &uplink.StandardMetadata{
|
||||
ContentType: contentType,
|
||||
}, metadata)
|
||||
if err != nil {
|
||||
uploads.RemoveByID(upload.ID)
|
||||
abortErr := stream.Abort()
|
||||
upload.fail(errs.Combine(err, abortErr))
|
||||
return
|
||||
}
|
||||
|
||||
_, err = io.Copy(stream, upload.Stream)
|
||||
uploads.RemoveByID(upload.ID)
|
||||
|
||||
if err != nil {
|
||||
abortErr := stream.Abort()
|
||||
upload.fail(errs.Combine(err, abortErr))
|
||||
return
|
||||
}
|
||||
|
||||
err = stream.Commit()
|
||||
if err != nil {
|
||||
upload.fail(errs.Combine(err, err))
|
||||
return
|
||||
}
|
||||
|
||||
// TODO how set ETag here
|
||||
upload.complete(minioObjectInfo(bucket, "", stream.Info()))
|
||||
}()
|
||||
|
||||
return upload.ID, nil
|
||||
}
|
||||
|
||||
func (layer *gatewayLayer) PutObjectPart(ctx context.Context, bucket, object, uploadID string, partID int, data *hash.Reader) (info minio.PartInfo, err error) {
|
||||
defer mon.Task()(&ctx)(&err)
|
||||
|
||||
uploads := layer.gateway.multipart
|
||||
|
||||
upload, err := uploads.Get(bucket, object, uploadID)
|
||||
if err != nil {
|
||||
return minio.PartInfo{}, err
|
||||
}
|
||||
|
||||
part, err := upload.Stream.AddPart(partID, data)
|
||||
if err != nil {
|
||||
return minio.PartInfo{}, err
|
||||
}
|
||||
|
||||
err = <-part.Done
|
||||
if err != nil {
|
||||
return minio.PartInfo{}, err
|
||||
}
|
||||
|
||||
partInfo := minio.PartInfo{
|
||||
PartNumber: part.Number,
|
||||
LastModified: time.Now(),
|
||||
ETag: data.SHA256HexString(),
|
||||
Size: atomic.LoadInt64(&part.Size),
|
||||
}
|
||||
|
||||
upload.addCompletedPart(partInfo)
|
||||
|
||||
return partInfo, nil
|
||||
}
|
||||
|
||||
func (layer *gatewayLayer) AbortMultipartUpload(ctx context.Context, bucket, object, uploadID string) (err error) {
|
||||
defer mon.Task()(&ctx)(&err)
|
||||
|
||||
uploads := layer.gateway.multipart
|
||||
|
||||
upload, err := uploads.Remove(bucket, object, uploadID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
errAbort := Error.New("abort")
|
||||
upload.Stream.Abort(errAbort)
|
||||
r := <-upload.Done
|
||||
if r.Error != errAbort {
|
||||
return r.Error
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (layer *gatewayLayer) CompleteMultipartUpload(ctx context.Context, bucket, object, uploadID string, uploadedParts []minio.CompletePart) (objInfo minio.ObjectInfo, err error) {
|
||||
defer mon.Task()(&ctx)(&err)
|
||||
|
||||
uploads := layer.gateway.multipart
|
||||
upload, err := uploads.Remove(bucket, object, uploadID)
|
||||
if err != nil {
|
||||
return minio.ObjectInfo{}, err
|
||||
}
|
||||
|
||||
// notify stream that there aren't more parts coming
|
||||
upload.Stream.Close()
|
||||
// wait for completion
|
||||
result := <-upload.Done
|
||||
// return the final info
|
||||
return result.Info, result.Error
|
||||
}
|
||||
|
||||
func (layer *gatewayLayer) ListObjectParts(ctx context.Context, bucket, object, uploadID string, partNumberMarker int, maxParts int) (result minio.ListPartsInfo, err error) {
|
||||
defer mon.Task()(&ctx)(&err)
|
||||
|
||||
uploads := layer.gateway.multipart
|
||||
upload, err := uploads.Get(bucket, object, uploadID)
|
||||
if err != nil {
|
||||
return minio.ListPartsInfo{}, err
|
||||
}
|
||||
|
||||
list := minio.ListPartsInfo{}
|
||||
|
||||
list.Bucket = bucket
|
||||
list.Object = object
|
||||
list.UploadID = uploadID
|
||||
list.PartNumberMarker = partNumberMarker
|
||||
list.MaxParts = maxParts
|
||||
list.UserDefined = upload.Metadata
|
||||
list.Parts = upload.getCompletedParts()
|
||||
|
||||
sort.Slice(list.Parts, func(i, k int) bool {
|
||||
return list.Parts[i].PartNumber < list.Parts[k].PartNumber
|
||||
})
|
||||
|
||||
var first int
|
||||
for i, p := range list.Parts {
|
||||
first = i
|
||||
if partNumberMarker <= p.PartNumber {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
list.Parts = list.Parts[first:]
|
||||
if len(list.Parts) > maxParts {
|
||||
list.NextPartNumberMarker = list.Parts[maxParts].PartNumber
|
||||
list.Parts = list.Parts[:maxParts]
|
||||
list.IsTruncated = true
|
||||
}
|
||||
|
||||
return list, nil
|
||||
}
|
||||
|
||||
// TODO: implement
|
||||
// func (layer *gatewayLayer) ListMultipartUploads(ctx context.Context, bucket, prefix, keyMarker, uploadIDMarker, delimiter string, maxUploads int) (result minio.ListMultipartsInfo, err error) {
|
||||
// func (layer *gatewayLayer) CopyObjectPart(ctx context.Context, srcBucket, srcObject, destBucket, destObject string, uploadID string, partID int, startOffset int64, length int64, srcInfo minio.ObjectInfo) (info minio.PartInfo, err error) {
|
||||
|
||||
// MultipartUploads manages pending multipart uploads
|
||||
type MultipartUploads struct {
|
||||
mu sync.RWMutex
|
||||
lastID int
|
||||
pending map[string]*MultipartUpload
|
||||
}
|
||||
|
||||
// NewMultipartUploads creates new MultipartUploads
|
||||
func NewMultipartUploads() *MultipartUploads {
|
||||
return &MultipartUploads{
|
||||
pending: map[string]*MultipartUpload{},
|
||||
}
|
||||
}
|
||||
|
||||
// Create creates a new upload
|
||||
func (uploads *MultipartUploads) Create(bucket, object string, metadata map[string]string) (*MultipartUpload, error) {
|
||||
uploads.mu.Lock()
|
||||
defer uploads.mu.Unlock()
|
||||
|
||||
for id, upload := range uploads.pending {
|
||||
if upload.Bucket == bucket && upload.Object == object {
|
||||
upload.Stream.Abort(Error.New("aborted by another upload to the same location"))
|
||||
delete(uploads.pending, id)
|
||||
}
|
||||
}
|
||||
|
||||
uploads.lastID++
|
||||
uploadID := "Upload" + strconv.Itoa(uploads.lastID)
|
||||
|
||||
upload := NewMultipartUpload(uploadID, bucket, object, metadata)
|
||||
uploads.pending[uploadID] = upload
|
||||
|
||||
return upload, nil
|
||||
}
|
||||
|
||||
// Get finds a pending upload
|
||||
func (uploads *MultipartUploads) Get(bucket, object, uploadID string) (*MultipartUpload, error) {
|
||||
uploads.mu.Lock()
|
||||
defer uploads.mu.Unlock()
|
||||
|
||||
upload, ok := uploads.pending[uploadID]
|
||||
if !ok {
|
||||
return nil, Error.New("pending upload %q missing", uploadID)
|
||||
}
|
||||
if upload.Bucket != bucket || upload.Object != object {
|
||||
return nil, Error.New("pending upload %q bucket/object name mismatch", uploadID)
|
||||
}
|
||||
|
||||
return upload, nil
|
||||
}
|
||||
|
||||
// Remove returns and removes a pending upload
|
||||
func (uploads *MultipartUploads) Remove(bucket, object, uploadID string) (*MultipartUpload, error) {
|
||||
uploads.mu.RLock()
|
||||
defer uploads.mu.RUnlock()
|
||||
|
||||
upload, ok := uploads.pending[uploadID]
|
||||
if !ok {
|
||||
return nil, Error.New("pending upload %q missing", uploadID)
|
||||
}
|
||||
if upload.Bucket != bucket || upload.Object != object {
|
||||
return nil, Error.New("pending upload %q bucket/object name mismatch", uploadID)
|
||||
}
|
||||
|
||||
delete(uploads.pending, uploadID)
|
||||
|
||||
return upload, nil
|
||||
}
|
||||
|
||||
// RemoveByID removes pending upload by id
|
||||
func (uploads *MultipartUploads) RemoveByID(uploadID string) {
|
||||
uploads.mu.RLock()
|
||||
defer uploads.mu.RUnlock()
|
||||
delete(uploads.pending, uploadID)
|
||||
}
|
||||
|
||||
// MultipartUpload is partial info about a pending upload
|
||||
type MultipartUpload struct {
|
||||
ID string
|
||||
Bucket string
|
||||
Object string
|
||||
Metadata map[string]string
|
||||
Done chan (*MultipartUploadResult)
|
||||
Stream *MultipartStream
|
||||
|
||||
mu sync.Mutex
|
||||
completed []minio.PartInfo
|
||||
}
|
||||
|
||||
// MultipartUploadResult contains either an Error or the uploaded ObjectInfo
|
||||
type MultipartUploadResult struct {
|
||||
Error error
|
||||
Info minio.ObjectInfo
|
||||
}
|
||||
|
||||
// NewMultipartUpload creates a new MultipartUpload
|
||||
func NewMultipartUpload(uploadID string, bucket, object string, metadata map[string]string) *MultipartUpload {
|
||||
upload := &MultipartUpload{
|
||||
ID: uploadID,
|
||||
Bucket: bucket,
|
||||
Object: object,
|
||||
Metadata: metadata,
|
||||
Done: make(chan *MultipartUploadResult, 1),
|
||||
Stream: NewMultipartStream(),
|
||||
}
|
||||
return upload
|
||||
}
|
||||
|
||||
// addCompletedPart adds a completed part to the list
|
||||
func (upload *MultipartUpload) addCompletedPart(part minio.PartInfo) {
|
||||
upload.mu.Lock()
|
||||
defer upload.mu.Unlock()
|
||||
|
||||
upload.completed = append(upload.completed, part)
|
||||
}
|
||||
|
||||
func (upload *MultipartUpload) getCompletedParts() []minio.PartInfo {
|
||||
upload.mu.Lock()
|
||||
defer upload.mu.Unlock()
|
||||
|
||||
return append([]minio.PartInfo{}, upload.completed...)
|
||||
}
|
||||
|
||||
// fail aborts the upload with an error
|
||||
func (upload *MultipartUpload) fail(err error) {
|
||||
upload.Done <- &MultipartUploadResult{Error: err}
|
||||
close(upload.Done)
|
||||
}
|
||||
|
||||
// complete completes the upload
|
||||
func (upload *MultipartUpload) complete(info minio.ObjectInfo) {
|
||||
upload.Done <- &MultipartUploadResult{Info: info}
|
||||
close(upload.Done)
|
||||
}
|
||||
|
||||
// MultipartStream serializes multiple readers into a single reader
|
||||
type MultipartStream struct {
|
||||
mu sync.Mutex
|
||||
moreParts sync.Cond
|
||||
err error
|
||||
closed bool
|
||||
finished bool
|
||||
nextID int
|
||||
nextNumber int
|
||||
currentPart *StreamPart
|
||||
parts []*StreamPart
|
||||
}
|
||||
|
||||
// StreamPart is a reader waiting in MultipartStream
|
||||
type StreamPart struct {
|
||||
Number int
|
||||
ID int
|
||||
Size int64
|
||||
Reader *hash.Reader
|
||||
Done chan error
|
||||
}
|
||||
|
||||
// NewMultipartStream creates a new MultipartStream
|
||||
func NewMultipartStream() *MultipartStream {
|
||||
stream := &MultipartStream{}
|
||||
stream.moreParts.L = &stream.mu
|
||||
stream.nextID = 1
|
||||
return stream
|
||||
}
|
||||
|
||||
// Abort aborts the stream reading
|
||||
func (stream *MultipartStream) Abort(err error) {
|
||||
stream.mu.Lock()
|
||||
defer stream.mu.Unlock()
|
||||
|
||||
if stream.finished {
|
||||
return
|
||||
}
|
||||
|
||||
if stream.err == nil {
|
||||
stream.err = err
|
||||
}
|
||||
stream.finished = true
|
||||
stream.closed = true
|
||||
|
||||
for _, part := range stream.parts {
|
||||
part.Done <- err
|
||||
close(part.Done)
|
||||
}
|
||||
stream.parts = nil
|
||||
|
||||
stream.moreParts.Broadcast()
|
||||
}
|
||||
|
||||
// Close closes the stream, but lets it complete
|
||||
func (stream *MultipartStream) Close() {
|
||||
stream.mu.Lock()
|
||||
defer stream.mu.Unlock()
|
||||
|
||||
stream.closed = true
|
||||
stream.moreParts.Broadcast()
|
||||
}
|
||||
|
||||
// Read implements io.Reader interface, blocking when there's no part
|
||||
func (stream *MultipartStream) Read(data []byte) (n int, err error) {
|
||||
stream.mu.Lock()
|
||||
for {
|
||||
// has an error occurred?
|
||||
if stream.err != nil {
|
||||
stream.mu.Unlock()
|
||||
return 0, Error.Wrap(err)
|
||||
}
|
||||
// still uploading the current part?
|
||||
if stream.currentPart != nil {
|
||||
break
|
||||
}
|
||||
// do we have the next part?
|
||||
if len(stream.parts) > 0 && stream.nextID == stream.parts[0].ID {
|
||||
stream.currentPart = stream.parts[0]
|
||||
stream.parts = stream.parts[1:]
|
||||
stream.nextID++
|
||||
break
|
||||
}
|
||||
// we don't have the next part and are closed, hence we are complete
|
||||
if stream.closed {
|
||||
stream.finished = true
|
||||
stream.mu.Unlock()
|
||||
return 0, io.EOF
|
||||
}
|
||||
|
||||
stream.moreParts.Wait()
|
||||
}
|
||||
stream.mu.Unlock()
|
||||
|
||||
// read as much as we can
|
||||
n, err = stream.currentPart.Reader.Read(data)
|
||||
atomic.AddInt64(&stream.currentPart.Size, int64(n))
|
||||
|
||||
if err == io.EOF {
|
||||
// the part completed, hence advance to the next one
|
||||
err = nil
|
||||
close(stream.currentPart.Done)
|
||||
stream.currentPart = nil
|
||||
} else if err != nil {
|
||||
// something bad happened, abort the whole thing
|
||||
stream.Abort(err)
|
||||
return n, Error.Wrap(err)
|
||||
}
|
||||
|
||||
return n, err
|
||||
}
|
||||
|
||||
// AddPart adds a new part to the stream to wait
|
||||
func (stream *MultipartStream) AddPart(partID int, data *hash.Reader) (*StreamPart, error) {
|
||||
stream.mu.Lock()
|
||||
defer stream.mu.Unlock()
|
||||
|
||||
if partID < stream.nextID {
|
||||
return nil, Error.New("part %d already uploaded, next part ID is %d", partID, stream.nextID)
|
||||
}
|
||||
|
||||
for _, p := range stream.parts {
|
||||
if p.ID == partID {
|
||||
// Replace the reader of this part with the new one.
|
||||
// This could happen if the read timeout for this part has expired
|
||||
// and the client tries to upload the part again.
|
||||
p.Reader = data
|
||||
return p, nil
|
||||
}
|
||||
}
|
||||
|
||||
stream.nextNumber++
|
||||
part := &StreamPart{
|
||||
Number: stream.nextNumber - 1,
|
||||
ID: partID,
|
||||
Size: 0,
|
||||
Reader: data,
|
||||
Done: make(chan error, 1),
|
||||
}
|
||||
|
||||
stream.parts = append(stream.parts, part)
|
||||
sort.Slice(stream.parts, func(i, k int) bool {
|
||||
return stream.parts[i].ID < stream.parts[k].ID
|
||||
})
|
||||
|
||||
stream.moreParts.Broadcast()
|
||||
|
||||
return part, nil
|
||||
}
|
@ -1,6 +1,11 @@
|
||||
// Copyright (C) 2019 Storj Labs, Inc.
|
||||
// See LICENSE for copying information.
|
||||
|
||||
// This is disabled for the time-being to allow removing minio dependencies from
|
||||
// storj.io/storj package.
|
||||
|
||||
// +build ignore
|
||||
|
||||
package s3client
|
||||
|
||||
import (
|
||||
|
@ -99,7 +99,7 @@ install_sim(){
|
||||
go install -race -v -o ${bin_dir}/storj-sim storj.io/storj/cmd/storj-sim >/dev/null 2>&1
|
||||
go install -race -v -o ${bin_dir}/versioncontrol storj.io/storj/cmd/versioncontrol >/dev/null 2>&1
|
||||
go install -race -v -o ${bin_dir}/uplink storj.io/storj/cmd/uplink >/dev/null 2>&1
|
||||
go install -race -v -o ${bin_dir}/gateway storj.io/storj/cmd/gateway >/dev/null 2>&1
|
||||
cd ${scriptdir}/../../../cmd/gateway && go install -race -v -o ${bin_dir}/gateway storj.io/storj/cmd/gateway >/dev/null 2>&1
|
||||
go install -race -v -o ${bin_dir}/identity storj.io/storj/cmd/identity >/dev/null 2>&1
|
||||
go install -race -v -o ${bin_dir}/certificates storj.io/storj/cmd/certificates >/dev/null 2>&1
|
||||
|
||||
@ -179,6 +179,8 @@ fi
|
||||
|
||||
echo "Setting up environments for versions" ${unique_versions}
|
||||
|
||||
scriptdir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||
|
||||
# Get latest release tags and clean up git worktree
|
||||
git worktree prune
|
||||
for version in ${unique_versions}; do
|
||||
@ -218,10 +220,10 @@ for version in ${unique_versions}; do
|
||||
mkdir -p ${bin_dir}
|
||||
# uncomment for Jenkins testing:
|
||||
go install -race -v -o ${bin_dir}/uplink storj.io/storj/cmd/uplink >/dev/null 2>&1
|
||||
go install -race -v -o ${bin_dir}/gateway storj.io/storj/cmd/gateway >/dev/null 2>&1
|
||||
cd ${scriptdir}/../../../cmd/gateway && go install -race -v -o ${bin_dir}/gateway storj.io/storj/cmd/gateway >/dev/null 2>&1
|
||||
# uncomment for local testing:
|
||||
# GOBIN=${bin_dir} go install -race -v storj.io/storj/cmd/uplink > /dev/null 2>&1
|
||||
# GOBIN=${bin_dir} go install -race -v storj.io/storj/cmd/gateway > /dev/null 2>&1
|
||||
# GOBIN=${bin_dir} cd ${scriptdir}/../../../cmd/gateway && go install -race -v storj.io/storj/cmd/gateway > /dev/null 2>&1
|
||||
popd
|
||||
echo "Finished installing. ${bin_dir}:" $(ls ${bin_dir})
|
||||
echo "Binary shasums:"
|
||||
@ -236,7 +238,6 @@ done
|
||||
test_dir=$(version_dir "test_dir")
|
||||
cp -r $(version_dir ${stage1_sat_version}) ${test_dir}
|
||||
echo -e "\nSetting up stage 1 in ${test_dir}"
|
||||
scriptdir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||
test_versions_path="$( dirname "${scriptdir}" )/testversions/test-versions.sh"
|
||||
setup_stage "${test_dir}" "${stage1_sat_version}" "${stage1_storagenode_versions}" "1"
|
||||
|
||||
|
@ -62,6 +62,8 @@ replace_in_file(){
|
||||
esac
|
||||
}
|
||||
|
||||
scriptdir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||
|
||||
# mirroring install-sim from the Makefile since it won't work on private Jenkins
|
||||
install_sim(){
|
||||
local bin_dir="$1"
|
||||
@ -72,7 +74,7 @@ install_sim(){
|
||||
go install -race -v -o ${bin_dir}/storj-sim storj.io/storj/cmd/storj-sim >/dev/null 2>&1
|
||||
go install -race -v -o ${bin_dir}/versioncontrol storj.io/storj/cmd/versioncontrol >/dev/null 2>&1
|
||||
go install -race -v -o ${bin_dir}/uplink storj.io/storj/cmd/uplink >/dev/null 2>&1
|
||||
go install -race -v -o ${bin_dir}/gateway storj.io/storj/cmd/gateway >/dev/null 2>&1
|
||||
cd ${scriptdir}/../../../cmd/gateway && go install -race -v -o ${bin_dir}/gateway storj.io/storj/cmd/gateway >/dev/null 2>&1
|
||||
go install -race -v -o ${bin_dir}/identity storj.io/storj/cmd/identity >/dev/null 2>&1
|
||||
go install -race -v -o ${bin_dir}/certificates storj.io/storj/cmd/certificates >/dev/null 2>&1
|
||||
|
||||
@ -178,10 +180,10 @@ for version in ${unique_versions}; do
|
||||
pushd ${dir}
|
||||
mkdir -p ${bin_dir}
|
||||
go install -race -v -o ${bin_dir}/uplink storj.io/storj/cmd/uplink >/dev/null 2>&1
|
||||
go install -race -v -o ${bin_dir}/gateway storj.io/storj/cmd/gateway >/dev/null 2>&1
|
||||
cd ${scriptdir}/../../../cmd/gateway && go install -race -v -o ${bin_dir}/gateway storj.io/storj/cmd/gateway >/dev/null 2>&1
|
||||
# uncomment for local testing
|
||||
# GOBIN=${bin_dir} go install -race -v storj.io/storj/cmd/uplink >/dev/null 2>&1
|
||||
# GOBIN=${bin_dir} go install -race -v storj.io/storj/cmd/gateway >/dev/null 2>&1
|
||||
# GOBIN=${bin_dir} cd ${scriptdir}/../../../cmd/gateway && go install -race -v storj.io/storj/cmd/gateway >/dev/null 2>&1
|
||||
popd
|
||||
echo "Finished installing. ${bin_dir}:" $(ls ${bin_dir})
|
||||
echo "Binary shasums:"
|
||||
@ -207,7 +209,6 @@ done
|
||||
test_dir=$(version_dir "test_dir")
|
||||
cp -r $(version_dir ${stage1_sat_version}) ${test_dir}
|
||||
echo -e "\nSetting up stage 1 in ${test_dir}"
|
||||
scriptdir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||
setup_stage "${test_dir}" "${stage1_sat_version}" "${stage1_storagenode_versions}"
|
||||
|
||||
# Uploading files to the network using the latest release version for each uplink version
|
||||
|
Loading…
Reference in New Issue
Block a user