From 59b3eb190eab64139fe02095a608dcaa06c8f5ad Mon Sep 17 00:00:00 2001 From: Alexander Leitner Date: Tue, 2 Apr 2019 10:55:58 -0400 Subject: [PATCH] API endpoint checking object and segment health from the satellite (#1546) * Generate protobuf for checking object and segment health * Initial cmd client for health check * Register the health inspector on the satellite peer --- cmd/inspector/main.go | 77 ++++ go.mod | 15 +- go.sum | 33 +- pkg/pb/inspector.pb.go | 613 ++++++++++++++++++++++---- pkg/pb/inspector.proto | 43 ++ satellite/inspector/inspector.go | 178 ++++++++ satellite/inspector/inspector_test.go | 104 +++++ satellite/metainfo/metainfo.go | 54 +-- satellite/peer.go | 16 + 9 files changed, 994 insertions(+), 139 deletions(-) create mode 100644 satellite/inspector/inspector.go create mode 100644 satellite/inspector/inspector_test.go diff --git a/cmd/inspector/main.go b/cmd/inspector/main.go index 5cba48f91..197e93e4c 100644 --- a/cmd/inspector/main.go +++ b/cmd/inspector/main.go @@ -62,6 +62,10 @@ var ( Use: "statdb", Short: "commands for statdb", } + healthCmd = &cobra.Command{ + Use: "health", + Short: "commands for querying health of a stored data", + } irreparableCmd = &cobra.Command{ Use: "irreparable", Short: "list segments in irreparable database", @@ -121,6 +125,18 @@ var ( Args: cobra.MinimumNArgs(1), RunE: CreateCSVStats, } + objectHealthCmd = &cobra.Command{ + Use: "object ", + Short: "Get stats about an object's health", + Args: cobra.MinimumNArgs(3), + RunE: ObjectHealth, + } + segmentHealthCmd = &cobra.Command{ + Use: "segment ", + Short: "Get stats about a segment's health", + Args: cobra.MinimumNArgs(4), + RunE: SegmentHealth, + } ) // Inspector gives access to kademlia, overlay cache @@ -129,6 +145,7 @@ type Inspector struct { kadclient pb.KadInspectorClient overlayclient pb.OverlayInspectorClient irrdbclient pb.IrreparableInspectorClient + healthclient pb.HealthInspectorClient } // NewInspector creates a new gRPC inspector client for access to kad, @@ -154,6 +171,7 @@ func NewInspector(address, path string) (*Inspector, error) { kadclient: pb.NewKadInspectorClient(conn), overlayclient: pb.NewOverlayInspectorClient(conn), irrdbclient: pb.NewIrreparableInspectorClient(conn), + healthclient: pb.NewHealthInspectorClient(conn), }, nil } @@ -445,6 +463,61 @@ func CreateCSVStats(cmd *cobra.Command, args []string) (err error) { return nil } +// ObjectHealth gets information about the health of an object on the network +func ObjectHealth(cmd *cobra.Command, args []string) (err error) { + ctx := context.Background() + + i, err := NewInspector(*Addr, *IdentityPath) + if err != nil { + return ErrArgs.Wrap(err) + } + + req := &pb.ObjectHealthRequest{ + ProjectId: []byte(args[0]), + Bucket: []byte(args[1]), + EncryptedPath: []byte(args[2]), + StartAfterSegment: 0, // start from first segment + EndBeforeSegment: 0, // No end, so we stop when we've hit limit or arrived at the last segment + Limit: 0, // No limit, so we stop when we've arrived at the last segment + } + + _, err = i.healthclient.ObjectHealth(ctx, req) + if err != nil { + return ErrRequest.Wrap(err) + } + + return nil +} + +// SegmentHealth gets information about the health of a segment on the network +func SegmentHealth(cmd *cobra.Command, args []string) (err error) { + ctx := context.Background() + + i, err := NewInspector(*Addr, *IdentityPath) + if err != nil { + return ErrArgs.Wrap(err) + } + + segmentIndex, err := strconv.ParseInt(args[1], 10, 64) + if err != nil { + return ErrRequest.Wrap(err) + } + + req := &pb.SegmentHealthRequest{ + ProjectId: []byte(args[0]), + SegmentIndex: segmentIndex, + Bucket: []byte(args[2]), + EncryptedPath: []byte(args[3]), + } + + _, err = i.healthclient.SegmentHealth(ctx, req) + if err != nil { + return ErrRequest.Wrap(err) + } + + return nil +} + func getSegments(cmd *cobra.Command, args []string) error { if irreparableLimit <= int32(0) { return ErrArgs.New("limit must be greater than 0") @@ -508,6 +581,7 @@ func init() { rootCmd.AddCommand(kadCmd) rootCmd.AddCommand(statsCmd) rootCmd.AddCommand(irreparableCmd) + rootCmd.AddCommand(healthCmd) kadCmd.AddCommand(countNodeCmd) kadCmd.AddCommand(pingNodeCmd) @@ -520,6 +594,9 @@ func init() { statsCmd.AddCommand(createStatsCmd) statsCmd.AddCommand(createCSVStatsCmd) + healthCmd.AddCommand(objectHealthCmd) + healthCmd.AddCommand(segmentHealthCmd) + irreparableCmd.Flags().Int32Var(&irreparableLimit, "limit", 50, "max number of results per page") flag.Parse() diff --git a/go.mod b/go.mod index 5730ff30d..286285fed 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,6 @@ module storj.io/storj require ( github.com/btcsuite/btcutil v0.0.0-20180706230648-ab6388e0c60a github.com/garyburd/redigo v1.0.1-0.20170216214944-0d253a66e6e1 // indirect - github.com/go-ole/go-ole v1.2.1 // indirect github.com/graphql-go/graphql v0.7.6 github.com/hanwen/go-fuse v0.0.0-20181027161220-c029b69a13a7 github.com/inconshreveable/mousetrap v1.0.0 // indirect @@ -20,7 +19,6 @@ exclude gopkg.in/olivere/elastic.v5 v5.0.72 // buggy import, see https://github. require ( github.com/Shopify/go-lua v0.0.0-20181106184032-48449c60c0a9 github.com/Shopify/toxiproxy v2.1.4+incompatible // indirect - github.com/StackExchange/wmi v0.0.0-20180725035823-b12b22c5341f // indirect github.com/alicebob/gopher-json v0.0.0-20180125190556-5a6b3ba71ee6 // indirect github.com/alicebob/miniredis v0.0.0-20180911162847-3657542c8629 github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da // indirect @@ -73,7 +71,6 @@ require ( github.com/minio/sha256-simd v0.0.0-20171213220625-ad98a36ba0da // indirect github.com/minio/sio v0.0.0-20180327104954-6a41828a60f0 // indirect github.com/mitchellh/go-homedir v0.0.0-20180801233206-58046073cbff // indirect - github.com/mr-tron/base58 v0.0.0-20180922112544-9ad991d48a42 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.0 // indirect @@ -90,7 +87,6 @@ require ( github.com/pkg/profile v1.2.1 // indirect github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a // indirect github.com/rs/cors v1.5.0 // indirect - github.com/shirou/gopsutil v2.17.12+incompatible github.com/sirupsen/logrus v1.3.0 // indirect github.com/skyrings/skyring-common v0.0.0-20160929130248-d1c0bb1cbd5e github.com/spacemonkeygo/errors v0.0.0-20171212215202-9064522e9fd1 // indirect @@ -110,13 +106,14 @@ require ( go.uber.org/atomic v1.3.2 // indirect go.uber.org/multierr v1.1.0 // indirect go.uber.org/zap v1.9.1 - golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b - golang.org/x/net v0.0.0-20190225153610-fe579d43d832 + golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576 + golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53 golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 - golang.org/x/sys v0.0.0-20190225065934-cc5685c2db12 + golang.org/x/sys v0.0.0-20190321052220-f7bb7a8bee54 golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2 // indirect golang.org/x/time v0.0.0-20181108054448-85acf8d2951c // indirect - golang.org/x/tools v0.0.0-20190225234524-2dc4ef2775b8 + golang.org/x/tools v0.0.0-20190321154406-ae772f11d294 + google.golang.org/appengine v1.4.0 // indirect google.golang.org/genproto v0.0.0-20190219182410-082222b4a5c5 // indirect google.golang.org/grpc v1.19.0 gopkg.in/Shopify/sarama.v1 v1.18.0 // indirect @@ -125,4 +122,6 @@ require ( gopkg.in/spacemonkeygo/monkit.v2 v2.0.0-20180827161543-6ebf5a752f9b gopkg.in/vmihailenco/msgpack.v2 v2.9.1 // indirect gopkg.in/yaml.v2 v2.2.2 // indirect + labix.org/v2/mgo v0.0.0-20140701140051-000000000287 // indirect + launchpad.net/gocheck v0.0.0-20140225173054-000000000087 // indirect ) diff --git a/go.sum b/go.sum index d94335c6e..daaa4d8cb 100644 --- a/go.sum +++ b/go.sum @@ -13,8 +13,6 @@ github.com/Shopify/toxiproxy v2.1.4+incompatible h1:TKdv8HiTLgE5wdJuEML90aBgNWso github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= github.com/Sirupsen/logrus v1.0.6 h1:HCAGQRk48dRVPA5Y+Yh0qdCSTzPOyU1tBJ7Q9YzotII= github.com/Sirupsen/logrus v1.0.6/go.mod h1:rmk17hk6i8ZSAJkSDa7nOxamrG+SP4P0mm+DAvExv4U= -github.com/StackExchange/wmi v0.0.0-20180725035823-b12b22c5341f h1:5ZfJxyXo8KyX8DgGXC5B7ILL8y51fci/qYz2B4j8iLY= -github.com/StackExchange/wmi v0.0.0-20180725035823-b12b22c5341f/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= 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 v0.0.0-20180911162847-3657542c8629 h1:gLoh8jzwIxdisBnHiWRIuReqtH9cpslSE2564UWXun0= @@ -90,8 +88,6 @@ github.com/garyburd/redigo v1.0.1-0.20170216214944-0d253a66e6e1/go.mod h1:NR3MbY github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= 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-ole/go-ole v1.2.1 h1:2lOsA72HgjxAuMlKpFiCbHTvu44PIVkZ5hqm3RSdI/E= -github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= 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.0 h1:7LxgVwFb2hIQtMm87NdgAVfXjnt4OePseqT1tKx+opk= @@ -233,8 +229,6 @@ github.com/mitchellh/mapstructure v1.0.0 h1:vVpGvMXJPqSDh2VYHF7gsfQj8Ncx+Xw5Y1KH github.com/mitchellh/mapstructure v1.0.0/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.1 h1:0fcGQkeJPHl7DauilpdNG27ZxXHDSg+rbbTpfpniZd8= github.com/mitchellh/mapstructure v1.1.1/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mr-tron/base58 v0.0.0-20180922112544-9ad991d48a42 h1:/H+QBVxPZWp7WG8dBXXP/qCWP8QU0YczIvvKes/bNpk= -github.com/mr-tron/base58 v0.0.0-20180922112544-9ad991d48a42/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= 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= @@ -290,8 +284,6 @@ 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/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/shirou/gopsutil v2.17.12+incompatible h1:FNbznluSK3DQggqiVw3wK/tFKJrKlLPBuQ+V8XkkCOc= -github.com/shirou/gopsutil v2.17.12+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/sirupsen/logrus v1.0.6 h1:hcP1GmhGigz/O7h1WVUM5KklBp1JoNS9FggWKdj/j3s= github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= github.com/sirupsen/logrus v1.3.0 h1:hI/7Q+DtNZ2kINb6qt/lS+IyXnHQe9e90POfeewL/ME= @@ -358,8 +350,9 @@ go.uber.org/zap v1.9.1 h1:XCJQEf3W6eZaVwhRBof6ImoYGJSITeKWsyeh3HFu/5o= go.uber.org/zap v1.9.1/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-20180910181607-0e37d006457b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b h1:+/WWzjwW6gidDJnMKWLKLX1gxn7irUTF1fLpQovfQ5M= -golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/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-20190320223903-b7391e95e576 h1:aUX/1G2gFSs4AsJJg2cL3HuoRhCSCz733FE5GUSuaT4= +golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -370,14 +363,13 @@ golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20180911220305-26e67e76b6c3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181106065722-10aee1819953 h1:LuZIitY8waaxUfNIdtajyE/YzA/zyf0YxXG27VpLrkg= golang.org/x/net v0.0.0-20181106065722-10aee1819953/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-20190225153610-fe579d43d832 h1:2IdId8zoI92l1bUzjAOygcAOkmCe13HY1j0rqPPPzB8= -golang.org/x/net v0.0.0-20190225153610-fe579d43d832/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-20190320064053-1272bf9dcd53 h1:kcXqo9vE6fsZY5X5Rd7R1l7fTgnWaDCVmln65REefiE= +golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be h1:vEDujvNQGv4jgYKudGeI/+DAX4Jffq6hpD55MmoEvKs= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180821140842-3b58ed4ad339/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -387,8 +379,9 @@ golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180906133057-8cf3aee42992/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-20190225065934-cc5685c2db12 h1:Zw7eRv6INHGfu15LVRN1vrrwusJbnfJjAZn3D1VkQIE= -golang.org/x/sys v0.0.0-20190225065934-cc5685c2db12/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-20190321052220-f7bb7a8bee54 h1:xe1/2UUJRmA9iDglQSlkx8c5n3twv58+K0mPpC2zmhA= +golang.org/x/sys v0.0.0-20190321052220-f7bb7a8bee54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2 h1:z99zHgr7hKfrUcX/KsoJk5FJfjTceCKIp96+biqP4To= @@ -401,8 +394,8 @@ golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20180911133044-677d2ff680c1 h1:dzEuQYa6+a3gROnSlgly5ERUm4SZKJt+dh+4iSbO+bI= golang.org/x/tools v0.0.0-20180911133044-677d2ff680c1/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190225234524-2dc4ef2775b8 h1:/cqPBp9ki3f154KKPOsnC8IaiCB9VKiDexY9bGI0jhI= -golang.org/x/tools v0.0.0-20190225234524-2dc4ef2775b8/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190321154406-ae772f11d294 h1:gMPF/7U3xs3RNmp7bh9BoJnRg81e5uKSYpyaGoAmadw= +golang.org/x/tools v0.0.0-20190321154406-ae772f11d294/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= google.golang.org/api v0.0.0-20180818000503-e21acd801f91/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.0.0-20180826000528-7954115fcf34/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= @@ -453,3 +446,7 @@ gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +labix.org/v2/mgo v0.0.0-20140701140051-000000000287 h1:L0cnkNl4TfAXzvdrqsYEmxOHOCv2p5I3taaReO8BWFs= +labix.org/v2/mgo v0.0.0-20140701140051-000000000287/go.mod h1:Lg7AYkt1uXJoR9oeSZ3W/8IXLdvOfIITgZnommstyz4= +launchpad.net/gocheck v0.0.0-20140225173054-000000000087 h1:Izowp2XBH6Ya6rv+hqbceQyw/gSGoXfH/UPoTGduL54= +launchpad.net/gocheck v0.0.0-20140225173054-000000000087/go.mod h1:hj7XX3B/0A+80Vse0e+BUHsHMTEhd0O4cpUHr/e/BUM= diff --git a/pkg/pb/inspector.pb.go b/pkg/pb/inspector.pb.go index 6b8d32e20..731b36596 100644 --- a/pkg/pb/inspector.pb.go +++ b/pkg/pb/inspector.pb.go @@ -1296,6 +1296,316 @@ func (m *DashboardResponse) GetLastQueried() *timestamp.Timestamp { return nil } +type SegmentHealthRequest struct { + Bucket []byte `protobuf:"bytes,1,opt,name=bucket,proto3" json:"bucket,omitempty"` + EncryptedPath []byte `protobuf:"bytes,2,opt,name=encrypted_path,json=encryptedPath,proto3" json:"encrypted_path,omitempty"` + SegmentIndex int64 `protobuf:"varint,3,opt,name=segment_index,json=segmentIndex,proto3" json:"segment_index,omitempty"` + ProjectId []byte `protobuf:"bytes,4,opt,name=project_id,json=projectId,proto3" json:"project_id,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *SegmentHealthRequest) Reset() { *m = SegmentHealthRequest{} } +func (m *SegmentHealthRequest) String() string { return proto.CompactTextString(m) } +func (*SegmentHealthRequest) ProtoMessage() {} +func (*SegmentHealthRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_a07d9034b2dd9d26, []int{29} +} +func (m *SegmentHealthRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_SegmentHealthRequest.Unmarshal(m, b) +} +func (m *SegmentHealthRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_SegmentHealthRequest.Marshal(b, m, deterministic) +} +func (m *SegmentHealthRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_SegmentHealthRequest.Merge(m, src) +} +func (m *SegmentHealthRequest) XXX_Size() int { + return xxx_messageInfo_SegmentHealthRequest.Size(m) +} +func (m *SegmentHealthRequest) XXX_DiscardUnknown() { + xxx_messageInfo_SegmentHealthRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_SegmentHealthRequest proto.InternalMessageInfo + +func (m *SegmentHealthRequest) GetBucket() []byte { + if m != nil { + return m.Bucket + } + return nil +} + +func (m *SegmentHealthRequest) GetEncryptedPath() []byte { + if m != nil { + return m.EncryptedPath + } + return nil +} + +func (m *SegmentHealthRequest) GetSegmentIndex() int64 { + if m != nil { + return m.SegmentIndex + } + return 0 +} + +func (m *SegmentHealthRequest) GetProjectId() []byte { + if m != nil { + return m.ProjectId + } + return nil +} + +type SegmentHealth struct { + MinimumRequired int32 `protobuf:"varint,1,opt,name=minimum_required,json=minimumRequired,proto3" json:"minimum_required,omitempty"` + Total int32 `protobuf:"varint,2,opt,name=total,proto3" json:"total,omitempty"` + RepairThreshold int32 `protobuf:"varint,3,opt,name=repair_threshold,json=repairThreshold,proto3" json:"repair_threshold,omitempty"` + SuccessThreshold int32 `protobuf:"varint,4,opt,name=success_threshold,json=successThreshold,proto3" json:"success_threshold,omitempty"` + OnlineNodes int32 `protobuf:"varint,5,opt,name=online_nodes,json=onlineNodes,proto3" json:"online_nodes,omitempty"` + Segment []byte `protobuf:"bytes,6,opt,name=segment,proto3" json:"segment,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *SegmentHealth) Reset() { *m = SegmentHealth{} } +func (m *SegmentHealth) String() string { return proto.CompactTextString(m) } +func (*SegmentHealth) ProtoMessage() {} +func (*SegmentHealth) Descriptor() ([]byte, []int) { + return fileDescriptor_a07d9034b2dd9d26, []int{30} +} +func (m *SegmentHealth) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_SegmentHealth.Unmarshal(m, b) +} +func (m *SegmentHealth) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_SegmentHealth.Marshal(b, m, deterministic) +} +func (m *SegmentHealth) XXX_Merge(src proto.Message) { + xxx_messageInfo_SegmentHealth.Merge(m, src) +} +func (m *SegmentHealth) XXX_Size() int { + return xxx_messageInfo_SegmentHealth.Size(m) +} +func (m *SegmentHealth) XXX_DiscardUnknown() { + xxx_messageInfo_SegmentHealth.DiscardUnknown(m) +} + +var xxx_messageInfo_SegmentHealth proto.InternalMessageInfo + +func (m *SegmentHealth) GetMinimumRequired() int32 { + if m != nil { + return m.MinimumRequired + } + return 0 +} + +func (m *SegmentHealth) GetTotal() int32 { + if m != nil { + return m.Total + } + return 0 +} + +func (m *SegmentHealth) GetRepairThreshold() int32 { + if m != nil { + return m.RepairThreshold + } + return 0 +} + +func (m *SegmentHealth) GetSuccessThreshold() int32 { + if m != nil { + return m.SuccessThreshold + } + return 0 +} + +func (m *SegmentHealth) GetOnlineNodes() int32 { + if m != nil { + return m.OnlineNodes + } + return 0 +} + +func (m *SegmentHealth) GetSegment() []byte { + if m != nil { + return m.Segment + } + return nil +} + +type SegmentHealthResponse struct { + Health *SegmentHealth `protobuf:"bytes,1,opt,name=health,proto3" json:"health,omitempty"` + Redundancy *RedundancyScheme `protobuf:"bytes,2,opt,name=redundancy,proto3" json:"redundancy,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *SegmentHealthResponse) Reset() { *m = SegmentHealthResponse{} } +func (m *SegmentHealthResponse) String() string { return proto.CompactTextString(m) } +func (*SegmentHealthResponse) ProtoMessage() {} +func (*SegmentHealthResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_a07d9034b2dd9d26, []int{31} +} +func (m *SegmentHealthResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_SegmentHealthResponse.Unmarshal(m, b) +} +func (m *SegmentHealthResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_SegmentHealthResponse.Marshal(b, m, deterministic) +} +func (m *SegmentHealthResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_SegmentHealthResponse.Merge(m, src) +} +func (m *SegmentHealthResponse) XXX_Size() int { + return xxx_messageInfo_SegmentHealthResponse.Size(m) +} +func (m *SegmentHealthResponse) XXX_DiscardUnknown() { + xxx_messageInfo_SegmentHealthResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_SegmentHealthResponse proto.InternalMessageInfo + +func (m *SegmentHealthResponse) GetHealth() *SegmentHealth { + if m != nil { + return m.Health + } + return nil +} + +func (m *SegmentHealthResponse) GetRedundancy() *RedundancyScheme { + if m != nil { + return m.Redundancy + } + return nil +} + +type ObjectHealthRequest struct { + EncryptedPath []byte `protobuf:"bytes,1,opt,name=encrypted_path,json=encryptedPath,proto3" json:"encrypted_path,omitempty"` + Bucket []byte `protobuf:"bytes,2,opt,name=bucket,proto3" json:"bucket,omitempty"` + ProjectId []byte `protobuf:"bytes,3,opt,name=project_id,json=projectId,proto3" json:"project_id,omitempty"` + StartAfterSegment int64 `protobuf:"varint,4,opt,name=start_after_segment,json=startAfterSegment,proto3" json:"start_after_segment,omitempty"` + EndBeforeSegment int64 `protobuf:"varint,5,opt,name=end_before_segment,json=endBeforeSegment,proto3" json:"end_before_segment,omitempty"` + Limit int32 `protobuf:"varint,6,opt,name=limit,proto3" json:"limit,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ObjectHealthRequest) Reset() { *m = ObjectHealthRequest{} } +func (m *ObjectHealthRequest) String() string { return proto.CompactTextString(m) } +func (*ObjectHealthRequest) ProtoMessage() {} +func (*ObjectHealthRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_a07d9034b2dd9d26, []int{32} +} +func (m *ObjectHealthRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ObjectHealthRequest.Unmarshal(m, b) +} +func (m *ObjectHealthRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ObjectHealthRequest.Marshal(b, m, deterministic) +} +func (m *ObjectHealthRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_ObjectHealthRequest.Merge(m, src) +} +func (m *ObjectHealthRequest) XXX_Size() int { + return xxx_messageInfo_ObjectHealthRequest.Size(m) +} +func (m *ObjectHealthRequest) XXX_DiscardUnknown() { + xxx_messageInfo_ObjectHealthRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_ObjectHealthRequest proto.InternalMessageInfo + +func (m *ObjectHealthRequest) GetEncryptedPath() []byte { + if m != nil { + return m.EncryptedPath + } + return nil +} + +func (m *ObjectHealthRequest) GetBucket() []byte { + if m != nil { + return m.Bucket + } + return nil +} + +func (m *ObjectHealthRequest) GetProjectId() []byte { + if m != nil { + return m.ProjectId + } + return nil +} + +func (m *ObjectHealthRequest) GetStartAfterSegment() int64 { + if m != nil { + return m.StartAfterSegment + } + return 0 +} + +func (m *ObjectHealthRequest) GetEndBeforeSegment() int64 { + if m != nil { + return m.EndBeforeSegment + } + return 0 +} + +func (m *ObjectHealthRequest) GetLimit() int32 { + if m != nil { + return m.Limit + } + return 0 +} + +type ObjectHealthResponse struct { + Segments []*SegmentHealth `protobuf:"bytes,1,rep,name=segments,proto3" json:"segments,omitempty"` + Redundancy *RedundancyScheme `protobuf:"bytes,2,opt,name=redundancy,proto3" json:"redundancy,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ObjectHealthResponse) Reset() { *m = ObjectHealthResponse{} } +func (m *ObjectHealthResponse) String() string { return proto.CompactTextString(m) } +func (*ObjectHealthResponse) ProtoMessage() {} +func (*ObjectHealthResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_a07d9034b2dd9d26, []int{33} +} +func (m *ObjectHealthResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ObjectHealthResponse.Unmarshal(m, b) +} +func (m *ObjectHealthResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ObjectHealthResponse.Marshal(b, m, deterministic) +} +func (m *ObjectHealthResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_ObjectHealthResponse.Merge(m, src) +} +func (m *ObjectHealthResponse) XXX_Size() int { + return xxx_messageInfo_ObjectHealthResponse.Size(m) +} +func (m *ObjectHealthResponse) XXX_DiscardUnknown() { + xxx_messageInfo_ObjectHealthResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_ObjectHealthResponse proto.InternalMessageInfo + +func (m *ObjectHealthResponse) GetSegments() []*SegmentHealth { + if m != nil { + return m.Segments + } + return nil +} + +func (m *ObjectHealthResponse) GetRedundancy() *RedundancyScheme { + if m != nil { + return m.Redundancy + } + return nil +} + func init() { proto.RegisterType((*ListIrreparableSegmentsRequest)(nil), "inspector.ListIrreparableSegmentsRequest") proto.RegisterType((*IrreparableSegment)(nil), "inspector.IrreparableSegment") @@ -1326,98 +1636,126 @@ func init() { proto.RegisterType((*StatSummaryResponse)(nil), "inspector.StatSummaryResponse") proto.RegisterType((*DashboardRequest)(nil), "inspector.DashboardRequest") proto.RegisterType((*DashboardResponse)(nil), "inspector.DashboardResponse") + proto.RegisterType((*SegmentHealthRequest)(nil), "inspector.SegmentHealthRequest") + proto.RegisterType((*SegmentHealth)(nil), "inspector.SegmentHealth") + proto.RegisterType((*SegmentHealthResponse)(nil), "inspector.SegmentHealthResponse") + proto.RegisterType((*ObjectHealthRequest)(nil), "inspector.ObjectHealthRequest") + proto.RegisterType((*ObjectHealthResponse)(nil), "inspector.ObjectHealthResponse") } func init() { proto.RegisterFile("inspector.proto", fileDescriptor_a07d9034b2dd9d26) } var fileDescriptor_a07d9034b2dd9d26 = []byte{ - // 1370 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x57, 0xcb, 0x72, 0x1b, 0x45, - 0x14, 0xcd, 0xe8, 0x15, 0xe9, 0xca, 0xd1, 0xa3, 0x65, 0x88, 0x10, 0x89, 0x6d, 0xa6, 0x80, 0x38, - 0x49, 0x95, 0x12, 0x44, 0x58, 0x04, 0x2a, 0x8b, 0x58, 0x26, 0x89, 0x2a, 0x21, 0x31, 0xe3, 0xb0, - 0xa1, 0x52, 0xa8, 0x5a, 0x9a, 0xb6, 0x32, 0x65, 0x69, 0x7a, 0x32, 0xdd, 0x0a, 0xf8, 0x0f, 0xf8, - 0x02, 0x16, 0x6c, 0xf9, 0x09, 0xaa, 0xf8, 0x01, 0x76, 0xec, 0x59, 0x64, 0x43, 0x15, 0xff, 0xc0, - 0x8e, 0xea, 0xdb, 0x3d, 0x2f, 0x8d, 0x85, 0x5d, 0x14, 0xec, 0x34, 0xe7, 0x9e, 0x3e, 0x7d, 0xef, - 0xed, 0xee, 0xd3, 0x2d, 0x68, 0x7a, 0xbe, 0x08, 0xd8, 0x54, 0xf2, 0xb0, 0x1f, 0x84, 0x5c, 0x72, - 0x52, 0x8b, 0x81, 0x1e, 0xcc, 0xf8, 0x8c, 0x6b, 0xb8, 0x07, 0x3e, 0x77, 0x99, 0xf9, 0xdd, 0x0c, - 0xb8, 0xe7, 0x4b, 0x16, 0xba, 0x13, 0x03, 0x6c, 0xcd, 0x38, 0x9f, 0xcd, 0xd9, 0x2d, 0xfc, 0x9a, - 0x2c, 0x8f, 0x6e, 0xb9, 0xcb, 0x90, 0x4a, 0x8f, 0xfb, 0x26, 0xbe, 0xbd, 0x1a, 0x97, 0xde, 0x82, - 0x09, 0x49, 0x17, 0x81, 0x26, 0xd8, 0x4f, 0x61, 0xeb, 0x89, 0x27, 0xe4, 0x28, 0x0c, 0x59, 0x40, - 0x43, 0x3a, 0x99, 0xb3, 0x43, 0x36, 0x5b, 0x30, 0x5f, 0x0a, 0x87, 0xbd, 0x5a, 0x32, 0x21, 0xc9, - 0x26, 0x94, 0xe7, 0xde, 0xc2, 0x93, 0x5d, 0x6b, 0xc7, 0xda, 0x2d, 0x3b, 0xfa, 0x83, 0xbc, 0x0d, - 0x15, 0x7e, 0x74, 0x24, 0x98, 0xec, 0x16, 0x10, 0x36, 0x5f, 0xf6, 0x9f, 0x16, 0x90, 0xbc, 0x18, - 0x21, 0x50, 0x0a, 0xa8, 0x7c, 0x89, 0x1a, 0x1b, 0x0e, 0xfe, 0x26, 0x77, 0xa1, 0x21, 0x74, 0x78, - 0xec, 0x32, 0x49, 0xbd, 0x39, 0x4a, 0xd5, 0x07, 0xa4, 0x9f, 0x54, 0x79, 0xa0, 0x7f, 0x39, 0x97, - 0x0c, 0x73, 0x1f, 0x89, 0x64, 0x1b, 0xea, 0x73, 0x2e, 0xe4, 0x38, 0xf0, 0xd8, 0x94, 0x89, 0x6e, - 0x11, 0x53, 0x00, 0x05, 0x1d, 0x20, 0x42, 0xfa, 0xd0, 0x99, 0x53, 0x21, 0xc7, 0x2a, 0x11, 0x2f, - 0x1c, 0x53, 0x29, 0xd9, 0x22, 0x90, 0xdd, 0xd2, 0x8e, 0xb5, 0x5b, 0x74, 0xda, 0x2a, 0xe4, 0x60, - 0xe4, 0xbe, 0x0e, 0x90, 0xdb, 0xb0, 0x99, 0xa5, 0x8e, 0xa7, 0x7c, 0xe9, 0xcb, 0x6e, 0x19, 0x07, - 0x90, 0x30, 0x4d, 0x1e, 0xaa, 0x88, 0xfd, 0x02, 0xb6, 0xd7, 0x36, 0x4e, 0x04, 0xdc, 0x17, 0x8c, - 0xdc, 0x85, 0xaa, 0x49, 0x5b, 0x74, 0xad, 0x9d, 0xe2, 0x6e, 0x7d, 0x70, 0xb5, 0x9f, 0x2c, 0x7a, - 0x7e, 0xa4, 0x13, 0xd3, 0xed, 0x4f, 0xa1, 0xf9, 0x90, 0xc9, 0x43, 0x49, 0x93, 0x75, 0xb8, 0x06, - 0x17, 0xd5, 0x4e, 0x18, 0x7b, 0xae, 0xee, 0xe2, 0x5e, 0xe3, 0xd7, 0x37, 0xdb, 0x17, 0x7e, 0x7f, - 0xb3, 0x5d, 0x79, 0xca, 0x5d, 0x36, 0xda, 0x77, 0x2a, 0x2a, 0x3c, 0x72, 0xed, 0x1f, 0x2d, 0x68, - 0x25, 0x83, 0x4d, 0x2e, 0xdb, 0x50, 0xa7, 0x4b, 0xd7, 0x8b, 0xea, 0xb2, 0xb0, 0x2e, 0x40, 0x08, - 0xeb, 0x49, 0x08, 0xb8, 0x7f, 0x70, 0x29, 0x2c, 0x43, 0x70, 0x14, 0x42, 0xde, 0x83, 0x8d, 0x65, - 0xa0, 0xb6, 0x8f, 0x91, 0x28, 0xa2, 0x44, 0x5d, 0x63, 0x5a, 0x23, 0xa1, 0x68, 0x91, 0x12, 0x8a, - 0x18, 0x0a, 0xaa, 0xd8, 0x7f, 0x58, 0x40, 0x86, 0x21, 0xa3, 0x92, 0xfd, 0xab, 0xe2, 0x56, 0xeb, - 0x28, 0xe4, 0xea, 0xe8, 0x43, 0x47, 0x13, 0xc4, 0x72, 0x3a, 0x65, 0x42, 0x64, 0xb2, 0x6d, 0x63, - 0xe8, 0x50, 0x47, 0x56, 0x73, 0xd6, 0xc4, 0x52, 0xbe, 0xac, 0xdb, 0xb0, 0x69, 0x28, 0x59, 0x4d, - 0xb3, 0x39, 0x74, 0x2c, 0x2d, 0x6a, 0xbf, 0x05, 0x9d, 0x4c, 0x91, 0x7a, 0x11, 0xec, 0x1b, 0x40, - 0x30, 0xae, 0x6a, 0x4a, 0x96, 0x66, 0x13, 0xca, 0xe9, 0x45, 0xd1, 0x1f, 0x76, 0x07, 0xda, 0x69, - 0x2e, 0xb6, 0x49, 0x81, 0x0f, 0x99, 0xdc, 0x5b, 0x4e, 0x8f, 0x59, 0xdc, 0x3b, 0xfb, 0x11, 0x90, - 0x34, 0x98, 0xa8, 0x4a, 0x2e, 0xe9, 0x3c, 0x52, 0xc5, 0x0f, 0x72, 0x05, 0x8a, 0x9e, 0x2b, 0xba, - 0x85, 0x9d, 0xe2, 0xee, 0xc6, 0x1e, 0xa4, 0xfa, 0xab, 0x60, 0x7b, 0x80, 0x1b, 0x47, 0x2b, 0x45, - 0x2b, 0xb3, 0x05, 0x85, 0xb5, 0x8b, 0x52, 0xf0, 0x5c, 0xfb, 0xab, 0x54, 0x4a, 0xf1, 0xe4, 0x67, - 0x0c, 0x22, 0x3b, 0x50, 0x56, 0xeb, 0xa9, 0x13, 0xa9, 0x0f, 0xa0, 0x8f, 0x1e, 0xa7, 0x08, 0x8e, - 0x0e, 0xd8, 0x37, 0xa0, 0xa2, 0x35, 0xcf, 0xc1, 0xed, 0x03, 0x68, 0xae, 0x3a, 0x90, 0x09, 0xdf, - 0x5a, 0xc7, 0x7f, 0x0c, 0xcd, 0x03, 0xcf, 0x9f, 0x21, 0x74, 0xbe, 0x2a, 0x49, 0x17, 0x2e, 0x52, - 0xd7, 0x0d, 0x99, 0x10, 0xb8, 0xe5, 0x6a, 0x4e, 0xf4, 0x69, 0xdb, 0xd0, 0x4a, 0xc4, 0x4c, 0xf9, - 0x0d, 0x28, 0xf0, 0x63, 0x54, 0xab, 0x3a, 0x05, 0x7e, 0x6c, 0xdf, 0x83, 0xf6, 0x13, 0xce, 0x8f, - 0x97, 0x41, 0x7a, 0xca, 0x46, 0x3c, 0x65, 0xed, 0x8c, 0x29, 0x5e, 0x00, 0x49, 0x0f, 0x8f, 0x7b, - 0x5c, 0x52, 0xe5, 0xa0, 0x42, 0xb6, 0x4c, 0xc4, 0xc9, 0x87, 0x50, 0x5a, 0x30, 0x49, 0x63, 0x53, - 0x8d, 0xe3, 0x5f, 0x30, 0x49, 0x5d, 0x2a, 0xa9, 0x83, 0x71, 0xfb, 0x1b, 0x68, 0x62, 0xa1, 0xfe, - 0x11, 0x3f, 0x6f, 0x37, 0x6e, 0x66, 0x53, 0xad, 0x0f, 0xda, 0x89, 0xfa, 0x7d, 0x1d, 0x48, 0xb2, - 0xff, 0xc1, 0x82, 0x56, 0x32, 0x81, 0x49, 0xde, 0x86, 0x92, 0x3c, 0x09, 0x74, 0xf2, 0x8d, 0x41, - 0x23, 0x19, 0xfe, 0xfc, 0x24, 0x60, 0x0e, 0xc6, 0x48, 0x1f, 0xaa, 0x3c, 0x60, 0x21, 0x95, 0x3c, - 0xcc, 0x17, 0xf1, 0xcc, 0x44, 0x9c, 0x98, 0xa3, 0xf8, 0x53, 0x1a, 0xd0, 0xa9, 0x27, 0x4f, 0xf0, - 0xb8, 0x67, 0xf8, 0x43, 0x13, 0x71, 0x62, 0x8e, 0xbd, 0x80, 0xe6, 0x03, 0xcf, 0x77, 0x9f, 0x32, - 0x1a, 0x9e, 0xb7, 0xf0, 0xf7, 0xa1, 0x2c, 0x24, 0x0d, 0xb5, 0xef, 0xe4, 0x29, 0x3a, 0x98, 0xdc, - 0x98, 0xda, 0x74, 0xf4, 0x87, 0x7d, 0x07, 0x5a, 0xc9, 0x74, 0xa6, 0x0d, 0x67, 0xef, 0x6d, 0x02, - 0xad, 0xfd, 0xe5, 0x22, 0xc8, 0xb8, 0xc0, 0x27, 0xd0, 0x4e, 0x61, 0xab, 0x52, 0x6b, 0xb7, 0x7d, - 0x03, 0x36, 0xd2, 0x9e, 0x6b, 0xff, 0x65, 0x41, 0x47, 0x01, 0x87, 0xcb, 0xc5, 0x82, 0x86, 0x27, - 0xb1, 0xd2, 0x55, 0x80, 0xa5, 0x60, 0xee, 0x58, 0x04, 0x74, 0xca, 0x8c, 0x7d, 0xd4, 0x14, 0x72, - 0xa8, 0x00, 0x72, 0x0d, 0x9a, 0xf4, 0x35, 0xf5, 0xe6, 0xea, 0xe2, 0x32, 0x1c, 0xed, 0xc2, 0x8d, - 0x18, 0xd6, 0x44, 0xe5, 0xac, 0x4a, 0xc7, 0xf3, 0x67, 0xb8, 0x55, 0xa2, 0x0b, 0x43, 0x30, 0x77, - 0xa4, 0x21, 0xe5, 0xe6, 0x48, 0x61, 0x9a, 0xa1, 0xbd, 0x17, 0x67, 0xff, 0x5c, 0x13, 0x3e, 0x80, - 0x06, 0x12, 0x26, 0xd4, 0x77, 0xbf, 0xf5, 0x5c, 0xf9, 0xd2, 0x98, 0xee, 0x25, 0x85, 0xee, 0x45, - 0x20, 0xb9, 0x05, 0x9d, 0x24, 0xa7, 0x84, 0x5b, 0xd1, 0x06, 0x1d, 0x87, 0xe2, 0x01, 0xd8, 0x56, - 0x2a, 0x5e, 0x4e, 0x38, 0x0d, 0xdd, 0xa8, 0x1f, 0xbf, 0x15, 0xa1, 0x9d, 0x02, 0x4d, 0x37, 0xce, - 0x7d, 0x33, 0x5d, 0x87, 0x16, 0x12, 0xa7, 0xdc, 0xf7, 0xd9, 0x54, 0xbd, 0xc1, 0x84, 0x69, 0x4c, - 0x53, 0xe1, 0xc3, 0x04, 0x26, 0x37, 0xa1, 0x3d, 0xe1, 0x5c, 0x0a, 0x19, 0xd2, 0x60, 0x1c, 0x9d, - 0xa4, 0x22, 0x1e, 0xfa, 0x56, 0x1c, 0x30, 0x07, 0x49, 0xe9, 0xe2, 0x1b, 0xc8, 0xa7, 0xf3, 0x98, - 0x5b, 0x42, 0x6e, 0x33, 0xc2, 0x53, 0x54, 0xf6, 0xdd, 0x0a, 0xb5, 0xac, 0xa9, 0x11, 0x1e, 0x51, - 0xef, 0xe0, 0x4e, 0x96, 0x02, 0x7b, 0x54, 0x1f, 0x6c, 0xa5, 0x1e, 0x26, 0xa7, 0xec, 0x09, 0x47, - 0x93, 0xc9, 0x47, 0x50, 0xd1, 0xb7, 0x5d, 0xf7, 0x22, 0x0e, 0x7b, 0xa7, 0xaf, 0xdf, 0x97, 0xfd, - 0xe8, 0x7d, 0xd9, 0xdf, 0x37, 0xef, 0x4f, 0xc7, 0x10, 0xc9, 0x67, 0x50, 0xc7, 0x97, 0x58, 0xe0, - 0xf9, 0x33, 0xe6, 0x76, 0xab, 0x38, 0xae, 0x97, 0x1b, 0xf7, 0x3c, 0x7a, 0x97, 0x3a, 0xa0, 0xe8, - 0x07, 0xc8, 0x26, 0xf7, 0x60, 0x03, 0x07, 0xbf, 0x5a, 0xb2, 0xd0, 0x63, 0x6e, 0xb7, 0x76, 0xe6, - 0x68, 0x9c, 0xec, 0x4b, 0x4d, 0x1f, 0xfc, 0x52, 0x84, 0x8d, 0xc7, 0xd4, 0x1d, 0x45, 0xa5, 0x91, - 0x11, 0x40, 0x72, 0xa9, 0x92, 0x2b, 0xa9, 0xa2, 0x73, 0x77, 0x6d, 0xef, 0xea, 0x9a, 0xa8, 0xd9, - 0x17, 0x43, 0xa8, 0x46, 0xbe, 0x4f, 0x7a, 0x29, 0xea, 0xca, 0xcd, 0xd2, 0x7b, 0xf7, 0xd4, 0x98, - 0x11, 0x19, 0x01, 0x24, 0xce, 0x9e, 0xc9, 0x27, 0x77, 0x5f, 0x64, 0xf2, 0x39, 0xe5, 0x3a, 0x18, - 0x42, 0x35, 0x72, 0xd9, 0x4c, 0x3e, 0x2b, 0xde, 0x9e, 0xc9, 0x27, 0x67, 0xcb, 0x43, 0xa8, 0x46, - 0x1e, 0x95, 0x11, 0x59, 0xf1, 0xc9, 0x8c, 0x48, 0xce, 0xd4, 0x1e, 0x40, 0x2d, 0xb6, 0x27, 0x92, - 0x66, 0xae, 0x1a, 0x59, 0xef, 0xca, 0xe9, 0x41, 0xad, 0x33, 0xf8, 0xb9, 0x00, 0xad, 0x67, 0xaf, - 0x59, 0x38, 0xa7, 0x27, 0xff, 0xcb, 0x0a, 0xfe, 0x47, 0x79, 0xaa, 0xa6, 0x45, 0xcf, 0xed, 0x4c, - 0xd3, 0x56, 0x1e, 0xf0, 0x99, 0xa6, 0xe5, 0xde, 0xe7, 0x4f, 0xa0, 0x9e, 0x7a, 0x31, 0x92, 0x4c, - 0xea, 0xb9, 0xe7, 0x72, 0x6f, 0x6b, 0x5d, 0xd8, 0xb4, 0xee, 0x27, 0x0b, 0x3a, 0xf8, 0x4f, 0xe8, - 0x50, 0xf2, 0x90, 0x25, 0xdd, 0xdb, 0x83, 0xb2, 0xd6, 0xbf, 0xbc, 0x72, 0xde, 0x4f, 0x55, 0x3e, - 0xc5, 0x08, 0xec, 0x0b, 0xe4, 0x11, 0xd4, 0x62, 0x97, 0xcc, 0xb6, 0x6d, 0xc5, 0x50, 0xb3, 0x6d, - 0x5b, 0x35, 0x56, 0xfb, 0xc2, 0xe0, 0x7b, 0x0b, 0x36, 0x53, 0xff, 0x82, 0x92, 0x34, 0x03, 0xb8, - 0xbc, 0xe6, 0xbf, 0x15, 0xb9, 0x9e, 0x3e, 0x05, 0xff, 0xf8, 0xc7, 0xb5, 0x77, 0xe3, 0x3c, 0x54, - 0x9d, 0xcc, 0x5e, 0xe9, 0xeb, 0x42, 0x30, 0x99, 0x54, 0xd0, 0x50, 0x3e, 0xfe, 0x3b, 0x00, 0x00, - 0xff, 0xff, 0xe0, 0xc7, 0x2f, 0x50, 0x9b, 0x0f, 0x00, 0x00, + // 1735 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x58, 0x4d, 0x73, 0x1b, 0x4d, + 0x11, 0xce, 0xea, 0x2b, 0x56, 0x4b, 0xd6, 0xc7, 0xc8, 0xef, 0xfb, 0x0a, 0x25, 0xb1, 0x9c, 0xe5, + 0x23, 0x4e, 0x42, 0x29, 0x41, 0x84, 0x43, 0x48, 0xe5, 0x10, 0xdb, 0x24, 0x51, 0x25, 0x24, 0xce, + 0xda, 0x5c, 0xa8, 0x14, 0xaa, 0x91, 0x76, 0x2c, 0x2d, 0x96, 0x76, 0x36, 0xbb, 0xb3, 0x21, 0xfe, + 0x03, 0x14, 0xfc, 0x01, 0xaa, 0xe0, 0xca, 0x9f, 0xa0, 0xe0, 0x0f, 0x70, 0xe3, 0xce, 0x21, 0x17, + 0x0a, 0xf8, 0x0d, 0xdc, 0xa8, 0xe9, 0x99, 0xfd, 0x94, 0x84, 0x5d, 0xc0, 0x7b, 0xd3, 0x3e, 0xfd, + 0x4c, 0x6f, 0x77, 0x4f, 0x6f, 0xcf, 0x33, 0x82, 0xa6, 0xe3, 0x06, 0x1e, 0x9b, 0x0a, 0xee, 0x0f, + 0x3c, 0x9f, 0x0b, 0x4e, 0xaa, 0x31, 0xd0, 0x83, 0x19, 0x9f, 0x71, 0x05, 0xf7, 0xc0, 0xe5, 0x36, + 0xd3, 0xbf, 0x9b, 0x1e, 0x77, 0x5c, 0xc1, 0x7c, 0x7b, 0xa2, 0x81, 0xdd, 0x19, 0xe7, 0xb3, 0x05, + 0x7b, 0x80, 0x4f, 0x93, 0xf0, 0xec, 0x81, 0x1d, 0xfa, 0x54, 0x38, 0xdc, 0xd5, 0xf6, 0x7e, 0xde, + 0x2e, 0x9c, 0x25, 0x0b, 0x04, 0x5d, 0x7a, 0x8a, 0x60, 0xbe, 0x81, 0xdd, 0xd7, 0x4e, 0x20, 0x46, + 0xbe, 0xcf, 0x3c, 0xea, 0xd3, 0xc9, 0x82, 0x9d, 0xb0, 0xd9, 0x92, 0xb9, 0x22, 0xb0, 0xd8, 0x87, + 0x90, 0x05, 0x82, 0xec, 0x40, 0x79, 0xe1, 0x2c, 0x1d, 0xd1, 0x35, 0xf6, 0x8c, 0xfd, 0xb2, 0xa5, + 0x1e, 0xc8, 0x97, 0x50, 0xe1, 0x67, 0x67, 0x01, 0x13, 0xdd, 0x02, 0xc2, 0xfa, 0xc9, 0xfc, 0x87, + 0x01, 0x64, 0xd5, 0x19, 0x21, 0x50, 0xf2, 0xa8, 0x98, 0xa3, 0x8f, 0xba, 0x85, 0xbf, 0xc9, 0x63, + 0x68, 0x04, 0xca, 0x3c, 0xb6, 0x99, 0xa0, 0xce, 0x02, 0x5d, 0xd5, 0x86, 0x64, 0x90, 0x64, 0x79, + 0xac, 0x7e, 0x59, 0xdb, 0x9a, 0x79, 0x84, 0x44, 0xd2, 0x87, 0xda, 0x82, 0x07, 0x62, 0xec, 0x39, + 0x6c, 0xca, 0x82, 0x6e, 0x11, 0x43, 0x00, 0x09, 0x1d, 0x23, 0x42, 0x06, 0xd0, 0x59, 0xd0, 0x40, + 0x8c, 0x65, 0x20, 0x8e, 0x3f, 0xa6, 0x42, 0xb0, 0xa5, 0x27, 0xba, 0xa5, 0x3d, 0x63, 0xbf, 0x68, + 0xb5, 0xa5, 0xc9, 0x42, 0xcb, 0x33, 0x65, 0x20, 0x0f, 0x61, 0x27, 0x4b, 0x1d, 0x4f, 0x79, 0xe8, + 0x8a, 0x6e, 0x19, 0x17, 0x10, 0x3f, 0x4d, 0x3e, 0x94, 0x16, 0xf3, 0x3d, 0xf4, 0x37, 0x16, 0x2e, + 0xf0, 0xb8, 0x1b, 0x30, 0xf2, 0x18, 0xb6, 0x74, 0xd8, 0x41, 0xd7, 0xd8, 0x2b, 0xee, 0xd7, 0x86, + 0xb7, 0x06, 0xc9, 0xa6, 0xaf, 0xae, 0xb4, 0x62, 0xba, 0xf9, 0x43, 0x68, 0xbe, 0x60, 0xe2, 0x44, + 0xd0, 0x64, 0x1f, 0xee, 0xc0, 0x75, 0xd9, 0x09, 0x63, 0xc7, 0x56, 0x55, 0x3c, 0x68, 0xfc, 0xf9, + 0x73, 0xff, 0xda, 0x5f, 0x3f, 0xf7, 0x2b, 0x6f, 0xb8, 0xcd, 0x46, 0x47, 0x56, 0x45, 0x9a, 0x47, + 0xb6, 0xf9, 0x3b, 0x03, 0x5a, 0xc9, 0x62, 0x1d, 0x4b, 0x1f, 0x6a, 0x34, 0xb4, 0x9d, 0x28, 0x2f, + 0x03, 0xf3, 0x02, 0x84, 0x30, 0x9f, 0x84, 0x80, 0xfd, 0x83, 0x5b, 0x61, 0x68, 0x82, 0x25, 0x11, + 0x72, 0x1b, 0xea, 0xa1, 0x27, 0xdb, 0x47, 0xbb, 0x28, 0xa2, 0x8b, 0x9a, 0xc2, 0x94, 0x8f, 0x84, + 0xa2, 0x9c, 0x94, 0xd0, 0x89, 0xa6, 0xa0, 0x17, 0xf3, 0x6f, 0x06, 0x90, 0x43, 0x9f, 0x51, 0xc1, + 0xfe, 0xab, 0xe4, 0xf2, 0x79, 0x14, 0x56, 0xf2, 0x18, 0x40, 0x47, 0x11, 0x82, 0x70, 0x3a, 0x65, + 0x41, 0x90, 0x89, 0xb6, 0x8d, 0xa6, 0x13, 0x65, 0xc9, 0xc7, 0xac, 0x88, 0xa5, 0xd5, 0xb4, 0x1e, + 0xc2, 0x8e, 0xa6, 0x64, 0x7d, 0xea, 0xe6, 0x50, 0xb6, 0xb4, 0x53, 0xf3, 0x0b, 0xe8, 0x64, 0x92, + 0x54, 0x9b, 0x60, 0xde, 0x03, 0x82, 0x76, 0x99, 0x53, 0xb2, 0x35, 0x3b, 0x50, 0x4e, 0x6f, 0x8a, + 0x7a, 0x30, 0x3b, 0xd0, 0x4e, 0x73, 0xb1, 0x4c, 0x12, 0x7c, 0xc1, 0xc4, 0x41, 0x38, 0x3d, 0x67, + 0x71, 0xed, 0xcc, 0x97, 0x40, 0xd2, 0x60, 0xe2, 0x55, 0x70, 0x41, 0x17, 0x91, 0x57, 0x7c, 0x20, + 0x37, 0xa1, 0xe8, 0xd8, 0x41, 0xb7, 0xb0, 0x57, 0xdc, 0xaf, 0x1f, 0x40, 0xaa, 0xbe, 0x12, 0x36, + 0x87, 0xd8, 0x38, 0xca, 0x53, 0xb4, 0x33, 0xbb, 0x50, 0xd8, 0xb8, 0x29, 0x05, 0xc7, 0x36, 0x7f, + 0x92, 0x0a, 0x29, 0x7e, 0xf9, 0x25, 0x8b, 0xc8, 0x1e, 0x94, 0xe5, 0x7e, 0xaa, 0x40, 0x6a, 0x43, + 0x18, 0xe0, 0x8c, 0x93, 0x04, 0x4b, 0x19, 0xcc, 0x7b, 0x50, 0x51, 0x3e, 0xaf, 0xc0, 0x1d, 0x00, + 0x28, 0xae, 0xfc, 0x20, 0x13, 0xbe, 0xb1, 0x89, 0xff, 0x0a, 0x9a, 0xc7, 0x8e, 0x3b, 0x43, 0xe8, + 0x6a, 0x59, 0x92, 0x2e, 0x5c, 0xa7, 0xb6, 0xed, 0xb3, 0x20, 0xc0, 0x96, 0xab, 0x5a, 0xd1, 0xa3, + 0x69, 0x42, 0x2b, 0x71, 0xa6, 0xd3, 0x6f, 0x40, 0x81, 0x9f, 0xa3, 0xb7, 0x2d, 0xab, 0xc0, 0xcf, + 0xcd, 0xa7, 0xd0, 0x7e, 0xcd, 0xf9, 0x79, 0xe8, 0xa5, 0x5f, 0xd9, 0x88, 0x5f, 0x59, 0xbd, 0xe4, + 0x15, 0xef, 0x81, 0xa4, 0x97, 0xc7, 0x35, 0x2e, 0xc9, 0x74, 0xd0, 0x43, 0x36, 0x4d, 0xc4, 0xc9, + 0x77, 0xa0, 0xb4, 0x64, 0x82, 0xc6, 0x43, 0x35, 0xb6, 0xff, 0x98, 0x09, 0x6a, 0x53, 0x41, 0x2d, + 0xb4, 0x9b, 0x3f, 0x83, 0x26, 0x26, 0xea, 0x9e, 0xf1, 0xab, 0x56, 0xe3, 0x7e, 0x36, 0xd4, 0xda, + 0xb0, 0x9d, 0x78, 0x7f, 0xa6, 0x0c, 0x49, 0xf4, 0xbf, 0x31, 0xa0, 0x95, 0xbc, 0x40, 0x07, 0x6f, + 0x42, 0x49, 0x5c, 0x78, 0x2a, 0xf8, 0xc6, 0xb0, 0x91, 0x2c, 0x3f, 0xbd, 0xf0, 0x98, 0x85, 0x36, + 0x32, 0x80, 0x2d, 0xee, 0x31, 0x9f, 0x0a, 0xee, 0xaf, 0x26, 0xf1, 0x56, 0x5b, 0xac, 0x98, 0x23, + 0xf9, 0x53, 0xea, 0xd1, 0xa9, 0x23, 0x2e, 0xf0, 0x73, 0xcf, 0xf0, 0x0f, 0xb5, 0xc5, 0x8a, 0x39, + 0xe6, 0x12, 0x9a, 0xcf, 0x1d, 0xd7, 0x7e, 0xc3, 0xa8, 0x7f, 0xd5, 0xc4, 0xbf, 0x05, 0xe5, 0x40, + 0x50, 0x5f, 0xcd, 0x9d, 0x55, 0x8a, 0x32, 0x26, 0x27, 0xa6, 0x1a, 0x3a, 0xea, 0xc1, 0x7c, 0x04, + 0xad, 0xe4, 0x75, 0xba, 0x0c, 0x97, 0xf7, 0x36, 0x81, 0xd6, 0x51, 0xb8, 0xf4, 0x32, 0x53, 0xe0, + 0x07, 0xd0, 0x4e, 0x61, 0x79, 0x57, 0x1b, 0xdb, 0xbe, 0x01, 0xf5, 0xf4, 0xcc, 0x35, 0xff, 0x65, + 0x40, 0x47, 0x02, 0x27, 0xe1, 0x72, 0x49, 0xfd, 0x8b, 0xd8, 0xd3, 0x2d, 0x80, 0x30, 0x60, 0xf6, + 0x38, 0xf0, 0xe8, 0x94, 0xe9, 0xf1, 0x51, 0x95, 0xc8, 0x89, 0x04, 0xc8, 0x1d, 0x68, 0xd2, 0x8f, + 0xd4, 0x59, 0xc8, 0x83, 0x4b, 0x73, 0xd4, 0x14, 0x6e, 0xc4, 0xb0, 0x22, 0xca, 0xc9, 0x2a, 0xfd, + 0x38, 0xee, 0x0c, 0x5b, 0x25, 0x3a, 0x30, 0x02, 0x66, 0x8f, 0x14, 0x24, 0xa7, 0x39, 0x52, 0x98, + 0x62, 0xa8, 0xd9, 0x8b, 0x6f, 0xff, 0x91, 0x22, 0x7c, 0x1b, 0x1a, 0x48, 0x98, 0x50, 0xd7, 0xfe, + 0x85, 0x63, 0x8b, 0xb9, 0x1e, 0xba, 0xdb, 0x12, 0x3d, 0x88, 0x40, 0xf2, 0x00, 0x3a, 0x49, 0x4c, + 0x09, 0xb7, 0xa2, 0x06, 0x74, 0x6c, 0x8a, 0x17, 0x60, 0x59, 0x69, 0x30, 0x9f, 0x70, 0xea, 0xdb, + 0x51, 0x3d, 0xfe, 0x52, 0x84, 0x76, 0x0a, 0xd4, 0xd5, 0xb8, 0xf2, 0xc9, 0x74, 0x17, 0x5a, 0x48, + 0x9c, 0x72, 0xd7, 0x65, 0x53, 0xa9, 0xc1, 0x02, 0x5d, 0x98, 0xa6, 0xc4, 0x0f, 0x13, 0x98, 0xdc, + 0x87, 0xf6, 0x84, 0x73, 0x11, 0x08, 0x9f, 0x7a, 0xe3, 0xe8, 0x4b, 0x2a, 0xe2, 0x47, 0xdf, 0x8a, + 0x0d, 0xfa, 0x43, 0x92, 0x7e, 0x51, 0x03, 0xb9, 0x74, 0x11, 0x73, 0x4b, 0xc8, 0x6d, 0x46, 0x78, + 0x8a, 0xca, 0x3e, 0xe5, 0xa8, 0x65, 0x45, 0x8d, 0xf0, 0x88, 0xfa, 0x08, 0x3b, 0x59, 0x04, 0x58, + 0xa3, 0xda, 0x70, 0x37, 0x25, 0x4c, 0xd6, 0xf4, 0x84, 0xa5, 0xc8, 0xe4, 0x7b, 0x50, 0x51, 0xa7, + 0x5d, 0xf7, 0x3a, 0x2e, 0xfb, 0xc6, 0x40, 0xe9, 0xcb, 0x41, 0xa4, 0x2f, 0x07, 0x47, 0x5a, 0x7f, + 0x5a, 0x9a, 0x48, 0x9e, 0x40, 0x0d, 0x95, 0x98, 0xe7, 0xb8, 0x33, 0x66, 0x77, 0xb7, 0x70, 0x5d, + 0x6f, 0x65, 0xdd, 0x69, 0xa4, 0x4b, 0x2d, 0x90, 0xf4, 0x63, 0x64, 0x93, 0xa7, 0x50, 0xc7, 0xc5, + 0x1f, 0x42, 0xe6, 0x3b, 0xcc, 0xee, 0x56, 0x2f, 0x5d, 0x8d, 0x2f, 0x7b, 0xa7, 0xe8, 0xe6, 0x6f, + 0x0d, 0xd8, 0xd1, 0xda, 0xea, 0x25, 0xa3, 0x0b, 0x31, 0x8f, 0xbe, 0xf3, 0x2f, 0xa1, 0x32, 0xc1, + 0x13, 0x43, 0x0b, 0x52, 0xfd, 0x24, 0xdb, 0x8d, 0xb9, 0x53, 0xff, 0xc2, 0x13, 0xcc, 0x1e, 0xa3, + 0x60, 0xc5, 0x0f, 0xdd, 0xda, 0x8e, 0xd1, 0x63, 0xa9, 0x5c, 0xbf, 0x09, 0x91, 0x1e, 0x1d, 0x3b, + 0xae, 0xcd, 0x3e, 0xe9, 0xd6, 0xae, 0x6b, 0x70, 0x24, 0x31, 0xf9, 0x19, 0x79, 0x3e, 0xff, 0x39, + 0x9b, 0x0a, 0xd9, 0x3b, 0x25, 0xf4, 0x53, 0xd5, 0xc8, 0xc8, 0x36, 0xff, 0x6e, 0xc0, 0x76, 0x26, + 0x36, 0xb9, 0x7b, 0x4b, 0xc7, 0x75, 0x96, 0xe1, 0x72, 0xec, 0xb3, 0x0f, 0xa1, 0xe3, 0x33, 0x5b, + 0x6b, 0xee, 0xa6, 0xc6, 0x2d, 0x0d, 0x27, 0x87, 0xbb, 0x12, 0xdf, 0xfa, 0x70, 0xbf, 0x0b, 0x2d, + 0x2d, 0x62, 0xc5, 0xdc, 0x67, 0xc1, 0x9c, 0x2f, 0x6c, 0x2d, 0x8d, 0x9b, 0x0a, 0x3f, 0x8d, 0x60, + 0xd9, 0x81, 0x91, 0x96, 0x49, 0xb8, 0x25, 0xe4, 0xb6, 0xb4, 0x21, 0x21, 0xdf, 0x86, 0x3a, 0x77, + 0x17, 0x8e, 0xcb, 0xc6, 0x6a, 0xc2, 0x94, 0x91, 0x57, 0x53, 0x18, 0x4e, 0x21, 0x79, 0x78, 0xe9, + 0xe4, 0xb1, 0xa1, 0xea, 0x56, 0xf4, 0x68, 0xfe, 0xd2, 0x80, 0x2f, 0x72, 0x7b, 0xa0, 0xbf, 0xac, + 0x87, 0x50, 0x99, 0x23, 0xa2, 0x8f, 0xb0, 0x6e, 0xba, 0x07, 0x33, 0x2b, 0x34, 0x8f, 0x3c, 0x01, + 0xf0, 0x99, 0x1d, 0xba, 0x36, 0x75, 0xa7, 0x17, 0xfa, 0x4c, 0xb8, 0x91, 0xba, 0x2d, 0x58, 0xb1, + 0xf1, 0x64, 0x3a, 0x67, 0x4b, 0x66, 0xa5, 0xe8, 0xe6, 0x3f, 0x0d, 0xe8, 0xbc, 0x9d, 0xc8, 0xea, + 0x67, 0x7b, 0x61, 0x75, 0xcf, 0x8d, 0x75, 0x7b, 0x9e, 0xb4, 0x4c, 0x21, 0xd3, 0x32, 0xd9, 0x6d, + 0x2e, 0xe6, 0xb6, 0x59, 0xca, 0x51, 0x3c, 0x14, 0xc6, 0xf4, 0x4c, 0x30, 0x7f, 0x1c, 0x15, 0x49, + 0x5f, 0x44, 0xd0, 0xf4, 0x4c, 0x5a, 0xa2, 0x8b, 0xd2, 0x77, 0x81, 0x30, 0xd7, 0x1e, 0x4f, 0xd8, + 0x19, 0xf7, 0x59, 0x4c, 0x57, 0x43, 0xaf, 0xc5, 0x5c, 0xfb, 0x00, 0x0d, 0x11, 0x3b, 0x3e, 0x69, + 0x2a, 0xa9, 0xbb, 0x99, 0xf9, 0x6b, 0x03, 0x76, 0xb2, 0x99, 0xea, 0x8a, 0x3f, 0x5a, 0xb9, 0x90, + 0x6c, 0xae, 0x79, 0xcc, 0xfc, 0x9f, 0xaa, 0x3e, 0xfc, 0x53, 0x11, 0xea, 0xaf, 0xa8, 0x3d, 0x8a, + 0xde, 0x42, 0x46, 0x00, 0x89, 0xae, 0x25, 0x37, 0x53, 0xef, 0x5f, 0x91, 0xbb, 0xbd, 0x5b, 0x1b, + 0xac, 0x3a, 0x9d, 0x43, 0xd8, 0x8a, 0xa4, 0x17, 0xe9, 0xa5, 0xa8, 0x39, 0x71, 0xd7, 0xbb, 0xb1, + 0xd6, 0xa6, 0x9d, 0x8c, 0x00, 0x12, 0x71, 0x95, 0x89, 0x67, 0x45, 0xb2, 0x65, 0xe2, 0x59, 0xa3, + 0xc8, 0x0e, 0x61, 0x2b, 0x12, 0x3a, 0x99, 0x78, 0x72, 0xf2, 0x2a, 0x13, 0xcf, 0x8a, 0x32, 0x3a, + 0x84, 0xad, 0x48, 0x26, 0x64, 0x9c, 0xe4, 0xa4, 0x4a, 0xc6, 0xc9, 0x8a, 0xae, 0x78, 0x0e, 0xd5, + 0x58, 0x21, 0x90, 0x34, 0x33, 0xaf, 0x25, 0x7a, 0x37, 0xd7, 0x1b, 0x95, 0x9f, 0xe1, 0x1f, 0x0a, + 0xd0, 0x7a, 0xfb, 0x91, 0xf9, 0x0b, 0x7a, 0xf1, 0xb5, 0xec, 0xe0, 0xff, 0x29, 0x4e, 0x59, 0xb4, + 0xe8, 0xc6, 0x9b, 0x29, 0x5a, 0xee, 0x0e, 0x9d, 0x29, 0xda, 0xca, 0x15, 0xf9, 0x35, 0xd4, 0x52, + 0x97, 0x36, 0x92, 0x09, 0x7d, 0xe5, 0xc6, 0xda, 0xdb, 0xdd, 0x64, 0xd6, 0xa5, 0xfb, 0xbd, 0x01, + 0x1d, 0xfc, 0x33, 0xe2, 0x44, 0x70, 0x9f, 0x25, 0xd5, 0x3b, 0x80, 0xb2, 0xf2, 0xff, 0x55, 0xee, + 0xc8, 0x5d, 0xeb, 0x79, 0xcd, 0x59, 0x6c, 0x5e, 0x23, 0x2f, 0xa1, 0x1a, 0x0b, 0x95, 0x6c, 0xd9, + 0x72, 0x9a, 0x26, 0x5b, 0xb6, 0xbc, 0xb6, 0x31, 0xaf, 0x0d, 0x7f, 0x65, 0xc0, 0x4e, 0xea, 0x8f, + 0x88, 0x24, 0x4c, 0x0f, 0xbe, 0xda, 0xf0, 0xf7, 0x06, 0xb9, 0x9b, 0xfe, 0x0a, 0xfe, 0xe3, 0x7f, + 0x47, 0xbd, 0x7b, 0x57, 0xa1, 0xea, 0x82, 0xfd, 0xd1, 0x80, 0xa6, 0x9a, 0x3d, 0x49, 0x14, 0xef, + 0xa0, 0x9e, 0x1e, 0x64, 0x24, 0x5d, 0x9a, 0x35, 0xb3, 0xbc, 0xd7, 0xdf, 0x68, 0x8f, 0x6b, 0x77, + 0x9a, 0x3f, 0x76, 0xfb, 0x1b, 0x47, 0xa0, 0x76, 0xba, 0xb7, 0x99, 0x10, 0x79, 0x3d, 0x28, 0xfd, + 0xb4, 0xe0, 0x4d, 0x26, 0x15, 0x14, 0x24, 0xdf, 0xff, 0x77, 0x00, 0x00, 0x00, 0xff, 0xff, 0x1d, + 0x67, 0x84, 0xd4, 0xdb, 0x13, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -2006,3 +2344,104 @@ var _IrreparableInspector_serviceDesc = grpc.ServiceDesc{ Streams: []grpc.StreamDesc{}, Metadata: "inspector.proto", } + +// HealthInspectorClient is the client API for HealthInspector service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type HealthInspectorClient interface { + // ObjectHealth will returns stats about the health of an object + ObjectHealth(ctx context.Context, in *ObjectHealthRequest, opts ...grpc.CallOption) (*ObjectHealthResponse, error) + // SegmentHealth will returns stats about the health of a segment + SegmentHealth(ctx context.Context, in *SegmentHealthRequest, opts ...grpc.CallOption) (*SegmentHealthResponse, error) +} + +type healthInspectorClient struct { + cc *grpc.ClientConn +} + +func NewHealthInspectorClient(cc *grpc.ClientConn) HealthInspectorClient { + return &healthInspectorClient{cc} +} + +func (c *healthInspectorClient) ObjectHealth(ctx context.Context, in *ObjectHealthRequest, opts ...grpc.CallOption) (*ObjectHealthResponse, error) { + out := new(ObjectHealthResponse) + err := c.cc.Invoke(ctx, "/inspector.HealthInspector/ObjectHealth", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *healthInspectorClient) SegmentHealth(ctx context.Context, in *SegmentHealthRequest, opts ...grpc.CallOption) (*SegmentHealthResponse, error) { + out := new(SegmentHealthResponse) + err := c.cc.Invoke(ctx, "/inspector.HealthInspector/SegmentHealth", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// HealthInspectorServer is the server API for HealthInspector service. +type HealthInspectorServer interface { + // ObjectHealth will returns stats about the health of an object + ObjectHealth(context.Context, *ObjectHealthRequest) (*ObjectHealthResponse, error) + // SegmentHealth will returns stats about the health of a segment + SegmentHealth(context.Context, *SegmentHealthRequest) (*SegmentHealthResponse, error) +} + +func RegisterHealthInspectorServer(s *grpc.Server, srv HealthInspectorServer) { + s.RegisterService(&_HealthInspector_serviceDesc, srv) +} + +func _HealthInspector_ObjectHealth_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ObjectHealthRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HealthInspectorServer).ObjectHealth(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/inspector.HealthInspector/ObjectHealth", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HealthInspectorServer).ObjectHealth(ctx, req.(*ObjectHealthRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _HealthInspector_SegmentHealth_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SegmentHealthRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HealthInspectorServer).SegmentHealth(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/inspector.HealthInspector/SegmentHealth", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HealthInspectorServer).SegmentHealth(ctx, req.(*SegmentHealthRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _HealthInspector_serviceDesc = grpc.ServiceDesc{ + ServiceName: "inspector.HealthInspector", + HandlerType: (*HealthInspectorServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "ObjectHealth", + Handler: _HealthInspector_ObjectHealth_Handler, + }, + { + MethodName: "SegmentHealth", + Handler: _HealthInspector_SegmentHealth_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "inspector.proto", +} diff --git a/pkg/pb/inspector.proto b/pkg/pb/inspector.proto index e5c4b245c..ee1cfec6b 100644 --- a/pkg/pb/inspector.proto +++ b/pkg/pb/inspector.proto @@ -50,6 +50,14 @@ service IrreparableInspector { rpc ListIrreparableSegments(ListIrreparableSegmentsRequest) returns (ListIrreparableSegmentsResponse); } +service HealthInspector { + // ObjectHealth will return stats about the health of an object + rpc ObjectHealth(ObjectHealthRequest) returns (ObjectHealthResponse) {} + // SegmentHealth will return stats about the health of a segment + rpc SegmentHealth(SegmentHealthRequest) returns (SegmentHealthResponse) {} +} + + // ListSegments message ListIrreparableSegmentsRequest { int32 limit = 1; @@ -198,3 +206,38 @@ message DashboardResponse { google.protobuf.Timestamp last_pinged = 8; google.protobuf.Timestamp last_queried = 9; } + +message SegmentHealthRequest { + bytes bucket = 1; // segment bucket name + bytes encrypted_path = 2; // segment encrypted path + int64 segment_index = 3; // segment index + bytes project_id = 4; // segment project id +} + +message SegmentHealth { + int32 minimum_required = 1; // minimum required stripes for reconstruction (k) + int32 total = 2; // total amount of pieces we generated (n) + int32 repair_threshold = 3; // amount of pieces we need to drop to before triggering repair (m) + int32 success_threshold = 4; // amount of pieces we need to store to call it a success (o) + int32 online_nodes = 5; // amount of pieces with nodes that are online + bytes segment = 6; // path formatted segment index +} + +message SegmentHealthResponse { + SegmentHealth health = 1; // Information about a segment's health + pointerdb.RedundancyScheme redundancy = 2; // expected segment info +} + +message ObjectHealthRequest { + bytes encrypted_path = 1; // object encrypted path + bytes bucket = 2; // object bucket name + bytes project_id = 3; // object project id + int64 start_after_segment = 4; // Get all segments after specified segment index + int64 end_before_segment = 5; // Stop at segment before specified segment index + int32 limit = 6; // Max number of segments that are checked +} + +message ObjectHealthResponse { + repeated SegmentHealth segments = 1; // actual segment info + pointerdb.RedundancyScheme redundancy = 2; // expected segment info +} \ No newline at end of file diff --git a/satellite/inspector/inspector.go b/satellite/inspector/inspector.go new file mode 100644 index 000000000..6a9405657 --- /dev/null +++ b/satellite/inspector/inspector.go @@ -0,0 +1,178 @@ +// Copyright (C) 2019 Storj Labs, Inc. +// See LICENSE for copying information. + +package inspector + +import ( + "context" + "strconv" + + "github.com/skyrings/skyring-common/tools/uuid" + "github.com/zeebo/errs" + "go.uber.org/zap" + monkit "gopkg.in/spacemonkeygo/monkit.v2" + + "storj.io/storj/pkg/eestream" + "storj.io/storj/pkg/overlay" + "storj.io/storj/pkg/pb" + "storj.io/storj/pkg/pointerdb" + "storj.io/storj/pkg/storj" + "storj.io/storj/satellite/metainfo" +) + +var ( + mon = monkit.Package() + // Error wraps errors returned from Server struct methods + Error = errs.Class("Endpoint error") +) + +const lastSegmentIndex = int64(-1) + +// Endpoint for checking object and segment health +type Endpoint struct { + log *zap.Logger + cache *overlay.Cache + pointerdb *pointerdb.Service +} + +// NewEndpoint will initialize an Endpoint struct +func NewEndpoint(log *zap.Logger, cache *overlay.Cache, pdb *pointerdb.Service) *Endpoint { + return &Endpoint{ + log: log, + cache: cache, + pointerdb: pdb, + } +} + +// ObjectHealth will check the health of an object +func (endpoint *Endpoint) ObjectHealth(ctx context.Context, in *pb.ObjectHealthRequest) (resp *pb.ObjectHealthResponse, err error) { + defer mon.Task()(&ctx)(&err) + + var segmentHealthResponses []*pb.SegmentHealth + var redundancy *pb.RedundancyScheme + + limit := int64(100) + if in.GetLimit() > 0 { + limit = int64(in.GetLimit()) + } + + var start int64 + if in.GetStartAfterSegment() > 0 { + start = in.GetStartAfterSegment() + 1 + } + + end := limit + start + if in.GetEndBeforeSegment() > 0 { + end = in.GetEndBeforeSegment() + } + + bucket := in.GetBucket() + encryptedPath := in.GetEncryptedPath() + projectID := in.GetProjectId() + + segmentIndex := start + for segmentIndex < end { + if segmentIndex-start >= limit { + break + } + + segment := &pb.SegmentHealthRequest{ + Bucket: bucket, + EncryptedPath: encryptedPath, + SegmentIndex: segmentIndex, + ProjectId: projectID, + } + + segmentHealth, err := endpoint.SegmentHealth(ctx, segment) + if err != nil { + if segmentIndex == lastSegmentIndex { + return nil, Error.Wrap(err) + } + + segmentIndex = lastSegmentIndex + continue + } + + segmentHealthResponses = append(segmentHealthResponses, segmentHealth.GetHealth()) + redundancy = segmentHealth.GetRedundancy() + + if segmentIndex == lastSegmentIndex { + break + } + + segmentIndex++ + } + + return &pb.ObjectHealthResponse{ + Segments: segmentHealthResponses, + Redundancy: redundancy, + }, nil +} + +// SegmentHealth will check the health of a segment +func (endpoint *Endpoint) SegmentHealth(ctx context.Context, in *pb.SegmentHealthRequest) (resp *pb.SegmentHealthResponse, err error) { + defer mon.Task()(&ctx)(&err) + + health := &pb.SegmentHealth{} + + projectID, err := uuid.Parse(string(in.GetProjectId())) + if err != nil { + return nil, Error.Wrap(err) + } + + path, err := metainfo.CreatePath(*projectID, in.GetSegmentIndex(), in.GetBucket(), in.GetEncryptedPath()) + if err != nil { + return nil, Error.Wrap(err) + } + + pointer, err := endpoint.pointerdb.Get(path) + if err != nil { + return nil, Error.Wrap(err) + } + + if pointer.GetType() != pb.Pointer_REMOTE { + return nil, Error.New("cannot check health of inline segment") + } + + redundancy, err := eestream.NewRedundancyStrategyFromProto(pointer.GetRemote().GetRedundancy()) + if err != nil { + return nil, Error.Wrap(err) + } + + var nodeIDs storj.NodeIDList + for _, piece := range pointer.GetRemote().GetRemotePieces() { + nodeIDs = append(nodeIDs, piece.NodeId) + } + + nodes, err := endpoint.cache.GetAll(ctx, nodeIDs) + if err != nil { + return nil, Error.Wrap(err) + } + + neededForRepair := health.GetOnlineNodes() - int32(redundancy.RepairThreshold()) + if neededForRepair < 0 { + neededForRepair = int32(0) + } + + neededForSuccess := health.GetOnlineNodes() - int32(redundancy.OptimalThreshold()) + if neededForSuccess < 0 { + neededForSuccess = int32(0) + } + + health.MinimumRequired = int32(redundancy.RequiredCount()) + health.Total = int32(redundancy.TotalCount()) + health.RepairThreshold = neededForRepair + health.SuccessThreshold = neededForSuccess + health.OnlineNodes = int32(len(nodes)) + + if in.GetSegmentIndex() > -1 { + health.Segment = []byte("s" + strconv.FormatInt(in.GetSegmentIndex(), 10)) + } else { + health.Segment = []byte("l") + } + + return &pb.SegmentHealthResponse{ + Health: health, + Redundancy: pointer.GetRemote().GetRedundancy(), + }, nil +} diff --git a/satellite/inspector/inspector_test.go b/satellite/inspector/inspector_test.go new file mode 100644 index 000000000..9069cce3a --- /dev/null +++ b/satellite/inspector/inspector_test.go @@ -0,0 +1,104 @@ +// Copyright (C) 2019 Storj Labs, Inc. +// See LICENSE for copying information. + +package inspector_test + +import ( + "bytes" + "crypto/rand" + "fmt" + "strings" + "testing" + + "github.com/stretchr/testify/require" + + "storj.io/storj/internal/memory" + "storj.io/storj/internal/testcontext" + "storj.io/storj/internal/testplanet" + "storj.io/storj/pkg/pb" + "storj.io/storj/pkg/storj" + "storj.io/storj/storage" +) + +func TestInspectorStats(t *testing.T) { + ctx := testcontext.New(t) + defer ctx.Cleanup() + + planet, err := testplanet.New(t, 1, 6, 1) + require.NoError(t, err) + defer ctx.Check(planet.Shutdown) + + planet.Start(ctx) + + uplink := planet.Uplinks[0] + testData := make([]byte, 1*memory.MiB) + _, err = rand.Read(testData) + require.NoError(t, err) + + bucket := "testbucket" + + err = uplink.Upload(ctx, planet.Satellites[0], bucket, "test/path", testData) + require.NoError(t, err) + + healthEndpoint := planet.Satellites[0].Inspector.Endpoint + + // Get path of random segment we just uploaded and check the health + _ = planet.Satellites[0].Metainfo.Database.Iterate(storage.IterateOptions{Recurse: true}, + func(it storage.Iterator) error { + var item storage.ListItem + for it.Next(&item) { + if bytes.Contains(item.Key, []byte(fmt.Sprintf("%s/", bucket))) { + break + } + } + + fullPath := storj.SplitPath(item.Key.String()) + require.Falsef(t, len(fullPath) < 4, "Could not retrieve a full path from pointerdb") + + projectID := fullPath[0] + bucket := fullPath[2] + encryptedPath := strings.Join(fullPath[3:], "/") + + { // Test Segment Health Request + req := &pb.SegmentHealthRequest{ + ProjectId: []byte(projectID), + EncryptedPath: []byte(encryptedPath), + Bucket: []byte(bucket), + SegmentIndex: -1, + } + + resp, err := healthEndpoint.SegmentHealth(ctx, req) + require.NoError(t, err) + + require.Equal(t, int32(0), resp.GetHealth().GetSuccessThreshold()) + require.Equal(t, int32(1), resp.GetHealth().GetMinimumRequired()) + require.Equal(t, int32(4), resp.GetHealth().GetTotal()) + require.Equal(t, int32(0), resp.GetHealth().GetRepairThreshold()) + } + + { // Test Object Health Request + objectHealthReq := &pb.ObjectHealthRequest{ + ProjectId: []byte(projectID), + EncryptedPath: []byte(encryptedPath), + Bucket: []byte(bucket), + StartAfterSegment: 0, + EndBeforeSegment: 0, + Limit: 0, + } + resp, err := healthEndpoint.ObjectHealth(ctx, objectHealthReq) + + require.Len(t, resp.GetSegments(), 1) + + segments := resp.GetSegments() + require.Equal(t, int32(0), segments[0].GetSuccessThreshold()) + require.Equal(t, int32(1), segments[0].GetMinimumRequired()) + require.Equal(t, int32(4), segments[0].GetTotal()) + require.Equal(t, int32(0), segments[0].GetRepairThreshold()) + + require.NoError(t, err) + } + + return nil + }, + ) +} diff --git a/satellite/metainfo/metainfo.go b/satellite/metainfo/metainfo.go index e3924c664..956a4c2b4 100644 --- a/satellite/metainfo/metainfo.go +++ b/satellite/metainfo/metainfo.go @@ -6,6 +6,7 @@ package metainfo import ( "bytes" "context" + "errors" "strconv" "github.com/skyrings/skyring-common/tools/uuid" @@ -98,7 +99,7 @@ func (endpoint *Endpoint) SegmentInfo(ctx context.Context, req *pb.SegmentInfoRe return nil, status.Errorf(codes.InvalidArgument, err.Error()) } - path, err := endpoint.createPath(keyInfo.ProjectID, req.Segment, req.Bucket, req.Path) + path, err := CreatePath(keyInfo.ProjectID, req.Segment, req.Bucket, req.Path) if err != nil { return nil, status.Errorf(codes.InvalidArgument, err.Error()) } @@ -184,7 +185,7 @@ func (endpoint *Endpoint) CommitSegment(ctx context.Context, req *pb.SegmentComm return nil, status.Errorf(codes.Internal, err.Error()) } - path, err := endpoint.createPath(keyInfo.ProjectID, req.Segment, req.Bucket, req.Path) + path, err := CreatePath(keyInfo.ProjectID, req.Segment, req.Bucket, req.Path) if err != nil { return nil, status.Errorf(codes.InvalidArgument, err.Error()) } @@ -216,7 +217,7 @@ func (endpoint *Endpoint) DownloadSegment(ctx context.Context, req *pb.SegmentDo return nil, status.Errorf(codes.InvalidArgument, err.Error()) } - path, err := endpoint.createPath(keyInfo.ProjectID, req.Segment, req.Bucket, req.Path) + path, err := CreatePath(keyInfo.ProjectID, req.Segment, req.Bucket, req.Path) if err != nil { return nil, status.Errorf(codes.InvalidArgument, err.Error()) } @@ -264,7 +265,7 @@ func (endpoint *Endpoint) DeleteSegment(ctx context.Context, req *pb.SegmentDele return nil, status.Errorf(codes.InvalidArgument, err.Error()) } - path, err := endpoint.createPath(keyInfo.ProjectID, req.Segment, req.Bucket, req.Path) + path, err := CreatePath(keyInfo.ProjectID, req.Segment, req.Bucket, req.Path) if err != nil { return nil, status.Errorf(codes.InvalidArgument, err.Error()) } @@ -310,7 +311,7 @@ func (endpoint *Endpoint) ListSegments(ctx context.Context, req *pb.ListSegments return nil, status.Errorf(codes.Unauthenticated, err.Error()) } - prefix, err := endpoint.createPath(keyInfo.ProjectID, -1, req.Bucket, req.Prefix) + prefix, err := CreatePath(keyInfo.ProjectID, -1, req.Bucket, req.Prefix) if err != nil { return nil, status.Errorf(codes.InvalidArgument, err.Error()) } @@ -339,27 +340,6 @@ func createBucketID(projectID uuid.UUID, bucket []byte) []byte { return []byte(storj.JoinPaths(entries...)) } -func (endpoint *Endpoint) createPath(projectID uuid.UUID, segmentIndex int64, bucket, path []byte) (storj.Path, error) { - if segmentIndex < -1 { - return "", Error.New("invalid segment index") - } - segment := "l" - if segmentIndex > -1 { - segment = "s" + strconv.FormatInt(segmentIndex, 10) - } - - entries := make([]string, 0) - entries = append(entries, projectID.String()) - entries = append(entries, segment) - if len(bucket) != 0 { - entries = append(entries, string(bucket)) - } - if len(path) != 0 { - entries = append(entries, string(path)) - } - return storj.JoinPaths(entries...), nil -} - func (endpoint *Endpoint) filterValidPieces(pointer *pb.Pointer) error { if pointer.Type == pb.Pointer_REMOTE { var remotePieces []*pb.RemotePiece @@ -457,3 +437,25 @@ func (endpoint *Endpoint) validatePointer(pointer *pb.Pointer) error { } return nil } + +// CreatePath will create a Segment path +func CreatePath(projectID uuid.UUID, segmentIndex int64, bucket, path []byte) (storj.Path, error) { + if segmentIndex < -1 { + return "", errors.New("invalid segment index") + } + segment := "l" + if segmentIndex > -1 { + segment = "s" + strconv.FormatInt(segmentIndex, 10) + } + + entries := make([]string, 0) + entries = append(entries, projectID.String()) + entries = append(entries, segment) + if len(bucket) != 0 { + entries = append(entries, string(bucket)) + } + if len(path) != 0 { + entries = append(entries, string(path)) + } + return storj.JoinPaths(entries...), nil +} diff --git a/satellite/peer.go b/satellite/peer.go index c660e3a5e..8ba70e21a 100644 --- a/satellite/peer.go +++ b/satellite/peer.go @@ -46,6 +46,7 @@ import ( "storj.io/storj/satellite/console" "storj.io/storj/satellite/console/consoleauth" "storj.io/storj/satellite/console/consoleweb" + "storj.io/storj/satellite/inspector" "storj.io/storj/satellite/mailservice" "storj.io/storj/satellite/mailservice/simulate" "storj.io/storj/satellite/metainfo" @@ -146,6 +147,10 @@ type Peer struct { Endpoint2 *metainfo.Endpoint } + Inspector struct { + Endpoint *inspector.Endpoint + } + Agreements struct { Endpoint *bwagreement.Server } @@ -383,6 +388,17 @@ func New(log *zap.Logger, full *identity.FullIdentity, db DB, config *Config) (* peer.Accounting.Rollup = rollup.New(peer.Log.Named("rollup"), peer.DB.Accounting(), config.Rollup.Interval) } + { // setup inspector + log.Debug("Setting up inspector") + peer.Inspector.Endpoint = inspector.NewEndpoint( + peer.Log.Named("inspector"), + peer.Overlay.Service, + peer.Metainfo.Service, + ) + + pb.RegisterHealthInspectorServer(peer.Server.PrivateGRPC(), peer.Inspector.Endpoint) + } + { // setup mailservice log.Debug("Setting up mail service") // TODO(yar): test multiple satellites using same OAUTH credentials