From 983c2c4b57006d753df578ae5d4ca5dcb3746ef2 Mon Sep 17 00:00:00 2001 From: Paul Meyer <49727155+katexochen@users.noreply.github.com> Date: Wed, 16 Nov 2022 16:43:54 +0100 Subject: [PATCH] debugd: sent info from cdbg to debugd Signed-off-by: Paul Meyer <49727155+katexochen@users.noreply.github.com> --- debugd/cmd/debugd/debugd.go | 14 +- debugd/internal/cdbg/cmd/deploy.go | 74 ++- debugd/internal/debugd/constants.go | 16 +- debugd/internal/debugd/deploy/download.go | 74 ++- .../internal/debugd/deploy/download_test.go | 151 +++-- debugd/internal/debugd/info/info.go | 116 ++++ debugd/internal/debugd/info/info_test.go | 303 ++++++++++ debugd/internal/debugd/metadata/scheduler.go | 103 ++-- .../debugd/metadata/scheduler_test.go | 116 ++-- debugd/internal/debugd/server/server.go | 70 ++- debugd/internal/debugd/server/server_test.go | 170 ++++-- debugd/service/debugd.pb.go | 536 ++++++++++++++---- debugd/service/debugd.proto | 20 + debugd/service/debugd_grpc.pb.go | 72 +++ 14 files changed, 1496 insertions(+), 339 deletions(-) create mode 100644 debugd/internal/debugd/info/info.go create mode 100644 debugd/internal/debugd/info/info_test.go diff --git a/debugd/cmd/debugd/debugd.go b/debugd/cmd/debugd/debugd.go index 37a7018ff..90733f117 100644 --- a/debugd/cmd/debugd/debugd.go +++ b/debugd/cmd/debugd/debugd.go @@ -16,6 +16,7 @@ import ( "github.com/edgelesssys/constellation/v2/debugd/internal/bootstrapper" "github.com/edgelesssys/constellation/v2/debugd/internal/debugd/deploy" + "github.com/edgelesssys/constellation/v2/debugd/internal/debugd/info" "github.com/edgelesssys/constellation/v2/debugd/internal/debugd/metadata" "github.com/edgelesssys/constellation/v2/debugd/internal/debugd/metadata/cloudprovider" "github.com/edgelesssys/constellation/v2/debugd/internal/debugd/metadata/fallback" @@ -53,7 +54,8 @@ func main() { log.Errorf("root login: %w") } - download := deploy.New(log.Named("download"), &net.Dialer{}, serviceManager, streamer) + infoMap := info.NewMap() + download := deploy.New(log.Named("download"), &net.Dialer{}, serviceManager, streamer, infoMap) var fetcher metadata.Fetcher csp := os.Getenv("CONSTEL_CSP") switch platform.FromString(csp) { @@ -87,7 +89,7 @@ func main() { fetcher = fallback.Fetcher{} } sched := metadata.NewScheduler(log.Named("scheduler"), fetcher, download) - serv := server.New(log.Named("server"), serviceManager, streamer) + serv := server.New(log.Named("server"), serviceManager, streamer, infoMap) if err := deploy.DefaultServiceUnit(ctx, serviceManager); err != nil { log.With(zap.Error(err)).Fatalf("Failed to create default service unit") } @@ -95,12 +97,8 @@ func main() { writeDebugBanner(log) wg := &sync.WaitGroup{} - - wg.Add(1) - go sched.Start(ctx, wg) - wg.Add(1) - go server.Start(log, wg, serv) - + sched.Start(ctx, wg) + server.Start(log, wg, serv) wg.Wait() } diff --git a/debugd/internal/cdbg/cmd/deploy.go b/debugd/internal/cdbg/cmd/deploy.go index 50f80f7a7..9f26b845b 100644 --- a/debugd/internal/cdbg/cmd/deploy.go +++ b/debugd/internal/cdbg/cmd/deploy.go @@ -9,6 +9,7 @@ package cmd import ( "context" "fmt" + "io" "log" "net" "strconv" @@ -38,6 +39,7 @@ func newDeployCmd() *cobra.Command { } deployCmd.Flags().StringSlice("ips", nil, "override the ips that the bootstrapper will be uploaded to (defaults to ips from constellation config)") deployCmd.Flags().String("bootstrapper", "./bootstrapper", "override the path to the bootstrapper binary uploaded to instances") + deployCmd.Flags().StringToString("info", nil, "additional info to be passed to the debugd, in the form --info key1=value1,key2=value2") return deployCmd } @@ -83,9 +85,16 @@ func deploy(cmd *cobra.Command, fileHandler file.Handler, constellationConfig *c ips = []string{idFile.IP} } + infos, err := cmd.Flags().GetStringToString("info") + if err != nil { + return err + } + for _, ip := range ips { + input := deployOnEndpointInput{ - debugdEndpoint: net.JoinHostPort(ip, strconv.Itoa(constants.DebugdPort)), + debugdEndpoint: ip, + infos: infos, bootstrapperPath: bootstrapperPath, reader: reader, } @@ -100,20 +109,70 @@ func deploy(cmd *cobra.Command, fileHandler file.Handler, constellationConfig *c type deployOnEndpointInput struct { debugdEndpoint string bootstrapperPath string + infos map[string]string reader fileToStreamReader } // deployOnEndpoint deploys a custom built bootstrapper binary to a debugd endpoint. func deployOnEndpoint(ctx context.Context, in deployOnEndpointInput) error { log.Printf("Deploying on %v\n", in.debugdEndpoint) - dialCTX, cancel := context.WithTimeout(ctx, debugd.GRPCTimeout) - defer cancel() - conn, err := grpc.DialContext(dialCTX, in.debugdEndpoint, grpc.WithTransportCredentials(insecure.NewCredentials())) + + client, closer, err := newDebugdClient(ctx, in.debugdEndpoint) if err != nil { - return fmt.Errorf("connecting to other instance via gRPC: %w", err) + return fmt.Errorf("creating debugd client: %w", err) } - defer conn.Close() - client := pb.NewDebugdClient(conn) + defer closer.Close() + + if err := setInfo(ctx, client, in.infos); err != nil { + return fmt.Errorf("sending info: %w", err) + } + + if err := uploadBootstrapper(ctx, client, in); err != nil { + return fmt.Errorf("uploading bootstrapper: %w", err) + } + + return nil +} + +func newDebugdClient(ctx context.Context, ip string) (pb.DebugdClient, io.Closer, error) { + conn, err := grpc.DialContext( + ctx, + net.JoinHostPort(ip, strconv.Itoa(constants.DebugdPort)), + grpc.WithTransportCredentials(insecure.NewCredentials()), + ) + if err != nil { + return nil, nil, fmt.Errorf("connecting to other instance via gRPC: %w", err) + } + + return pb.NewDebugdClient(conn), conn, nil +} + +func setInfo(ctx context.Context, client pb.DebugdClient, infos map[string]string) error { + ctx, cancel := context.WithTimeout(ctx, debugd.GRPCTimeout) + defer cancel() + + log.Printf("Setting info with length %d", len(infos)) + + var infosPb []*pb.Info + for key, value := range infos { + infosPb = append(infosPb, &pb.Info{Key: key, Value: value}) + } + + req := &pb.SetInfoRequest{Info: infosPb} + + if _, err := client.SetInfo(ctx, req, grpc.WaitForReady(true)); err != nil { + return fmt.Errorf("setting info: %w", err) + } + + log.Println("Info set") + return nil +} + +func uploadBootstrapper(ctx context.Context, client pb.DebugdClient, in deployOnEndpointInput) error { + ctx, cancel := context.WithTimeout(ctx, debugd.GRPCTimeout) + defer cancel() + + log.Println("Uploading bootstrapper") stream, err := client.UploadBootstrapper(ctx, grpc.WaitForReady(true)) if err != nil { @@ -132,6 +191,7 @@ func deployOnEndpoint(ctx context.Context, in deployOnEndpointInput) error { if uploadResponse.Status != pb.UploadBootstrapperStatus_UPLOAD_BOOTSTRAPPER_SUCCESS || streamErr != nil { return fmt.Errorf("uploading bootstrapper to instance %v failed: %v / %w", in.debugdEndpoint, uploadResponse, streamErr) } + log.Println("Uploaded bootstrapper") return nil } diff --git a/debugd/internal/debugd/constants.go b/debugd/internal/debugd/constants.go index 951d4a61d..e72fc0116 100644 --- a/debugd/internal/debugd/constants.go +++ b/debugd/internal/debugd/constants.go @@ -10,14 +10,14 @@ import "time" // Debugd internal constants. const ( - DebugdMetadataFlag = "constellation-debugd" - GRPCTimeout = 5 * time.Minute - DiscoverDebugdInterval = 30 * time.Second - BootstrapperDownloadRetryBackoff = 1 * time.Minute - BootstrapperDeployFilename = "/run/state/bin/bootstrapper" - Chunksize = 1024 - BootstrapperSystemdUnitName = "bootstrapper.service" - BootstrapperSystemdUnitContents = `[Unit] + DebugdMetadataFlag = "constellation-debugd" + GRPCTimeout = 5 * time.Minute + DiscoverDebugdInterval = 30 * time.Second + DownloadRetryBackoff = 1 * time.Minute + BootstrapperDeployFilename = "/run/state/bin/bootstrapper" + Chunksize = 1024 + BootstrapperSystemdUnitName = "bootstrapper.service" + BootstrapperSystemdUnitContents = `[Unit] Description=Constellation Bootstrapper Wants=network-online.target After=network-online.target diff --git a/debugd/internal/debugd/deploy/download.go b/debugd/internal/debugd/deploy/download.go index 1d749ba22..09312b70a 100644 --- a/debugd/internal/debugd/deploy/download.go +++ b/debugd/internal/debugd/deploy/download.go @@ -9,9 +9,9 @@ package deploy import ( "context" "fmt" + "io" "net" "strconv" - "time" "github.com/edgelesssys/constellation/v2/debugd/internal/bootstrapper" "github.com/edgelesssys/constellation/v2/debugd/internal/debugd" @@ -25,42 +25,57 @@ import ( // Download downloads a bootstrapper from a given debugd instance. type Download struct { - log *logger.Logger - dialer NetDialer - writer streamToFileWriter - serviceManager serviceManager - attemptedDownloads map[string]time.Time + log *logger.Logger + dialer NetDialer + writer streamToFileWriter + serviceManager serviceManager + info infoSetter } // New creates a new Download. -func New(log *logger.Logger, dialer NetDialer, serviceManager serviceManager, writer streamToFileWriter) *Download { +func New(log *logger.Logger, dialer NetDialer, serviceManager serviceManager, + writer streamToFileWriter, info infoSetter, +) *Download { return &Download{ - log: log, - dialer: dialer, - writer: writer, - serviceManager: serviceManager, - attemptedDownloads: map[string]time.Time{}, + log: log, + dialer: dialer, + writer: writer, + info: info, + serviceManager: serviceManager, } } +// DownloadInfo will try to download the info from another instance. +func (d *Download) DownloadInfo(ctx context.Context, ip string) error { + log := d.log.With(zap.String("ip", ip)) + serverAddr := net.JoinHostPort(ip, strconv.Itoa(constants.DebugdPort)) + + client, closer, err := d.newClient(ctx, serverAddr, log) + if err != nil { + return err + } + defer closer.Close() + + log.Infof("Trying to download info") + resp, err := client.GetInfo(ctx, &pb.GetInfoRequest{}) + if err != nil { + return fmt.Errorf("getting info from other instance: %w", err) + } + log.Infof("Successfully downloaded info") + + return d.info.SetProto(resp.Info) +} + // DownloadDeployment will open a new grpc connection to another instance, attempting to download a bootstrapper from that instance. func (d *Download) DownloadDeployment(ctx context.Context, ip string) error { log := d.log.With(zap.String("ip", ip)) serverAddr := net.JoinHostPort(ip, strconv.Itoa(constants.DebugdPort)) - // only retry download from same endpoint after backoff - if lastAttempt, ok := d.attemptedDownloads[serverAddr]; ok && time.Since(lastAttempt) < debugd.BootstrapperDownloadRetryBackoff { - return fmt.Errorf("download failed too recently: %v / %v", time.Since(lastAttempt), debugd.BootstrapperDownloadRetryBackoff) - } - - log.Infof("Connecting to server") - d.attemptedDownloads[serverAddr] = time.Now() - conn, err := d.dial(ctx, serverAddr) + client, closer, err := d.newClient(ctx, serverAddr, log) if err != nil { - return fmt.Errorf("connecting to other instance via gRPC: %w", err) + return err } - defer conn.Close() - client := pb.NewDebugdClient(conn) + defer closer.Close() log.Infof("Trying to download bootstrapper") stream, err := client.DownloadBootstrapper(ctx, &pb.DownloadBootstrapperRequest{}) @@ -84,6 +99,15 @@ func (d *Download) DownloadDeployment(ctx context.Context, ip string) error { return nil } +func (d *Download) newClient(ctx context.Context, serverAddr string, log *logger.Logger) (pb.DebugdClient, io.Closer, error) { + log.Infof("Connecting to server") + conn, err := d.dial(ctx, serverAddr) + if err != nil { + return nil, nil, fmt.Errorf("connecting to other instance via gRPC: %w", err) + } + return pb.NewDebugdClient(conn), conn, nil +} + func (d *Download) dial(ctx context.Context, target string) (*grpc.ClientConn, error) { return grpc.DialContext(ctx, target, d.grpcWithDialer(), @@ -97,6 +121,10 @@ func (d *Download) grpcWithDialer() grpc.DialOption { }) } +type infoSetter interface { + SetProto(infos []*pb.Info) error +} + type serviceManager interface { SystemdAction(ctx context.Context, request ServiceManagerRequest) error } diff --git a/debugd/internal/debugd/deploy/download_test.go b/debugd/internal/debugd/deploy/download_test.go index 5cc5e6c27..56000dc10 100644 --- a/debugd/internal/debugd/deploy/download_test.go +++ b/debugd/internal/debugd/deploy/download_test.go @@ -14,7 +14,6 @@ import ( "net" "strconv" "testing" - "time" "github.com/edgelesssys/constellation/v2/debugd/internal/bootstrapper" "github.com/edgelesssys/constellation/v2/debugd/internal/debugd" @@ -39,45 +38,36 @@ func TestDownloadBootstrapper(t *testing.T) { someErr := errors.New("failed") testCases := map[string]struct { - server fakeDownloadServer - serviceManager stubServiceManager - attemptedDownloads map[string]time.Time - wantChunks [][]byte - wantDownloadErr bool - wantFile bool - wantSystemdAction bool - wantDeployed bool + server fakeDownloadServer + serviceManager stubServiceManager + wantChunks [][]byte + wantDownloadErr bool + wantFile bool + wantSystemdAction bool + wantDeployed bool }{ "download works": { server: fakeDownloadServer{ chunks: [][]byte{[]byte("test")}, }, - attemptedDownloads: map[string]time.Time{}, - wantChunks: [][]byte{[]byte("test")}, - wantDownloadErr: false, - wantFile: true, - wantSystemdAction: true, - wantDeployed: true, - }, - "second download is not attempted twice": { - server: fakeDownloadServer{chunks: [][]byte{[]byte("test")}}, - attemptedDownloads: map[string]time.Time{"192.0.2.0:" + strconv.Itoa(constants.DebugdPort): time.Now()}, - wantDownloadErr: true, + wantChunks: [][]byte{[]byte("test")}, + wantDownloadErr: false, + wantFile: true, + wantSystemdAction: true, + wantDeployed: true, }, "download rpc call error is detected": { - server: fakeDownloadServer{downladErr: someErr}, - attemptedDownloads: map[string]time.Time{}, - wantDownloadErr: true, + server: fakeDownloadServer{downladErr: someErr}, + wantDownloadErr: true, }, "service restart error is detected": { - server: fakeDownloadServer{chunks: [][]byte{[]byte("test")}}, - serviceManager: stubServiceManager{systemdActionErr: someErr}, - attemptedDownloads: map[string]time.Time{}, - wantChunks: [][]byte{[]byte("test")}, - wantDownloadErr: true, - wantFile: true, - wantDeployed: true, - wantSystemdAction: false, + server: fakeDownloadServer{chunks: [][]byte{[]byte("test")}}, + serviceManager: stubServiceManager{systemdActionErr: someErr}, + wantChunks: [][]byte{[]byte("test")}, + wantDownloadErr: true, + wantFile: true, + wantDeployed: true, + wantSystemdAction: false, }, } @@ -96,11 +86,10 @@ func TestDownloadBootstrapper(t *testing.T) { defer grpcServ.GracefulStop() download := &Download{ - log: logger.NewTest(t), - dialer: dialer, - writer: writer, - serviceManager: &tc.serviceManager, - attemptedDownloads: tc.attemptedDownloads, + log: logger.NewTest(t), + dialer: dialer, + writer: writer, + serviceManager: &tc.serviceManager, } err := download.DownloadDeployment(context.Background(), ip) @@ -127,6 +116,76 @@ func TestDownloadBootstrapper(t *testing.T) { } } +func TestDownloadInfo(t *testing.T) { + someErr := errors.New("failed") + someInfo := []*pb.Info{ + {Key: "foo", Value: "bar"}, + {Key: "baz", Value: "qux"}, + } + + testCases := map[string]struct { + server stubDebugdServer + infoSetter stubInfoSetter + wantErr bool + wantInfo []*pb.Info + }{ + "download works": { + server: stubDebugdServer{info: someInfo}, + infoSetter: stubInfoSetter{}, + wantInfo: someInfo, + }, + "empty info ok": { + server: stubDebugdServer{info: []*pb.Info{}}, + infoSetter: stubInfoSetter{}, + wantInfo: nil, + }, + "nil info ok": { + server: stubDebugdServer{}, + infoSetter: stubInfoSetter{}, + wantInfo: nil, + }, + "getInfo fails": { + server: stubDebugdServer{getInfoErr: someErr}, + infoSetter: stubInfoSetter{}, + wantErr: true, + }, + "setInfo fails": { + server: stubDebugdServer{info: someInfo}, + infoSetter: stubInfoSetter{setProtoErr: someErr}, + wantErr: true, + }, + } + + for name, tc := range testCases { + t.Run(name, func(t *testing.T) { + assert := assert.New(t) + + ip := "192.0.2.1" + dialer := testdialer.NewBufconnDialer() + grpcServer := grpc.NewServer() + pb.RegisterDebugdServer(grpcServer, &tc.server) + lis := dialer.GetListener(net.JoinHostPort(ip, strconv.Itoa(constants.DebugdPort))) + go grpcServer.Serve(lis) + defer grpcServer.GracefulStop() + + download := &Download{ + log: logger.NewTest(t), + dialer: dialer, + info: &tc.infoSetter, + } + + err := download.DownloadInfo(context.Background(), ip) + + if tc.wantErr { + assert.Error(err) + } else { + assert.NoError(err) + assert.Equal(len(tc.wantInfo), len(tc.infoSetter.info)) + } + }) + } +} + type stubServiceManager struct { requests []ServiceManagerRequest systemdActionErr error @@ -172,3 +231,23 @@ func (s *fakeDownloadServer) DownloadBootstrapper(request *pb.DownloadBootstrapp } return s.downladErr } + +type stubDebugdServer struct { + info []*pb.Info + getInfoErr error + pb.UnimplementedDebugdServer +} + +func (s *stubDebugdServer) GetInfo(ctx context.Context, request *pb.GetInfoRequest) (*pb.GetInfoResponse, error) { + return &pb.GetInfoResponse{Info: s.info}, s.getInfoErr +} + +type stubInfoSetter struct { + info []*pb.Info + setProtoErr error +} + +func (s *stubInfoSetter) SetProto(infos []*pb.Info) error { + s.info = infos + return s.setProtoErr +} diff --git a/debugd/internal/debugd/info/info.go b/debugd/internal/debugd/info/info.go new file mode 100644 index 000000000..4e43e4551 --- /dev/null +++ b/debugd/internal/debugd/info/info.go @@ -0,0 +1,116 @@ +/* +Copyright (c) Edgeless Systems GmbH + +SPDX-License-Identifier: AGPL-3.0-only +*/ + +package info + +import ( + "errors" + "sync" + + servicepb "github.com/edgelesssys/constellation/v2/debugd/service" +) + +// Map is a thread-safe map of info, with triggers that are run +// when the map is set. +type Map struct { + m map[string]string + received bool + mux sync.RWMutex + onReceiveTrigger []func(*Map) +} + +// NewMap creates a new Map object. +func NewMap() *Map { + return &Map{ + m: make(map[string]string), + } +} + +// Get returns the value of the info with the given key. +func (i *Map) Get(key string) (string, bool, error) { + i.mux.RLock() + defer i.mux.RUnlock() + + if !i.received { + return "", false, errors.New("info not set yet") + } + + value, ok := i.m[key] + return value, ok, nil +} + +// GetCopy returns a copy of the info map. +func (i *Map) GetCopy() (map[string]string, error) { + i.mux.RLock() + defer i.mux.RUnlock() + + if !i.received { + return nil, errors.New("info not set yet") + } + + m := make(map[string]string) + for k, v := range i.m { + m[k] = v + } + + return m, nil +} + +// SetProto sets the info map to the given infos proto slice. +// It returns an error if the info map has already been set. +// Registered triggers are run after the info map is set. +func (i *Map) SetProto(infos []*servicepb.Info) error { + i.mux.Lock() + defer i.mux.Unlock() + + if i.received { + return errors.New("info already set") + } + + infoMap := make(map[string]string) + for _, info := range infos { + infoMap[info.Key] = info.Value + } + + i.m = infoMap + i.received = true + + for _, trigger := range i.onReceiveTrigger { + trigger(i) + } + + return nil +} + +// RegisterOnReceiveTrigger registers a function that is called when the info map is set. +// The function mustn't block or be long-running. +func (i *Map) RegisterOnReceiveTrigger(f func(*Map)) { + i.mux.Lock() + defer i.mux.Unlock() + + if i.received { + f(i) + return + } + + i.onReceiveTrigger = append(i.onReceiveTrigger, f) +} + +// GetProto returns the info map as a slice of info proto. +func (i *Map) GetProto() ([]*servicepb.Info, error) { + i.mux.RLock() + defer i.mux.RUnlock() + + if !i.received { + return nil, errors.New("info not set yet") + } + + var infos []*servicepb.Info + for key, value := range i.m { + infos = append(infos, &servicepb.Info{Key: key, Value: value}) + } + return infos, nil +} diff --git a/debugd/internal/debugd/info/info_test.go b/debugd/internal/debugd/info/info_test.go new file mode 100644 index 000000000..00aae765f --- /dev/null +++ b/debugd/internal/debugd/info/info_test.go @@ -0,0 +1,303 @@ +/* +Copyright (c) Edgeless Systems GmbH + +SPDX-License-Identifier: AGPL-3.0-only +*/ + +package info + +import ( + "testing" + + pb "github.com/edgelesssys/constellation/v2/debugd/service" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestNew(t *testing.T) { + assert := assert.New(t) + + i := NewMap() + + assert.NotNil(i) + assert.NotNil(i.m) + assert.False(i.received) +} + +func TestGet(t *testing.T) { + testCases := map[string]struct { + infosMap map[string]string + key string + want string + wantOk bool + wantErr bool + }{ + "empty map": { + infosMap: map[string]string{}, + key: "key", + }, + "key not found": { + infosMap: map[string]string{ + "key1": "value1", + "key2": "value2", + }, + key: "key3", + }, + "key found": { + infosMap: map[string]string{ + "key1": "value1", + "key2": "value2", + }, + key: "key2", + want: "value2", + wantOk: true, + }, + "not received": { + infosMap: nil, + key: "key", + wantErr: true, + }, + } + + for name, tc := range testCases { + t.Run(name, func(t *testing.T) { + assert := assert.New(t) + + infos := &Map{m: tc.infosMap} + if infos.m != nil { + infos.received = true + } + + got, gotOk, err := infos.Get(tc.key) + + if tc.wantErr { + assert.Error(err) + } else { + assert.NoError(err) + assert.Equal(tc.wantOk, gotOk) + assert.Equal(tc.want, got) + } + }) + } +} + +func TestGetCopy(t *testing.T) { + testCases := map[string]struct { + infosMap map[string]string + received bool + wantMap map[string]string + wantErr bool + }{ + "empty": { + infosMap: map[string]string{}, + received: true, + wantMap: map[string]string{}, + }, + "one": { + infosMap: map[string]string{ + "key1": "value1", + }, + received: true, + wantMap: map[string]string{ + "key1": "value1", + }, + }, + "multiple": { + infosMap: map[string]string{ + "key1": "value1", + "key2": "value2", + }, + received: true, + wantMap: map[string]string{ + "key1": "value1", + "key2": "value2", + }, + }, + "not received": { + infosMap: nil, + received: false, + wantErr: true, + }, + } + + for name, tc := range testCases { + t.Run(name, func(t *testing.T) { + assert := assert.New(t) + + i := &Map{m: tc.infosMap, received: tc.received} + + gotMap, err := i.GetCopy() + + if tc.wantErr { + assert.Error(err) + } else { + assert.NoError(err) + assert.Equal(tc.wantMap, gotMap) + } + }) + } +} + +func TestSetProto(t *testing.T) { + testCases := map[string]struct { + infosPB []*pb.Info + received bool + wantMap map[string]string + wantErr bool + }{ + "empty": { + infosPB: []*pb.Info{}, + wantMap: map[string]string{}, + }, + "one": { + infosPB: []*pb.Info{ + {Key: "foo", Value: "bar"}, + }, + wantMap: map[string]string{ + "foo": "bar", + }, + }, + "multiple": { + infosPB: []*pb.Info{ + {Key: "foo", Value: "bar"}, + {Key: "baz", Value: "qux"}, + }, + wantMap: map[string]string{ + "foo": "bar", + "baz": "qux", + }, + }, + "already received": { + infosPB: []*pb.Info{}, + received: true, + wantErr: true, + }, + } + + for name, tc := range testCases { + t.Run(name, func(t *testing.T) { + assert := assert.New(t) + + i := &Map{received: tc.received} + err := i.SetProto(tc.infosPB) + + if tc.wantErr { + assert.Error(err) + } else { + assert.NoError(err) + assert.Equal(tc.wantMap, i.m) + } + }) + } +} + +func TestTrigger(t *testing.T) { + assert := assert.New(t) + require := require.New(t) + + m := NewMap() + + var tr1, tr2, tr3 bool + m.RegisterOnReceiveTrigger(func(*Map) { tr1 = true }) + m.RegisterOnReceiveTrigger(func(*Map) { tr2 = true }) + m.RegisterOnReceiveTrigger(func(*Map) { tr3 = true }) + + err := m.SetProto([]*pb.Info{}) + require.NoError(err) + + assert.True(tr1) + assert.True(tr2) + assert.True(tr3) +} + +func TestGetProto(t *testing.T) { + testCases := map[string]struct { + infosMap map[string]string + wantPB []*pb.Info + wantErr bool + }{ + "empty": { + infosMap: map[string]string{}, + wantPB: []*pb.Info{}, + }, + "one": { + infosMap: map[string]string{ + "foo": "bar", + }, + wantPB: []*pb.Info{ + {Key: "foo", Value: "bar"}, + }, + }, + "multiple": { + infosMap: map[string]string{ + "foo": "bar", + "baz": "qux", + }, + wantPB: []*pb.Info{ + {Key: "foo", Value: "bar"}, + {Key: "baz", Value: "qux"}, + }, + }, + "not received": { + infosMap: nil, + wantErr: true, + }, + } + + for name, tc := range testCases { + t.Run(name, func(t *testing.T) { + assert := assert.New(t) + + i := &Map{m: tc.infosMap} + if i.m != nil { + i.received = true + } + + gotPB, err := i.GetProto() + + if tc.wantErr { + assert.Error(err) + } else { + assert.NoError(err) + assert.Equal(len(tc.wantPB), len(gotPB)) + } + }) + } +} + +func TestConcurrency(t *testing.T) { + i := NewMap() + + get := func() { + _, _, _ = i.Get("foo") + } + + getCopy := func() { + _, _ = i.GetCopy() + } + + setProto := func() { + _ = i.SetProto([]*pb.Info{{Key: "foo", Value: "bar"}}) + } + + getProto := func() { + _, _ = i.GetProto() + } + + go get() + go get() + go get() + go get() + go getCopy() + go getCopy() + go getCopy() + go getCopy() + go setProto() + go setProto() + go setProto() + go setProto() + go getProto() + go getProto() + go getProto() + go getProto() +} diff --git a/debugd/internal/debugd/metadata/scheduler.go b/debugd/internal/debugd/metadata/scheduler.go index 028756e2b..0687cfb85 100644 --- a/debugd/internal/debugd/metadata/scheduler.go +++ b/debugd/internal/debugd/metadata/scheduler.go @@ -8,29 +8,27 @@ package metadata import ( "context" - "errors" - "io/fs" "sync" "time" "github.com/edgelesssys/constellation/v2/debugd/internal/debugd" "github.com/edgelesssys/constellation/v2/internal/logger" - "github.com/edgelesssys/constellation/v2/internal/role" "go.uber.org/zap" ) // Fetcher retrieves other debugd IPs from cloud provider metadata. type Fetcher interface { - Role(ctx context.Context) (role.Role, error) DiscoverDebugdIPs(ctx context.Context) ([]string, error) - DiscoverLoadbalancerIP(ctx context.Context) (string, error) } // Scheduler schedules fetching of metadata using timers. type Scheduler struct { - log *logger.Logger - fetcher Fetcher - downloader downloader + log *logger.Logger + fetcher Fetcher + downloader downloader + deploymentDone bool + infoDone bool + interval time.Duration } // NewScheduler returns a new scheduler. @@ -39,68 +37,69 @@ func NewScheduler(log *logger.Logger, fetcher Fetcher, downloader downloader) *S log: log, fetcher: fetcher, downloader: downloader, + interval: debugd.DiscoverDebugdInterval, } } // Start the loops for discovering debugd endpoints. func (s *Scheduler) Start(ctx context.Context, wg *sync.WaitGroup) { - defer wg.Done() + ticker := time.NewTicker(s.interval) wg.Add(1) - go s.discoveryLoop(ctx, wg) -} + go func() { + defer wg.Done() + defer ticker.Stop() -// discoveryLoop discovers new debugd endpoints from cloud-provider metadata periodically. -func (s *Scheduler) discoveryLoop(ctx context.Context, wg *sync.WaitGroup) { - defer wg.Done() - // execute debugd discovery once at the start to skip wait for first tick - ips, err := s.fetcher.DiscoverDebugdIPs(ctx) - if err != nil { - s.log.With(zap.Error(err)).Errorf("Discovering debugd IPs failed") - } else { - if s.downloadDeployment(ctx, ips) { - return - } - } - - ticker := time.NewTicker(debugd.DiscoverDebugdInterval) - defer ticker.Stop() - for { - var err error - select { - case <-ticker.C: - ips, err = s.fetcher.DiscoverDebugdIPs(ctx) + for { + ips, err := s.fetcher.DiscoverDebugdIPs(ctx) if err != nil { - s.log.With(zap.Error(err)).Errorf("Discovering debugd IPs failed") + s.log.With(zap.Error(err)).Warnf("Discovering debugd IPs failed") continue + } else { + s.log.With(zap.Strings("ips", ips)).Infof("Discovered instances") + s.download(ctx, ips) + if s.deploymentDone && s.infoDone { + return + } } - s.log.With(zap.Strings("ips", ips)).Infof("Discovered instances") - if s.downloadDeployment(ctx, ips) { + + select { + case <-ctx.Done(): return + case <-ticker.C: } - case <-ctx.Done(): + } + }() +} + +// download tries to download deployment from a list of ips and logs errors encountered. +func (s *Scheduler) download(ctx context.Context, ips []string) { + for _, ip := range ips { + if !s.deploymentDone { + if err := s.downloader.DownloadDeployment(ctx, ip); err != nil { + s.log.With(zap.Error(err), zap.String("peer", ip)). + Warnf("Downloading deployment from %s: %s", ip, err) + } else { + s.deploymentDone = true + } + } + + if !s.infoDone { + if err := s.downloader.DownloadInfo(ctx, ip); err != nil { + s.log.With(zap.Error(err), zap.String("peer", ip)). + Warnf("Downloading info from %s: %s", ip, err) + } else { + s.infoDone = true + } + } + + if s.deploymentDone && s.infoDone { return } } } -// downloadDeployment tries to download deployment from a list of ips and logs errors encountered. -func (s *Scheduler) downloadDeployment(ctx context.Context, ips []string) (success bool) { - for _, ip := range ips { - err := s.downloader.DownloadDeployment(ctx, ip) - if err == nil { - return true - } - if errors.Is(err, fs.ErrExist) { - // bootstrapper was already uploaded - s.log.Infof("Bootstrapper was already uploaded.") - return true - } - s.log.With(zap.Error(err), zap.String("peer", ip)).Errorf("Downloading deployment from peer failed") - } - return false -} - type downloader interface { DownloadDeployment(ctx context.Context, ip string) error + DownloadInfo(ctx context.Context, ip string) error } diff --git a/debugd/internal/debugd/metadata/scheduler_test.go b/debugd/internal/debugd/metadata/scheduler_test.go index 6b2e29823..83b058c78 100644 --- a/debugd/internal/debugd/metadata/scheduler_test.go +++ b/debugd/internal/debugd/metadata/scheduler_test.go @@ -14,7 +14,6 @@ import ( "time" "github.com/edgelesssys/constellation/v2/internal/logger" - "github.com/edgelesssys/constellation/v2/internal/role" "github.com/stretchr/testify/assert" "go.uber.org/goleak" ) @@ -27,27 +26,41 @@ func TestSchedulerStart(t *testing.T) { someErr := errors.New("failed") testCases := map[string]struct { - fetcher stubFetcher - downloader stubDownloader - timeout time.Duration - wantDebugdDownloads []string + fetcher stubFetcher + downloader stubDownloader + wantDiscoverCount int + wantDeploymentDownloads []string + wantInfoDownloads []string }{ - "scheduler works and calls fetcher functions at least once": {}, - "download for discovered debugd ips is started": { - fetcher: stubFetcher{ - ips: []string{"192.0.2.1", "192.0.2.2"}, - }, - downloader: stubDownloader{downloadErr: someErr}, - wantDebugdDownloads: []string{"192.0.2.1", "192.0.2.2"}, + "no errors occur": { + fetcher: stubFetcher{ips: []string{"192.0.2.1", "192.0.2.2"}}, + downloader: stubDownloader{}, + wantDiscoverCount: 1, + wantDeploymentDownloads: []string{"192.0.2.1"}, + wantInfoDownloads: []string{"192.0.2.1"}, }, - "if download is successful, second download is not attempted": { - fetcher: stubFetcher{ - ips: []string{"192.0.2.1", "192.0.2.2"}, - }, - wantDebugdDownloads: []string{"192.0.2.1"}, + "download deployment fails": { + fetcher: stubFetcher{ips: []string{"192.0.2.1", "192.0.2.2"}}, + downloader: stubDownloader{downloadDeploymentErrs: []error{someErr, someErr}}, + wantDiscoverCount: 2, + wantDeploymentDownloads: []string{"192.0.2.1", "192.0.2.2", "192.0.2.1"}, + wantInfoDownloads: []string{"192.0.2.1"}, }, - "endpoint discovery can fail": { - fetcher: stubFetcher{discoverErr: someErr}, + "download info fails": { + fetcher: stubFetcher{ips: []string{"192.0.2.1", "192.0.2.2"}}, + downloader: stubDownloader{downloadInfoErrs: []error{someErr, someErr}}, + wantDiscoverCount: 2, + wantDeploymentDownloads: []string{"192.0.2.1"}, + wantInfoDownloads: []string{"192.0.2.1", "192.0.2.2", "192.0.2.1"}, + }, + "endpoint discovery fails": { + fetcher: stubFetcher{ + discoverErrs: []error{someErr, someErr, someErr}, + ips: []string{"192.0.2.1", "192.0.2.2"}, + }, + wantDiscoverCount: 4, + wantDeploymentDownloads: []string{"192.0.2.1"}, + wantInfoDownloads: []string{"192.0.2.1"}, }, } @@ -55,50 +68,67 @@ func TestSchedulerStart(t *testing.T) { t.Run(name, func(t *testing.T) { assert := assert.New(t) - wg := &sync.WaitGroup{} - ctx, cancel := context.WithTimeout(context.Background(), tc.timeout) - defer cancel() scheduler := Scheduler{ log: logger.NewTest(t), fetcher: &tc.fetcher, downloader: &tc.downloader, + interval: 20 * time.Millisecond, } - wg.Add(1) - go scheduler.Start(ctx, wg) + wg := &sync.WaitGroup{} + scheduler.Start(context.Background(), wg) wg.Wait() - assert.Equal(tc.wantDebugdDownloads, tc.downloader.ips) - assert.Greater(tc.fetcher.discoverCalls, 0) + + assert.Equal(tc.wantDeploymentDownloads, tc.downloader.downloadDeploymentIPs) + assert.Equal(tc.wantInfoDownloads, tc.downloader.downloadInfoIPs) + assert.Equal(tc.wantDiscoverCount, tc.fetcher.discoverCalls) }) } } type stubFetcher struct { - discoverCalls int - - ips []string - discoverErr error -} - -func (s *stubFetcher) Role(_ context.Context) (role.Role, error) { - return role.Unknown, nil + ips []string + discoverErrs []error + discoverErrIdx int + discoverCalls int } func (s *stubFetcher) DiscoverDebugdIPs(ctx context.Context) ([]string, error) { s.discoverCalls++ - return s.ips, s.discoverErr -} - -func (s *stubFetcher) DiscoverLoadbalancerIP(ctx context.Context) (string, error) { - return "", nil + var err error + if s.discoverErrIdx < len(s.discoverErrs) { + err = s.discoverErrs[s.discoverErrIdx] + s.discoverErrIdx++ + return nil, err + } + return s.ips, nil } type stubDownloader struct { - ips []string - downloadErr error + downloadDeploymentErrs []error + downloadDeploymentErrIdx int + downloadDeploymentIPs []string + downloadInfoErrs []error + downloadInfoErrIdx int + downloadInfoIPs []string } func (s *stubDownloader) DownloadDeployment(ctx context.Context, ip string) error { - s.ips = append(s.ips, ip) - return s.downloadErr + s.downloadDeploymentIPs = append(s.downloadDeploymentIPs, ip) + var err error + if s.downloadDeploymentErrIdx < len(s.downloadDeploymentErrs) { + err = s.downloadDeploymentErrs[s.downloadDeploymentErrIdx] + s.downloadDeploymentErrIdx++ + } + return err +} + +func (s *stubDownloader) DownloadInfo(ctx context.Context, ip string) error { + s.downloadInfoIPs = append(s.downloadInfoIPs, ip) + var err error + if s.downloadInfoErrIdx < len(s.downloadInfoErrs) { + err = s.downloadInfoErrs[s.downloadInfoErrIdx] + s.downloadInfoErrIdx++ + } + return err } diff --git a/debugd/internal/debugd/server/server.go b/debugd/internal/debugd/server/server.go index e9f830fc8..a250ded2a 100644 --- a/debugd/internal/debugd/server/server.go +++ b/debugd/internal/debugd/server/server.go @@ -19,6 +19,7 @@ import ( "github.com/edgelesssys/constellation/v2/debugd/internal/bootstrapper" "github.com/edgelesssys/constellation/v2/debugd/internal/debugd" "github.com/edgelesssys/constellation/v2/debugd/internal/debugd/deploy" + "github.com/edgelesssys/constellation/v2/debugd/internal/debugd/info" pb "github.com/edgelesssys/constellation/v2/debugd/service" "github.com/edgelesssys/constellation/v2/internal/constants" "github.com/edgelesssys/constellation/v2/internal/logger" @@ -31,18 +32,50 @@ type debugdServer struct { log *logger.Logger serviceManager serviceManager streamer streamer + info *info.Map + pb.UnimplementedDebugdServer } // New creates a new debugdServer according to the gRPC spec. -func New(log *logger.Logger, serviceManager serviceManager, streamer streamer) pb.DebugdServer { +func New(log *logger.Logger, serviceManager serviceManager, streamer streamer, infos *info.Map) pb.DebugdServer { return &debugdServer{ log: log, serviceManager: serviceManager, streamer: streamer, + info: infos, } } +// SetInfo sets the info of the debugd instance. +func (s *debugdServer) SetInfo(ctx context.Context, req *pb.SetInfoRequest) (*pb.SetInfoResponse, error) { + s.log.Infof("Received SetInfo request") + + if len(req.Info) == 0 { + s.log.Infof("Info is empty") + } + + if err := s.info.SetProto(req.Info); err != nil { + s.log.With(zap.Error(err)).Errorf("Setting info failed") + return &pb.SetInfoResponse{}, err + } + s.log.Infof("Info set") + + return &pb.SetInfoResponse{}, nil +} + +// GetInfo returns the info of the debugd instance. +func (s *debugdServer) GetInfo(ctx context.Context, req *pb.GetInfoRequest) (*pb.GetInfoResponse, error) { + s.log.Infof("Received GetInfo request") + + info, err := s.info.GetProto() + if err != nil { + return nil, err + } + + return &pb.GetInfoResponse{Info: info}, nil +} + // UploadBootstrapper receives a bootstrapper binary in a stream of chunks and writes to a file. func (s *debugdServer) UploadBootstrapper(stream pb.Debugd_UploadBootstrapperServer) error { startAction := deploy.ServiceManagerRequest{ @@ -97,25 +130,28 @@ func (s *debugdServer) UploadSystemServiceUnits(ctx context.Context, in *pb.Uplo return &pb.UploadSystemdServiceUnitsResponse{Status: pb.UploadSystemdServiceUnitsStatus_UPLOAD_SYSTEMD_SERVICE_UNITS_SUCCESS}, nil } -// Start will start the gRPC server and block. +// Start will start the gRPC server as goroutine. func Start(log *logger.Logger, wg *sync.WaitGroup, serv pb.DebugdServer) { - defer wg.Done() + wg.Add(1) + go func() { + defer wg.Done() - grpcLog := log.Named("gRPC") - grpcLog.WithIncreasedLevel(zap.WarnLevel).ReplaceGRPCLogger() + grpcLog := log.Named("gRPC") + grpcLog.WithIncreasedLevel(zap.WarnLevel).ReplaceGRPCLogger() - grpcServer := grpc.NewServer( - grpcLog.GetServerStreamInterceptor(), - grpcLog.GetServerUnaryInterceptor(), - grpc.KeepaliveParams(keepalive.ServerParameters{Time: 15 * time.Second}), - ) - pb.RegisterDebugdServer(grpcServer, serv) - lis, err := net.Listen("tcp", net.JoinHostPort("0.0.0.0", strconv.Itoa(constants.DebugdPort))) - if err != nil { - log.With(zap.Error(err)).Fatalf("Listening failed") - } - log.Infof("gRPC server is waiting for connections") - grpcServer.Serve(lis) + grpcServer := grpc.NewServer( + grpcLog.GetServerStreamInterceptor(), + grpcLog.GetServerUnaryInterceptor(), + grpc.KeepaliveParams(keepalive.ServerParameters{Time: 15 * time.Second}), + ) + pb.RegisterDebugdServer(grpcServer, serv) + lis, err := net.Listen("tcp", net.JoinHostPort("0.0.0.0", strconv.Itoa(constants.DebugdPort))) + if err != nil { + log.With(zap.Error(err)).Fatalf("Listening failed") + } + log.Infof("gRPC server is waiting for connections") + grpcServer.Serve(lis) + }() } type serviceManager interface { diff --git a/debugd/internal/debugd/server/server_test.go b/debugd/internal/debugd/server/server_test.go index 13ac96e11..9dc7e3c5e 100644 --- a/debugd/internal/debugd/server/server_test.go +++ b/debugd/internal/debugd/server/server_test.go @@ -17,6 +17,7 @@ import ( "github.com/edgelesssys/constellation/v2/debugd/internal/bootstrapper" "github.com/edgelesssys/constellation/v2/debugd/internal/debugd/deploy" + "github.com/edgelesssys/constellation/v2/debugd/internal/debugd/info" pb "github.com/edgelesssys/constellation/v2/debugd/service" "github.com/edgelesssys/constellation/v2/internal/constants" "github.com/edgelesssys/constellation/v2/internal/grpc/testdialer" @@ -32,6 +33,125 @@ func TestMain(m *testing.M) { goleak.VerifyTestMain(m) } +func TestSetInfo(t *testing.T) { + endpoint := "192.0.2.1:" + strconv.Itoa(constants.DebugdPort) + + testCases := map[string]struct { + info *info.Map + infoReceived bool + setInfo []*pb.Info + wantErr bool + }{ + "set info works": { + setInfo: []*pb.Info{{Key: "foo", Value: "bar"}}, + info: info.NewMap(), + }, + "set empty info works": { + setInfo: []*pb.Info{}, + info: info.NewMap(), + }, + "set fails when info already set": { + info: info.NewMap(), + infoReceived: true, + setInfo: []*pb.Info{{Key: "foo", Value: "bar"}}, + wantErr: true, + }, + } + + for name, tc := range testCases { + t.Run(name, func(t *testing.T) { + assert := assert.New(t) + require := require.New(t) + + serv := debugdServer{ + log: logger.NewTest(t), + info: tc.info, + } + + if tc.infoReceived { + err := tc.info.SetProto(tc.setInfo) + require.NoError(err) + } + + grpcServ, conn, err := setupServerWithConn(endpoint, &serv) + require.NoError(err) + defer conn.Close() + client := pb.NewDebugdClient(conn) + + _, err = client.SetInfo(context.Background(), &pb.SetInfoRequest{Info: tc.setInfo}) + grpcServ.GracefulStop() + + if tc.wantErr { + assert.Error(err) + } else { + assert.NoError(err) + for i := range tc.setInfo { + value, ok, err := tc.info.Get(tc.setInfo[i].Key) + assert.NoError(err) + assert.True(ok) + assert.Equal(tc.setInfo[i].Value, value) + } + } + }) + } +} + +func TestGetInfo(t *testing.T) { + endpoint := "192.0.2.1:" + strconv.Itoa(constants.DebugdPort) + + testCases := map[string]struct { + info *info.Map + getInfo []*pb.Info + wantErr bool + }{ + "get info works": { + getInfo: []*pb.Info{{Key: "foo", Value: "bar"}}, + info: info.NewMap(), + }, + "get empty info works": { + getInfo: []*pb.Info{}, + info: info.NewMap(), + }, + "get unset info fails": { + getInfo: nil, + info: info.NewMap(), + wantErr: true, + }, + } + + for name, tc := range testCases { + t.Run(name, func(t *testing.T) { + assert := assert.New(t) + require := require.New(t) + + if tc.getInfo != nil { + err := tc.info.SetProto(tc.getInfo) + require.NoError(err) + } + + serv := debugdServer{ + log: logger.NewTest(t), + info: tc.info, + } + + grpcServ, conn, err := setupServerWithConn(endpoint, &serv) + require.NoError(err) + defer conn.Close() + client := pb.NewDebugdClient(conn) + + resp, err := client.GetInfo(context.Background(), &pb.GetInfoRequest{}) + grpcServ.GracefulStop() + + if tc.wantErr { + assert.Error(err) + } else { + assert.NoError(err) + assert.Equal(len(tc.getInfo), len(resp.Info)) + } + }) + } +} + func TestUploadBootstrapper(t *testing.T) { endpoint := "192.0.2.1:" + strconv.Itoa(constants.DebugdPort) @@ -45,33 +165,21 @@ func TestUploadBootstrapper(t *testing.T) { wantChunks [][]byte }{ "upload works": { - uploadChunks: [][]byte{ - []byte("test"), - }, - wantFile: true, - wantChunks: [][]byte{ - []byte("test"), - }, + uploadChunks: [][]byte{[]byte("test")}, + wantFile: true, + wantChunks: [][]byte{[]byte("test")}, wantResponseStatus: pb.UploadBootstrapperStatus_UPLOAD_BOOTSTRAPPER_SUCCESS, }, "recv fails": { - streamer: fakeStreamer{ - writeStreamErr: errors.New("recv error"), - }, + streamer: fakeStreamer{writeStreamErr: errors.New("recv error")}, wantResponseStatus: pb.UploadBootstrapperStatus_UPLOAD_BOOTSTRAPPER_UPLOAD_FAILED, wantErr: true, }, "starting bootstrapper fails": { - uploadChunks: [][]byte{ - []byte("test"), - }, - serviceManager: stubServiceManager{ - systemdActionErr: errors.New("starting bootstrapper error"), - }, - wantFile: true, - wantChunks: [][]byte{ - []byte("test"), - }, + uploadChunks: [][]byte{[]byte("test")}, + serviceManager: stubServiceManager{systemdActionErr: errors.New("starting bootstrapper error")}, + wantFile: true, + wantChunks: [][]byte{[]byte("test")}, wantResponseStatus: pb.UploadBootstrapperStatus_UPLOAD_BOOTSTRAPPER_START_FAILED, }, } @@ -126,23 +234,15 @@ func TestDownloadBootstrapper(t *testing.T) { wantChunks [][]byte }{ "download works": { - request: &pb.DownloadBootstrapperRequest{}, - streamer: fakeStreamer{ - readStreamChunks: [][]byte{ - []byte("test"), - }, - }, - wantErr: false, - wantChunks: [][]byte{ - []byte("test"), - }, + request: &pb.DownloadBootstrapperRequest{}, + streamer: fakeStreamer{readStreamChunks: [][]byte{[]byte("test")}}, + wantErr: false, + wantChunks: [][]byte{[]byte("test")}, }, "download fails": { - request: &pb.DownloadBootstrapperRequest{}, - streamer: fakeStreamer{ - readStreamErr: errors.New("read bootstrapper fails"), - }, - wantErr: true, + request: &pb.DownloadBootstrapperRequest{}, + streamer: fakeStreamer{readStreamErr: errors.New("read bootstrapper fails")}, + wantErr: true, }, } diff --git a/debugd/service/debugd.pb.go b/debugd/service/debugd.pb.go index 0adb49d0d..65a6d0eb9 100644 --- a/debugd/service/debugd.pb.go +++ b/debugd/service/debugd.pb.go @@ -118,6 +118,231 @@ func (UploadSystemdServiceUnitsStatus) EnumDescriptor() ([]byte, []int) { return file_debugd_proto_rawDescGZIP(), []int{1} } +type SetInfoRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Info []*Info `protobuf:"bytes,1,rep,name=info,proto3" json:"info,omitempty"` +} + +func (x *SetInfoRequest) Reset() { + *x = SetInfoRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_debugd_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SetInfoRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SetInfoRequest) ProtoMessage() {} + +func (x *SetInfoRequest) ProtoReflect() protoreflect.Message { + mi := &file_debugd_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SetInfoRequest.ProtoReflect.Descriptor instead. +func (*SetInfoRequest) Descriptor() ([]byte, []int) { + return file_debugd_proto_rawDescGZIP(), []int{0} +} + +func (x *SetInfoRequest) GetInfo() []*Info { + if x != nil { + return x.Info + } + return nil +} + +type SetInfoResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *SetInfoResponse) Reset() { + *x = SetInfoResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_debugd_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SetInfoResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SetInfoResponse) ProtoMessage() {} + +func (x *SetInfoResponse) ProtoReflect() protoreflect.Message { + mi := &file_debugd_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SetInfoResponse.ProtoReflect.Descriptor instead. +func (*SetInfoResponse) Descriptor() ([]byte, []int) { + return file_debugd_proto_rawDescGZIP(), []int{1} +} + +type GetInfoRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *GetInfoRequest) Reset() { + *x = GetInfoRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_debugd_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetInfoRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetInfoRequest) ProtoMessage() {} + +func (x *GetInfoRequest) ProtoReflect() protoreflect.Message { + mi := &file_debugd_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetInfoRequest.ProtoReflect.Descriptor instead. +func (*GetInfoRequest) Descriptor() ([]byte, []int) { + return file_debugd_proto_rawDescGZIP(), []int{2} +} + +type GetInfoResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Info []*Info `protobuf:"bytes,1,rep,name=info,proto3" json:"info,omitempty"` +} + +func (x *GetInfoResponse) Reset() { + *x = GetInfoResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_debugd_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetInfoResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetInfoResponse) ProtoMessage() {} + +func (x *GetInfoResponse) ProtoReflect() protoreflect.Message { + mi := &file_debugd_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetInfoResponse.ProtoReflect.Descriptor instead. +func (*GetInfoResponse) Descriptor() ([]byte, []int) { + return file_debugd_proto_rawDescGZIP(), []int{3} +} + +func (x *GetInfoResponse) GetInfo() []*Info { + if x != nil { + return x.Info + } + return nil +} + +type Info struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + Value string `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` +} + +func (x *Info) Reset() { + *x = Info{} + if protoimpl.UnsafeEnabled { + mi := &file_debugd_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Info) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Info) ProtoMessage() {} + +func (x *Info) ProtoReflect() protoreflect.Message { + mi := &file_debugd_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Info.ProtoReflect.Descriptor instead. +func (*Info) Descriptor() ([]byte, []int) { + return file_debugd_proto_rawDescGZIP(), []int{4} +} + +func (x *Info) GetKey() string { + if x != nil { + return x.Key + } + return "" +} + +func (x *Info) GetValue() string { + if x != nil { + return x.Value + } + return "" +} + type DownloadBootstrapperRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -127,7 +352,7 @@ type DownloadBootstrapperRequest struct { func (x *DownloadBootstrapperRequest) Reset() { *x = DownloadBootstrapperRequest{} if protoimpl.UnsafeEnabled { - mi := &file_debugd_proto_msgTypes[0] + mi := &file_debugd_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -140,7 +365,7 @@ func (x *DownloadBootstrapperRequest) String() string { func (*DownloadBootstrapperRequest) ProtoMessage() {} func (x *DownloadBootstrapperRequest) ProtoReflect() protoreflect.Message { - mi := &file_debugd_proto_msgTypes[0] + mi := &file_debugd_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -153,7 +378,7 @@ func (x *DownloadBootstrapperRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DownloadBootstrapperRequest.ProtoReflect.Descriptor instead. func (*DownloadBootstrapperRequest) Descriptor() ([]byte, []int) { - return file_debugd_proto_rawDescGZIP(), []int{0} + return file_debugd_proto_rawDescGZIP(), []int{5} } type Chunk struct { @@ -167,7 +392,7 @@ type Chunk struct { func (x *Chunk) Reset() { *x = Chunk{} if protoimpl.UnsafeEnabled { - mi := &file_debugd_proto_msgTypes[1] + mi := &file_debugd_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -180,7 +405,7 @@ func (x *Chunk) String() string { func (*Chunk) ProtoMessage() {} func (x *Chunk) ProtoReflect() protoreflect.Message { - mi := &file_debugd_proto_msgTypes[1] + mi := &file_debugd_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -193,7 +418,7 @@ func (x *Chunk) ProtoReflect() protoreflect.Message { // Deprecated: Use Chunk.ProtoReflect.Descriptor instead. func (*Chunk) Descriptor() ([]byte, []int) { - return file_debugd_proto_rawDescGZIP(), []int{1} + return file_debugd_proto_rawDescGZIP(), []int{6} } func (x *Chunk) GetContent() []byte { @@ -214,7 +439,7 @@ type UploadBootstrapperResponse struct { func (x *UploadBootstrapperResponse) Reset() { *x = UploadBootstrapperResponse{} if protoimpl.UnsafeEnabled { - mi := &file_debugd_proto_msgTypes[2] + mi := &file_debugd_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -227,7 +452,7 @@ func (x *UploadBootstrapperResponse) String() string { func (*UploadBootstrapperResponse) ProtoMessage() {} func (x *UploadBootstrapperResponse) ProtoReflect() protoreflect.Message { - mi := &file_debugd_proto_msgTypes[2] + mi := &file_debugd_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -240,7 +465,7 @@ func (x *UploadBootstrapperResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use UploadBootstrapperResponse.ProtoReflect.Descriptor instead. func (*UploadBootstrapperResponse) Descriptor() ([]byte, []int) { - return file_debugd_proto_rawDescGZIP(), []int{2} + return file_debugd_proto_rawDescGZIP(), []int{7} } func (x *UploadBootstrapperResponse) GetStatus() UploadBootstrapperStatus { @@ -262,7 +487,7 @@ type ServiceUnit struct { func (x *ServiceUnit) Reset() { *x = ServiceUnit{} if protoimpl.UnsafeEnabled { - mi := &file_debugd_proto_msgTypes[3] + mi := &file_debugd_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -275,7 +500,7 @@ func (x *ServiceUnit) String() string { func (*ServiceUnit) ProtoMessage() {} func (x *ServiceUnit) ProtoReflect() protoreflect.Message { - mi := &file_debugd_proto_msgTypes[3] + mi := &file_debugd_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -288,7 +513,7 @@ func (x *ServiceUnit) ProtoReflect() protoreflect.Message { // Deprecated: Use ServiceUnit.ProtoReflect.Descriptor instead. func (*ServiceUnit) Descriptor() ([]byte, []int) { - return file_debugd_proto_rawDescGZIP(), []int{3} + return file_debugd_proto_rawDescGZIP(), []int{8} } func (x *ServiceUnit) GetName() string { @@ -316,7 +541,7 @@ type UploadSystemdServiceUnitsRequest struct { func (x *UploadSystemdServiceUnitsRequest) Reset() { *x = UploadSystemdServiceUnitsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_debugd_proto_msgTypes[4] + mi := &file_debugd_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -329,7 +554,7 @@ func (x *UploadSystemdServiceUnitsRequest) String() string { func (*UploadSystemdServiceUnitsRequest) ProtoMessage() {} func (x *UploadSystemdServiceUnitsRequest) ProtoReflect() protoreflect.Message { - mi := &file_debugd_proto_msgTypes[4] + mi := &file_debugd_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -342,7 +567,7 @@ func (x *UploadSystemdServiceUnitsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UploadSystemdServiceUnitsRequest.ProtoReflect.Descriptor instead. func (*UploadSystemdServiceUnitsRequest) Descriptor() ([]byte, []int) { - return file_debugd_proto_rawDescGZIP(), []int{4} + return file_debugd_proto_rawDescGZIP(), []int{9} } func (x *UploadSystemdServiceUnitsRequest) GetUnits() []*ServiceUnit { @@ -363,7 +588,7 @@ type UploadSystemdServiceUnitsResponse struct { func (x *UploadSystemdServiceUnitsResponse) Reset() { *x = UploadSystemdServiceUnitsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_debugd_proto_msgTypes[5] + mi := &file_debugd_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -376,7 +601,7 @@ func (x *UploadSystemdServiceUnitsResponse) String() string { func (*UploadSystemdServiceUnitsResponse) ProtoMessage() {} func (x *UploadSystemdServiceUnitsResponse) ProtoReflect() protoreflect.Message { - mi := &file_debugd_proto_msgTypes[5] + mi := &file_debugd_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -389,7 +614,7 @@ func (x *UploadSystemdServiceUnitsResponse) ProtoReflect() protoreflect.Message // Deprecated: Use UploadSystemdServiceUnitsResponse.ProtoReflect.Descriptor instead. func (*UploadSystemdServiceUnitsResponse) Descriptor() ([]byte, []int) { - return file_debugd_proto_rawDescGZIP(), []int{5} + return file_debugd_proto_rawDescGZIP(), []int{10} } func (x *UploadSystemdServiceUnitsResponse) GetStatus() UploadSystemdServiceUnitsStatus { @@ -403,72 +628,92 @@ var File_debugd_proto protoreflect.FileDescriptor var file_debugd_proto_rawDesc = []byte{ 0x0a, 0x0c, 0x64, 0x65, 0x62, 0x75, 0x67, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06, - 0x64, 0x65, 0x62, 0x75, 0x67, 0x64, 0x22, 0x1d, 0x0a, 0x1b, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, - 0x61, 0x64, 0x42, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x21, 0x0a, 0x05, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x12, 0x18, - 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x22, 0x56, 0x0a, 0x1a, 0x55, 0x70, 0x6c, 0x6f, - 0x61, 0x64, 0x42, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x38, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x20, 0x2e, 0x64, 0x65, 0x62, 0x75, 0x67, 0x64, 0x2e, - 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x42, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x70, - 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x22, 0x3d, 0x0a, 0x0b, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x6e, 0x69, 0x74, 0x12, - 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x22, - 0x4d, 0x0a, 0x20, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x64, - 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x6e, 0x69, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x29, 0x0a, 0x05, 0x75, 0x6e, 0x69, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x64, 0x65, 0x62, 0x75, 0x67, 0x64, 0x2e, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x55, 0x6e, 0x69, 0x74, 0x52, 0x05, 0x75, 0x6e, 0x69, 0x74, 0x73, 0x22, 0x64, - 0x0a, 0x21, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x64, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x6e, 0x69, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x3f, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0e, 0x32, 0x27, 0x2e, 0x64, 0x65, 0x62, 0x75, 0x67, 0x64, 0x2e, 0x55, 0x70, 0x6c, - 0x6f, 0x61, 0x64, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x55, 0x6e, 0x69, 0x74, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x2a, 0xad, 0x01, 0x0a, 0x18, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x42, - 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x12, 0x1f, 0x0a, 0x1b, 0x55, 0x50, 0x4c, 0x4f, 0x41, 0x44, 0x5f, 0x42, 0x4f, 0x4f, 0x54, - 0x53, 0x54, 0x52, 0x41, 0x50, 0x50, 0x45, 0x52, 0x5f, 0x53, 0x55, 0x43, 0x43, 0x45, 0x53, 0x53, - 0x10, 0x00, 0x12, 0x25, 0x0a, 0x21, 0x55, 0x50, 0x4c, 0x4f, 0x41, 0x44, 0x5f, 0x42, 0x4f, 0x4f, - 0x54, 0x53, 0x54, 0x52, 0x41, 0x50, 0x50, 0x45, 0x52, 0x5f, 0x55, 0x50, 0x4c, 0x4f, 0x41, 0x44, - 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x01, 0x12, 0x24, 0x0a, 0x20, 0x55, 0x50, 0x4c, - 0x4f, 0x41, 0x44, 0x5f, 0x42, 0x4f, 0x4f, 0x54, 0x53, 0x54, 0x52, 0x41, 0x50, 0x50, 0x45, 0x52, - 0x5f, 0x53, 0x54, 0x41, 0x52, 0x54, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x02, 0x12, - 0x23, 0x0a, 0x1f, 0x55, 0x50, 0x4c, 0x4f, 0x41, 0x44, 0x5f, 0x42, 0x4f, 0x4f, 0x54, 0x53, 0x54, - 0x52, 0x41, 0x50, 0x50, 0x45, 0x52, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x5f, 0x45, 0x58, 0x49, 0x53, - 0x54, 0x53, 0x10, 0x03, 0x2a, 0x75, 0x0a, 0x1f, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x79, - 0x73, 0x74, 0x65, 0x6d, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x6e, 0x69, 0x74, - 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x28, 0x0a, 0x24, 0x55, 0x50, 0x4c, 0x4f, 0x41, - 0x44, 0x5f, 0x53, 0x59, 0x53, 0x54, 0x45, 0x4d, 0x44, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x49, 0x43, - 0x45, 0x5f, 0x55, 0x4e, 0x49, 0x54, 0x53, 0x5f, 0x53, 0x55, 0x43, 0x43, 0x45, 0x53, 0x53, 0x10, - 0x00, 0x12, 0x28, 0x0a, 0x24, 0x55, 0x50, 0x4c, 0x4f, 0x41, 0x44, 0x5f, 0x53, 0x59, 0x53, 0x54, - 0x45, 0x4d, 0x44, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x55, 0x4e, 0x49, 0x54, - 0x53, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x10, 0x01, 0x32, 0x98, 0x02, 0x0a, 0x06, - 0x44, 0x65, 0x62, 0x75, 0x67, 0x64, 0x12, 0x4b, 0x0a, 0x12, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, - 0x42, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x12, 0x0d, 0x2e, 0x64, - 0x65, 0x62, 0x75, 0x67, 0x64, 0x2e, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x1a, 0x22, 0x2e, 0x64, 0x65, - 0x62, 0x75, 0x67, 0x64, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x42, 0x6f, 0x6f, 0x74, 0x73, - 0x74, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x00, 0x28, 0x01, 0x12, 0x4e, 0x0a, 0x14, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x42, - 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x12, 0x23, 0x2e, 0x64, 0x65, - 0x62, 0x75, 0x67, 0x64, 0x2e, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x42, 0x6f, 0x6f, - 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x0d, 0x2e, 0x64, 0x65, 0x62, 0x75, 0x67, 0x64, 0x2e, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x22, - 0x00, 0x30, 0x01, 0x12, 0x71, 0x0a, 0x18, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x79, 0x73, - 0x74, 0x65, 0x6d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x6e, 0x69, 0x74, 0x73, 0x12, - 0x28, 0x2e, 0x64, 0x65, 0x62, 0x75, 0x67, 0x64, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x53, - 0x79, 0x73, 0x74, 0x65, 0x6d, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x6e, 0x69, - 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x64, 0x65, 0x62, 0x75, + 0x64, 0x65, 0x62, 0x75, 0x67, 0x64, 0x22, 0x32, 0x0a, 0x0e, 0x53, 0x65, 0x74, 0x49, 0x6e, 0x66, + 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x04, 0x69, 0x6e, 0x66, 0x6f, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x64, 0x65, 0x62, 0x75, 0x67, 0x64, 0x2e, + 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x22, 0x11, 0x0a, 0x0f, 0x53, 0x65, + 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x10, 0x0a, + 0x0e, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, + 0x33, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x20, 0x0a, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x0c, 0x2e, 0x64, 0x65, 0x62, 0x75, 0x67, 0x64, 0x2e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x04, + 0x69, 0x6e, 0x66, 0x6f, 0x22, 0x2e, 0x0a, 0x04, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x10, 0x0a, 0x03, + 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, + 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x22, 0x1d, 0x0a, 0x1b, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, + 0x42, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x22, 0x21, 0x0a, 0x05, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x12, 0x18, 0x0a, 0x07, + 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, + 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x22, 0x56, 0x0a, 0x1a, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, + 0x42, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x38, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x20, 0x2e, 0x64, 0x65, 0x62, 0x75, 0x67, 0x64, 0x2e, 0x55, 0x70, + 0x6c, 0x6f, 0x61, 0x64, 0x42, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x3d, + 0x0a, 0x0b, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x6e, 0x69, 0x74, 0x12, 0x12, 0x0a, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x4d, 0x0a, + 0x20, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x64, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x6e, 0x69, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x29, 0x0a, 0x05, 0x75, 0x6e, 0x69, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x13, 0x2e, 0x64, 0x65, 0x62, 0x75, 0x67, 0x64, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x55, 0x6e, 0x69, 0x74, 0x52, 0x05, 0x75, 0x6e, 0x69, 0x74, 0x73, 0x22, 0x64, 0x0a, 0x21, + 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x64, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x55, 0x6e, 0x69, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x3f, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x27, 0x2e, 0x64, 0x65, 0x62, 0x75, 0x67, 0x64, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, + 0x64, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, + 0x6e, 0x69, 0x74, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x2a, 0xad, 0x01, 0x0a, 0x18, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x42, 0x6f, 0x6f, + 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, + 0x1f, 0x0a, 0x1b, 0x55, 0x50, 0x4c, 0x4f, 0x41, 0x44, 0x5f, 0x42, 0x4f, 0x4f, 0x54, 0x53, 0x54, + 0x52, 0x41, 0x50, 0x50, 0x45, 0x52, 0x5f, 0x53, 0x55, 0x43, 0x43, 0x45, 0x53, 0x53, 0x10, 0x00, + 0x12, 0x25, 0x0a, 0x21, 0x55, 0x50, 0x4c, 0x4f, 0x41, 0x44, 0x5f, 0x42, 0x4f, 0x4f, 0x54, 0x53, + 0x54, 0x52, 0x41, 0x50, 0x50, 0x45, 0x52, 0x5f, 0x55, 0x50, 0x4c, 0x4f, 0x41, 0x44, 0x5f, 0x46, + 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x01, 0x12, 0x24, 0x0a, 0x20, 0x55, 0x50, 0x4c, 0x4f, 0x41, + 0x44, 0x5f, 0x42, 0x4f, 0x4f, 0x54, 0x53, 0x54, 0x52, 0x41, 0x50, 0x50, 0x45, 0x52, 0x5f, 0x53, + 0x54, 0x41, 0x52, 0x54, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x02, 0x12, 0x23, 0x0a, + 0x1f, 0x55, 0x50, 0x4c, 0x4f, 0x41, 0x44, 0x5f, 0x42, 0x4f, 0x4f, 0x54, 0x53, 0x54, 0x52, 0x41, + 0x50, 0x50, 0x45, 0x52, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x5f, 0x45, 0x58, 0x49, 0x53, 0x54, 0x53, + 0x10, 0x03, 0x2a, 0x75, 0x0a, 0x1f, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x79, 0x73, 0x74, + 0x65, 0x6d, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x6e, 0x69, 0x74, 0x73, 0x53, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x28, 0x0a, 0x24, 0x55, 0x50, 0x4c, 0x4f, 0x41, 0x44, 0x5f, + 0x53, 0x59, 0x53, 0x54, 0x45, 0x4d, 0x44, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x49, 0x43, 0x45, 0x5f, + 0x55, 0x4e, 0x49, 0x54, 0x53, 0x5f, 0x53, 0x55, 0x43, 0x43, 0x45, 0x53, 0x53, 0x10, 0x00, 0x12, + 0x28, 0x0a, 0x24, 0x55, 0x50, 0x4c, 0x4f, 0x41, 0x44, 0x5f, 0x53, 0x59, 0x53, 0x54, 0x45, 0x4d, + 0x44, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x55, 0x4e, 0x49, 0x54, 0x53, 0x5f, + 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x10, 0x01, 0x32, 0x94, 0x03, 0x0a, 0x06, 0x44, 0x65, + 0x62, 0x75, 0x67, 0x64, 0x12, 0x3c, 0x0a, 0x07, 0x53, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, + 0x16, 0x2e, 0x64, 0x65, 0x62, 0x75, 0x67, 0x64, 0x2e, 0x53, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x64, 0x65, 0x62, 0x75, 0x67, 0x64, + 0x2e, 0x53, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x00, 0x12, 0x3c, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x16, 0x2e, + 0x64, 0x65, 0x62, 0x75, 0x67, 0x64, 0x2e, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x64, 0x65, 0x62, 0x75, 0x67, 0x64, 0x2e, 0x47, + 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, + 0x12, 0x4b, 0x0a, 0x12, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x42, 0x6f, 0x6f, 0x74, 0x73, 0x74, + 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x12, 0x0d, 0x2e, 0x64, 0x65, 0x62, 0x75, 0x67, 0x64, 0x2e, + 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x1a, 0x22, 0x2e, 0x64, 0x65, 0x62, 0x75, 0x67, 0x64, 0x2e, 0x55, + 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x42, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x70, 0x65, + 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x28, 0x01, 0x12, 0x4e, 0x0a, + 0x14, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x42, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, + 0x61, 0x70, 0x70, 0x65, 0x72, 0x12, 0x23, 0x2e, 0x64, 0x65, 0x62, 0x75, 0x67, 0x64, 0x2e, 0x44, + 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x42, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, + 0x70, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0d, 0x2e, 0x64, 0x65, 0x62, + 0x75, 0x67, 0x64, 0x2e, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x22, 0x00, 0x30, 0x01, 0x12, 0x71, 0x0a, + 0x18, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x55, 0x6e, 0x69, 0x74, 0x73, 0x12, 0x28, 0x2e, 0x64, 0x65, 0x62, 0x75, 0x67, 0x64, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x64, - 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x6e, 0x69, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x38, 0x5a, 0x36, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x65, 0x64, 0x67, 0x65, 0x6c, 0x65, 0x73, 0x73, 0x73, 0x79, 0x73, - 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x65, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x76, - 0x32, 0x2f, 0x64, 0x65, 0x62, 0x75, 0x67, 0x64, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x6e, 0x69, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x64, 0x65, 0x62, 0x75, 0x67, 0x64, 0x2e, 0x55, 0x70, 0x6c, + 0x6f, 0x61, 0x64, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x55, 0x6e, 0x69, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, + 0x42, 0x38, 0x5a, 0x36, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x65, + 0x64, 0x67, 0x65, 0x6c, 0x65, 0x73, 0x73, 0x73, 0x79, 0x73, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x74, + 0x65, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x32, 0x2f, 0x64, 0x65, 0x62, 0x75, + 0x67, 0x64, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, } var ( @@ -484,32 +729,43 @@ func file_debugd_proto_rawDescGZIP() []byte { } var file_debugd_proto_enumTypes = make([]protoimpl.EnumInfo, 2) -var file_debugd_proto_msgTypes = make([]protoimpl.MessageInfo, 6) +var file_debugd_proto_msgTypes = make([]protoimpl.MessageInfo, 11) var file_debugd_proto_goTypes = []interface{}{ (UploadBootstrapperStatus)(0), // 0: debugd.UploadBootstrapperStatus (UploadSystemdServiceUnitsStatus)(0), // 1: debugd.UploadSystemdServiceUnitsStatus - (*DownloadBootstrapperRequest)(nil), // 2: debugd.DownloadBootstrapperRequest - (*Chunk)(nil), // 3: debugd.Chunk - (*UploadBootstrapperResponse)(nil), // 4: debugd.UploadBootstrapperResponse - (*ServiceUnit)(nil), // 5: debugd.ServiceUnit - (*UploadSystemdServiceUnitsRequest)(nil), // 6: debugd.UploadSystemdServiceUnitsRequest - (*UploadSystemdServiceUnitsResponse)(nil), // 7: debugd.UploadSystemdServiceUnitsResponse + (*SetInfoRequest)(nil), // 2: debugd.SetInfoRequest + (*SetInfoResponse)(nil), // 3: debugd.SetInfoResponse + (*GetInfoRequest)(nil), // 4: debugd.GetInfoRequest + (*GetInfoResponse)(nil), // 5: debugd.GetInfoResponse + (*Info)(nil), // 6: debugd.Info + (*DownloadBootstrapperRequest)(nil), // 7: debugd.DownloadBootstrapperRequest + (*Chunk)(nil), // 8: debugd.Chunk + (*UploadBootstrapperResponse)(nil), // 9: debugd.UploadBootstrapperResponse + (*ServiceUnit)(nil), // 10: debugd.ServiceUnit + (*UploadSystemdServiceUnitsRequest)(nil), // 11: debugd.UploadSystemdServiceUnitsRequest + (*UploadSystemdServiceUnitsResponse)(nil), // 12: debugd.UploadSystemdServiceUnitsResponse } var file_debugd_proto_depIdxs = []int32{ - 0, // 0: debugd.UploadBootstrapperResponse.status:type_name -> debugd.UploadBootstrapperStatus - 5, // 1: debugd.UploadSystemdServiceUnitsRequest.units:type_name -> debugd.ServiceUnit - 1, // 2: debugd.UploadSystemdServiceUnitsResponse.status:type_name -> debugd.UploadSystemdServiceUnitsStatus - 3, // 3: debugd.Debugd.UploadBootstrapper:input_type -> debugd.Chunk - 2, // 4: debugd.Debugd.DownloadBootstrapper:input_type -> debugd.DownloadBootstrapperRequest - 6, // 5: debugd.Debugd.UploadSystemServiceUnits:input_type -> debugd.UploadSystemdServiceUnitsRequest - 4, // 6: debugd.Debugd.UploadBootstrapper:output_type -> debugd.UploadBootstrapperResponse - 3, // 7: debugd.Debugd.DownloadBootstrapper:output_type -> debugd.Chunk - 7, // 8: debugd.Debugd.UploadSystemServiceUnits:output_type -> debugd.UploadSystemdServiceUnitsResponse - 6, // [6:9] is the sub-list for method output_type - 3, // [3:6] is the sub-list for method input_type - 3, // [3:3] is the sub-list for extension type_name - 3, // [3:3] is the sub-list for extension extendee - 0, // [0:3] is the sub-list for field type_name + 6, // 0: debugd.SetInfoRequest.info:type_name -> debugd.Info + 6, // 1: debugd.GetInfoResponse.info:type_name -> debugd.Info + 0, // 2: debugd.UploadBootstrapperResponse.status:type_name -> debugd.UploadBootstrapperStatus + 10, // 3: debugd.UploadSystemdServiceUnitsRequest.units:type_name -> debugd.ServiceUnit + 1, // 4: debugd.UploadSystemdServiceUnitsResponse.status:type_name -> debugd.UploadSystemdServiceUnitsStatus + 2, // 5: debugd.Debugd.SetInfo:input_type -> debugd.SetInfoRequest + 4, // 6: debugd.Debugd.GetInfo:input_type -> debugd.GetInfoRequest + 8, // 7: debugd.Debugd.UploadBootstrapper:input_type -> debugd.Chunk + 7, // 8: debugd.Debugd.DownloadBootstrapper:input_type -> debugd.DownloadBootstrapperRequest + 11, // 9: debugd.Debugd.UploadSystemServiceUnits:input_type -> debugd.UploadSystemdServiceUnitsRequest + 3, // 10: debugd.Debugd.SetInfo:output_type -> debugd.SetInfoResponse + 5, // 11: debugd.Debugd.GetInfo:output_type -> debugd.GetInfoResponse + 9, // 12: debugd.Debugd.UploadBootstrapper:output_type -> debugd.UploadBootstrapperResponse + 8, // 13: debugd.Debugd.DownloadBootstrapper:output_type -> debugd.Chunk + 12, // 14: debugd.Debugd.UploadSystemServiceUnits:output_type -> debugd.UploadSystemdServiceUnitsResponse + 10, // [10:15] is the sub-list for method output_type + 5, // [5:10] is the sub-list for method input_type + 5, // [5:5] is the sub-list for extension type_name + 5, // [5:5] is the sub-list for extension extendee + 0, // [0:5] is the sub-list for field type_name } func init() { file_debugd_proto_init() } @@ -519,7 +775,7 @@ func file_debugd_proto_init() { } if !protoimpl.UnsafeEnabled { file_debugd_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DownloadBootstrapperRequest); i { + switch v := v.(*SetInfoRequest); i { case 0: return &v.state case 1: @@ -531,7 +787,7 @@ func file_debugd_proto_init() { } } file_debugd_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Chunk); i { + switch v := v.(*SetInfoResponse); i { case 0: return &v.state case 1: @@ -543,7 +799,7 @@ func file_debugd_proto_init() { } } file_debugd_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UploadBootstrapperResponse); i { + switch v := v.(*GetInfoRequest); i { case 0: return &v.state case 1: @@ -555,7 +811,7 @@ func file_debugd_proto_init() { } } file_debugd_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ServiceUnit); i { + switch v := v.(*GetInfoResponse); i { case 0: return &v.state case 1: @@ -567,7 +823,7 @@ func file_debugd_proto_init() { } } file_debugd_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UploadSystemdServiceUnitsRequest); i { + switch v := v.(*Info); i { case 0: return &v.state case 1: @@ -579,6 +835,66 @@ func file_debugd_proto_init() { } } file_debugd_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DownloadBootstrapperRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_debugd_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Chunk); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_debugd_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UploadBootstrapperResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_debugd_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ServiceUnit); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_debugd_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UploadSystemdServiceUnitsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_debugd_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*UploadSystemdServiceUnitsResponse); i { case 0: return &v.state @@ -597,7 +913,7 @@ func file_debugd_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_debugd_proto_rawDesc, NumEnums: 2, - NumMessages: 6, + NumMessages: 11, NumExtensions: 0, NumServices: 1, }, diff --git a/debugd/service/debugd.proto b/debugd/service/debugd.proto index 7df02c628..f8ec1fbfc 100644 --- a/debugd/service/debugd.proto +++ b/debugd/service/debugd.proto @@ -5,11 +5,31 @@ option go_package = "github.com/edgelesssys/constellation/v2/debugd/service"; package debugd; service Debugd { + rpc SetInfo (SetInfoRequest) returns (SetInfoResponse) {} + rpc GetInfo (GetInfoRequest) returns (GetInfoResponse) {} rpc UploadBootstrapper(stream Chunk) returns (UploadBootstrapperResponse) {} rpc DownloadBootstrapper(DownloadBootstrapperRequest) returns (stream Chunk) {} rpc UploadSystemServiceUnits(UploadSystemdServiceUnitsRequest) returns (UploadSystemdServiceUnitsResponse) {} } +message SetInfoRequest { + repeated Info info = 1; +} + +message SetInfoResponse {} + +message GetInfoRequest {} + +message GetInfoResponse { + repeated Info info = 1; +} + +message Info { + string key = 1; + string value = 2; +} + + message DownloadBootstrapperRequest {} message Chunk { diff --git a/debugd/service/debugd_grpc.pb.go b/debugd/service/debugd_grpc.pb.go index 935e35407..825406eae 100644 --- a/debugd/service/debugd_grpc.pb.go +++ b/debugd/service/debugd_grpc.pb.go @@ -22,6 +22,8 @@ const _ = grpc.SupportPackageIsVersion7 // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. type DebugdClient interface { + SetInfo(ctx context.Context, in *SetInfoRequest, opts ...grpc.CallOption) (*SetInfoResponse, error) + GetInfo(ctx context.Context, in *GetInfoRequest, opts ...grpc.CallOption) (*GetInfoResponse, error) UploadBootstrapper(ctx context.Context, opts ...grpc.CallOption) (Debugd_UploadBootstrapperClient, error) DownloadBootstrapper(ctx context.Context, in *DownloadBootstrapperRequest, opts ...grpc.CallOption) (Debugd_DownloadBootstrapperClient, error) UploadSystemServiceUnits(ctx context.Context, in *UploadSystemdServiceUnitsRequest, opts ...grpc.CallOption) (*UploadSystemdServiceUnitsResponse, error) @@ -35,6 +37,24 @@ func NewDebugdClient(cc grpc.ClientConnInterface) DebugdClient { return &debugdClient{cc} } +func (c *debugdClient) SetInfo(ctx context.Context, in *SetInfoRequest, opts ...grpc.CallOption) (*SetInfoResponse, error) { + out := new(SetInfoResponse) + err := c.cc.Invoke(ctx, "/debugd.Debugd/SetInfo", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *debugdClient) GetInfo(ctx context.Context, in *GetInfoRequest, opts ...grpc.CallOption) (*GetInfoResponse, error) { + out := new(GetInfoResponse) + err := c.cc.Invoke(ctx, "/debugd.Debugd/GetInfo", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *debugdClient) UploadBootstrapper(ctx context.Context, opts ...grpc.CallOption) (Debugd_UploadBootstrapperClient, error) { stream, err := c.cc.NewStream(ctx, &Debugd_ServiceDesc.Streams[0], "/debugd.Debugd/UploadBootstrapper", opts...) if err != nil { @@ -114,6 +134,8 @@ func (c *debugdClient) UploadSystemServiceUnits(ctx context.Context, in *UploadS // All implementations must embed UnimplementedDebugdServer // for forward compatibility type DebugdServer interface { + SetInfo(context.Context, *SetInfoRequest) (*SetInfoResponse, error) + GetInfo(context.Context, *GetInfoRequest) (*GetInfoResponse, error) UploadBootstrapper(Debugd_UploadBootstrapperServer) error DownloadBootstrapper(*DownloadBootstrapperRequest, Debugd_DownloadBootstrapperServer) error UploadSystemServiceUnits(context.Context, *UploadSystemdServiceUnitsRequest) (*UploadSystemdServiceUnitsResponse, error) @@ -124,6 +146,12 @@ type DebugdServer interface { type UnimplementedDebugdServer struct { } +func (UnimplementedDebugdServer) SetInfo(context.Context, *SetInfoRequest) (*SetInfoResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method SetInfo not implemented") +} +func (UnimplementedDebugdServer) GetInfo(context.Context, *GetInfoRequest) (*GetInfoResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetInfo not implemented") +} func (UnimplementedDebugdServer) UploadBootstrapper(Debugd_UploadBootstrapperServer) error { return status.Errorf(codes.Unimplemented, "method UploadBootstrapper not implemented") } @@ -146,6 +174,42 @@ func RegisterDebugdServer(s grpc.ServiceRegistrar, srv DebugdServer) { s.RegisterService(&Debugd_ServiceDesc, srv) } +func _Debugd_SetInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SetInfoRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DebugdServer).SetInfo(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/debugd.Debugd/SetInfo", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DebugdServer).SetInfo(ctx, req.(*SetInfoRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Debugd_GetInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetInfoRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DebugdServer).GetInfo(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/debugd.Debugd/GetInfo", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DebugdServer).GetInfo(ctx, req.(*GetInfoRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _Debugd_UploadBootstrapper_Handler(srv interface{}, stream grpc.ServerStream) error { return srv.(DebugdServer).UploadBootstrapper(&debugdUploadBootstrapperServer{stream}) } @@ -218,6 +282,14 @@ var Debugd_ServiceDesc = grpc.ServiceDesc{ ServiceName: "debugd.Debugd", HandlerType: (*DebugdServer)(nil), Methods: []grpc.MethodDesc{ + { + MethodName: "SetInfo", + Handler: _Debugd_SetInfo_Handler, + }, + { + MethodName: "GetInfo", + Handler: _Debugd_GetInfo_Handler, + }, { MethodName: "UploadSystemServiceUnits", Handler: _Debugd_UploadSystemServiceUnits_Handler,