From a3f9bda390af55fc1d8354120222e1ad63b55d18 Mon Sep 17 00:00:00 2001 From: Dmitriy Matrenichev Date: Wed, 2 Oct 2024 18:09:59 +0300 Subject: [PATCH] chore: add proto-codec/codec Unify usage of proto codec v2 across out projects. Signed-off-by: Dmitriy Matrenichev --- Dockerfile | 10 +-- Makefile | 8 +- cmd/discovery-service/main.go | 2 +- go.mod | 15 ++-- go.sum | 30 +++---- internal/proto/proto.go | 151 ---------------------------------- pkg/server/logging.go | 2 +- pkg/server/server_test.go | 2 +- 8 files changed, 36 insertions(+), 184 deletions(-) delete mode 100644 internal/proto/proto.go diff --git a/Dockerfile b/Dockerfile index 4ca38bd..b3d7ef3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,17 +1,17 @@ -# syntax = docker/dockerfile-upstream:1.9.0-labs +# syntax = docker/dockerfile-upstream:1.10.0-labs # THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT. # -# Generated on 2024-09-02T13:05:25Z by kres b5ca957. +# Generated on 2024-10-02T15:00:30Z by kres 34e72ac. ARG TOOLCHAIN -FROM ghcr.io/siderolabs/ca-certificates:v1.7.0 AS image-ca-certificates +FROM ghcr.io/siderolabs/ca-certificates:v1.8.0 AS image-ca-certificates -FROM ghcr.io/siderolabs/fhs:v1.7.0 AS image-fhs +FROM ghcr.io/siderolabs/fhs:v1.8.0 AS image-fhs # runs markdownlint -FROM docker.io/oven/bun:1.1.26-alpine AS lint-markdown +FROM docker.io/oven/bun:1.1.29-alpine AS lint-markdown WORKDIR /src RUN bun i markdownlint-cli@0.41.0 sentences-per-line@0.2.1 COPY .markdownlint.json . diff --git a/Makefile b/Makefile index effff8e..68d3db0 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ # THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT. # -# Generated on 2024-09-02T13:05:25Z by kres b5ca957. +# Generated on 2024-10-02T15:00:30Z by kres 34e72ac. # common variables @@ -21,11 +21,11 @@ PROTOBUF_GO_VERSION ?= 1.34.2 GRPC_GO_VERSION ?= 1.5.1 GRPC_GATEWAY_VERSION ?= 2.22.0 VTPROTOBUF_VERSION ?= 0.6.0 -GOIMPORTS_VERSION ?= 0.24.0 +GOIMPORTS_VERSION ?= 0.25.0 DEEPCOPY_VERSION ?= v0.5.6 -GOLANGCILINT_VERSION ?= v1.60.3 +GOLANGCILINT_VERSION ?= v1.61.0 GOFUMPT_VERSION ?= v0.7.0 -GO_VERSION ?= 1.23.0 +GO_VERSION ?= 1.23.2 GO_BUILDFLAGS ?= GO_LDFLAGS ?= CGO_ENABLED ?= 0 diff --git a/cmd/discovery-service/main.go b/cmd/discovery-service/main.go index 70d71cf..cc1edb3 100644 --- a/cmd/discovery-service/main.go +++ b/cmd/discovery-service/main.go @@ -17,9 +17,9 @@ import ( "github.com/prometheus/client_golang/prometheus" "github.com/siderolabs/go-debug" + _ "github.com/siderolabs/proto-codec/codec" // enable vtproto codecV2 "go.uber.org/zap" - _ "github.com/siderolabs/discovery-service/internal/proto" "github.com/siderolabs/discovery-service/pkg/service" ) diff --git a/go.mod b/go.mod index 8c74b14..f79436e 100644 --- a/go.mod +++ b/go.mod @@ -7,18 +7,19 @@ require ( github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1 github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 github.com/jonboulle/clockwork v0.4.1-0.20231224152657-fc59783b0293 - github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 + github.com/planetscale/vtprotobuf v0.6.1-0.20240917153116-6f2963f01587 github.com/prometheus/client_golang v1.20.4 github.com/siderolabs/discovery-api v0.1.4 github.com/siderolabs/discovery-client v0.1.10 github.com/siderolabs/gen v0.5.0 github.com/siderolabs/go-debug v0.4.0 + github.com/siderolabs/proto-codec v0.1.0 github.com/stretchr/testify v1.9.0 go.uber.org/zap v1.27.0 - golang.org/x/net v0.28.0 + golang.org/x/net v0.29.0 golang.org/x/sync v0.8.0 golang.org/x/time v0.6.0 - google.golang.org/grpc v1.67.0 + google.golang.org/grpc v1.67.1 google.golang.org/protobuf v1.34.2 ) @@ -27,16 +28,16 @@ require ( github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/klauspost/compress v1.17.9 // indirect + github.com/klauspost/compress v1.17.10 // indirect github.com/kylelemons/godebug v1.1.0 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.57.0 // indirect + github.com/prometheus/common v0.60.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/sys v0.24.0 // indirect - golang.org/x/text v0.17.0 // indirect + golang.org/x/sys v0.25.0 // indirect + golang.org/x/text v0.18.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240827150818-7e3bb234dfed // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 40ad215..b288181 100644 --- a/go.sum +++ b/go.sum @@ -16,8 +16,8 @@ github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 h1:pRhl55Yx1eC7BZ1N+BBWwn github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0/go.mod h1:XKMd7iuf/RGPSMJ/U4HP0zS2Z9Fh8Ps9a+6X26m/tmI= github.com/jonboulle/clockwork v0.4.1-0.20231224152657-fc59783b0293 h1:l3TVsYI+QxIp0CW7YCizx9WG26Lj7DXnc1pdlBKk3gY= github.com/jonboulle/clockwork v0.4.1-0.20231224152657-fc59783b0293/go.mod h1:xgRqUGwRcjKCO1vbZUEtSLrqKoPSsUpK7fnezOII0kc= -github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= -github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/klauspost/compress v1.17.10 h1:oXAz+Vh0PMUvJczoi+flxpnBEPxoER1IaAnU/NMPtT0= +github.com/klauspost/compress v1.17.10/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -26,16 +26,16 @@ github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0 github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo= -github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8= +github.com/planetscale/vtprotobuf v0.6.1-0.20240917153116-6f2963f01587 h1:xzZOeCMQLA/W198ZkdVdt4EKFKJtS26B773zNU377ZY= +github.com/planetscale/vtprotobuf v0.6.1-0.20240917153116-6f2963f01587/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8= 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 v1.20.4 h1:Tgh3Yr67PaOv/uTqloMsCEdeuFTatm5zIq5+qNN23vI= github.com/prometheus/client_golang v1.20.4/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= -github.com/prometheus/common v0.57.0 h1:Ro/rKjwdq9mZn1K5QPctzh+MA4Lp0BuYk5ZZEVhoNcY= -github.com/prometheus/common v0.57.0/go.mod h1:7uRPFSUTbfZWsJ7MHY56sqt7hLQu3bxXHDnNhl8E9qI= +github.com/prometheus/common v0.60.0 h1:+V9PAREWNvJMAuJ1x1BaWl9dewMW4YrHZQbx0sJNllA= +github.com/prometheus/common v0.60.0/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw= github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= @@ -48,6 +48,8 @@ github.com/siderolabs/gen v0.5.0 h1:Afdjx+zuZDf53eH5DB+E+T2JeCwBXGinV66A6osLgQI= github.com/siderolabs/gen v0.5.0/go.mod h1:1GUMBNliW98Xeq8GPQeVMYqQE09LFItE8enR3wgMh3Q= github.com/siderolabs/go-debug v0.4.0 h1:pbFt6Rzumm90s3GvbRer7yIxFNc0gQ94I53omkqswHA= github.com/siderolabs/go-debug v0.4.0/go.mod h1:9/dyHLRRIpqlJ0uTYyHo1XuZgoCgXzjjF+aIVTnr9Dc= +github.com/siderolabs/proto-codec v0.1.0 h1:+gP7ksOGW7vNltqrs/5UTKRKczmav3UJi0CIFWEHUOA= +github.com/siderolabs/proto-codec v0.1.0/go.mod h1:rIvmhKJG8+JwSCGPX+cQljpOMDmuHhLKPkt6KaFwEaU= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= @@ -56,20 +58,20 @@ go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= -golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= +golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= -golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= -golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= +golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= +golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U= golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= google.golang.org/genproto/googleapis/rpc v0.0.0-20240827150818-7e3bb234dfed h1:J6izYgfBXAI3xTKLgxzTmUltdYaLsuBxFCgDHWJ/eXg= google.golang.org/genproto/googleapis/rpc v0.0.0-20240827150818-7e3bb234dfed/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= -google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw= -google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= +google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= +google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/internal/proto/proto.go b/internal/proto/proto.go deleted file mode 100644 index c7a6d11..0000000 --- a/internal/proto/proto.go +++ /dev/null @@ -1,151 +0,0 @@ -// Copyright (c) 2024 Sidero Labs, Inc. -// -// Use of this software is governed by the Business Source License -// included in the LICENSE file. - -// Package proto contains wrappers to inject vtprotobuf marshaling. -package proto - -import ( - "fmt" - - "google.golang.org/grpc/encoding" - protoenc "google.golang.org/grpc/encoding/proto" - "google.golang.org/grpc/mem" - "google.golang.org/protobuf/proto" -) - -// Codec provides protobuf [encoding.CodecV2]. -type Codec struct{} - -// Marshal implements [encoding.CodecV2]. -func (Codec) Marshal(v any) (mem.BufferSlice, error) { - size, err := getSize(v) - if err != nil { - return nil, err - } - - if mem.IsBelowBufferPoolingThreshold(size) { - buf, err := marshal(v) - if err != nil { - return nil, err - } - - return mem.BufferSlice{mem.SliceBuffer(buf)}, nil - } - - pool := mem.DefaultBufferPool() - - buf := pool.Get(size) - if err := marshalAppend((*buf)[:size], v); err != nil { - pool.Put(buf) - - return nil, err - } - - return mem.BufferSlice{mem.NewBuffer(buf, pool)}, nil -} - -func getSize(v any) (int, error) { - // our types implement Message (with or without vtproto additions depending on build configuration) - // no types implement protobuf API v1 only, so don't check for it - switch v := v.(type) { - case vtprotoMessage: - return v.SizeVT(), nil - case proto.Message: - return proto.Size(v), nil - default: - return -1, fmt.Errorf("failed to get size, message is %T, must satisfy the vtprotoMessage, proto.Message or protoadapt.MessageV1 ", v) - } -} - -func marshal(v any) ([]byte, error) { - // our types implement Message (with or without vtproto additions depending on build configuration) - // no types implement protobuf API v1 only, so don't check for it - switch v := v.(type) { - case vtprotoMessage: - return v.MarshalVT() - case proto.Message: - return proto.Marshal(v) - default: - return nil, fmt.Errorf("failed to marshal, message is %T, must satisfy the vtprotoMessage, proto.Message or protoadapt.MessageV1 ", v) - } -} - -func marshalAppend(dst []byte, v any) error { - takeErr := func(_ any, e error) error { return e } - - // our types implement Message (with or without vtproto additions depending on build configuration) - // no types implement protobuf API v1 only, so don't check for it - switch v := v.(type) { - case vtprotoMessage: - return takeErr(v.MarshalToSizedBufferVT(dst)) - case proto.Message: - return takeErr((proto.MarshalOptions{}).MarshalAppend(dst[:0], v)) - default: - return fmt.Errorf("failed to marshal-append, message is %T, must satisfy the vtprotoMessage, proto.Message or protoadapt.MessageV1 ", v) - } -} - -// Unmarshal implements [encoding.CodecV2]. -func (Codec) Unmarshal(data mem.BufferSlice, v any) error { - buf := data.MaterializeToBuffer(mem.DefaultBufferPool()) - defer buf.Free() - - // our types implement Message (with or without vtproto additions depending on build configuration) - // no types implement protobuf API v1 only, so don't check for it - switch v := v.(type) { - case vtprotoMessage: - return v.UnmarshalVT(buf.ReadOnlyData()) - case Message: - return proto.Unmarshal(buf.ReadOnlyData(), v) - default: - return fmt.Errorf("failed to unmarshal, message is %T, must satisfy the vtprotoMessage, proto.Message or protoadapt.MessageV1", v) - } -} - -// Name implements encoding.Codec. -func (Codec) Name() string { return protoenc.Name } // overrides google.golang.org/grpc/encoding/proto codec - -// Message is the main interface for protobuf API v2 messages. -type Message = proto.Message - -// vtprotoMessage is the interface for vtproto additions. -// -// We use only a subset of that interface but include additional methods -// to prevent accidental successful type assertion for unrelated types. -type vtprotoMessage interface { - MarshalVT() ([]byte, error) - MarshalToSizedBufferVT([]byte) (int, error) - UnmarshalVT([]byte) error - SizeVT() int -} - -// Marshal returns the wire-format encoding of m. -func Marshal(m Message) ([]byte, error) { - // our types implement Message (with or without vtproto additions depending on build configuration) - if vm, ok := m.(vtprotoMessage); ok { - return vm.MarshalVT() - } - - // no types implement protobuf API v1 only, so don't check for it - - return proto.Marshal(m) -} - -// Unmarshal parses the wire-format message in b and places the result in m. -// The provided message must be mutable (e.g., a non-nil pointer to a message). -func Unmarshal(b []byte, m Message) error { - // our types implement Message (with or without vtproto additions depending on build configuration) - if vm, ok := m.(vtprotoMessage); ok { - return vm.UnmarshalVT(b) - } - - // no types implement protobuf API v1 only, so don't check for it - - return proto.Unmarshal(b, m) -} - -func init() { - encoding.RegisterCodecV2(Codec{}) -} diff --git a/pkg/server/logging.go b/pkg/server/logging.go index b790ca7..e54985d 100644 --- a/pkg/server/logging.go +++ b/pkg/server/logging.go @@ -50,7 +50,7 @@ func AddLoggingFieldsStreamServerInterceptor() grpc.StreamServerInterceptor { ctx := ss.Context() wrapped := grpc_middleware.WrapServerStream(ss) - wrapped.WrappedContext = logging.InjectFields(ctx, fieldExtractor(ctx, nil)) + wrapped.WrappedContext = logging.InjectFields(ctx, fieldExtractor(ctx, nil)) //nolint:fatcontext return handler(srv, wrapped) } diff --git a/pkg/server/server_test.go b/pkg/server/server_test.go index 36c544e..19b6fb9 100644 --- a/pkg/server/server_test.go +++ b/pkg/server/server_test.go @@ -20,6 +20,7 @@ import ( prom "github.com/prometheus/client_golang/prometheus" promtestutil "github.com/prometheus/client_golang/prometheus/testutil" "github.com/siderolabs/discovery-api/api/v1alpha1/server/pb" + _ "github.com/siderolabs/proto-codec/codec" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.uber.org/zap/zaptest" @@ -35,7 +36,6 @@ import ( "github.com/siderolabs/discovery-service/internal/grpclog" "github.com/siderolabs/discovery-service/internal/limiter" - _ "github.com/siderolabs/discovery-service/internal/proto" "github.com/siderolabs/discovery-service/internal/state" "github.com/siderolabs/discovery-service/pkg/limits" "github.com/siderolabs/discovery-service/pkg/server"